1############################################
2# Copyright (c) 2012 Microsoft Corporation
3#
4# Z3 Python interface
5#
6# Author: Leonardo de Moura (leonardo)
7############################################
8
9"""Z3 is a high performance theorem prover developed at Microsoft Research.
10
11Z3 is used in many applications such as: software/hardware verification and testing,
12constraint solving, analysis of hybrid systems, security, biology (in silico analysis),
13and geometrical problems.
14
15Several online tutorials for Z3Py are available at:
16http://rise4fun.com/Z3Py/tutorial/guide
17
18Please send feedback, comments and/or corrections on the Issue tracker for
19https://github.com/Z3prover/z3.git. Your comments are very valuable.
20
21Small example:
22
23>>> x = Int('x')
24>>> y = Int('y')
25>>> s = Solver()
26>>> s.add(x > 0)
27>>> s.add(x < 2)
28>>> s.add(y == x + 1)
29>>> s.check()
30sat
31>>> m = s.model()
32>>> m[x]
331
34>>> m[y]
352
36
37Z3 exceptions:
38
39>>> try:
40...   x = BitVec('x', 32)
41...   y = Bool('y')
42...   # the expression x + y is type incorrect
43...   n = x + y
44... except Z3Exception as ex:
45...   print("failed: %s" % ex)
46failed: sort mismatch
47"""
48from . import z3core
49from .z3core import *
50from .z3types import *
51from .z3consts import *
52from .z3printer import *
53from fractions import Fraction
54import sys
55import io
56import math
57import copy
58if sys.version_info.major >= 3:
59    from typing import Iterable
60
61Z3_DEBUG = __debug__
62
63
64def z3_debug():
65    global Z3_DEBUG
66    return Z3_DEBUG
67
68
69if sys.version_info.major < 3:
70    def _is_int(v):
71        return isinstance(v, (int, long))
72else:
73    def _is_int(v):
74        return isinstance(v, int)
75
76
77def enable_trace(msg):
78    Z3_enable_trace(msg)
79
80
81def disable_trace(msg):
82    Z3_disable_trace(msg)
83
84
85def get_version_string():
86    major = ctypes.c_uint(0)
87    minor = ctypes.c_uint(0)
88    build = ctypes.c_uint(0)
89    rev = ctypes.c_uint(0)
90    Z3_get_version(major, minor, build, rev)
91    return "%s.%s.%s" % (major.value, minor.value, build.value)
92
93
94def get_version():
95    major = ctypes.c_uint(0)
96    minor = ctypes.c_uint(0)
97    build = ctypes.c_uint(0)
98    rev = ctypes.c_uint(0)
99    Z3_get_version(major, minor, build, rev)
100    return (major.value, minor.value, build.value, rev.value)
101
102
103def get_full_version():
104    return Z3_get_full_version()
105
106# We use _z3_assert instead of the assert command because we want to
107# produce nice error messages in Z3Py at rise4fun.com
108
109
110def _z3_assert(cond, msg):
111    if not cond:
112        raise Z3Exception(msg)
113
114
115def _z3_check_cint_overflow(n, name):
116    _z3_assert(ctypes.c_int(n).value == n, name + " is too large")
117
118
119def open_log(fname):
120    """Log interaction to a file. This function must be invoked immediately after init(). """
121    Z3_open_log(fname)
122
123
124def append_log(s):
125    """Append user-defined string to interaction log. """
126    Z3_append_log(s)
127
128
129def to_symbol(s, ctx=None):
130    """Convert an integer or string into a Z3 symbol."""
131    if _is_int(s):
132        return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
133    else:
134        return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
135
136
137def _symbol2py(ctx, s):
138    """Convert a Z3 symbol back into a Python object. """
139    if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
140        return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
141    else:
142        return Z3_get_symbol_string(ctx.ref(), s)
143
144# Hack for having nary functions that can receive one argument that is the
145# list of arguments.
146# Use this when function takes a single list of arguments
147
148
149def _get_args(args):
150    try:
151        if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
152            return args[0]
153        elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)):
154            return [arg for arg in args[0]]
155        else:
156            return args
157    except TypeError:  # len is not necessarily defined when args is not a sequence (use reflection?)
158        return args
159
160# Use this when function takes multiple arguments
161
162
163def _get_args_ast_list(args):
164    try:
165        if isinstance(args, (set, AstVector, tuple)):
166            return [arg for arg in args]
167        else:
168            return args
169    except Exception:
170        return args
171
172
173def _to_param_value(val):
174    if isinstance(val, bool):
175        return "true" if val else "false"
176    return str(val)
177
178
179def z3_error_handler(c, e):
180    # Do nothing error handler, just avoid exit(0)
181    # The wrappers in z3core.py will raise a Z3Exception if an error is detected
182    return
183
184
185class Context:
186    """A Context manages all other Z3 objects, global configuration options, etc.
187
188    Z3Py uses a default global context. For most applications this is sufficient.
189    An application may use multiple Z3 contexts. Objects created in one context
190    cannot be used in another one. However, several objects may be "translated" from
191    one context to another. It is not safe to access Z3 objects from multiple threads.
192    The only exception is the method `interrupt()` that can be used to interrupt() a long
193    computation.
194    The initialization method receives global configuration options for the new context.
195    """
196
197    def __init__(self, *args, **kws):
198        if z3_debug():
199            _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
200        conf = Z3_mk_config()
201        for key in kws:
202            value = kws[key]
203            Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
204        prev = None
205        for a in args:
206            if prev is None:
207                prev = a
208            else:
209                Z3_set_param_value(conf, str(prev), _to_param_value(a))
210                prev = None
211        self.ctx = Z3_mk_context_rc(conf)
212        self.eh = Z3_set_error_handler(self.ctx, z3_error_handler)
213        Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
214        Z3_del_config(conf)
215
216    def __del__(self):
217        Z3_del_context(self.ctx)
218        self.ctx = None
219        self.eh = None
220
221    def ref(self):
222        """Return a reference to the actual C pointer to the Z3 context."""
223        return self.ctx
224
225    def interrupt(self):
226        """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
227
228        This method can be invoked from a thread different from the one executing the
229        interruptible procedure.
230        """
231        Z3_interrupt(self.ref())
232
233
234# Global Z3 context
235_main_ctx = None
236
237
238def main_ctx():
239    """Return a reference to the global Z3 context.
240
241    >>> x = Real('x')
242    >>> x.ctx == main_ctx()
243    True
244    >>> c = Context()
245    >>> c == main_ctx()
246    False
247    >>> x2 = Real('x', c)
248    >>> x2.ctx == c
249    True
250    >>> eq(x, x2)
251    False
252    """
253    global _main_ctx
254    if _main_ctx is None:
255        _main_ctx = Context()
256    return _main_ctx
257
258
259def _get_ctx(ctx):
260    if ctx is None:
261        return main_ctx()
262    else:
263        return ctx
264
265
266def get_ctx(ctx):
267    return _get_ctx(ctx)
268
269
270def set_param(*args, **kws):
271    """Set Z3 global (or module) parameters.
272
273    >>> set_param(precision=10)
274    """
275    if z3_debug():
276        _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
277    new_kws = {}
278    for k in kws:
279        v = kws[k]
280        if not set_pp_option(k, v):
281            new_kws[k] = v
282    for key in new_kws:
283        value = new_kws[key]
284        Z3_global_param_set(str(key).upper(), _to_param_value(value))
285    prev = None
286    for a in args:
287        if prev is None:
288            prev = a
289        else:
290            Z3_global_param_set(str(prev), _to_param_value(a))
291            prev = None
292
293
294def reset_params():
295    """Reset all global (or module) parameters.
296    """
297    Z3_global_param_reset_all()
298
299
300def set_option(*args, **kws):
301    """Alias for 'set_param' for backward compatibility.
302    """
303    return set_param(*args, **kws)
304
305
306def get_param(name):
307    """Return the value of a Z3 global (or module) parameter
308
309    >>> get_param('nlsat.reorder')
310    'true'
311    """
312    ptr = (ctypes.c_char_p * 1)()
313    if Z3_global_param_get(str(name), ptr):
314        r = z3core._to_pystr(ptr[0])
315        return r
316    raise Z3Exception("failed to retrieve value for '%s'" % name)
317
318#########################################
319#
320# ASTs base class
321#
322#########################################
323
324# Mark objects that use pretty printer
325
326
327class Z3PPObject:
328    """Superclass for all Z3 objects that have support for pretty printing."""
329
330    def use_pp(self):
331        return True
332
333    def _repr_html_(self):
334        in_html = in_html_mode()
335        set_html_mode(True)
336        res = repr(self)
337        set_html_mode(in_html)
338        return res
339
340
341class AstRef(Z3PPObject):
342    """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
343
344    def __init__(self, ast, ctx=None):
345        self.ast = ast
346        self.ctx = _get_ctx(ctx)
347        Z3_inc_ref(self.ctx.ref(), self.as_ast())
348
349    def __del__(self):
350        if self.ctx.ref() is not None and self.ast is not None:
351            Z3_dec_ref(self.ctx.ref(), self.as_ast())
352            self.ast = None
353
354    def __deepcopy__(self, memo={}):
355        return _to_ast_ref(self.ast, self.ctx)
356
357    def __str__(self):
358        return obj_to_string(self)
359
360    def __repr__(self):
361        return obj_to_string(self)
362
363    def __eq__(self, other):
364        return self.eq(other)
365
366    def __hash__(self):
367        return self.hash()
368
369    def __nonzero__(self):
370        return self.__bool__()
371
372    def __bool__(self):
373        if is_true(self):
374            return True
375        elif is_false(self):
376            return False
377        elif is_eq(self) and self.num_args() == 2:
378            return self.arg(0).eq(self.arg(1))
379        else:
380            raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
381
382    def sexpr(self):
383        """Return a string representing the AST node in s-expression notation.
384
385        >>> x = Int('x')
386        >>> ((x + 1)*x).sexpr()
387        '(* (+ x 1) x)'
388        """
389        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
390
391    def as_ast(self):
392        """Return a pointer to the corresponding C Z3_ast object."""
393        return self.ast
394
395    def get_id(self):
396        """Return unique identifier for object. It can be used for hash-tables and maps."""
397        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
398
399    def ctx_ref(self):
400        """Return a reference to the C context where this AST node is stored."""
401        return self.ctx.ref()
402
403    def eq(self, other):
404        """Return `True` if `self` and `other` are structurally identical.
405
406        >>> x = Int('x')
407        >>> n1 = x + 1
408        >>> n2 = 1 + x
409        >>> n1.eq(n2)
410        False
411        >>> n1 = simplify(n1)
412        >>> n2 = simplify(n2)
413        >>> n1.eq(n2)
414        True
415        """
416        if z3_debug():
417            _z3_assert(is_ast(other), "Z3 AST expected")
418        return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
419
420    def translate(self, target):
421        """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
422
423        >>> c1 = Context()
424        >>> c2 = Context()
425        >>> x  = Int('x', c1)
426        >>> y  = Int('y', c2)
427        >>> # Nodes in different contexts can't be mixed.
428        >>> # However, we can translate nodes from one context to another.
429        >>> x.translate(c2) + y
430        x + y
431        """
432        if z3_debug():
433            _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
434        return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
435
436    def __copy__(self):
437        return self.translate(self.ctx)
438
439    def hash(self):
440        """Return a hashcode for the `self`.
441
442        >>> n1 = simplify(Int('x') + 1)
443        >>> n2 = simplify(2 + Int('x') - 1)
444        >>> n1.hash() == n2.hash()
445        True
446        """
447        return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
448
449
450def is_ast(a):
451    """Return `True` if `a` is an AST node.
452
453    >>> is_ast(10)
454    False
455    >>> is_ast(IntVal(10))
456    True
457    >>> is_ast(Int('x'))
458    True
459    >>> is_ast(BoolSort())
460    True
461    >>> is_ast(Function('f', IntSort(), IntSort()))
462    True
463    >>> is_ast("x")
464    False
465    >>> is_ast(Solver())
466    False
467    """
468    return isinstance(a, AstRef)
469
470
471def eq(a, b):
472    """Return `True` if `a` and `b` are structurally identical AST nodes.
473
474    >>> x = Int('x')
475    >>> y = Int('y')
476    >>> eq(x, y)
477    False
478    >>> eq(x + 1, x + 1)
479    True
480    >>> eq(x + 1, 1 + x)
481    False
482    >>> eq(simplify(x + 1), simplify(1 + x))
483    True
484    """
485    if z3_debug():
486        _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
487    return a.eq(b)
488
489
490def _ast_kind(ctx, a):
491    if is_ast(a):
492        a = a.as_ast()
493    return Z3_get_ast_kind(ctx.ref(), a)
494
495
496def _ctx_from_ast_arg_list(args, default_ctx=None):
497    ctx = None
498    for a in args:
499        if is_ast(a) or is_probe(a):
500            if ctx is None:
501                ctx = a.ctx
502            else:
503                if z3_debug():
504                    _z3_assert(ctx == a.ctx, "Context mismatch")
505    if ctx is None:
506        ctx = default_ctx
507    return ctx
508
509
510def _ctx_from_ast_args(*args):
511    return _ctx_from_ast_arg_list(args)
512
513
514def _to_func_decl_array(args):
515    sz = len(args)
516    _args = (FuncDecl * sz)()
517    for i in range(sz):
518        _args[i] = args[i].as_func_decl()
519    return _args, sz
520
521
522def _to_ast_array(args):
523    sz = len(args)
524    _args = (Ast * sz)()
525    for i in range(sz):
526        _args[i] = args[i].as_ast()
527    return _args, sz
528
529
530def _to_ref_array(ref, args):
531    sz = len(args)
532    _args = (ref * sz)()
533    for i in range(sz):
534        _args[i] = args[i].as_ast()
535    return _args, sz
536
537
538def _to_ast_ref(a, ctx):
539    k = _ast_kind(ctx, a)
540    if k == Z3_SORT_AST:
541        return _to_sort_ref(a, ctx)
542    elif k == Z3_FUNC_DECL_AST:
543        return _to_func_decl_ref(a, ctx)
544    else:
545        return _to_expr_ref(a, ctx)
546
547
548#########################################
549#
550# Sorts
551#
552#########################################
553
554def _sort_kind(ctx, s):
555    return Z3_get_sort_kind(ctx.ref(), s)
556
557
558class SortRef(AstRef):
559    """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
560
561    def as_ast(self):
562        return Z3_sort_to_ast(self.ctx_ref(), self.ast)
563
564    def get_id(self):
565        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
566
567    def kind(self):
568        """Return the Z3 internal kind of a sort.
569        This method can be used to test if `self` is one of the Z3 builtin sorts.
570
571        >>> b = BoolSort()
572        >>> b.kind() == Z3_BOOL_SORT
573        True
574        >>> b.kind() == Z3_INT_SORT
575        False
576        >>> A = ArraySort(IntSort(), IntSort())
577        >>> A.kind() == Z3_ARRAY_SORT
578        True
579        >>> A.kind() == Z3_INT_SORT
580        False
581        """
582        return _sort_kind(self.ctx, self.ast)
583
584    def subsort(self, other):
585        """Return `True` if `self` is a subsort of `other`.
586
587        >>> IntSort().subsort(RealSort())
588        True
589        """
590        return False
591
592    def cast(self, val):
593        """Try to cast `val` as an element of sort `self`.
594
595        This method is used in Z3Py to convert Python objects such as integers,
596        floats, longs and strings into Z3 expressions.
597
598        >>> x = Int('x')
599        >>> RealSort().cast(x)
600        ToReal(x)
601        """
602        if z3_debug():
603            _z3_assert(is_expr(val), "Z3 expression expected")
604            _z3_assert(self.eq(val.sort()), "Sort mismatch")
605        return val
606
607    def name(self):
608        """Return the name (string) of sort `self`.
609
610        >>> BoolSort().name()
611        'Bool'
612        >>> ArraySort(IntSort(), IntSort()).name()
613        'Array'
614        """
615        return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
616
617    def __eq__(self, other):
618        """Return `True` if `self` and `other` are the same Z3 sort.
619
620        >>> p = Bool('p')
621        >>> p.sort() == BoolSort()
622        True
623        >>> p.sort() == IntSort()
624        False
625        """
626        if other is None:
627            return False
628        return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
629
630    def __ne__(self, other):
631        """Return `True` if `self` and `other` are not the same Z3 sort.
632
633        >>> p = Bool('p')
634        >>> p.sort() != BoolSort()
635        False
636        >>> p.sort() != IntSort()
637        True
638        """
639        return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
640
641    def __hash__(self):
642        """ Hash code. """
643        return AstRef.__hash__(self)
644
645
646def is_sort(s):
647    """Return `True` if `s` is a Z3 sort.
648
649    >>> is_sort(IntSort())
650    True
651    >>> is_sort(Int('x'))
652    False
653    >>> is_expr(Int('x'))
654    True
655    """
656    return isinstance(s, SortRef)
657
658
659def _to_sort_ref(s, ctx):
660    if z3_debug():
661        _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
662    k = _sort_kind(ctx, s)
663    if k == Z3_BOOL_SORT:
664        return BoolSortRef(s, ctx)
665    elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
666        return ArithSortRef(s, ctx)
667    elif k == Z3_BV_SORT:
668        return BitVecSortRef(s, ctx)
669    elif k == Z3_ARRAY_SORT:
670        return ArraySortRef(s, ctx)
671    elif k == Z3_DATATYPE_SORT:
672        return DatatypeSortRef(s, ctx)
673    elif k == Z3_FINITE_DOMAIN_SORT:
674        return FiniteDomainSortRef(s, ctx)
675    elif k == Z3_FLOATING_POINT_SORT:
676        return FPSortRef(s, ctx)
677    elif k == Z3_ROUNDING_MODE_SORT:
678        return FPRMSortRef(s, ctx)
679    elif k == Z3_RE_SORT:
680        return ReSortRef(s, ctx)
681    elif k == Z3_SEQ_SORT:
682        return SeqSortRef(s, ctx)
683    elif k == Z3_CHAR_SORT:
684        return CharSortRef(s, ctx)
685    return SortRef(s, ctx)
686
687
688def _sort(ctx, a):
689    return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
690
691
692def DeclareSort(name, ctx=None):
693    """Create a new uninterpreted sort named `name`.
694
695    If `ctx=None`, then the new sort is declared in the global Z3Py context.
696
697    >>> A = DeclareSort('A')
698    >>> a = Const('a', A)
699    >>> b = Const('b', A)
700    >>> a.sort() == A
701    True
702    >>> b.sort() == A
703    True
704    >>> a == b
705    a == b
706    """
707    ctx = _get_ctx(ctx)
708    return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
709
710#########################################
711#
712# Function Declarations
713#
714#########################################
715
716
717class FuncDeclRef(AstRef):
718    """Function declaration. Every constant and function have an associated declaration.
719
720    The declaration assigns a name, a sort (i.e., type), and for function
721    the sort (i.e., type) of each of its arguments. Note that, in Z3,
722    a constant is a function with 0 arguments.
723    """
724
725    def as_ast(self):
726        return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
727
728    def get_id(self):
729        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
730
731    def as_func_decl(self):
732        return self.ast
733
734    def name(self):
735        """Return the name of the function declaration `self`.
736
737        >>> f = Function('f', IntSort(), IntSort())
738        >>> f.name()
739        'f'
740        >>> isinstance(f.name(), str)
741        True
742        """
743        return _symbol2py(self.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
744
745    def arity(self):
746        """Return the number of arguments of a function declaration.
747        If `self` is a constant, then `self.arity()` is 0.
748
749        >>> f = Function('f', IntSort(), RealSort(), BoolSort())
750        >>> f.arity()
751        2
752        """
753        return int(Z3_get_arity(self.ctx_ref(), self.ast))
754
755    def domain(self, i):
756        """Return the sort of the argument `i` of a function declaration.
757        This method assumes that `0 <= i < self.arity()`.
758
759        >>> f = Function('f', IntSort(), RealSort(), BoolSort())
760        >>> f.domain(0)
761        Int
762        >>> f.domain(1)
763        Real
764        """
765        if z3_debug():
766            _z3_assert(i < self.arity(), "Index out of bounds")
767        return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
768
769    def range(self):
770        """Return the sort of the range of a function declaration.
771        For constants, this is the sort of the constant.
772
773        >>> f = Function('f', IntSort(), RealSort(), BoolSort())
774        >>> f.range()
775        Bool
776        """
777        return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.ast), self.ctx)
778
779    def kind(self):
780        """Return the internal kind of a function declaration.
781        It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
782
783        >>> x = Int('x')
784        >>> d = (x + 1).decl()
785        >>> d.kind() == Z3_OP_ADD
786        True
787        >>> d.kind() == Z3_OP_MUL
788        False
789        """
790        return Z3_get_decl_kind(self.ctx_ref(), self.ast)
791
792    def params(self):
793        ctx = self.ctx
794        n = Z3_get_decl_num_parameters(self.ctx_ref(), self.ast)
795        result = [None for i in range(n)]
796        for i in range(n):
797            k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.ast, i)
798            if k == Z3_PARAMETER_INT:
799                result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.ast, i)
800            elif k == Z3_PARAMETER_DOUBLE:
801                result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.ast, i)
802            elif k == Z3_PARAMETER_RATIONAL:
803                result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.ast, i)
804            elif k == Z3_PARAMETER_SYMBOL:
805                result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.ast, i)
806            elif k == Z3_PARAMETER_SORT:
807                result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.ast, i), ctx)
808            elif k == Z3_PARAMETER_AST:
809                result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.ast, i), ctx)
810            elif k == Z3_PARAMETER_FUNC_DECL:
811                result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.ast, i), ctx)
812            else:
813                assert(False)
814        return result
815
816    def __call__(self, *args):
817        """Create a Z3 application expression using the function `self`, and the given arguments.
818
819        The arguments must be Z3 expressions. This method assumes that
820        the sorts of the elements in `args` match the sorts of the
821        domain. Limited coercion is supported.  For example, if
822        args[0] is a Python integer, and the function expects a Z3
823        integer, then the argument is automatically converted into a
824        Z3 integer.
825
826        >>> f = Function('f', IntSort(), RealSort(), BoolSort())
827        >>> x = Int('x')
828        >>> y = Real('y')
829        >>> f(x, y)
830        f(x, y)
831        >>> f(x, x)
832        f(x, ToReal(x))
833        """
834        args = _get_args(args)
835        num = len(args)
836        if z3_debug():
837            _z3_assert(num == self.arity(), "Incorrect number of arguments to %s" % self)
838        _args = (Ast * num)()
839        saved = []
840        for i in range(num):
841            # self.domain(i).cast(args[i]) may create a new Z3 expression,
842            # then we must save in 'saved' to prevent it from being garbage collected.
843            tmp = self.domain(i).cast(args[i])
844            saved.append(tmp)
845            _args[i] = tmp.as_ast()
846        return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
847
848
849def is_func_decl(a):
850    """Return `True` if `a` is a Z3 function declaration.
851
852    >>> f = Function('f', IntSort(), IntSort())
853    >>> is_func_decl(f)
854    True
855    >>> x = Real('x')
856    >>> is_func_decl(x)
857    False
858    """
859    return isinstance(a, FuncDeclRef)
860
861
862def Function(name, *sig):
863    """Create a new Z3 uninterpreted function with the given sorts.
864
865    >>> f = Function('f', IntSort(), IntSort())
866    >>> f(f(0))
867    f(f(0))
868    """
869    sig = _get_args(sig)
870    if z3_debug():
871        _z3_assert(len(sig) > 0, "At least two arguments expected")
872    arity = len(sig) - 1
873    rng = sig[arity]
874    if z3_debug():
875        _z3_assert(is_sort(rng), "Z3 sort expected")
876    dom = (Sort * arity)()
877    for i in range(arity):
878        if z3_debug():
879            _z3_assert(is_sort(sig[i]), "Z3 sort expected")
880        dom[i] = sig[i].ast
881    ctx = rng.ctx
882    return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
883
884
885def FreshFunction(*sig):
886    """Create a new fresh Z3 uninterpreted function with the given sorts.
887    """
888    sig = _get_args(sig)
889    if z3_debug():
890        _z3_assert(len(sig) > 0, "At least two arguments expected")
891    arity = len(sig) - 1
892    rng = sig[arity]
893    if z3_debug():
894        _z3_assert(is_sort(rng), "Z3 sort expected")
895    dom = (z3.Sort * arity)()
896    for i in range(arity):
897        if z3_debug():
898            _z3_assert(is_sort(sig[i]), "Z3 sort expected")
899        dom[i] = sig[i].ast
900    ctx = rng.ctx
901    return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
902
903
904def _to_func_decl_ref(a, ctx):
905    return FuncDeclRef(a, ctx)
906
907
908def RecFunction(name, *sig):
909    """Create a new Z3 recursive with the given sorts."""
910    sig = _get_args(sig)
911    if z3_debug():
912        _z3_assert(len(sig) > 0, "At least two arguments expected")
913    arity = len(sig) - 1
914    rng = sig[arity]
915    if z3_debug():
916        _z3_assert(is_sort(rng), "Z3 sort expected")
917    dom = (Sort * arity)()
918    for i in range(arity):
919        if z3_debug():
920            _z3_assert(is_sort(sig[i]), "Z3 sort expected")
921        dom[i] = sig[i].ast
922    ctx = rng.ctx
923    return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
924
925
926def RecAddDefinition(f, args, body):
927    """Set the body of a recursive function.
928       Recursive definitions can be simplified if they are applied to ground
929       arguments.
930    >>> ctx = Context()
931    >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
932    >>> n = Int('n', ctx)
933    >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
934    >>> simplify(fac(5))
935    120
936    >>> s = Solver(ctx=ctx)
937    >>> s.add(fac(n) < 3)
938    >>> s.check()
939    sat
940    >>> s.model().eval(fac(5))
941    120
942    """
943    if is_app(args):
944        args = [args]
945    ctx = body.ctx
946    args = _get_args(args)
947    n = len(args)
948    _args = (Ast * n)()
949    for i in range(n):
950        _args[i] = args[i].ast
951    Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
952
953#########################################
954#
955# Expressions
956#
957#########################################
958
959
960class ExprRef(AstRef):
961    """Constraints, formulas and terms are expressions in Z3.
962
963    Expressions are ASTs. Every expression has a sort.
964    There are three main kinds of expressions:
965    function applications, quantifiers and bounded variables.
966    A constant is a function application with 0 arguments.
967    For quantifier free problems, all expressions are
968    function applications.
969    """
970
971    def as_ast(self):
972        return self.ast
973
974    def get_id(self):
975        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
976
977    def sort(self):
978        """Return the sort of expression `self`.
979
980        >>> x = Int('x')
981        >>> (x + 1).sort()
982        Int
983        >>> y = Real('y')
984        >>> (x + y).sort()
985        Real
986        """
987        return _sort(self.ctx, self.as_ast())
988
989    def sort_kind(self):
990        """Shorthand for `self.sort().kind()`.
991
992        >>> a = Array('a', IntSort(), IntSort())
993        >>> a.sort_kind() == Z3_ARRAY_SORT
994        True
995        >>> a.sort_kind() == Z3_INT_SORT
996        False
997        """
998        return self.sort().kind()
999
1000    def __eq__(self, other):
1001        """Return a Z3 expression that represents the constraint `self == other`.
1002
1003        If `other` is `None`, then this method simply returns `False`.
1004
1005        >>> a = Int('a')
1006        >>> b = Int('b')
1007        >>> a == b
1008        a == b
1009        >>> a is None
1010        False
1011        """
1012        if other is None:
1013            return False
1014        a, b = _coerce_exprs(self, other)
1015        return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
1016
1017    def __hash__(self):
1018        """ Hash code. """
1019        return AstRef.__hash__(self)
1020
1021    def __ne__(self, other):
1022        """Return a Z3 expression that represents the constraint `self != other`.
1023
1024        If `other` is `None`, then this method simply returns `True`.
1025
1026        >>> a = Int('a')
1027        >>> b = Int('b')
1028        >>> a != b
1029        a != b
1030        >>> a is not None
1031        True
1032        """
1033        if other is None:
1034            return True
1035        a, b = _coerce_exprs(self, other)
1036        _args, sz = _to_ast_array((a, b))
1037        return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
1038
1039    def params(self):
1040        return self.decl().params()
1041
1042    def decl(self):
1043        """Return the Z3 function declaration associated with a Z3 application.
1044
1045        >>> f = Function('f', IntSort(), IntSort())
1046        >>> a = Int('a')
1047        >>> t = f(a)
1048        >>> eq(t.decl(), f)
1049        True
1050        >>> (a + 1).decl()
1051        +
1052        """
1053        if z3_debug():
1054            _z3_assert(is_app(self), "Z3 application expected")
1055        return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_ast()), self.ctx)
1056
1057    def num_args(self):
1058        """Return the number of arguments of a Z3 application.
1059
1060        >>> a = Int('a')
1061        >>> b = Int('b')
1062        >>> (a + b).num_args()
1063        2
1064        >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1065        >>> t = f(a, b, 0)
1066        >>> t.num_args()
1067        3
1068        """
1069        if z3_debug():
1070            _z3_assert(is_app(self), "Z3 application expected")
1071        return int(Z3_get_app_num_args(self.ctx_ref(), self.as_ast()))
1072
1073    def arg(self, idx):
1074        """Return argument `idx` of the application `self`.
1075
1076        This method assumes that `self` is a function application with at least `idx+1` arguments.
1077
1078        >>> a = Int('a')
1079        >>> b = Int('b')
1080        >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1081        >>> t = f(a, b, 0)
1082        >>> t.arg(0)
1083        a
1084        >>> t.arg(1)
1085        b
1086        >>> t.arg(2)
1087        0
1088        """
1089        if z3_debug():
1090            _z3_assert(is_app(self), "Z3 application expected")
1091            _z3_assert(idx < self.num_args(), "Invalid argument index")
1092        return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_ast(), idx), self.ctx)
1093
1094    def children(self):
1095        """Return a list containing the children of the given expression
1096
1097        >>> a = Int('a')
1098        >>> b = Int('b')
1099        >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1100        >>> t = f(a, b, 0)
1101        >>> t.children()
1102        [a, b, 0]
1103        """
1104        if is_app(self):
1105            return [self.arg(i) for i in range(self.num_args())]
1106        else:
1107            return []
1108
1109
1110def _to_expr_ref(a, ctx):
1111    if isinstance(a, Pattern):
1112        return PatternRef(a, ctx)
1113    ctx_ref = ctx.ref()
1114    k = Z3_get_ast_kind(ctx_ref, a)
1115    if k == Z3_QUANTIFIER_AST:
1116        return QuantifierRef(a, ctx)
1117    sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1118    if sk == Z3_BOOL_SORT:
1119        return BoolRef(a, ctx)
1120    if sk == Z3_INT_SORT:
1121        if k == Z3_NUMERAL_AST:
1122            return IntNumRef(a, ctx)
1123        return ArithRef(a, ctx)
1124    if sk == Z3_REAL_SORT:
1125        if k == Z3_NUMERAL_AST:
1126            return RatNumRef(a, ctx)
1127        if _is_algebraic(ctx, a):
1128            return AlgebraicNumRef(a, ctx)
1129        return ArithRef(a, ctx)
1130    if sk == Z3_BV_SORT:
1131        if k == Z3_NUMERAL_AST:
1132            return BitVecNumRef(a, ctx)
1133        else:
1134            return BitVecRef(a, ctx)
1135    if sk == Z3_ARRAY_SORT:
1136        return ArrayRef(a, ctx)
1137    if sk == Z3_DATATYPE_SORT:
1138        return DatatypeRef(a, ctx)
1139    if sk == Z3_FLOATING_POINT_SORT:
1140        if k == Z3_APP_AST and _is_numeral(ctx, a):
1141            return FPNumRef(a, ctx)
1142        else:
1143            return FPRef(a, ctx)
1144    if sk == Z3_FINITE_DOMAIN_SORT:
1145        if k == Z3_NUMERAL_AST:
1146            return FiniteDomainNumRef(a, ctx)
1147        else:
1148            return FiniteDomainRef(a, ctx)
1149    if sk == Z3_ROUNDING_MODE_SORT:
1150        return FPRMRef(a, ctx)
1151    if sk == Z3_SEQ_SORT:
1152        return SeqRef(a, ctx)
1153    if sk == Z3_RE_SORT:
1154        return ReRef(a, ctx)
1155    return ExprRef(a, ctx)
1156
1157
1158def _coerce_expr_merge(s, a):
1159    if is_expr(a):
1160        s1 = a.sort()
1161        if s is None:
1162            return s1
1163        if s1.eq(s):
1164            return s
1165        elif s.subsort(s1):
1166            return s1
1167        elif s1.subsort(s):
1168            return s
1169        else:
1170            if z3_debug():
1171                _z3_assert(s1.ctx == s.ctx, "context mismatch")
1172                _z3_assert(False, "sort mismatch")
1173    else:
1174        return s
1175
1176
1177def _coerce_exprs(a, b, ctx=None):
1178    if not is_expr(a) and not is_expr(b):
1179        a = _py2expr(a, ctx)
1180        b = _py2expr(b, ctx)
1181    if isinstance(a, str) and isinstance(b, SeqRef):
1182        a = StringVal(a, b.ctx)
1183    if isinstance(b, str) and isinstance(a, SeqRef):
1184        b = StringVal(b, a.ctx)
1185    s = None
1186    s = _coerce_expr_merge(s, a)
1187    s = _coerce_expr_merge(s, b)
1188    a = s.cast(a)
1189    b = s.cast(b)
1190    return (a, b)
1191
1192
1193def _reduce(func, sequence, initial):
1194    result = initial
1195    for element in sequence:
1196        result = func(result, element)
1197    return result
1198
1199
1200def _coerce_expr_list(alist, ctx=None):
1201    has_expr = False
1202    for a in alist:
1203        if is_expr(a):
1204            has_expr = True
1205            break
1206    if not has_expr:
1207        alist = [_py2expr(a, ctx) for a in alist]
1208    s = _reduce(_coerce_expr_merge, alist, None)
1209    return [s.cast(a) for a in alist]
1210
1211
1212def is_expr(a):
1213    """Return `True` if `a` is a Z3 expression.
1214
1215    >>> a = Int('a')
1216    >>> is_expr(a)
1217    True
1218    >>> is_expr(a + 1)
1219    True
1220    >>> is_expr(IntSort())
1221    False
1222    >>> is_expr(1)
1223    False
1224    >>> is_expr(IntVal(1))
1225    True
1226    >>> x = Int('x')
1227    >>> is_expr(ForAll(x, x >= 0))
1228    True
1229    >>> is_expr(FPVal(1.0))
1230    True
1231    """
1232    return isinstance(a, ExprRef)
1233
1234
1235def is_app(a):
1236    """Return `True` if `a` is a Z3 function application.
1237
1238    Note that, constants are function applications with 0 arguments.
1239
1240    >>> a = Int('a')
1241    >>> is_app(a)
1242    True
1243    >>> is_app(a + 1)
1244    True
1245    >>> is_app(IntSort())
1246    False
1247    >>> is_app(1)
1248    False
1249    >>> is_app(IntVal(1))
1250    True
1251    >>> x = Int('x')
1252    >>> is_app(ForAll(x, x >= 0))
1253    False
1254    """
1255    if not isinstance(a, ExprRef):
1256        return False
1257    k = _ast_kind(a.ctx, a)
1258    return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1259
1260
1261def is_const(a):
1262    """Return `True` if `a` is Z3 constant/variable expression.
1263
1264    >>> a = Int('a')
1265    >>> is_const(a)
1266    True
1267    >>> is_const(a + 1)
1268    False
1269    >>> is_const(1)
1270    False
1271    >>> is_const(IntVal(1))
1272    True
1273    >>> x = Int('x')
1274    >>> is_const(ForAll(x, x >= 0))
1275    False
1276    """
1277    return is_app(a) and a.num_args() == 0
1278
1279
1280def is_var(a):
1281    """Return `True` if `a` is variable.
1282
1283    Z3 uses de-Bruijn indices for representing bound variables in
1284    quantifiers.
1285
1286    >>> x = Int('x')
1287    >>> is_var(x)
1288    False
1289    >>> is_const(x)
1290    True
1291    >>> f = Function('f', IntSort(), IntSort())
1292    >>> # Z3 replaces x with bound variables when ForAll is executed.
1293    >>> q = ForAll(x, f(x) == x)
1294    >>> b = q.body()
1295    >>> b
1296    f(Var(0)) == Var(0)
1297    >>> b.arg(1)
1298    Var(0)
1299    >>> is_var(b.arg(1))
1300    True
1301    """
1302    return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1303
1304
1305def get_var_index(a):
1306    """Return the de-Bruijn index of the Z3 bounded variable `a`.
1307
1308    >>> x = Int('x')
1309    >>> y = Int('y')
1310    >>> is_var(x)
1311    False
1312    >>> is_const(x)
1313    True
1314    >>> f = Function('f', IntSort(), IntSort(), IntSort())
1315    >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1316    >>> q = ForAll([x, y], f(x, y) == x + y)
1317    >>> q.body()
1318    f(Var(1), Var(0)) == Var(1) + Var(0)
1319    >>> b = q.body()
1320    >>> b.arg(0)
1321    f(Var(1), Var(0))
1322    >>> v1 = b.arg(0).arg(0)
1323    >>> v2 = b.arg(0).arg(1)
1324    >>> v1
1325    Var(1)
1326    >>> v2
1327    Var(0)
1328    >>> get_var_index(v1)
1329    1
1330    >>> get_var_index(v2)
1331    0
1332    """
1333    if z3_debug():
1334        _z3_assert(is_var(a), "Z3 bound variable expected")
1335    return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1336
1337
1338def is_app_of(a, k):
1339    """Return `True` if `a` is an application of the given kind `k`.
1340
1341    >>> x = Int('x')
1342    >>> n = x + 1
1343    >>> is_app_of(n, Z3_OP_ADD)
1344    True
1345    >>> is_app_of(n, Z3_OP_MUL)
1346    False
1347    """
1348    return is_app(a) and a.decl().kind() == k
1349
1350
1351def If(a, b, c, ctx=None):
1352    """Create a Z3 if-then-else expression.
1353
1354    >>> x = Int('x')
1355    >>> y = Int('y')
1356    >>> max = If(x > y, x, y)
1357    >>> max
1358    If(x > y, x, y)
1359    >>> simplify(max)
1360    If(x <= y, y, x)
1361    """
1362    if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1363        return Cond(a, b, c, ctx)
1364    else:
1365        ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1366        s = BoolSort(ctx)
1367        a = s.cast(a)
1368        b, c = _coerce_exprs(b, c, ctx)
1369        if z3_debug():
1370            _z3_assert(a.ctx == b.ctx, "Context mismatch")
1371        return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1372
1373
1374def Distinct(*args):
1375    """Create a Z3 distinct expression.
1376
1377    >>> x = Int('x')
1378    >>> y = Int('y')
1379    >>> Distinct(x, y)
1380    x != y
1381    >>> z = Int('z')
1382    >>> Distinct(x, y, z)
1383    Distinct(x, y, z)
1384    >>> simplify(Distinct(x, y, z))
1385    Distinct(x, y, z)
1386    >>> simplify(Distinct(x, y, z), blast_distinct=True)
1387    And(Not(x == y), Not(x == z), Not(y == z))
1388    """
1389    args = _get_args(args)
1390    ctx = _ctx_from_ast_arg_list(args)
1391    if z3_debug():
1392        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1393    args = _coerce_expr_list(args, ctx)
1394    _args, sz = _to_ast_array(args)
1395    return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1396
1397
1398def _mk_bin(f, a, b):
1399    args = (Ast * 2)()
1400    if z3_debug():
1401        _z3_assert(a.ctx == b.ctx, "Context mismatch")
1402    args[0] = a.as_ast()
1403    args[1] = b.as_ast()
1404    return f(a.ctx.ref(), 2, args)
1405
1406
1407def Const(name, sort):
1408    """Create a constant of the given sort.
1409
1410    >>> Const('x', IntSort())
1411    x
1412    """
1413    if z3_debug():
1414        _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1415    ctx = sort.ctx
1416    return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1417
1418
1419def Consts(names, sort):
1420    """Create several constants of the given sort.
1421
1422    `names` is a string containing the names of all constants to be created.
1423    Blank spaces separate the names of different constants.
1424
1425    >>> x, y, z = Consts('x y z', IntSort())
1426    >>> x + y + z
1427    x + y + z
1428    """
1429    if isinstance(names, str):
1430        names = names.split(" ")
1431    return [Const(name, sort) for name in names]
1432
1433
1434def FreshConst(sort, prefix="c"):
1435    """Create a fresh constant of a specified sort"""
1436    ctx = _get_ctx(sort.ctx)
1437    return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1438
1439
1440def Var(idx, s):
1441    """Create a Z3 free variable. Free variables are used to create quantified formulas.
1442
1443    >>> Var(0, IntSort())
1444    Var(0)
1445    >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1446    False
1447    """
1448    if z3_debug():
1449        _z3_assert(is_sort(s), "Z3 sort expected")
1450    return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1451
1452
1453def RealVar(idx, ctx=None):
1454    """
1455    Create a real free variable. Free variables are used to create quantified formulas.
1456    They are also used to create polynomials.
1457
1458    >>> RealVar(0)
1459    Var(0)
1460    """
1461    return Var(idx, RealSort(ctx))
1462
1463
1464def RealVarVector(n, ctx=None):
1465    """
1466    Create a list of Real free variables.
1467    The variables have ids: 0, 1, ..., n-1
1468
1469    >>> x0, x1, x2, x3 = RealVarVector(4)
1470    >>> x2
1471    Var(2)
1472    """
1473    return [RealVar(i, ctx) for i in range(n)]
1474
1475#########################################
1476#
1477# Booleans
1478#
1479#########################################
1480
1481
1482class BoolSortRef(SortRef):
1483    """Boolean sort."""
1484
1485    def cast(self, val):
1486        """Try to cast `val` as a Boolean.
1487
1488        >>> x = BoolSort().cast(True)
1489        >>> x
1490        True
1491        >>> is_expr(x)
1492        True
1493        >>> is_expr(True)
1494        False
1495        >>> x.sort()
1496        Bool
1497        """
1498        if isinstance(val, bool):
1499            return BoolVal(val, self.ctx)
1500        if z3_debug():
1501            if not is_expr(val):
1502                msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1503                _z3_assert(is_expr(val), msg % (val, type(val)))
1504            if not self.eq(val.sort()):
1505                _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1506        return val
1507
1508    def subsort(self, other):
1509        return isinstance(other, ArithSortRef)
1510
1511    def is_int(self):
1512        return True
1513
1514    def is_bool(self):
1515        return True
1516
1517
1518class BoolRef(ExprRef):
1519    """All Boolean expressions are instances of this class."""
1520
1521    def sort(self):
1522        return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
1523
1524    def __rmul__(self, other):
1525        return self * other
1526
1527    def __mul__(self, other):
1528        """Create the Z3 expression `self * other`.
1529        """
1530        if other == 1:
1531            return self
1532        if other == 0:
1533            return 0
1534        return If(self, other, 0)
1535
1536
1537def is_bool(a):
1538    """Return `True` if `a` is a Z3 Boolean expression.
1539
1540    >>> p = Bool('p')
1541    >>> is_bool(p)
1542    True
1543    >>> q = Bool('q')
1544    >>> is_bool(And(p, q))
1545    True
1546    >>> x = Real('x')
1547    >>> is_bool(x)
1548    False
1549    >>> is_bool(x == 0)
1550    True
1551    """
1552    return isinstance(a, BoolRef)
1553
1554
1555def is_true(a):
1556    """Return `True` if `a` is the Z3 true expression.
1557
1558    >>> p = Bool('p')
1559    >>> is_true(p)
1560    False
1561    >>> is_true(simplify(p == p))
1562    True
1563    >>> x = Real('x')
1564    >>> is_true(x == 0)
1565    False
1566    >>> # True is a Python Boolean expression
1567    >>> is_true(True)
1568    False
1569    """
1570    return is_app_of(a, Z3_OP_TRUE)
1571
1572
1573def is_false(a):
1574    """Return `True` if `a` is the Z3 false expression.
1575
1576    >>> p = Bool('p')
1577    >>> is_false(p)
1578    False
1579    >>> is_false(False)
1580    False
1581    >>> is_false(BoolVal(False))
1582    True
1583    """
1584    return is_app_of(a, Z3_OP_FALSE)
1585
1586
1587def is_and(a):
1588    """Return `True` if `a` is a Z3 and expression.
1589
1590    >>> p, q = Bools('p q')
1591    >>> is_and(And(p, q))
1592    True
1593    >>> is_and(Or(p, q))
1594    False
1595    """
1596    return is_app_of(a, Z3_OP_AND)
1597
1598
1599def is_or(a):
1600    """Return `True` if `a` is a Z3 or expression.
1601
1602    >>> p, q = Bools('p q')
1603    >>> is_or(Or(p, q))
1604    True
1605    >>> is_or(And(p, q))
1606    False
1607    """
1608    return is_app_of(a, Z3_OP_OR)
1609
1610
1611def is_implies(a):
1612    """Return `True` if `a` is a Z3 implication expression.
1613
1614    >>> p, q = Bools('p q')
1615    >>> is_implies(Implies(p, q))
1616    True
1617    >>> is_implies(And(p, q))
1618    False
1619    """
1620    return is_app_of(a, Z3_OP_IMPLIES)
1621
1622
1623def is_not(a):
1624    """Return `True` if `a` is a Z3 not expression.
1625
1626    >>> p = Bool('p')
1627    >>> is_not(p)
1628    False
1629    >>> is_not(Not(p))
1630    True
1631    """
1632    return is_app_of(a, Z3_OP_NOT)
1633
1634
1635def is_eq(a):
1636    """Return `True` if `a` is a Z3 equality expression.
1637
1638    >>> x, y = Ints('x y')
1639    >>> is_eq(x == y)
1640    True
1641    """
1642    return is_app_of(a, Z3_OP_EQ)
1643
1644
1645def is_distinct(a):
1646    """Return `True` if `a` is a Z3 distinct expression.
1647
1648    >>> x, y, z = Ints('x y z')
1649    >>> is_distinct(x == y)
1650    False
1651    >>> is_distinct(Distinct(x, y, z))
1652    True
1653    """
1654    return is_app_of(a, Z3_OP_DISTINCT)
1655
1656
1657def BoolSort(ctx=None):
1658    """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1659
1660    >>> BoolSort()
1661    Bool
1662    >>> p = Const('p', BoolSort())
1663    >>> is_bool(p)
1664    True
1665    >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1666    >>> r(0, 1)
1667    r(0, 1)
1668    >>> is_bool(r(0, 1))
1669    True
1670    """
1671    ctx = _get_ctx(ctx)
1672    return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1673
1674
1675def BoolVal(val, ctx=None):
1676    """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1677
1678    >>> BoolVal(True)
1679    True
1680    >>> is_true(BoolVal(True))
1681    True
1682    >>> is_true(True)
1683    False
1684    >>> is_false(BoolVal(False))
1685    True
1686    """
1687    ctx = _get_ctx(ctx)
1688    if val:
1689        return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1690    else:
1691        return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1692
1693
1694def Bool(name, ctx=None):
1695    """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1696
1697    >>> p = Bool('p')
1698    >>> q = Bool('q')
1699    >>> And(p, q)
1700    And(p, q)
1701    """
1702    ctx = _get_ctx(ctx)
1703    return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1704
1705
1706def Bools(names, ctx=None):
1707    """Return a tuple of Boolean constants.
1708
1709    `names` is a single string containing all names separated by blank spaces.
1710    If `ctx=None`, then the global context is used.
1711
1712    >>> p, q, r = Bools('p q r')
1713    >>> And(p, Or(q, r))
1714    And(p, Or(q, r))
1715    """
1716    ctx = _get_ctx(ctx)
1717    if isinstance(names, str):
1718        names = names.split(" ")
1719    return [Bool(name, ctx) for name in names]
1720
1721
1722def BoolVector(prefix, sz, ctx=None):
1723    """Return a list of Boolean constants of size `sz`.
1724
1725    The constants are named using the given prefix.
1726    If `ctx=None`, then the global context is used.
1727
1728    >>> P = BoolVector('p', 3)
1729    >>> P
1730    [p__0, p__1, p__2]
1731    >>> And(P)
1732    And(p__0, p__1, p__2)
1733    """
1734    return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1735
1736
1737def FreshBool(prefix="b", ctx=None):
1738    """Return a fresh Boolean constant in the given context using the given prefix.
1739
1740    If `ctx=None`, then the global context is used.
1741
1742    >>> b1 = FreshBool()
1743    >>> b2 = FreshBool()
1744    >>> eq(b1, b2)
1745    False
1746    """
1747    ctx = _get_ctx(ctx)
1748    return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1749
1750
1751def Implies(a, b, ctx=None):
1752    """Create a Z3 implies expression.
1753
1754    >>> p, q = Bools('p q')
1755    >>> Implies(p, q)
1756    Implies(p, q)
1757    """
1758    ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1759    s = BoolSort(ctx)
1760    a = s.cast(a)
1761    b = s.cast(b)
1762    return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1763
1764
1765def Xor(a, b, ctx=None):
1766    """Create a Z3 Xor expression.
1767
1768    >>> p, q = Bools('p q')
1769    >>> Xor(p, q)
1770    Xor(p, q)
1771    >>> simplify(Xor(p, q))
1772    Not(p) == q
1773    """
1774    ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1775    s = BoolSort(ctx)
1776    a = s.cast(a)
1777    b = s.cast(b)
1778    return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1779
1780
1781def Not(a, ctx=None):
1782    """Create a Z3 not expression or probe.
1783
1784    >>> p = Bool('p')
1785    >>> Not(Not(p))
1786    Not(Not(p))
1787    >>> simplify(Not(Not(p)))
1788    p
1789    """
1790    ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1791    if is_probe(a):
1792        # Not is also used to build probes
1793        return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1794    else:
1795        s = BoolSort(ctx)
1796        a = s.cast(a)
1797        return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1798
1799
1800def mk_not(a):
1801    if is_not(a):
1802        return a.arg(0)
1803    else:
1804        return Not(a)
1805
1806
1807def _has_probe(args):
1808    """Return `True` if one of the elements of the given collection is a Z3 probe."""
1809    for arg in args:
1810        if is_probe(arg):
1811            return True
1812    return False
1813
1814
1815def And(*args):
1816    """Create a Z3 and-expression or and-probe.
1817
1818    >>> p, q, r = Bools('p q r')
1819    >>> And(p, q, r)
1820    And(p, q, r)
1821    >>> P = BoolVector('p', 5)
1822    >>> And(P)
1823    And(p__0, p__1, p__2, p__3, p__4)
1824    """
1825    last_arg = None
1826    if len(args) > 0:
1827        last_arg = args[len(args) - 1]
1828    if isinstance(last_arg, Context):
1829        ctx = args[len(args) - 1]
1830        args = args[:len(args) - 1]
1831    elif len(args) == 1 and isinstance(args[0], AstVector):
1832        ctx = args[0].ctx
1833        args = [a for a in args[0]]
1834    else:
1835        ctx = None
1836    args = _get_args(args)
1837    ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1838    if z3_debug():
1839        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1840    if _has_probe(args):
1841        return _probe_and(args, ctx)
1842    else:
1843        args = _coerce_expr_list(args, ctx)
1844        _args, sz = _to_ast_array(args)
1845        return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
1846
1847
1848def Or(*args):
1849    """Create a Z3 or-expression or or-probe.
1850
1851    >>> p, q, r = Bools('p q r')
1852    >>> Or(p, q, r)
1853    Or(p, q, r)
1854    >>> P = BoolVector('p', 5)
1855    >>> Or(P)
1856    Or(p__0, p__1, p__2, p__3, p__4)
1857    """
1858    last_arg = None
1859    if len(args) > 0:
1860        last_arg = args[len(args) - 1]
1861    if isinstance(last_arg, Context):
1862        ctx = args[len(args) - 1]
1863        args = args[:len(args) - 1]
1864    elif len(args) == 1 and isinstance(args[0], AstVector):
1865        ctx = args[0].ctx
1866        args = [a for a in args[0]]
1867    else:
1868        ctx = None
1869    args = _get_args(args)
1870    ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1871    if z3_debug():
1872        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1873    if _has_probe(args):
1874        return _probe_or(args, ctx)
1875    else:
1876        args = _coerce_expr_list(args, ctx)
1877        _args, sz = _to_ast_array(args)
1878        return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
1879
1880#########################################
1881#
1882# Patterns
1883#
1884#########################################
1885
1886
1887class PatternRef(ExprRef):
1888    """Patterns are hints for quantifier instantiation.
1889
1890    """
1891
1892    def as_ast(self):
1893        return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
1894
1895    def get_id(self):
1896        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1897
1898
1899def is_pattern(a):
1900    """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
1901
1902    >>> f = Function('f', IntSort(), IntSort())
1903    >>> x = Int('x')
1904    >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
1905    >>> q
1906    ForAll(x, f(x) == 0)
1907    >>> q.num_patterns()
1908    1
1909    >>> is_pattern(q.pattern(0))
1910    True
1911    >>> q.pattern(0)
1912    f(Var(0))
1913    """
1914    return isinstance(a, PatternRef)
1915
1916
1917def MultiPattern(*args):
1918    """Create a Z3 multi-pattern using the given expressions `*args`
1919
1920    >>> f = Function('f', IntSort(), IntSort())
1921    >>> g = Function('g', IntSort(), IntSort())
1922    >>> x = Int('x')
1923    >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
1924    >>> q
1925    ForAll(x, f(x) != g(x))
1926    >>> q.num_patterns()
1927    1
1928    >>> is_pattern(q.pattern(0))
1929    True
1930    >>> q.pattern(0)
1931    MultiPattern(f(Var(0)), g(Var(0)))
1932    """
1933    if z3_debug():
1934        _z3_assert(len(args) > 0, "At least one argument expected")
1935        _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
1936    ctx = args[0].ctx
1937    args, sz = _to_ast_array(args)
1938    return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
1939
1940
1941def _to_pattern(arg):
1942    if is_pattern(arg):
1943        return arg
1944    else:
1945        return MultiPattern(arg)
1946
1947#########################################
1948#
1949# Quantifiers
1950#
1951#########################################
1952
1953
1954class QuantifierRef(BoolRef):
1955    """Universally and Existentially quantified formulas."""
1956
1957    def as_ast(self):
1958        return self.ast
1959
1960    def get_id(self):
1961        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1962
1963    def sort(self):
1964        """Return the Boolean sort or sort of Lambda."""
1965        if self.is_lambda():
1966            return _sort(self.ctx, self.as_ast())
1967        return BoolSort(self.ctx)
1968
1969    def is_forall(self):
1970        """Return `True` if `self` is a universal quantifier.
1971
1972        >>> f = Function('f', IntSort(), IntSort())
1973        >>> x = Int('x')
1974        >>> q = ForAll(x, f(x) == 0)
1975        >>> q.is_forall()
1976        True
1977        >>> q = Exists(x, f(x) != 0)
1978        >>> q.is_forall()
1979        False
1980        """
1981        return Z3_is_quantifier_forall(self.ctx_ref(), self.ast)
1982
1983    def is_exists(self):
1984        """Return `True` if `self` is an existential quantifier.
1985
1986        >>> f = Function('f', IntSort(), IntSort())
1987        >>> x = Int('x')
1988        >>> q = ForAll(x, f(x) == 0)
1989        >>> q.is_exists()
1990        False
1991        >>> q = Exists(x, f(x) != 0)
1992        >>> q.is_exists()
1993        True
1994        """
1995        return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
1996
1997    def is_lambda(self):
1998        """Return `True` if `self` is a lambda expression.
1999
2000        >>> f = Function('f', IntSort(), IntSort())
2001        >>> x = Int('x')
2002        >>> q = Lambda(x, f(x))
2003        >>> q.is_lambda()
2004        True
2005        >>> q = Exists(x, f(x) != 0)
2006        >>> q.is_lambda()
2007        False
2008        """
2009        return Z3_is_lambda(self.ctx_ref(), self.ast)
2010
2011    def __getitem__(self, arg):
2012        """Return the Z3 expression `self[arg]`.
2013        """
2014        if z3_debug():
2015            _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2016        arg = self.sort().domain().cast(arg)
2017        return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx)
2018
2019    def weight(self):
2020        """Return the weight annotation of `self`.
2021
2022        >>> f = Function('f', IntSort(), IntSort())
2023        >>> x = Int('x')
2024        >>> q = ForAll(x, f(x) == 0)
2025        >>> q.weight()
2026        1
2027        >>> q = ForAll(x, f(x) == 0, weight=10)
2028        >>> q.weight()
2029        10
2030        """
2031        return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
2032
2033    def num_patterns(self):
2034        """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2035
2036        >>> f = Function('f', IntSort(), IntSort())
2037        >>> g = Function('g', IntSort(), IntSort())
2038        >>> x = Int('x')
2039        >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2040        >>> q.num_patterns()
2041        2
2042        """
2043        return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
2044
2045    def pattern(self, idx):
2046        """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2047
2048        >>> f = Function('f', IntSort(), IntSort())
2049        >>> g = Function('g', IntSort(), IntSort())
2050        >>> x = Int('x')
2051        >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2052        >>> q.num_patterns()
2053        2
2054        >>> q.pattern(0)
2055        f(Var(0))
2056        >>> q.pattern(1)
2057        g(Var(0))
2058        """
2059        if z3_debug():
2060            _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2061        return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2062
2063    def num_no_patterns(self):
2064        """Return the number of no-patterns."""
2065        return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
2066
2067    def no_pattern(self, idx):
2068        """Return a no-pattern."""
2069        if z3_debug():
2070            _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2071        return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2072
2073    def body(self):
2074        """Return the expression being quantified.
2075
2076        >>> f = Function('f', IntSort(), IntSort())
2077        >>> x = Int('x')
2078        >>> q = ForAll(x, f(x) == 0)
2079        >>> q.body()
2080        f(Var(0)) == 0
2081        """
2082        return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
2083
2084    def num_vars(self):
2085        """Return the number of variables bounded by this quantifier.
2086
2087        >>> f = Function('f', IntSort(), IntSort(), IntSort())
2088        >>> x = Int('x')
2089        >>> y = Int('y')
2090        >>> q = ForAll([x, y], f(x, y) >= x)
2091        >>> q.num_vars()
2092        2
2093        """
2094        return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
2095
2096    def var_name(self, idx):
2097        """Return a string representing a name used when displaying the quantifier.
2098
2099        >>> f = Function('f', IntSort(), IntSort(), IntSort())
2100        >>> x = Int('x')
2101        >>> y = Int('y')
2102        >>> q = ForAll([x, y], f(x, y) >= x)
2103        >>> q.var_name(0)
2104        'x'
2105        >>> q.var_name(1)
2106        'y'
2107        """
2108        if z3_debug():
2109            _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2110        return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
2111
2112    def var_sort(self, idx):
2113        """Return the sort of a bound variable.
2114
2115        >>> f = Function('f', IntSort(), RealSort(), IntSort())
2116        >>> x = Int('x')
2117        >>> y = Real('y')
2118        >>> q = ForAll([x, y], f(x, y) >= x)
2119        >>> q.var_sort(0)
2120        Int
2121        >>> q.var_sort(1)
2122        Real
2123        """
2124        if z3_debug():
2125            _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2126        return _to_sort_ref(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
2127
2128    def children(self):
2129        """Return a list containing a single element self.body()
2130
2131        >>> f = Function('f', IntSort(), IntSort())
2132        >>> x = Int('x')
2133        >>> q = ForAll(x, f(x) == 0)
2134        >>> q.children()
2135        [f(Var(0)) == 0]
2136        """
2137        return [self.body()]
2138
2139
2140def is_quantifier(a):
2141    """Return `True` if `a` is a Z3 quantifier.
2142
2143    >>> f = Function('f', IntSort(), IntSort())
2144    >>> x = Int('x')
2145    >>> q = ForAll(x, f(x) == 0)
2146    >>> is_quantifier(q)
2147    True
2148    >>> is_quantifier(f(x))
2149    False
2150    """
2151    return isinstance(a, QuantifierRef)
2152
2153
2154def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2155    if z3_debug():
2156        _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2157        _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2158        _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2159        _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2160    if is_app(vs):
2161        ctx = vs.ctx
2162        vs = [vs]
2163    else:
2164        ctx = vs[0].ctx
2165    if not is_expr(body):
2166        body = BoolVal(body, ctx)
2167    num_vars = len(vs)
2168    if num_vars == 0:
2169        return body
2170    _vs = (Ast * num_vars)()
2171    for i in range(num_vars):
2172        # TODO: Check if is constant
2173        _vs[i] = vs[i].as_ast()
2174    patterns = [_to_pattern(p) for p in patterns]
2175    num_pats = len(patterns)
2176    _pats = (Pattern * num_pats)()
2177    for i in range(num_pats):
2178        _pats[i] = patterns[i].ast
2179    _no_pats, num_no_pats = _to_ast_array(no_patterns)
2180    qid = to_symbol(qid, ctx)
2181    skid = to_symbol(skid, ctx)
2182    return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2183                                                   num_vars, _vs,
2184                                                   num_pats, _pats,
2185                                                   num_no_pats, _no_pats,
2186                                                   body.as_ast()), ctx)
2187
2188
2189def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2190    """Create a Z3 forall formula.
2191
2192    The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2193
2194    >>> f = Function('f', IntSort(), IntSort(), IntSort())
2195    >>> x = Int('x')
2196    >>> y = Int('y')
2197    >>> ForAll([x, y], f(x, y) >= x)
2198    ForAll([x, y], f(x, y) >= x)
2199    >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2200    ForAll([x, y], f(x, y) >= x)
2201    >>> ForAll([x, y], f(x, y) >= x, weight=10)
2202    ForAll([x, y], f(x, y) >= x)
2203    """
2204    return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2205
2206
2207def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2208    """Create a Z3 exists formula.
2209
2210    The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2211
2212
2213    >>> f = Function('f', IntSort(), IntSort(), IntSort())
2214    >>> x = Int('x')
2215    >>> y = Int('y')
2216    >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2217    >>> q
2218    Exists([x, y], f(x, y) >= x)
2219    >>> is_quantifier(q)
2220    True
2221    >>> r = Tactic('nnf')(q).as_expr()
2222    >>> is_quantifier(r)
2223    False
2224    """
2225    return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2226
2227
2228def Lambda(vs, body):
2229    """Create a Z3 lambda expression.
2230
2231    >>> f = Function('f', IntSort(), IntSort(), IntSort())
2232    >>> mem0 = Array('mem0', IntSort(), IntSort())
2233    >>> lo, hi, e, i = Ints('lo hi e i')
2234    >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2235    >>> mem1
2236    Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2237    """
2238    ctx = body.ctx
2239    if is_app(vs):
2240        vs = [vs]
2241    num_vars = len(vs)
2242    _vs = (Ast * num_vars)()
2243    for i in range(num_vars):
2244        # TODO: Check if is constant
2245        _vs[i] = vs[i].as_ast()
2246    return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2247
2248#########################################
2249#
2250# Arithmetic
2251#
2252#########################################
2253
2254
2255class ArithSortRef(SortRef):
2256    """Real and Integer sorts."""
2257
2258    def is_real(self):
2259        """Return `True` if `self` is of the sort Real.
2260
2261        >>> x = Real('x')
2262        >>> x.is_real()
2263        True
2264        >>> (x + 1).is_real()
2265        True
2266        >>> x = Int('x')
2267        >>> x.is_real()
2268        False
2269        """
2270        return self.kind() == Z3_REAL_SORT
2271
2272    def is_int(self):
2273        """Return `True` if `self` is of the sort Integer.
2274
2275        >>> x = Int('x')
2276        >>> x.is_int()
2277        True
2278        >>> (x + 1).is_int()
2279        True
2280        >>> x = Real('x')
2281        >>> x.is_int()
2282        False
2283        """
2284        return self.kind() == Z3_INT_SORT
2285
2286    def subsort(self, other):
2287        """Return `True` if `self` is a subsort of `other`."""
2288        return self.is_int() and is_arith_sort(other) and other.is_real()
2289
2290    def cast(self, val):
2291        """Try to cast `val` as an Integer or Real.
2292
2293        >>> IntSort().cast(10)
2294        10
2295        >>> is_int(IntSort().cast(10))
2296        True
2297        >>> is_int(10)
2298        False
2299        >>> RealSort().cast(10)
2300        10
2301        >>> is_real(RealSort().cast(10))
2302        True
2303        """
2304        if is_expr(val):
2305            if z3_debug():
2306                _z3_assert(self.ctx == val.ctx, "Context mismatch")
2307            val_s = val.sort()
2308            if self.eq(val_s):
2309                return val
2310            if val_s.is_int() and self.is_real():
2311                return ToReal(val)
2312            if val_s.is_bool() and self.is_int():
2313                return If(val, 1, 0)
2314            if val_s.is_bool() and self.is_real():
2315                return ToReal(If(val, 1, 0))
2316            if z3_debug():
2317                _z3_assert(False, "Z3 Integer/Real expression expected")
2318        else:
2319            if self.is_int():
2320                return IntVal(val, self.ctx)
2321            if self.is_real():
2322                return RealVal(val, self.ctx)
2323            if z3_debug():
2324                msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2325                _z3_assert(False, msg % self)
2326
2327
2328def is_arith_sort(s):
2329    """Return `True` if s is an arithmetical sort (type).
2330
2331    >>> is_arith_sort(IntSort())
2332    True
2333    >>> is_arith_sort(RealSort())
2334    True
2335    >>> is_arith_sort(BoolSort())
2336    False
2337    >>> n = Int('x') + 1
2338    >>> is_arith_sort(n.sort())
2339    True
2340    """
2341    return isinstance(s, ArithSortRef)
2342
2343
2344class ArithRef(ExprRef):
2345    """Integer and Real expressions."""
2346
2347    def sort(self):
2348        """Return the sort (type) of the arithmetical expression `self`.
2349
2350        >>> Int('x').sort()
2351        Int
2352        >>> (Real('x') + 1).sort()
2353        Real
2354        """
2355        return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
2356
2357    def is_int(self):
2358        """Return `True` if `self` is an integer expression.
2359
2360        >>> x = Int('x')
2361        >>> x.is_int()
2362        True
2363        >>> (x + 1).is_int()
2364        True
2365        >>> y = Real('y')
2366        >>> (x + y).is_int()
2367        False
2368        """
2369        return self.sort().is_int()
2370
2371    def is_real(self):
2372        """Return `True` if `self` is an real expression.
2373
2374        >>> x = Real('x')
2375        >>> x.is_real()
2376        True
2377        >>> (x + 1).is_real()
2378        True
2379        """
2380        return self.sort().is_real()
2381
2382    def __add__(self, other):
2383        """Create the Z3 expression `self + other`.
2384
2385        >>> x = Int('x')
2386        >>> y = Int('y')
2387        >>> x + y
2388        x + y
2389        >>> (x + y).sort()
2390        Int
2391        """
2392        a, b = _coerce_exprs(self, other)
2393        return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctx)
2394
2395    def __radd__(self, other):
2396        """Create the Z3 expression `other + self`.
2397
2398        >>> x = Int('x')
2399        >>> 10 + x
2400        10 + x
2401        """
2402        a, b = _coerce_exprs(self, other)
2403        return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctx)
2404
2405    def __mul__(self, other):
2406        """Create the Z3 expression `self * other`.
2407
2408        >>> x = Real('x')
2409        >>> y = Real('y')
2410        >>> x * y
2411        x*y
2412        >>> (x * y).sort()
2413        Real
2414        """
2415        if isinstance(other, BoolRef):
2416            return If(other, self, 0)
2417        a, b = _coerce_exprs(self, other)
2418        return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
2419
2420    def __rmul__(self, other):
2421        """Create the Z3 expression `other * self`.
2422
2423        >>> x = Real('x')
2424        >>> 10 * x
2425        10*x
2426        """
2427        a, b = _coerce_exprs(self, other)
2428        return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctx)
2429
2430    def __sub__(self, other):
2431        """Create the Z3 expression `self - other`.
2432
2433        >>> x = Int('x')
2434        >>> y = Int('y')
2435        >>> x - y
2436        x - y
2437        >>> (x - y).sort()
2438        Int
2439        """
2440        a, b = _coerce_exprs(self, other)
2441        return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctx)
2442
2443    def __rsub__(self, other):
2444        """Create the Z3 expression `other - self`.
2445
2446        >>> x = Int('x')
2447        >>> 10 - x
2448        10 - x
2449        """
2450        a, b = _coerce_exprs(self, other)
2451        return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctx)
2452
2453    def __pow__(self, other):
2454        """Create the Z3 expression `self**other` (** is the power operator).
2455
2456        >>> x = Real('x')
2457        >>> x**3
2458        x**3
2459        >>> (x**3).sort()
2460        Real
2461        >>> simplify(IntVal(2)**8)
2462        256
2463        """
2464        a, b = _coerce_exprs(self, other)
2465        return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2466
2467    def __rpow__(self, other):
2468        """Create the Z3 expression `other**self` (** is the power operator).
2469
2470        >>> x = Real('x')
2471        >>> 2**x
2472        2**x
2473        >>> (2**x).sort()
2474        Real
2475        >>> simplify(2**IntVal(8))
2476        256
2477        """
2478        a, b = _coerce_exprs(self, other)
2479        return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2480
2481    def __div__(self, other):
2482        """Create the Z3 expression `other/self`.
2483
2484        >>> x = Int('x')
2485        >>> y = Int('y')
2486        >>> x/y
2487        x/y
2488        >>> (x/y).sort()
2489        Int
2490        >>> (x/y).sexpr()
2491        '(div x y)'
2492        >>> x = Real('x')
2493        >>> y = Real('y')
2494        >>> x/y
2495        x/y
2496        >>> (x/y).sort()
2497        Real
2498        >>> (x/y).sexpr()
2499        '(/ x y)'
2500        """
2501        a, b = _coerce_exprs(self, other)
2502        return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2503
2504    def __truediv__(self, other):
2505        """Create the Z3 expression `other/self`."""
2506        return self.__div__(other)
2507
2508    def __rdiv__(self, other):
2509        """Create the Z3 expression `other/self`.
2510
2511        >>> x = Int('x')
2512        >>> 10/x
2513        10/x
2514        >>> (10/x).sexpr()
2515        '(div 10 x)'
2516        >>> x = Real('x')
2517        >>> 10/x
2518        10/x
2519        >>> (10/x).sexpr()
2520        '(/ 10.0 x)'
2521        """
2522        a, b = _coerce_exprs(self, other)
2523        return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2524
2525    def __rtruediv__(self, other):
2526        """Create the Z3 expression `other/self`."""
2527        return self.__rdiv__(other)
2528
2529    def __mod__(self, other):
2530        """Create the Z3 expression `other%self`.
2531
2532        >>> x = Int('x')
2533        >>> y = Int('y')
2534        >>> x % y
2535        x%y
2536        >>> simplify(IntVal(10) % IntVal(3))
2537        1
2538        """
2539        a, b = _coerce_exprs(self, other)
2540        if z3_debug():
2541            _z3_assert(a.is_int(), "Z3 integer expression expected")
2542        return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2543
2544    def __rmod__(self, other):
2545        """Create the Z3 expression `other%self`.
2546
2547        >>> x = Int('x')
2548        >>> 10 % x
2549        10%x
2550        """
2551        a, b = _coerce_exprs(self, other)
2552        if z3_debug():
2553            _z3_assert(a.is_int(), "Z3 integer expression expected")
2554        return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2555
2556    def __neg__(self):
2557        """Return an expression representing `-self`.
2558
2559        >>> x = Int('x')
2560        >>> -x
2561        -x
2562        >>> simplify(-(-x))
2563        x
2564        """
2565        return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
2566
2567    def __pos__(self):
2568        """Return `self`.
2569
2570        >>> x = Int('x')
2571        >>> +x
2572        x
2573        """
2574        return self
2575
2576    def __le__(self, other):
2577        """Create the Z3 expression `other <= self`.
2578
2579        >>> x, y = Ints('x y')
2580        >>> x <= y
2581        x <= y
2582        >>> y = Real('y')
2583        >>> x <= y
2584        ToReal(x) <= y
2585        """
2586        a, b = _coerce_exprs(self, other)
2587        return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2588
2589    def __lt__(self, other):
2590        """Create the Z3 expression `other < self`.
2591
2592        >>> x, y = Ints('x y')
2593        >>> x < y
2594        x < y
2595        >>> y = Real('y')
2596        >>> x < y
2597        ToReal(x) < y
2598        """
2599        a, b = _coerce_exprs(self, other)
2600        return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2601
2602    def __gt__(self, other):
2603        """Create the Z3 expression `other > self`.
2604
2605        >>> x, y = Ints('x y')
2606        >>> x > y
2607        x > y
2608        >>> y = Real('y')
2609        >>> x > y
2610        ToReal(x) > y
2611        """
2612        a, b = _coerce_exprs(self, other)
2613        return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2614
2615    def __ge__(self, other):
2616        """Create the Z3 expression `other >= self`.
2617
2618        >>> x, y = Ints('x y')
2619        >>> x >= y
2620        x >= y
2621        >>> y = Real('y')
2622        >>> x >= y
2623        ToReal(x) >= y
2624        """
2625        a, b = _coerce_exprs(self, other)
2626        return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2627
2628
2629def is_arith(a):
2630    """Return `True` if `a` is an arithmetical expression.
2631
2632    >>> x = Int('x')
2633    >>> is_arith(x)
2634    True
2635    >>> is_arith(x + 1)
2636    True
2637    >>> is_arith(1)
2638    False
2639    >>> is_arith(IntVal(1))
2640    True
2641    >>> y = Real('y')
2642    >>> is_arith(y)
2643    True
2644    >>> is_arith(y + 1)
2645    True
2646    """
2647    return isinstance(a, ArithRef)
2648
2649
2650def is_int(a):
2651    """Return `True` if `a` is an integer expression.
2652
2653    >>> x = Int('x')
2654    >>> is_int(x + 1)
2655    True
2656    >>> is_int(1)
2657    False
2658    >>> is_int(IntVal(1))
2659    True
2660    >>> y = Real('y')
2661    >>> is_int(y)
2662    False
2663    >>> is_int(y + 1)
2664    False
2665    """
2666    return is_arith(a) and a.is_int()
2667
2668
2669def is_real(a):
2670    """Return `True` if `a` is a real expression.
2671
2672    >>> x = Int('x')
2673    >>> is_real(x + 1)
2674    False
2675    >>> y = Real('y')
2676    >>> is_real(y)
2677    True
2678    >>> is_real(y + 1)
2679    True
2680    >>> is_real(1)
2681    False
2682    >>> is_real(RealVal(1))
2683    True
2684    """
2685    return is_arith(a) and a.is_real()
2686
2687
2688def _is_numeral(ctx, a):
2689    return Z3_is_numeral_ast(ctx.ref(), a)
2690
2691
2692def _is_algebraic(ctx, a):
2693    return Z3_is_algebraic_number(ctx.ref(), a)
2694
2695
2696def is_int_value(a):
2697    """Return `True` if `a` is an integer value of sort Int.
2698
2699    >>> is_int_value(IntVal(1))
2700    True
2701    >>> is_int_value(1)
2702    False
2703    >>> is_int_value(Int('x'))
2704    False
2705    >>> n = Int('x') + 1
2706    >>> n
2707    x + 1
2708    >>> n.arg(1)
2709    1
2710    >>> is_int_value(n.arg(1))
2711    True
2712    >>> is_int_value(RealVal("1/3"))
2713    False
2714    >>> is_int_value(RealVal(1))
2715    False
2716    """
2717    return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2718
2719
2720def is_rational_value(a):
2721    """Return `True` if `a` is rational value of sort Real.
2722
2723    >>> is_rational_value(RealVal(1))
2724    True
2725    >>> is_rational_value(RealVal("3/5"))
2726    True
2727    >>> is_rational_value(IntVal(1))
2728    False
2729    >>> is_rational_value(1)
2730    False
2731    >>> n = Real('x') + 1
2732    >>> n.arg(1)
2733    1
2734    >>> is_rational_value(n.arg(1))
2735    True
2736    >>> is_rational_value(Real('x'))
2737    False
2738    """
2739    return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2740
2741
2742def is_algebraic_value(a):
2743    """Return `True` if `a` is an algebraic value of sort Real.
2744
2745    >>> is_algebraic_value(RealVal("3/5"))
2746    False
2747    >>> n = simplify(Sqrt(2))
2748    >>> n
2749    1.4142135623?
2750    >>> is_algebraic_value(n)
2751    True
2752    """
2753    return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2754
2755
2756def is_add(a):
2757    """Return `True` if `a` is an expression of the form b + c.
2758
2759    >>> x, y = Ints('x y')
2760    >>> is_add(x + y)
2761    True
2762    >>> is_add(x - y)
2763    False
2764    """
2765    return is_app_of(a, Z3_OP_ADD)
2766
2767
2768def is_mul(a):
2769    """Return `True` if `a` is an expression of the form b * c.
2770
2771    >>> x, y = Ints('x y')
2772    >>> is_mul(x * y)
2773    True
2774    >>> is_mul(x - y)
2775    False
2776    """
2777    return is_app_of(a, Z3_OP_MUL)
2778
2779
2780def is_sub(a):
2781    """Return `True` if `a` is an expression of the form b - c.
2782
2783    >>> x, y = Ints('x y')
2784    >>> is_sub(x - y)
2785    True
2786    >>> is_sub(x + y)
2787    False
2788    """
2789    return is_app_of(a, Z3_OP_SUB)
2790
2791
2792def is_div(a):
2793    """Return `True` if `a` is an expression of the form b / c.
2794
2795    >>> x, y = Reals('x y')
2796    >>> is_div(x / y)
2797    True
2798    >>> is_div(x + y)
2799    False
2800    >>> x, y = Ints('x y')
2801    >>> is_div(x / y)
2802    False
2803    >>> is_idiv(x / y)
2804    True
2805    """
2806    return is_app_of(a, Z3_OP_DIV)
2807
2808
2809def is_idiv(a):
2810    """Return `True` if `a` is an expression of the form b div c.
2811
2812    >>> x, y = Ints('x y')
2813    >>> is_idiv(x / y)
2814    True
2815    >>> is_idiv(x + y)
2816    False
2817    """
2818    return is_app_of(a, Z3_OP_IDIV)
2819
2820
2821def is_mod(a):
2822    """Return `True` if `a` is an expression of the form b % c.
2823
2824    >>> x, y = Ints('x y')
2825    >>> is_mod(x % y)
2826    True
2827    >>> is_mod(x + y)
2828    False
2829    """
2830    return is_app_of(a, Z3_OP_MOD)
2831
2832
2833def is_le(a):
2834    """Return `True` if `a` is an expression of the form b <= c.
2835
2836    >>> x, y = Ints('x y')
2837    >>> is_le(x <= y)
2838    True
2839    >>> is_le(x < y)
2840    False
2841    """
2842    return is_app_of(a, Z3_OP_LE)
2843
2844
2845def is_lt(a):
2846    """Return `True` if `a` is an expression of the form b < c.
2847
2848    >>> x, y = Ints('x y')
2849    >>> is_lt(x < y)
2850    True
2851    >>> is_lt(x == y)
2852    False
2853    """
2854    return is_app_of(a, Z3_OP_LT)
2855
2856
2857def is_ge(a):
2858    """Return `True` if `a` is an expression of the form b >= c.
2859
2860    >>> x, y = Ints('x y')
2861    >>> is_ge(x >= y)
2862    True
2863    >>> is_ge(x == y)
2864    False
2865    """
2866    return is_app_of(a, Z3_OP_GE)
2867
2868
2869def is_gt(a):
2870    """Return `True` if `a` is an expression of the form b > c.
2871
2872    >>> x, y = Ints('x y')
2873    >>> is_gt(x > y)
2874    True
2875    >>> is_gt(x == y)
2876    False
2877    """
2878    return is_app_of(a, Z3_OP_GT)
2879
2880
2881def is_is_int(a):
2882    """Return `True` if `a` is an expression of the form IsInt(b).
2883
2884    >>> x = Real('x')
2885    >>> is_is_int(IsInt(x))
2886    True
2887    >>> is_is_int(x)
2888    False
2889    """
2890    return is_app_of(a, Z3_OP_IS_INT)
2891
2892
2893def is_to_real(a):
2894    """Return `True` if `a` is an expression of the form ToReal(b).
2895
2896    >>> x = Int('x')
2897    >>> n = ToReal(x)
2898    >>> n
2899    ToReal(x)
2900    >>> is_to_real(n)
2901    True
2902    >>> is_to_real(x)
2903    False
2904    """
2905    return is_app_of(a, Z3_OP_TO_REAL)
2906
2907
2908def is_to_int(a):
2909    """Return `True` if `a` is an expression of the form ToInt(b).
2910
2911    >>> x = Real('x')
2912    >>> n = ToInt(x)
2913    >>> n
2914    ToInt(x)
2915    >>> is_to_int(n)
2916    True
2917    >>> is_to_int(x)
2918    False
2919    """
2920    return is_app_of(a, Z3_OP_TO_INT)
2921
2922
2923class IntNumRef(ArithRef):
2924    """Integer values."""
2925
2926    def as_long(self):
2927        """Return a Z3 integer numeral as a Python long (bignum) numeral.
2928
2929        >>> v = IntVal(1)
2930        >>> v + 1
2931        1 + 1
2932        >>> v.as_long() + 1
2933        2
2934        """
2935        if z3_debug():
2936            _z3_assert(self.is_int(), "Integer value expected")
2937        return int(self.as_string())
2938
2939    def as_string(self):
2940        """Return a Z3 integer numeral as a Python string.
2941        >>> v = IntVal(100)
2942        >>> v.as_string()
2943        '100'
2944        """
2945        return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
2946
2947    def as_binary_string(self):
2948        """Return a Z3 integer numeral as a Python binary string.
2949        >>> v = IntVal(10)
2950        >>> v.as_binary_string()
2951        '1010'
2952        """
2953        return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
2954
2955
2956class RatNumRef(ArithRef):
2957    """Rational values."""
2958
2959    def numerator(self):
2960        """ Return the numerator of a Z3 rational numeral.
2961
2962        >>> is_rational_value(RealVal("3/5"))
2963        True
2964        >>> n = RealVal("3/5")
2965        >>> n.numerator()
2966        3
2967        >>> is_rational_value(Q(3,5))
2968        True
2969        >>> Q(3,5).numerator()
2970        3
2971        """
2972        return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
2973
2974    def denominator(self):
2975        """ Return the denominator of a Z3 rational numeral.
2976
2977        >>> is_rational_value(Q(3,5))
2978        True
2979        >>> n = Q(3,5)
2980        >>> n.denominator()
2981        5
2982        """
2983        return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
2984
2985    def numerator_as_long(self):
2986        """ Return the numerator as a Python long.
2987
2988        >>> v = RealVal(10000000000)
2989        >>> v
2990        10000000000
2991        >>> v + 1
2992        10000000000 + 1
2993        >>> v.numerator_as_long() + 1 == 10000000001
2994        True
2995        """
2996        return self.numerator().as_long()
2997
2998    def denominator_as_long(self):
2999        """ Return the denominator as a Python long.
3000
3001        >>> v = RealVal("1/3")
3002        >>> v
3003        1/3
3004        >>> v.denominator_as_long()
3005        3
3006        """
3007        return self.denominator().as_long()
3008
3009    def is_int(self):
3010        return False
3011
3012    def is_real(self):
3013        return True
3014
3015    def is_int_value(self):
3016        return self.denominator().is_int() and self.denominator_as_long() == 1
3017
3018    def as_long(self):
3019        _z3_assert(self.is_int_value(), "Expected integer fraction")
3020        return self.numerator_as_long()
3021
3022    def as_decimal(self, prec):
3023        """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3024
3025        >>> v = RealVal("1/5")
3026        >>> v.as_decimal(3)
3027        '0.2'
3028        >>> v = RealVal("1/3")
3029        >>> v.as_decimal(3)
3030        '0.333?'
3031        """
3032        return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3033
3034    def as_string(self):
3035        """Return a Z3 rational numeral as a Python string.
3036
3037        >>> v = Q(3,6)
3038        >>> v.as_string()
3039        '1/2'
3040        """
3041        return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3042
3043    def as_fraction(self):
3044        """Return a Z3 rational as a Python Fraction object.
3045
3046        >>> v = RealVal("1/5")
3047        >>> v.as_fraction()
3048        Fraction(1, 5)
3049        """
3050        return Fraction(self.numerator_as_long(), self.denominator_as_long())
3051
3052
3053class AlgebraicNumRef(ArithRef):
3054    """Algebraic irrational values."""
3055
3056    def approx(self, precision=10):
3057        """Return a Z3 rational number that approximates the algebraic number `self`.
3058        The result `r` is such that |r - self| <= 1/10^precision
3059
3060        >>> x = simplify(Sqrt(2))
3061        >>> x.approx(20)
3062        6838717160008073720548335/4835703278458516698824704
3063        >>> x.approx(5)
3064        2965821/2097152
3065        """
3066        return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
3067
3068    def as_decimal(self, prec):
3069        """Return a string representation of the algebraic number `self` in decimal notation
3070        using `prec` decimal places.
3071
3072        >>> x = simplify(Sqrt(2))
3073        >>> x.as_decimal(10)
3074        '1.4142135623?'
3075        >>> x.as_decimal(20)
3076        '1.41421356237309504880?'
3077        """
3078        return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3079
3080    def poly(self):
3081        return AstVector(Z3_algebraic_get_poly(self.ctx_ref(), self.as_ast()), self.ctx)
3082
3083    def index(self):
3084        return Z3_algebraic_get_i(self.ctx_ref(), self.as_ast())
3085
3086
3087def _py2expr(a, ctx=None):
3088    if isinstance(a, bool):
3089        return BoolVal(a, ctx)
3090    if _is_int(a):
3091        return IntVal(a, ctx)
3092    if isinstance(a, float):
3093        return RealVal(a, ctx)
3094    if isinstance(a, str):
3095        return StringVal(a, ctx)
3096    if is_expr(a):
3097        return a
3098    if z3_debug():
3099        _z3_assert(False, "Python bool, int, long or float expected")
3100
3101
3102def IntSort(ctx=None):
3103    """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3104
3105    >>> IntSort()
3106    Int
3107    >>> x = Const('x', IntSort())
3108    >>> is_int(x)
3109    True
3110    >>> x.sort() == IntSort()
3111    True
3112    >>> x.sort() == BoolSort()
3113    False
3114    """
3115    ctx = _get_ctx(ctx)
3116    return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3117
3118
3119def RealSort(ctx=None):
3120    """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3121
3122    >>> RealSort()
3123    Real
3124    >>> x = Const('x', RealSort())
3125    >>> is_real(x)
3126    True
3127    >>> is_int(x)
3128    False
3129    >>> x.sort() == RealSort()
3130    True
3131    """
3132    ctx = _get_ctx(ctx)
3133    return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3134
3135
3136def _to_int_str(val):
3137    if isinstance(val, float):
3138        return str(int(val))
3139    elif isinstance(val, bool):
3140        if val:
3141            return "1"
3142        else:
3143            return "0"
3144    elif _is_int(val):
3145        return str(val)
3146    elif isinstance(val, str):
3147        return val
3148    if z3_debug():
3149        _z3_assert(False, "Python value cannot be used as a Z3 integer")
3150
3151
3152def IntVal(val, ctx=None):
3153    """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3154
3155    >>> IntVal(1)
3156    1
3157    >>> IntVal("100")
3158    100
3159    """
3160    ctx = _get_ctx(ctx)
3161    return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3162
3163
3164def RealVal(val, ctx=None):
3165    """Return a Z3 real value.
3166
3167    `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3168    If `ctx=None`, then the global context is used.
3169
3170    >>> RealVal(1)
3171    1
3172    >>> RealVal(1).sort()
3173    Real
3174    >>> RealVal("3/5")
3175    3/5
3176    >>> RealVal("1.5")
3177    3/2
3178    """
3179    ctx = _get_ctx(ctx)
3180    return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3181
3182
3183def RatVal(a, b, ctx=None):
3184    """Return a Z3 rational a/b.
3185
3186    If `ctx=None`, then the global context is used.
3187
3188    >>> RatVal(3,5)
3189    3/5
3190    >>> RatVal(3,5).sort()
3191    Real
3192    """
3193    if z3_debug():
3194        _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3195        _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3196    return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3197
3198
3199def Q(a, b, ctx=None):
3200    """Return a Z3 rational a/b.
3201
3202    If `ctx=None`, then the global context is used.
3203
3204    >>> Q(3,5)
3205    3/5
3206    >>> Q(3,5).sort()
3207    Real
3208    """
3209    return simplify(RatVal(a, b, ctx=ctx))
3210
3211
3212def Int(name, ctx=None):
3213    """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3214
3215    >>> x = Int('x')
3216    >>> is_int(x)
3217    True
3218    >>> is_int(x + 1)
3219    True
3220    """
3221    ctx = _get_ctx(ctx)
3222    return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3223
3224
3225def Ints(names, ctx=None):
3226    """Return a tuple of Integer constants.
3227
3228    >>> x, y, z = Ints('x y z')
3229    >>> Sum(x, y, z)
3230    x + y + z
3231    """
3232    ctx = _get_ctx(ctx)
3233    if isinstance(names, str):
3234        names = names.split(" ")
3235    return [Int(name, ctx) for name in names]
3236
3237
3238def IntVector(prefix, sz, ctx=None):
3239    """Return a list of integer constants of size `sz`.
3240
3241    >>> X = IntVector('x', 3)
3242    >>> X
3243    [x__0, x__1, x__2]
3244    >>> Sum(X)
3245    x__0 + x__1 + x__2
3246    """
3247    ctx = _get_ctx(ctx)
3248    return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3249
3250
3251def FreshInt(prefix="x", ctx=None):
3252    """Return a fresh integer constant in the given context using the given prefix.
3253
3254    >>> x = FreshInt()
3255    >>> y = FreshInt()
3256    >>> eq(x, y)
3257    False
3258    >>> x.sort()
3259    Int
3260    """
3261    ctx = _get_ctx(ctx)
3262    return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3263
3264
3265def Real(name, ctx=None):
3266    """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3267
3268    >>> x = Real('x')
3269    >>> is_real(x)
3270    True
3271    >>> is_real(x + 1)
3272    True
3273    """
3274    ctx = _get_ctx(ctx)
3275    return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3276
3277
3278def Reals(names, ctx=None):
3279    """Return a tuple of real constants.
3280
3281    >>> x, y, z = Reals('x y z')
3282    >>> Sum(x, y, z)
3283    x + y + z
3284    >>> Sum(x, y, z).sort()
3285    Real
3286    """
3287    ctx = _get_ctx(ctx)
3288    if isinstance(names, str):
3289        names = names.split(" ")
3290    return [Real(name, ctx) for name in names]
3291
3292
3293def RealVector(prefix, sz, ctx=None):
3294    """Return a list of real constants of size `sz`.
3295
3296    >>> X = RealVector('x', 3)
3297    >>> X
3298    [x__0, x__1, x__2]
3299    >>> Sum(X)
3300    x__0 + x__1 + x__2
3301    >>> Sum(X).sort()
3302    Real
3303    """
3304    ctx = _get_ctx(ctx)
3305    return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3306
3307
3308def FreshReal(prefix="b", ctx=None):
3309    """Return a fresh real constant in the given context using the given prefix.
3310
3311    >>> x = FreshReal()
3312    >>> y = FreshReal()
3313    >>> eq(x, y)
3314    False
3315    >>> x.sort()
3316    Real
3317    """
3318    ctx = _get_ctx(ctx)
3319    return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3320
3321
3322def ToReal(a):
3323    """ Return the Z3 expression ToReal(a).
3324
3325    >>> x = Int('x')
3326    >>> x.sort()
3327    Int
3328    >>> n = ToReal(x)
3329    >>> n
3330    ToReal(x)
3331    >>> n.sort()
3332    Real
3333    """
3334    if z3_debug():
3335        _z3_assert(a.is_int(), "Z3 integer expression expected.")
3336    ctx = a.ctx
3337    return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3338
3339
3340def ToInt(a):
3341    """ Return the Z3 expression ToInt(a).
3342
3343    >>> x = Real('x')
3344    >>> x.sort()
3345    Real
3346    >>> n = ToInt(x)
3347    >>> n
3348    ToInt(x)
3349    >>> n.sort()
3350    Int
3351    """
3352    if z3_debug():
3353        _z3_assert(a.is_real(), "Z3 real expression expected.")
3354    ctx = a.ctx
3355    return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3356
3357
3358def IsInt(a):
3359    """ Return the Z3 predicate IsInt(a).
3360
3361    >>> x = Real('x')
3362    >>> IsInt(x + "1/2")
3363    IsInt(x + 1/2)
3364    >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3365    [x = 1/2]
3366    >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3367    no solution
3368    """
3369    if z3_debug():
3370        _z3_assert(a.is_real(), "Z3 real expression expected.")
3371    ctx = a.ctx
3372    return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3373
3374
3375def Sqrt(a, ctx=None):
3376    """ Return a Z3 expression which represents the square root of a.
3377
3378    >>> x = Real('x')
3379    >>> Sqrt(x)
3380    x**(1/2)
3381    """
3382    if not is_expr(a):
3383        ctx = _get_ctx(ctx)
3384        a = RealVal(a, ctx)
3385    return a ** "1/2"
3386
3387
3388def Cbrt(a, ctx=None):
3389    """ Return a Z3 expression which represents the cubic root of a.
3390
3391    >>> x = Real('x')
3392    >>> Cbrt(x)
3393    x**(1/3)
3394    """
3395    if not is_expr(a):
3396        ctx = _get_ctx(ctx)
3397        a = RealVal(a, ctx)
3398    return a ** "1/3"
3399
3400#########################################
3401#
3402# Bit-Vectors
3403#
3404#########################################
3405
3406
3407class BitVecSortRef(SortRef):
3408    """Bit-vector sort."""
3409
3410    def size(self):
3411        """Return the size (number of bits) of the bit-vector sort `self`.
3412
3413        >>> b = BitVecSort(32)
3414        >>> b.size()
3415        32
3416        """
3417        return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
3418
3419    def subsort(self, other):
3420        return is_bv_sort(other) and self.size() < other.size()
3421
3422    def cast(self, val):
3423        """Try to cast `val` as a Bit-Vector.
3424
3425        >>> b = BitVecSort(32)
3426        >>> b.cast(10)
3427        10
3428        >>> b.cast(10).sexpr()
3429        '#x0000000a'
3430        """
3431        if is_expr(val):
3432            if z3_debug():
3433                _z3_assert(self.ctx == val.ctx, "Context mismatch")
3434            # Idea: use sign_extend if sort of val is a bitvector of smaller size
3435            return val
3436        else:
3437            return BitVecVal(val, self)
3438
3439
3440def is_bv_sort(s):
3441    """Return True if `s` is a Z3 bit-vector sort.
3442
3443    >>> is_bv_sort(BitVecSort(32))
3444    True
3445    >>> is_bv_sort(IntSort())
3446    False
3447    """
3448    return isinstance(s, BitVecSortRef)
3449
3450
3451class BitVecRef(ExprRef):
3452    """Bit-vector expressions."""
3453
3454    def sort(self):
3455        """Return the sort of the bit-vector expression `self`.
3456
3457        >>> x = BitVec('x', 32)
3458        >>> x.sort()
3459        BitVec(32)
3460        >>> x.sort() == BitVecSort(32)
3461        True
3462        """
3463        return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3464
3465    def size(self):
3466        """Return the number of bits of the bit-vector expression `self`.
3467
3468        >>> x = BitVec('x', 32)
3469        >>> (x + 1).size()
3470        32
3471        >>> Concat(x, x).size()
3472        64
3473        """
3474        return self.sort().size()
3475
3476    def __add__(self, other):
3477        """Create the Z3 expression `self + other`.
3478
3479        >>> x = BitVec('x', 32)
3480        >>> y = BitVec('y', 32)
3481        >>> x + y
3482        x + y
3483        >>> (x + y).sort()
3484        BitVec(32)
3485        """
3486        a, b = _coerce_exprs(self, other)
3487        return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3488
3489    def __radd__(self, other):
3490        """Create the Z3 expression `other + self`.
3491
3492        >>> x = BitVec('x', 32)
3493        >>> 10 + x
3494        10 + x
3495        """
3496        a, b = _coerce_exprs(self, other)
3497        return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3498
3499    def __mul__(self, other):
3500        """Create the Z3 expression `self * other`.
3501
3502        >>> x = BitVec('x', 32)
3503        >>> y = BitVec('y', 32)
3504        >>> x * y
3505        x*y
3506        >>> (x * y).sort()
3507        BitVec(32)
3508        """
3509        a, b = _coerce_exprs(self, other)
3510        return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3511
3512    def __rmul__(self, other):
3513        """Create the Z3 expression `other * self`.
3514
3515        >>> x = BitVec('x', 32)
3516        >>> 10 * x
3517        10*x
3518        """
3519        a, b = _coerce_exprs(self, other)
3520        return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3521
3522    def __sub__(self, other):
3523        """Create the Z3 expression `self - other`.
3524
3525        >>> x = BitVec('x', 32)
3526        >>> y = BitVec('y', 32)
3527        >>> x - y
3528        x - y
3529        >>> (x - y).sort()
3530        BitVec(32)
3531        """
3532        a, b = _coerce_exprs(self, other)
3533        return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3534
3535    def __rsub__(self, other):
3536        """Create the Z3 expression `other - self`.
3537
3538        >>> x = BitVec('x', 32)
3539        >>> 10 - x
3540        10 - x
3541        """
3542        a, b = _coerce_exprs(self, other)
3543        return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3544
3545    def __or__(self, other):
3546        """Create the Z3 expression bitwise-or `self | other`.
3547
3548        >>> x = BitVec('x', 32)
3549        >>> y = BitVec('y', 32)
3550        >>> x | y
3551        x | y
3552        >>> (x | y).sort()
3553        BitVec(32)
3554        """
3555        a, b = _coerce_exprs(self, other)
3556        return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3557
3558    def __ror__(self, other):
3559        """Create the Z3 expression bitwise-or `other | self`.
3560
3561        >>> x = BitVec('x', 32)
3562        >>> 10 | x
3563        10 | x
3564        """
3565        a, b = _coerce_exprs(self, other)
3566        return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3567
3568    def __and__(self, other):
3569        """Create the Z3 expression bitwise-and `self & other`.
3570
3571        >>> x = BitVec('x', 32)
3572        >>> y = BitVec('y', 32)
3573        >>> x & y
3574        x & y
3575        >>> (x & y).sort()
3576        BitVec(32)
3577        """
3578        a, b = _coerce_exprs(self, other)
3579        return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3580
3581    def __rand__(self, other):
3582        """Create the Z3 expression bitwise-or `other & self`.
3583
3584        >>> x = BitVec('x', 32)
3585        >>> 10 & x
3586        10 & x
3587        """
3588        a, b = _coerce_exprs(self, other)
3589        return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3590
3591    def __xor__(self, other):
3592        """Create the Z3 expression bitwise-xor `self ^ other`.
3593
3594        >>> x = BitVec('x', 32)
3595        >>> y = BitVec('y', 32)
3596        >>> x ^ y
3597        x ^ y
3598        >>> (x ^ y).sort()
3599        BitVec(32)
3600        """
3601        a, b = _coerce_exprs(self, other)
3602        return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3603
3604    def __rxor__(self, other):
3605        """Create the Z3 expression bitwise-xor `other ^ self`.
3606
3607        >>> x = BitVec('x', 32)
3608        >>> 10 ^ x
3609        10 ^ x
3610        """
3611        a, b = _coerce_exprs(self, other)
3612        return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3613
3614    def __pos__(self):
3615        """Return `self`.
3616
3617        >>> x = BitVec('x', 32)
3618        >>> +x
3619        x
3620        """
3621        return self
3622
3623    def __neg__(self):
3624        """Return an expression representing `-self`.
3625
3626        >>> x = BitVec('x', 32)
3627        >>> -x
3628        -x
3629        >>> simplify(-(-x))
3630        x
3631        """
3632        return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3633
3634    def __invert__(self):
3635        """Create the Z3 expression bitwise-not `~self`.
3636
3637        >>> x = BitVec('x', 32)
3638        >>> ~x
3639        ~x
3640        >>> simplify(~(~x))
3641        x
3642        """
3643        return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3644
3645    def __div__(self, other):
3646        """Create the Z3 expression (signed) division `self / other`.
3647
3648        Use the function UDiv() for unsigned division.
3649
3650        >>> x = BitVec('x', 32)
3651        >>> y = BitVec('y', 32)
3652        >>> x / y
3653        x/y
3654        >>> (x / y).sort()
3655        BitVec(32)
3656        >>> (x / y).sexpr()
3657        '(bvsdiv x y)'
3658        >>> UDiv(x, y).sexpr()
3659        '(bvudiv x y)'
3660        """
3661        a, b = _coerce_exprs(self, other)
3662        return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3663
3664    def __truediv__(self, other):
3665        """Create the Z3 expression (signed) division `self / other`."""
3666        return self.__div__(other)
3667
3668    def __rdiv__(self, other):
3669        """Create the Z3 expression (signed) division `other / self`.
3670
3671        Use the function UDiv() for unsigned division.
3672
3673        >>> x = BitVec('x', 32)
3674        >>> 10 / x
3675        10/x
3676        >>> (10 / x).sexpr()
3677        '(bvsdiv #x0000000a x)'
3678        >>> UDiv(10, x).sexpr()
3679        '(bvudiv #x0000000a x)'
3680        """
3681        a, b = _coerce_exprs(self, other)
3682        return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3683
3684    def __rtruediv__(self, other):
3685        """Create the Z3 expression (signed) division `other / self`."""
3686        return self.__rdiv__(other)
3687
3688    def __mod__(self, other):
3689        """Create the Z3 expression (signed) mod `self % other`.
3690
3691        Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3692
3693        >>> x = BitVec('x', 32)
3694        >>> y = BitVec('y', 32)
3695        >>> x % y
3696        x%y
3697        >>> (x % y).sort()
3698        BitVec(32)
3699        >>> (x % y).sexpr()
3700        '(bvsmod x y)'
3701        >>> URem(x, y).sexpr()
3702        '(bvurem x y)'
3703        >>> SRem(x, y).sexpr()
3704        '(bvsrem x y)'
3705        """
3706        a, b = _coerce_exprs(self, other)
3707        return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3708
3709    def __rmod__(self, other):
3710        """Create the Z3 expression (signed) mod `other % self`.
3711
3712        Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3713
3714        >>> x = BitVec('x', 32)
3715        >>> 10 % x
3716        10%x
3717        >>> (10 % x).sexpr()
3718        '(bvsmod #x0000000a x)'
3719        >>> URem(10, x).sexpr()
3720        '(bvurem #x0000000a x)'
3721        >>> SRem(10, x).sexpr()
3722        '(bvsrem #x0000000a x)'
3723        """
3724        a, b = _coerce_exprs(self, other)
3725        return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3726
3727    def __le__(self, other):
3728        """Create the Z3 expression (signed) `other <= self`.
3729
3730        Use the function ULE() for unsigned less than or equal to.
3731
3732        >>> x, y = BitVecs('x y', 32)
3733        >>> x <= y
3734        x <= y
3735        >>> (x <= y).sexpr()
3736        '(bvsle x y)'
3737        >>> ULE(x, y).sexpr()
3738        '(bvule x y)'
3739        """
3740        a, b = _coerce_exprs(self, other)
3741        return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3742
3743    def __lt__(self, other):
3744        """Create the Z3 expression (signed) `other < self`.
3745
3746        Use the function ULT() for unsigned less than.
3747
3748        >>> x, y = BitVecs('x y', 32)
3749        >>> x < y
3750        x < y
3751        >>> (x < y).sexpr()
3752        '(bvslt x y)'
3753        >>> ULT(x, y).sexpr()
3754        '(bvult x y)'
3755        """
3756        a, b = _coerce_exprs(self, other)
3757        return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3758
3759    def __gt__(self, other):
3760        """Create the Z3 expression (signed) `other > self`.
3761
3762        Use the function UGT() for unsigned greater than.
3763
3764        >>> x, y = BitVecs('x y', 32)
3765        >>> x > y
3766        x > y
3767        >>> (x > y).sexpr()
3768        '(bvsgt x y)'
3769        >>> UGT(x, y).sexpr()
3770        '(bvugt x y)'
3771        """
3772        a, b = _coerce_exprs(self, other)
3773        return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3774
3775    def __ge__(self, other):
3776        """Create the Z3 expression (signed) `other >= self`.
3777
3778        Use the function UGE() for unsigned greater than or equal to.
3779
3780        >>> x, y = BitVecs('x y', 32)
3781        >>> x >= y
3782        x >= y
3783        >>> (x >= y).sexpr()
3784        '(bvsge x y)'
3785        >>> UGE(x, y).sexpr()
3786        '(bvuge x y)'
3787        """
3788        a, b = _coerce_exprs(self, other)
3789        return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3790
3791    def __rshift__(self, other):
3792        """Create the Z3 expression (arithmetical) right shift `self >> other`
3793
3794        Use the function LShR() for the right logical shift
3795
3796        >>> x, y = BitVecs('x y', 32)
3797        >>> x >> y
3798        x >> y
3799        >>> (x >> y).sexpr()
3800        '(bvashr x y)'
3801        >>> LShR(x, y).sexpr()
3802        '(bvlshr x y)'
3803        >>> BitVecVal(4, 3)
3804        4
3805        >>> BitVecVal(4, 3).as_signed_long()
3806        -4
3807        >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3808        -2
3809        >>> simplify(BitVecVal(4, 3) >> 1)
3810        6
3811        >>> simplify(LShR(BitVecVal(4, 3), 1))
3812        2
3813        >>> simplify(BitVecVal(2, 3) >> 1)
3814        1
3815        >>> simplify(LShR(BitVecVal(2, 3), 1))
3816        1
3817        """
3818        a, b = _coerce_exprs(self, other)
3819        return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3820
3821    def __lshift__(self, other):
3822        """Create the Z3 expression left shift `self << other`
3823
3824        >>> x, y = BitVecs('x y', 32)
3825        >>> x << y
3826        x << y
3827        >>> (x << y).sexpr()
3828        '(bvshl x y)'
3829        >>> simplify(BitVecVal(2, 3) << 1)
3830        4
3831        """
3832        a, b = _coerce_exprs(self, other)
3833        return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3834
3835    def __rrshift__(self, other):
3836        """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
3837
3838        Use the function LShR() for the right logical shift
3839
3840        >>> x = BitVec('x', 32)
3841        >>> 10 >> x
3842        10 >> x
3843        >>> (10 >> x).sexpr()
3844        '(bvashr #x0000000a x)'
3845        """
3846        a, b = _coerce_exprs(self, other)
3847        return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3848
3849    def __rlshift__(self, other):
3850        """Create the Z3 expression left shift `other << self`.
3851
3852        Use the function LShR() for the right logical shift
3853
3854        >>> x = BitVec('x', 32)
3855        >>> 10 << x
3856        10 << x
3857        >>> (10 << x).sexpr()
3858        '(bvshl #x0000000a x)'
3859        """
3860        a, b = _coerce_exprs(self, other)
3861        return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3862
3863
3864class BitVecNumRef(BitVecRef):
3865    """Bit-vector values."""
3866
3867    def as_long(self):
3868        """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3869
3870        >>> v = BitVecVal(0xbadc0de, 32)
3871        >>> v
3872        195936478
3873        >>> print("0x%.8x" % v.as_long())
3874        0x0badc0de
3875        """
3876        return int(self.as_string())
3877
3878    def as_signed_long(self):
3879        """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3880        The most significant bit is assumed to be the sign.
3881
3882        >>> BitVecVal(4, 3).as_signed_long()
3883        -4
3884        >>> BitVecVal(7, 3).as_signed_long()
3885        -1
3886        >>> BitVecVal(3, 3).as_signed_long()
3887        3
3888        >>> BitVecVal(2**32 - 1, 32).as_signed_long()
3889        -1
3890        >>> BitVecVal(2**64 - 1, 64).as_signed_long()
3891        -1
3892        """
3893        sz = self.size()
3894        val = self.as_long()
3895        if val >= 2**(sz - 1):
3896            val = val - 2**sz
3897        if val < -2**(sz - 1):
3898            val = val + 2**sz
3899        return int(val)
3900
3901    def as_string(self):
3902        return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3903
3904    def as_binary_string(self):
3905        return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3906
3907
3908def is_bv(a):
3909    """Return `True` if `a` is a Z3 bit-vector expression.
3910
3911    >>> b = BitVec('b', 32)
3912    >>> is_bv(b)
3913    True
3914    >>> is_bv(b + 10)
3915    True
3916    >>> is_bv(Int('x'))
3917    False
3918    """
3919    return isinstance(a, BitVecRef)
3920
3921
3922def is_bv_value(a):
3923    """Return `True` if `a` is a Z3 bit-vector numeral value.
3924
3925    >>> b = BitVec('b', 32)
3926    >>> is_bv_value(b)
3927    False
3928    >>> b = BitVecVal(10, 32)
3929    >>> b
3930    10
3931    >>> is_bv_value(b)
3932    True
3933    """
3934    return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
3935
3936
3937def BV2Int(a, is_signed=False):
3938    """Return the Z3 expression BV2Int(a).
3939
3940    >>> b = BitVec('b', 3)
3941    >>> BV2Int(b).sort()
3942    Int
3943    >>> x = Int('x')
3944    >>> x > BV2Int(b)
3945    x > BV2Int(b)
3946    >>> x > BV2Int(b, is_signed=False)
3947    x > BV2Int(b)
3948    >>> x > BV2Int(b, is_signed=True)
3949    x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
3950    >>> solve(x > BV2Int(b), b == 1, x < 3)
3951    [x = 2, b = 1]
3952    """
3953    if z3_debug():
3954        _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
3955    ctx = a.ctx
3956    # investigate problem with bv2int
3957    return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
3958
3959
3960def Int2BV(a, num_bits):
3961    """Return the z3 expression Int2BV(a, num_bits).
3962    It is a bit-vector of width num_bits and represents the
3963    modulo of a by 2^num_bits
3964    """
3965    ctx = a.ctx
3966    return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
3967
3968
3969def BitVecSort(sz, ctx=None):
3970    """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
3971
3972    >>> Byte = BitVecSort(8)
3973    >>> Word = BitVecSort(16)
3974    >>> Byte
3975    BitVec(8)
3976    >>> x = Const('x', Byte)
3977    >>> eq(x, BitVec('x', 8))
3978    True
3979    """
3980    ctx = _get_ctx(ctx)
3981    return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
3982
3983
3984def BitVecVal(val, bv, ctx=None):
3985    """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
3986
3987    >>> v = BitVecVal(10, 32)
3988    >>> v
3989    10
3990    >>> print("0x%.8x" % v.as_long())
3991    0x0000000a
3992    """
3993    if is_bv_sort(bv):
3994        ctx = bv.ctx
3995        return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
3996    else:
3997        ctx = _get_ctx(ctx)
3998        return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
3999
4000
4001def BitVec(name, bv, ctx=None):
4002    """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4003    If `ctx=None`, then the global context is used.
4004
4005    >>> x  = BitVec('x', 16)
4006    >>> is_bv(x)
4007    True
4008    >>> x.size()
4009    16
4010    >>> x.sort()
4011    BitVec(16)
4012    >>> word = BitVecSort(16)
4013    >>> x2 = BitVec('x', word)
4014    >>> eq(x, x2)
4015    True
4016    """
4017    if isinstance(bv, BitVecSortRef):
4018        ctx = bv.ctx
4019    else:
4020        ctx = _get_ctx(ctx)
4021        bv = BitVecSort(bv, ctx)
4022    return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4023
4024
4025def BitVecs(names, bv, ctx=None):
4026    """Return a tuple of bit-vector constants of size bv.
4027
4028    >>> x, y, z = BitVecs('x y z', 16)
4029    >>> x.size()
4030    16
4031    >>> x.sort()
4032    BitVec(16)
4033    >>> Sum(x, y, z)
4034    0 + x + y + z
4035    >>> Product(x, y, z)
4036    1*x*y*z
4037    >>> simplify(Product(x, y, z))
4038    x*y*z
4039    """
4040    ctx = _get_ctx(ctx)
4041    if isinstance(names, str):
4042        names = names.split(" ")
4043    return [BitVec(name, bv, ctx) for name in names]
4044
4045
4046def Concat(*args):
4047    """Create a Z3 bit-vector concatenation expression.
4048
4049    >>> v = BitVecVal(1, 4)
4050    >>> Concat(v, v+1, v)
4051    Concat(Concat(1, 1 + 1), 1)
4052    >>> simplify(Concat(v, v+1, v))
4053    289
4054    >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4055    121
4056    """
4057    args = _get_args(args)
4058    sz = len(args)
4059    if z3_debug():
4060        _z3_assert(sz >= 2, "At least two arguments expected.")
4061
4062    ctx = None
4063    for a in args:
4064        if is_expr(a):
4065            ctx = a.ctx
4066            break
4067    if is_seq(args[0]) or isinstance(args[0], str):
4068        args = [_coerce_seq(s, ctx) for s in args]
4069        if z3_debug():
4070            _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4071        v = (Ast * sz)()
4072        for i in range(sz):
4073            v[i] = args[i].as_ast()
4074        return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4075
4076    if is_re(args[0]):
4077        if z3_debug():
4078            _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4079        v = (Ast * sz)()
4080        for i in range(sz):
4081            v[i] = args[i].as_ast()
4082        return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4083
4084    if z3_debug():
4085        _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4086    r = args[0]
4087    for i in range(sz - 1):
4088        r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4089    return r
4090
4091
4092def Extract(high, low, a):
4093    """Create a Z3 bit-vector extraction expression.
4094    Extract is overloaded to also work on sequence extraction.
4095    The functions SubString and SubSeq are redirected to Extract.
4096    For this case, the arguments are reinterpreted as:
4097        high - is a sequence (string)
4098        low  - is an offset
4099        a    - is the length to be extracted
4100
4101    >>> x = BitVec('x', 8)
4102    >>> Extract(6, 2, x)
4103    Extract(6, 2, x)
4104    >>> Extract(6, 2, x).sort()
4105    BitVec(5)
4106    >>> simplify(Extract(StringVal("abcd"),2,1))
4107    "c"
4108    """
4109    if isinstance(high, str):
4110        high = StringVal(high)
4111    if is_seq(high):
4112        s = high
4113        offset, length = _coerce_exprs(low, a, s.ctx)
4114        return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4115    if z3_debug():
4116        _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4117        _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4118                   "First and second arguments must be non negative integers")
4119        _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4120    return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4121
4122
4123def _check_bv_args(a, b):
4124    if z3_debug():
4125        _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4126
4127
4128def ULE(a, b):
4129    """Create the Z3 expression (unsigned) `other <= self`.
4130
4131    Use the operator <= for signed less than or equal to.
4132
4133    >>> x, y = BitVecs('x y', 32)
4134    >>> ULE(x, y)
4135    ULE(x, y)
4136    >>> (x <= y).sexpr()
4137    '(bvsle x y)'
4138    >>> ULE(x, y).sexpr()
4139    '(bvule x y)'
4140    """
4141    _check_bv_args(a, b)
4142    a, b = _coerce_exprs(a, b)
4143    return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4144
4145
4146def ULT(a, b):
4147    """Create the Z3 expression (unsigned) `other < self`.
4148
4149    Use the operator < for signed less than.
4150
4151    >>> x, y = BitVecs('x y', 32)
4152    >>> ULT(x, y)
4153    ULT(x, y)
4154    >>> (x < y).sexpr()
4155    '(bvslt x y)'
4156    >>> ULT(x, y).sexpr()
4157    '(bvult x y)'
4158    """
4159    _check_bv_args(a, b)
4160    a, b = _coerce_exprs(a, b)
4161    return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4162
4163
4164def UGE(a, b):
4165    """Create the Z3 expression (unsigned) `other >= self`.
4166
4167    Use the operator >= for signed greater than or equal to.
4168
4169    >>> x, y = BitVecs('x y', 32)
4170    >>> UGE(x, y)
4171    UGE(x, y)
4172    >>> (x >= y).sexpr()
4173    '(bvsge x y)'
4174    >>> UGE(x, y).sexpr()
4175    '(bvuge x y)'
4176    """
4177    _check_bv_args(a, b)
4178    a, b = _coerce_exprs(a, b)
4179    return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4180
4181
4182def UGT(a, b):
4183    """Create the Z3 expression (unsigned) `other > self`.
4184
4185    Use the operator > for signed greater than.
4186
4187    >>> x, y = BitVecs('x y', 32)
4188    >>> UGT(x, y)
4189    UGT(x, y)
4190    >>> (x > y).sexpr()
4191    '(bvsgt x y)'
4192    >>> UGT(x, y).sexpr()
4193    '(bvugt x y)'
4194    """
4195    _check_bv_args(a, b)
4196    a, b = _coerce_exprs(a, b)
4197    return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4198
4199
4200def UDiv(a, b):
4201    """Create the Z3 expression (unsigned) division `self / other`.
4202
4203    Use the operator / for signed division.
4204
4205    >>> x = BitVec('x', 32)
4206    >>> y = BitVec('y', 32)
4207    >>> UDiv(x, y)
4208    UDiv(x, y)
4209    >>> UDiv(x, y).sort()
4210    BitVec(32)
4211    >>> (x / y).sexpr()
4212    '(bvsdiv x y)'
4213    >>> UDiv(x, y).sexpr()
4214    '(bvudiv x y)'
4215    """
4216    _check_bv_args(a, b)
4217    a, b = _coerce_exprs(a, b)
4218    return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4219
4220
4221def URem(a, b):
4222    """Create the Z3 expression (unsigned) remainder `self % other`.
4223
4224    Use the operator % for signed modulus, and SRem() for signed remainder.
4225
4226    >>> x = BitVec('x', 32)
4227    >>> y = BitVec('y', 32)
4228    >>> URem(x, y)
4229    URem(x, y)
4230    >>> URem(x, y).sort()
4231    BitVec(32)
4232    >>> (x % y).sexpr()
4233    '(bvsmod x y)'
4234    >>> URem(x, y).sexpr()
4235    '(bvurem x y)'
4236    """
4237    _check_bv_args(a, b)
4238    a, b = _coerce_exprs(a, b)
4239    return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4240
4241
4242def SRem(a, b):
4243    """Create the Z3 expression signed remainder.
4244
4245    Use the operator % for signed modulus, and URem() for unsigned remainder.
4246
4247    >>> x = BitVec('x', 32)
4248    >>> y = BitVec('y', 32)
4249    >>> SRem(x, y)
4250    SRem(x, y)
4251    >>> SRem(x, y).sort()
4252    BitVec(32)
4253    >>> (x % y).sexpr()
4254    '(bvsmod x y)'
4255    >>> SRem(x, y).sexpr()
4256    '(bvsrem x y)'
4257    """
4258    _check_bv_args(a, b)
4259    a, b = _coerce_exprs(a, b)
4260    return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4261
4262
4263def LShR(a, b):
4264    """Create the Z3 expression logical right shift.
4265
4266    Use the operator >> for the arithmetical right shift.
4267
4268    >>> x, y = BitVecs('x y', 32)
4269    >>> LShR(x, y)
4270    LShR(x, y)
4271    >>> (x >> y).sexpr()
4272    '(bvashr x y)'
4273    >>> LShR(x, y).sexpr()
4274    '(bvlshr x y)'
4275    >>> BitVecVal(4, 3)
4276    4
4277    >>> BitVecVal(4, 3).as_signed_long()
4278    -4
4279    >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4280    -2
4281    >>> simplify(BitVecVal(4, 3) >> 1)
4282    6
4283    >>> simplify(LShR(BitVecVal(4, 3), 1))
4284    2
4285    >>> simplify(BitVecVal(2, 3) >> 1)
4286    1
4287    >>> simplify(LShR(BitVecVal(2, 3), 1))
4288    1
4289    """
4290    _check_bv_args(a, b)
4291    a, b = _coerce_exprs(a, b)
4292    return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4293
4294
4295def RotateLeft(a, b):
4296    """Return an expression representing `a` rotated to the left `b` times.
4297
4298    >>> a, b = BitVecs('a b', 16)
4299    >>> RotateLeft(a, b)
4300    RotateLeft(a, b)
4301    >>> simplify(RotateLeft(a, 0))
4302    a
4303    >>> simplify(RotateLeft(a, 16))
4304    a
4305    """
4306    _check_bv_args(a, b)
4307    a, b = _coerce_exprs(a, b)
4308    return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4309
4310
4311def RotateRight(a, b):
4312    """Return an expression representing `a` rotated to the right `b` times.
4313
4314    >>> a, b = BitVecs('a b', 16)
4315    >>> RotateRight(a, b)
4316    RotateRight(a, b)
4317    >>> simplify(RotateRight(a, 0))
4318    a
4319    >>> simplify(RotateRight(a, 16))
4320    a
4321    """
4322    _check_bv_args(a, b)
4323    a, b = _coerce_exprs(a, b)
4324    return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4325
4326
4327def SignExt(n, a):
4328    """Return a bit-vector expression with `n` extra sign-bits.
4329
4330    >>> x = BitVec('x', 16)
4331    >>> n = SignExt(8, x)
4332    >>> n.size()
4333    24
4334    >>> n
4335    SignExt(8, x)
4336    >>> n.sort()
4337    BitVec(24)
4338    >>> v0 = BitVecVal(2, 2)
4339    >>> v0
4340    2
4341    >>> v0.size()
4342    2
4343    >>> v  = simplify(SignExt(6, v0))
4344    >>> v
4345    254
4346    >>> v.size()
4347    8
4348    >>> print("%.x" % v.as_long())
4349    fe
4350    """
4351    if z3_debug():
4352        _z3_assert(_is_int(n), "First argument must be an integer")
4353        _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4354    return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4355
4356
4357def ZeroExt(n, a):
4358    """Return a bit-vector expression with `n` extra zero-bits.
4359
4360    >>> x = BitVec('x', 16)
4361    >>> n = ZeroExt(8, x)
4362    >>> n.size()
4363    24
4364    >>> n
4365    ZeroExt(8, x)
4366    >>> n.sort()
4367    BitVec(24)
4368    >>> v0 = BitVecVal(2, 2)
4369    >>> v0
4370    2
4371    >>> v0.size()
4372    2
4373    >>> v  = simplify(ZeroExt(6, v0))
4374    >>> v
4375    2
4376    >>> v.size()
4377    8
4378    """
4379    if z3_debug():
4380        _z3_assert(_is_int(n), "First argument must be an integer")
4381        _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4382    return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4383
4384
4385def RepeatBitVec(n, a):
4386    """Return an expression representing `n` copies of `a`.
4387
4388    >>> x = BitVec('x', 8)
4389    >>> n = RepeatBitVec(4, x)
4390    >>> n
4391    RepeatBitVec(4, x)
4392    >>> n.size()
4393    32
4394    >>> v0 = BitVecVal(10, 4)
4395    >>> print("%.x" % v0.as_long())
4396    a
4397    >>> v = simplify(RepeatBitVec(4, v0))
4398    >>> v.size()
4399    16
4400    >>> print("%.x" % v.as_long())
4401    aaaa
4402    """
4403    if z3_debug():
4404        _z3_assert(_is_int(n), "First argument must be an integer")
4405        _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4406    return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4407
4408
4409def BVRedAnd(a):
4410    """Return the reduction-and expression of `a`."""
4411    if z3_debug():
4412        _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4413    return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4414
4415
4416def BVRedOr(a):
4417    """Return the reduction-or expression of `a`."""
4418    if z3_debug():
4419        _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4420    return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4421
4422
4423def BVAddNoOverflow(a, b, signed):
4424    """A predicate the determines that bit-vector addition does not overflow"""
4425    _check_bv_args(a, b)
4426    a, b = _coerce_exprs(a, b)
4427    return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4428
4429
4430def BVAddNoUnderflow(a, b):
4431    """A predicate the determines that signed bit-vector addition does not underflow"""
4432    _check_bv_args(a, b)
4433    a, b = _coerce_exprs(a, b)
4434    return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4435
4436
4437def BVSubNoOverflow(a, b):
4438    """A predicate the determines that bit-vector subtraction does not overflow"""
4439    _check_bv_args(a, b)
4440    a, b = _coerce_exprs(a, b)
4441    return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4442
4443
4444def BVSubNoUnderflow(a, b, signed):
4445    """A predicate the determines that bit-vector subtraction does not underflow"""
4446    _check_bv_args(a, b)
4447    a, b = _coerce_exprs(a, b)
4448    return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4449
4450
4451def BVSDivNoOverflow(a, b):
4452    """A predicate the determines that bit-vector signed division does not overflow"""
4453    _check_bv_args(a, b)
4454    a, b = _coerce_exprs(a, b)
4455    return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4456
4457
4458def BVSNegNoOverflow(a):
4459    """A predicate the determines that bit-vector unary negation does not overflow"""
4460    if z3_debug():
4461        _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4462    return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4463
4464
4465def BVMulNoOverflow(a, b, signed):
4466    """A predicate the determines that bit-vector multiplication does not overflow"""
4467    _check_bv_args(a, b)
4468    a, b = _coerce_exprs(a, b)
4469    return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4470
4471
4472def BVMulNoUnderflow(a, b):
4473    """A predicate the determines that bit-vector signed multiplication does not underflow"""
4474    _check_bv_args(a, b)
4475    a, b = _coerce_exprs(a, b)
4476    return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4477
4478
4479#########################################
4480#
4481# Arrays
4482#
4483#########################################
4484
4485class ArraySortRef(SortRef):
4486    """Array sorts."""
4487
4488    def domain(self):
4489        """Return the domain of the array sort `self`.
4490
4491        >>> A = ArraySort(IntSort(), BoolSort())
4492        >>> A.domain()
4493        Int
4494        """
4495        return _to_sort_ref(Z3_get_array_sort_domain(self.ctx_ref(), self.ast), self.ctx)
4496
4497    def range(self):
4498        """Return the range of the array sort `self`.
4499
4500        >>> A = ArraySort(IntSort(), BoolSort())
4501        >>> A.range()
4502        Bool
4503        """
4504        return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
4505
4506
4507class ArrayRef(ExprRef):
4508    """Array expressions. """
4509
4510    def sort(self):
4511        """Return the array sort of the array expression `self`.
4512
4513        >>> a = Array('a', IntSort(), BoolSort())
4514        >>> a.sort()
4515        Array(Int, Bool)
4516        """
4517        return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4518
4519    def domain(self):
4520        """Shorthand for `self.sort().domain()`.
4521
4522        >>> a = Array('a', IntSort(), BoolSort())
4523        >>> a.domain()
4524        Int
4525        """
4526        return self.sort().domain()
4527
4528    def range(self):
4529        """Shorthand for `self.sort().range()`.
4530
4531        >>> a = Array('a', IntSort(), BoolSort())
4532        >>> a.range()
4533        Bool
4534        """
4535        return self.sort().range()
4536
4537    def __getitem__(self, arg):
4538        """Return the Z3 expression `self[arg]`.
4539
4540        >>> a = Array('a', IntSort(), BoolSort())
4541        >>> i = Int('i')
4542        >>> a[i]
4543        a[i]
4544        >>> a[i].sexpr()
4545        '(select a i)'
4546        """
4547        arg = self.domain().cast(arg)
4548        return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx)
4549
4550    def default(self):
4551        return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)
4552
4553
4554def is_array_sort(a):
4555    return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4556
4557
4558def is_array(a):
4559    """Return `True` if `a` is a Z3 array expression.
4560
4561    >>> a = Array('a', IntSort(), IntSort())
4562    >>> is_array(a)
4563    True
4564    >>> is_array(Store(a, 0, 1))
4565    True
4566    >>> is_array(a[0])
4567    False
4568    """
4569    return isinstance(a, ArrayRef)
4570
4571
4572def is_const_array(a):
4573    """Return `True` if `a` is a Z3 constant array.
4574
4575    >>> a = K(IntSort(), 10)
4576    >>> is_const_array(a)
4577    True
4578    >>> a = Array('a', IntSort(), IntSort())
4579    >>> is_const_array(a)
4580    False
4581    """
4582    return is_app_of(a, Z3_OP_CONST_ARRAY)
4583
4584
4585def is_K(a):
4586    """Return `True` if `a` is a Z3 constant array.
4587
4588    >>> a = K(IntSort(), 10)
4589    >>> is_K(a)
4590    True
4591    >>> a = Array('a', IntSort(), IntSort())
4592    >>> is_K(a)
4593    False
4594    """
4595    return is_app_of(a, Z3_OP_CONST_ARRAY)
4596
4597
4598def is_map(a):
4599    """Return `True` if `a` is a Z3 map array expression.
4600
4601    >>> f = Function('f', IntSort(), IntSort())
4602    >>> b = Array('b', IntSort(), IntSort())
4603    >>> a  = Map(f, b)
4604    >>> a
4605    Map(f, b)
4606    >>> is_map(a)
4607    True
4608    >>> is_map(b)
4609    False
4610    """
4611    return is_app_of(a, Z3_OP_ARRAY_MAP)
4612
4613
4614def is_default(a):
4615    """Return `True` if `a` is a Z3 default array expression.
4616    >>> d = Default(K(IntSort(), 10))
4617    >>> is_default(d)
4618    True
4619    """
4620    return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4621
4622
4623def get_map_func(a):
4624    """Return the function declaration associated with a Z3 map array expression.
4625
4626    >>> f = Function('f', IntSort(), IntSort())
4627    >>> b = Array('b', IntSort(), IntSort())
4628    >>> a  = Map(f, b)
4629    >>> eq(f, get_map_func(a))
4630    True
4631    >>> get_map_func(a)
4632    f
4633    >>> get_map_func(a)(0)
4634    f(0)
4635    """
4636    if z3_debug():
4637        _z3_assert(is_map(a), "Z3 array map expression expected.")
4638    return FuncDeclRef(
4639        Z3_to_func_decl(
4640            a.ctx_ref(),
4641            Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4642        ),
4643        ctx=a.ctx,
4644    )
4645
4646
4647def ArraySort(*sig):
4648    """Return the Z3 array sort with the given domain and range sorts.
4649
4650    >>> A = ArraySort(IntSort(), BoolSort())
4651    >>> A
4652    Array(Int, Bool)
4653    >>> A.domain()
4654    Int
4655    >>> A.range()
4656    Bool
4657    >>> AA = ArraySort(IntSort(), A)
4658    >>> AA
4659    Array(Int, Array(Int, Bool))
4660    """
4661    sig = _get_args(sig)
4662    if z3_debug():
4663        _z3_assert(len(sig) > 1, "At least two arguments expected")
4664    arity = len(sig) - 1
4665    r = sig[arity]
4666    d = sig[0]
4667    if z3_debug():
4668        for s in sig:
4669            _z3_assert(is_sort(s), "Z3 sort expected")
4670            _z3_assert(s.ctx == r.ctx, "Context mismatch")
4671    ctx = d.ctx
4672    if len(sig) == 2:
4673        return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4674    dom = (Sort * arity)()
4675    for i in range(arity):
4676        dom[i] = sig[i].ast
4677    return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4678
4679
4680def Array(name, dom, rng):
4681    """Return an array constant named `name` with the given domain and range sorts.
4682
4683    >>> a = Array('a', IntSort(), IntSort())
4684    >>> a.sort()
4685    Array(Int, Int)
4686    >>> a[0]
4687    a[0]
4688    """
4689    s = ArraySort(dom, rng)
4690    ctx = s.ctx
4691    return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4692
4693
4694def Update(a, i, v):
4695    """Return a Z3 store array expression.
4696
4697    >>> a    = Array('a', IntSort(), IntSort())
4698    >>> i, v = Ints('i v')
4699    >>> s    = Update(a, i, v)
4700    >>> s.sort()
4701    Array(Int, Int)
4702    >>> prove(s[i] == v)
4703    proved
4704    >>> j    = Int('j')
4705    >>> prove(Implies(i != j, s[j] == a[j]))
4706    proved
4707    """
4708    if z3_debug():
4709        _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4710    i = a.sort().domain().cast(i)
4711    v = a.sort().range().cast(v)
4712    ctx = a.ctx
4713    return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4714
4715
4716def Default(a):
4717    """ Return a default value for array expression.
4718    >>> b = K(IntSort(), 1)
4719    >>> prove(Default(b) == 1)
4720    proved
4721    """
4722    if z3_debug():
4723        _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4724    return a.default()
4725
4726
4727def Store(a, i, v):
4728    """Return a Z3 store array expression.
4729
4730    >>> a    = Array('a', IntSort(), IntSort())
4731    >>> i, v = Ints('i v')
4732    >>> s    = Store(a, i, v)
4733    >>> s.sort()
4734    Array(Int, Int)
4735    >>> prove(s[i] == v)
4736    proved
4737    >>> j    = Int('j')
4738    >>> prove(Implies(i != j, s[j] == a[j]))
4739    proved
4740    """
4741    return Update(a, i, v)
4742
4743
4744def Select(a, i):
4745    """Return a Z3 select array expression.
4746
4747    >>> a = Array('a', IntSort(), IntSort())
4748    >>> i = Int('i')
4749    >>> Select(a, i)
4750    a[i]
4751    >>> eq(Select(a, i), a[i])
4752    True
4753    """
4754    if z3_debug():
4755        _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4756    return a[i]
4757
4758
4759def Map(f, *args):
4760    """Return a Z3 map array expression.
4761
4762    >>> f = Function('f', IntSort(), IntSort(), IntSort())
4763    >>> a1 = Array('a1', IntSort(), IntSort())
4764    >>> a2 = Array('a2', IntSort(), IntSort())
4765    >>> b  = Map(f, a1, a2)
4766    >>> b
4767    Map(f, a1, a2)
4768    >>> prove(b[0] == f(a1[0], a2[0]))
4769    proved
4770    """
4771    args = _get_args(args)
4772    if z3_debug():
4773        _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
4774        _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
4775        _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
4776        _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
4777    _args, sz = _to_ast_array(args)
4778    ctx = f.ctx
4779    return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
4780
4781
4782def K(dom, v):
4783    """Return a Z3 constant array expression.
4784
4785    >>> a = K(IntSort(), 10)
4786    >>> a
4787    K(Int, 10)
4788    >>> a.sort()
4789    Array(Int, Int)
4790    >>> i = Int('i')
4791    >>> a[i]
4792    K(Int, 10)[i]
4793    >>> simplify(a[i])
4794    10
4795    """
4796    if z3_debug():
4797        _z3_assert(is_sort(dom), "Z3 sort expected")
4798    ctx = dom.ctx
4799    if not is_expr(v):
4800        v = _py2expr(v, ctx)
4801    return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
4802
4803
4804def Ext(a, b):
4805    """Return extensionality index for one-dimensional arrays.
4806    >> a, b = Consts('a b', SetSort(IntSort()))
4807    >> Ext(a, b)
4808    Ext(a, b)
4809    """
4810    ctx = a.ctx
4811    if z3_debug():
4812        _z3_assert(is_array_sort(a) and is_array(b), "arguments must be arrays")
4813    return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4814
4815
4816def SetHasSize(a, k):
4817    ctx = a.ctx
4818    k = _py2expr(k, ctx)
4819    return _to_expr_ref(Z3_mk_set_has_size(ctx.ref(), a.as_ast(), k.as_ast()), ctx)
4820
4821
4822def is_select(a):
4823    """Return `True` if `a` is a Z3 array select application.
4824
4825    >>> a = Array('a', IntSort(), IntSort())
4826    >>> is_select(a)
4827    False
4828    >>> i = Int('i')
4829    >>> is_select(a[i])
4830    True
4831    """
4832    return is_app_of(a, Z3_OP_SELECT)
4833
4834
4835def is_store(a):
4836    """Return `True` if `a` is a Z3 array store application.
4837
4838    >>> a = Array('a', IntSort(), IntSort())
4839    >>> is_store(a)
4840    False
4841    >>> is_store(Store(a, 0, 1))
4842    True
4843    """
4844    return is_app_of(a, Z3_OP_STORE)
4845
4846#########################################
4847#
4848# Sets
4849#
4850#########################################
4851
4852
4853def SetSort(s):
4854    """ Create a set sort over element sort s"""
4855    return ArraySort(s, BoolSort())
4856
4857
4858def EmptySet(s):
4859    """Create the empty set
4860    >>> EmptySet(IntSort())
4861    K(Int, False)
4862    """
4863    ctx = s.ctx
4864    return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
4865
4866
4867def FullSet(s):
4868    """Create the full set
4869    >>> FullSet(IntSort())
4870    K(Int, True)
4871    """
4872    ctx = s.ctx
4873    return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
4874
4875
4876def SetUnion(*args):
4877    """ Take the union of sets
4878    >>> a = Const('a', SetSort(IntSort()))
4879    >>> b = Const('b', SetSort(IntSort()))
4880    >>> SetUnion(a, b)
4881    union(a, b)
4882    """
4883    args = _get_args(args)
4884    ctx = _ctx_from_ast_arg_list(args)
4885    _args, sz = _to_ast_array(args)
4886    return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
4887
4888
4889def SetIntersect(*args):
4890    """ Take the union of sets
4891    >>> a = Const('a', SetSort(IntSort()))
4892    >>> b = Const('b', SetSort(IntSort()))
4893    >>> SetIntersect(a, b)
4894    intersection(a, b)
4895    """
4896    args = _get_args(args)
4897    ctx = _ctx_from_ast_arg_list(args)
4898    _args, sz = _to_ast_array(args)
4899    return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
4900
4901
4902def SetAdd(s, e):
4903    """ Add element e to set s
4904    >>> a = Const('a', SetSort(IntSort()))
4905    >>> SetAdd(a, 1)
4906    Store(a, 1, True)
4907    """
4908    ctx = _ctx_from_ast_arg_list([s, e])
4909    e = _py2expr(e, ctx)
4910    return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
4911
4912
4913def SetDel(s, e):
4914    """ Remove element e to set s
4915    >>> a = Const('a', SetSort(IntSort()))
4916    >>> SetDel(a, 1)
4917    Store(a, 1, False)
4918    """
4919    ctx = _ctx_from_ast_arg_list([s, e])
4920    e = _py2expr(e, ctx)
4921    return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
4922
4923
4924def SetComplement(s):
4925    """ The complement of set s
4926    >>> a = Const('a', SetSort(IntSort()))
4927    >>> SetComplement(a)
4928    complement(a)
4929    """
4930    ctx = s.ctx
4931    return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
4932
4933
4934def SetDifference(a, b):
4935    """ The set difference of a and b
4936    >>> a = Const('a', SetSort(IntSort()))
4937    >>> b = Const('b', SetSort(IntSort()))
4938    >>> SetDifference(a, b)
4939    setminus(a, b)
4940    """
4941    ctx = _ctx_from_ast_arg_list([a, b])
4942    return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4943
4944
4945def IsMember(e, s):
4946    """ Check if e is a member of set s
4947    >>> a = Const('a', SetSort(IntSort()))
4948    >>> IsMember(1, a)
4949    a[1]
4950    """
4951    ctx = _ctx_from_ast_arg_list([s, e])
4952    e = _py2expr(e, ctx)
4953    return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
4954
4955
4956def IsSubset(a, b):
4957    """ Check if a is a subset of b
4958    >>> a = Const('a', SetSort(IntSort()))
4959    >>> b = Const('b', SetSort(IntSort()))
4960    >>> IsSubset(a, b)
4961    subset(a, b)
4962    """
4963    ctx = _ctx_from_ast_arg_list([a, b])
4964    return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4965
4966
4967#########################################
4968#
4969# Datatypes
4970#
4971#########################################
4972
4973def _valid_accessor(acc):
4974    """Return `True` if acc is pair of the form (String, Datatype or Sort). """
4975    if not isinstance(acc, tuple):
4976        return False
4977    if len(acc) != 2:
4978        return False
4979    return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
4980
4981
4982class Datatype:
4983    """Helper class for declaring Z3 datatypes.
4984
4985    >>> List = Datatype('List')
4986    >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
4987    >>> List.declare('nil')
4988    >>> List = List.create()
4989    >>> # List is now a Z3 declaration
4990    >>> List.nil
4991    nil
4992    >>> List.cons(10, List.nil)
4993    cons(10, nil)
4994    >>> List.cons(10, List.nil).sort()
4995    List
4996    >>> cons = List.cons
4997    >>> nil  = List.nil
4998    >>> car  = List.car
4999    >>> cdr  = List.cdr
5000    >>> n = cons(1, cons(0, nil))
5001    >>> n
5002    cons(1, cons(0, nil))
5003    >>> simplify(cdr(n))
5004    cons(0, nil)
5005    >>> simplify(car(n))
5006    1
5007    """
5008
5009    def __init__(self, name, ctx=None):
5010        self.ctx = _get_ctx(ctx)
5011        self.name = name
5012        self.constructors = []
5013
5014    def __deepcopy__(self, memo={}):
5015        r = Datatype(self.name, self.ctx)
5016        r.constructors = copy.deepcopy(self.constructors)
5017        return r
5018
5019    def declare_core(self, name, rec_name, *args):
5020        if z3_debug():
5021            _z3_assert(isinstance(name, str), "String expected")
5022            _z3_assert(isinstance(rec_name, str), "String expected")
5023            _z3_assert(
5024                all([_valid_accessor(a) for a in args]),
5025                "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5026            )
5027        self.constructors.append((name, rec_name, args))
5028
5029    def declare(self, name, *args):
5030        """Declare constructor named `name` with the given accessors `args`.
5031        Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5032        or a reference to the datatypes being declared.
5033
5034        In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5035        declares the constructor named `cons` that builds a new List using an integer and a List.
5036        It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5037        of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5038        we use the method create() to create the actual datatype in Z3.
5039
5040        >>> List = Datatype('List')
5041        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5042        >>> List.declare('nil')
5043        >>> List = List.create()
5044        """
5045        if z3_debug():
5046            _z3_assert(isinstance(name, str), "String expected")
5047            _z3_assert(name != "", "Constructor name cannot be empty")
5048        return self.declare_core(name, "is-" + name, *args)
5049
5050    def __repr__(self):
5051        return "Datatype(%s, %s)" % (self.name, self.constructors)
5052
5053    def create(self):
5054        """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5055
5056        The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5057
5058        >>> List = Datatype('List')
5059        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5060        >>> List.declare('nil')
5061        >>> List = List.create()
5062        >>> List.nil
5063        nil
5064        >>> List.cons(10, List.nil)
5065        cons(10, nil)
5066        """
5067        return CreateDatatypes([self])[0]
5068
5069
5070class ScopedConstructor:
5071    """Auxiliary object used to create Z3 datatypes."""
5072
5073    def __init__(self, c, ctx):
5074        self.c = c
5075        self.ctx = ctx
5076
5077    def __del__(self):
5078        if self.ctx.ref() is not None:
5079            Z3_del_constructor(self.ctx.ref(), self.c)
5080
5081
5082class ScopedConstructorList:
5083    """Auxiliary object used to create Z3 datatypes."""
5084
5085    def __init__(self, c, ctx):
5086        self.c = c
5087        self.ctx = ctx
5088
5089    def __del__(self):
5090        if self.ctx.ref() is not None:
5091            Z3_del_constructor_list(self.ctx.ref(), self.c)
5092
5093
5094def CreateDatatypes(*ds):
5095    """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5096
5097    In the following example we define a Tree-List using two mutually recursive datatypes.
5098
5099    >>> TreeList = Datatype('TreeList')
5100    >>> Tree     = Datatype('Tree')
5101    >>> # Tree has two constructors: leaf and node
5102    >>> Tree.declare('leaf', ('val', IntSort()))
5103    >>> # a node contains a list of trees
5104    >>> Tree.declare('node', ('children', TreeList))
5105    >>> TreeList.declare('nil')
5106    >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5107    >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5108    >>> Tree.val(Tree.leaf(10))
5109    val(leaf(10))
5110    >>> simplify(Tree.val(Tree.leaf(10)))
5111    10
5112    >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5113    >>> n1
5114    node(cons(leaf(10), cons(leaf(20), nil)))
5115    >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5116    >>> simplify(n2 == n1)
5117    False
5118    >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5119    True
5120    """
5121    ds = _get_args(ds)
5122    if z3_debug():
5123        _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5124        _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5125        _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5126        _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5127    ctx = ds[0].ctx
5128    num = len(ds)
5129    names = (Symbol * num)()
5130    out = (Sort * num)()
5131    clists = (ConstructorList * num)()
5132    to_delete = []
5133    for i in range(num):
5134        d = ds[i]
5135        names[i] = to_symbol(d.name, ctx)
5136        num_cs = len(d.constructors)
5137        cs = (Constructor * num_cs)()
5138        for j in range(num_cs):
5139            c = d.constructors[j]
5140            cname = to_symbol(c[0], ctx)
5141            rname = to_symbol(c[1], ctx)
5142            fs = c[2]
5143            num_fs = len(fs)
5144            fnames = (Symbol * num_fs)()
5145            sorts = (Sort * num_fs)()
5146            refs = (ctypes.c_uint * num_fs)()
5147            for k in range(num_fs):
5148                fname = fs[k][0]
5149                ftype = fs[k][1]
5150                fnames[k] = to_symbol(fname, ctx)
5151                if isinstance(ftype, Datatype):
5152                    if z3_debug():
5153                        _z3_assert(
5154                            ds.count(ftype) == 1,
5155                            "One and only one occurrence of each datatype is expected",
5156                        )
5157                    sorts[k] = None
5158                    refs[k] = ds.index(ftype)
5159                else:
5160                    if z3_debug():
5161                        _z3_assert(is_sort(ftype), "Z3 sort expected")
5162                    sorts[k] = ftype.ast
5163                    refs[k] = 0
5164            cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5165            to_delete.append(ScopedConstructor(cs[j], ctx))
5166        clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5167        to_delete.append(ScopedConstructorList(clists[i], ctx))
5168    Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5169    result = []
5170    # Create a field for every constructor, recognizer and accessor
5171    for i in range(num):
5172        dref = DatatypeSortRef(out[i], ctx)
5173        num_cs = dref.num_constructors()
5174        for j in range(num_cs):
5175            cref = dref.constructor(j)
5176            cref_name = cref.name()
5177            cref_arity = cref.arity()
5178            if cref.arity() == 0:
5179                cref = cref()
5180            setattr(dref, cref_name, cref)
5181            rref = dref.recognizer(j)
5182            setattr(dref, "is_" + cref_name, rref)
5183            for k in range(cref_arity):
5184                aref = dref.accessor(j, k)
5185                setattr(dref, aref.name(), aref)
5186        result.append(dref)
5187    return tuple(result)
5188
5189
5190class DatatypeSortRef(SortRef):
5191    """Datatype sorts."""
5192
5193    def num_constructors(self):
5194        """Return the number of constructors in the given Z3 datatype.
5195
5196        >>> List = Datatype('List')
5197        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5198        >>> List.declare('nil')
5199        >>> List = List.create()
5200        >>> # List is now a Z3 declaration
5201        >>> List.num_constructors()
5202        2
5203        """
5204        return int(Z3_get_datatype_sort_num_constructors(self.ctx_ref(), self.ast))
5205
5206    def constructor(self, idx):
5207        """Return a constructor of the datatype `self`.
5208
5209        >>> List = Datatype('List')
5210        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5211        >>> List.declare('nil')
5212        >>> List = List.create()
5213        >>> # List is now a Z3 declaration
5214        >>> List.num_constructors()
5215        2
5216        >>> List.constructor(0)
5217        cons
5218        >>> List.constructor(1)
5219        nil
5220        """
5221        if z3_debug():
5222            _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5223        return FuncDeclRef(Z3_get_datatype_sort_constructor(self.ctx_ref(), self.ast, idx), self.ctx)
5224
5225    def recognizer(self, idx):
5226        """In Z3, each constructor has an associated recognizer predicate.
5227
5228        If the constructor is named `name`, then the recognizer `is_name`.
5229
5230        >>> List = Datatype('List')
5231        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5232        >>> List.declare('nil')
5233        >>> List = List.create()
5234        >>> # List is now a Z3 declaration
5235        >>> List.num_constructors()
5236        2
5237        >>> List.recognizer(0)
5238        is(cons)
5239        >>> List.recognizer(1)
5240        is(nil)
5241        >>> simplify(List.is_nil(List.cons(10, List.nil)))
5242        False
5243        >>> simplify(List.is_cons(List.cons(10, List.nil)))
5244        True
5245        >>> l = Const('l', List)
5246        >>> simplify(List.is_cons(l))
5247        is(cons, l)
5248        """
5249        if z3_debug():
5250            _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5251        return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
5252
5253    def accessor(self, i, j):
5254        """In Z3, each constructor has 0 or more accessor.
5255        The number of accessors is equal to the arity of the constructor.
5256
5257        >>> List = Datatype('List')
5258        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5259        >>> List.declare('nil')
5260        >>> List = List.create()
5261        >>> List.num_constructors()
5262        2
5263        >>> List.constructor(0)
5264        cons
5265        >>> num_accs = List.constructor(0).arity()
5266        >>> num_accs
5267        2
5268        >>> List.accessor(0, 0)
5269        car
5270        >>> List.accessor(0, 1)
5271        cdr
5272        >>> List.constructor(1)
5273        nil
5274        >>> num_accs = List.constructor(1).arity()
5275        >>> num_accs
5276        0
5277        """
5278        if z3_debug():
5279            _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5280            _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5281        return FuncDeclRef(
5282            Z3_get_datatype_sort_constructor_accessor(self.ctx_ref(), self.ast, i, j),
5283            ctx=self.ctx,
5284        )
5285
5286
5287class DatatypeRef(ExprRef):
5288    """Datatype expressions."""
5289
5290    def sort(self):
5291        """Return the datatype sort of the datatype expression `self`."""
5292        return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5293
5294
5295def TupleSort(name, sorts, ctx=None):
5296    """Create a named tuple sort base on a set of underlying sorts
5297    Example:
5298        >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5299    """
5300    tuple = Datatype(name, ctx)
5301    projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5302    tuple.declare(name, *projects)
5303    tuple = tuple.create()
5304    return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5305
5306
5307def DisjointSum(name, sorts, ctx=None):
5308    """Create a named tagged union sort base on a set of underlying sorts
5309    Example:
5310        >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5311    """
5312    sum = Datatype(name, ctx)
5313    for i in range(len(sorts)):
5314        sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5315    sum = sum.create()
5316    return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5317
5318
5319def EnumSort(name, values, ctx=None):
5320    """Return a new enumeration sort named `name` containing the given values.
5321
5322    The result is a pair (sort, list of constants).
5323    Example:
5324        >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5325    """
5326    if z3_debug():
5327        _z3_assert(isinstance(name, str), "Name must be a string")
5328        _z3_assert(all([isinstance(v, str) for v in values]), "Eumeration sort values must be strings")
5329        _z3_assert(len(values) > 0, "At least one value expected")
5330    ctx = _get_ctx(ctx)
5331    num = len(values)
5332    _val_names = (Symbol * num)()
5333    for i in range(num):
5334        _val_names[i] = to_symbol(values[i])
5335    _values = (FuncDecl * num)()
5336    _testers = (FuncDecl * num)()
5337    name = to_symbol(name)
5338    S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5339    V = []
5340    for i in range(num):
5341        V.append(FuncDeclRef(_values[i], ctx))
5342    V = [a() for a in V]
5343    return S, V
5344
5345#########################################
5346#
5347# Parameter Sets
5348#
5349#########################################
5350
5351
5352class ParamsRef:
5353    """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5354
5355    Consider using the function `args2params` to create instances of this object.
5356    """
5357
5358    def __init__(self, ctx=None, params=None):
5359        self.ctx = _get_ctx(ctx)
5360        if params is None:
5361            self.params = Z3_mk_params(self.ctx.ref())
5362        else:
5363            self.params = params
5364        Z3_params_inc_ref(self.ctx.ref(), self.params)
5365
5366    def __deepcopy__(self, memo={}):
5367        return ParamsRef(self.ctx, self.params)
5368
5369    def __del__(self):
5370        if self.ctx.ref() is not None:
5371            Z3_params_dec_ref(self.ctx.ref(), self.params)
5372
5373    def set(self, name, val):
5374        """Set parameter name with value val."""
5375        if z3_debug():
5376            _z3_assert(isinstance(name, str), "parameter name must be a string")
5377        name_sym = to_symbol(name, self.ctx)
5378        if isinstance(val, bool):
5379            Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5380        elif _is_int(val):
5381            Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5382        elif isinstance(val, float):
5383            Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5384        elif isinstance(val, str):
5385            Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5386        else:
5387            if z3_debug():
5388                _z3_assert(False, "invalid parameter value")
5389
5390    def __repr__(self):
5391        return Z3_params_to_string(self.ctx.ref(), self.params)
5392
5393    def validate(self, ds):
5394        _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5395        Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5396
5397
5398def args2params(arguments, keywords, ctx=None):
5399    """Convert python arguments into a Z3_params object.
5400    A ':' is added to the keywords, and '_' is replaced with '-'
5401
5402    >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5403    (params model true relevancy 2 elim_and true)
5404    """
5405    if z3_debug():
5406        _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5407    prev = None
5408    r = ParamsRef(ctx)
5409    for a in arguments:
5410        if prev is None:
5411            prev = a
5412        else:
5413            r.set(prev, a)
5414            prev = None
5415    for k in keywords:
5416        v = keywords[k]
5417        r.set(k, v)
5418    return r
5419
5420
5421class ParamDescrsRef:
5422    """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5423    """
5424
5425    def __init__(self, descr, ctx=None):
5426        _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5427        self.ctx = _get_ctx(ctx)
5428        self.descr = descr
5429        Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5430
5431    def __deepcopy__(self, memo={}):
5432        return ParamsDescrsRef(self.descr, self.ctx)
5433
5434    def __del__(self):
5435        if self.ctx.ref() is not None:
5436            Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5437
5438    def size(self):
5439        """Return the size of in the parameter description `self`.
5440        """
5441        return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5442
5443    def __len__(self):
5444        """Return the size of in the parameter description `self`.
5445        """
5446        return self.size()
5447
5448    def get_name(self, i):
5449        """Return the i-th parameter name in the parameter description `self`.
5450        """
5451        return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5452
5453    def get_kind(self, n):
5454        """Return the kind of the parameter named `n`.
5455        """
5456        return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5457
5458    def get_documentation(self, n):
5459        """Return the documentation string of the parameter named `n`.
5460        """
5461        return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5462
5463    def __getitem__(self, arg):
5464        if _is_int(arg):
5465            return self.get_name(arg)
5466        else:
5467            return self.get_kind(arg)
5468
5469    def __repr__(self):
5470        return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5471
5472#########################################
5473#
5474# Goals
5475#
5476#########################################
5477
5478
5479class Goal(Z3PPObject):
5480    """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5481
5482    Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5483    A goal has a solution if one of its subgoals has a solution.
5484    A goal is unsatisfiable if all subgoals are unsatisfiable.
5485    """
5486
5487    def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5488        if z3_debug():
5489            _z3_assert(goal is None or ctx is not None,
5490                       "If goal is different from None, then ctx must be also different from None")
5491        self.ctx = _get_ctx(ctx)
5492        self.goal = goal
5493        if self.goal is None:
5494            self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5495        Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5496
5497    def __del__(self):
5498        if self.goal is not None and self.ctx.ref() is not None:
5499            Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5500
5501    def depth(self):
5502        """Return the depth of the goal `self`.
5503        The depth corresponds to the number of tactics applied to `self`.
5504
5505        >>> x, y = Ints('x y')
5506        >>> g = Goal()
5507        >>> g.add(x == 0, y >= x + 1)
5508        >>> g.depth()
5509        0
5510        >>> r = Then('simplify', 'solve-eqs')(g)
5511        >>> # r has 1 subgoal
5512        >>> len(r)
5513        1
5514        >>> r[0].depth()
5515        2
5516        """
5517        return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5518
5519    def inconsistent(self):
5520        """Return `True` if `self` contains the `False` constraints.
5521
5522        >>> x, y = Ints('x y')
5523        >>> g = Goal()
5524        >>> g.inconsistent()
5525        False
5526        >>> g.add(x == 0, x == 1)
5527        >>> g
5528        [x == 0, x == 1]
5529        >>> g.inconsistent()
5530        False
5531        >>> g2 = Tactic('propagate-values')(g)[0]
5532        >>> g2.inconsistent()
5533        True
5534        """
5535        return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5536
5537    def prec(self):
5538        """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5539
5540        >>> g = Goal()
5541        >>> g.prec() == Z3_GOAL_PRECISE
5542        True
5543        >>> x, y = Ints('x y')
5544        >>> g.add(x == y + 1)
5545        >>> g.prec() == Z3_GOAL_PRECISE
5546        True
5547        >>> t  = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5548        >>> g2 = t(g)[0]
5549        >>> g2
5550        [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5551        >>> g2.prec() == Z3_GOAL_PRECISE
5552        False
5553        >>> g2.prec() == Z3_GOAL_UNDER
5554        True
5555        """
5556        return Z3_goal_precision(self.ctx.ref(), self.goal)
5557
5558    def precision(self):
5559        """Alias for `prec()`.
5560
5561        >>> g = Goal()
5562        >>> g.precision() == Z3_GOAL_PRECISE
5563        True
5564        """
5565        return self.prec()
5566
5567    def size(self):
5568        """Return the number of constraints in the goal `self`.
5569
5570        >>> g = Goal()
5571        >>> g.size()
5572        0
5573        >>> x, y = Ints('x y')
5574        >>> g.add(x == 0, y > x)
5575        >>> g.size()
5576        2
5577        """
5578        return int(Z3_goal_size(self.ctx.ref(), self.goal))
5579
5580    def __len__(self):
5581        """Return the number of constraints in the goal `self`.
5582
5583        >>> g = Goal()
5584        >>> len(g)
5585        0
5586        >>> x, y = Ints('x y')
5587        >>> g.add(x == 0, y > x)
5588        >>> len(g)
5589        2
5590        """
5591        return self.size()
5592
5593    def get(self, i):
5594        """Return a constraint in the goal `self`.
5595
5596        >>> g = Goal()
5597        >>> x, y = Ints('x y')
5598        >>> g.add(x == 0, y > x)
5599        >>> g.get(0)
5600        x == 0
5601        >>> g.get(1)
5602        y > x
5603        """
5604        return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5605
5606    def __getitem__(self, arg):
5607        """Return a constraint in the goal `self`.
5608
5609        >>> g = Goal()
5610        >>> x, y = Ints('x y')
5611        >>> g.add(x == 0, y > x)
5612        >>> g[0]
5613        x == 0
5614        >>> g[1]
5615        y > x
5616        """
5617        if arg >= len(self):
5618            raise IndexError
5619        return self.get(arg)
5620
5621    def assert_exprs(self, *args):
5622        """Assert constraints into the goal.
5623
5624        >>> x = Int('x')
5625        >>> g = Goal()
5626        >>> g.assert_exprs(x > 0, x < 2)
5627        >>> g
5628        [x > 0, x < 2]
5629        """
5630        args = _get_args(args)
5631        s = BoolSort(self.ctx)
5632        for arg in args:
5633            arg = s.cast(arg)
5634            Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5635
5636    def append(self, *args):
5637        """Add constraints.
5638
5639        >>> x = Int('x')
5640        >>> g = Goal()
5641        >>> g.append(x > 0, x < 2)
5642        >>> g
5643        [x > 0, x < 2]
5644        """
5645        self.assert_exprs(*args)
5646
5647    def insert(self, *args):
5648        """Add constraints.
5649
5650        >>> x = Int('x')
5651        >>> g = Goal()
5652        >>> g.insert(x > 0, x < 2)
5653        >>> g
5654        [x > 0, x < 2]
5655        """
5656        self.assert_exprs(*args)
5657
5658    def add(self, *args):
5659        """Add constraints.
5660
5661        >>> x = Int('x')
5662        >>> g = Goal()
5663        >>> g.add(x > 0, x < 2)
5664        >>> g
5665        [x > 0, x < 2]
5666        """
5667        self.assert_exprs(*args)
5668
5669    def convert_model(self, model):
5670        """Retrieve model from a satisfiable goal
5671        >>> a, b = Ints('a b')
5672        >>> g = Goal()
5673        >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5674        >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5675        >>> r = t(g)
5676        >>> r[0]
5677        [Or(b == 0, b == 1), Not(0 <= b)]
5678        >>> r[1]
5679        [Or(b == 0, b == 1), Not(1 <= b)]
5680        >>> # Remark: the subgoal r[0] is unsatisfiable
5681        >>> # Creating a solver for solving the second subgoal
5682        >>> s = Solver()
5683        >>> s.add(r[1])
5684        >>> s.check()
5685        sat
5686        >>> s.model()
5687        [b = 0]
5688        >>> # Model s.model() does not assign a value to `a`
5689        >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5690        >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5691        >>> r[1].convert_model(s.model())
5692        [b = 0, a = 1]
5693        """
5694        if z3_debug():
5695            _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5696        return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5697
5698    def __repr__(self):
5699        return obj_to_string(self)
5700
5701    def sexpr(self):
5702        """Return a textual representation of the s-expression representing the goal."""
5703        return Z3_goal_to_string(self.ctx.ref(), self.goal)
5704
5705    def dimacs(self, include_names=True):
5706        """Return a textual representation of the goal in DIMACS format."""
5707        return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5708
5709    def translate(self, target):
5710        """Copy goal `self` to context `target`.
5711
5712        >>> x = Int('x')
5713        >>> g = Goal()
5714        >>> g.add(x > 10)
5715        >>> g
5716        [x > 10]
5717        >>> c2 = Context()
5718        >>> g2 = g.translate(c2)
5719        >>> g2
5720        [x > 10]
5721        >>> g.ctx == main_ctx()
5722        True
5723        >>> g2.ctx == c2
5724        True
5725        >>> g2.ctx == main_ctx()
5726        False
5727        """
5728        if z3_debug():
5729            _z3_assert(isinstance(target, Context), "target must be a context")
5730        return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5731
5732    def __copy__(self):
5733        return self.translate(self.ctx)
5734
5735    def __deepcopy__(self, memo={}):
5736        return self.translate(self.ctx)
5737
5738    def simplify(self, *arguments, **keywords):
5739        """Return a new simplified goal.
5740
5741        This method is essentially invoking the simplify tactic.
5742
5743        >>> g = Goal()
5744        >>> x = Int('x')
5745        >>> g.add(x + 1 >= 2)
5746        >>> g
5747        [x + 1 >= 2]
5748        >>> g2 = g.simplify()
5749        >>> g2
5750        [x >= 1]
5751        >>> # g was not modified
5752        >>> g
5753        [x + 1 >= 2]
5754        """
5755        t = Tactic("simplify")
5756        return t.apply(self, *arguments, **keywords)[0]
5757
5758    def as_expr(self):
5759        """Return goal `self` as a single Z3 expression.
5760
5761        >>> x = Int('x')
5762        >>> g = Goal()
5763        >>> g.as_expr()
5764        True
5765        >>> g.add(x > 1)
5766        >>> g.as_expr()
5767        x > 1
5768        >>> g.add(x < 10)
5769        >>> g.as_expr()
5770        And(x > 1, x < 10)
5771        """
5772        sz = len(self)
5773        if sz == 0:
5774            return BoolVal(True, self.ctx)
5775        elif sz == 1:
5776            return self.get(0)
5777        else:
5778            return And([self.get(i) for i in range(len(self))], self.ctx)
5779
5780#########################################
5781#
5782# AST Vector
5783#
5784#########################################
5785
5786
5787class AstVector(Z3PPObject):
5788    """A collection (vector) of ASTs."""
5789
5790    def __init__(self, v=None, ctx=None):
5791        self.vector = None
5792        if v is None:
5793            self.ctx = _get_ctx(ctx)
5794            self.vector = Z3_mk_ast_vector(self.ctx.ref())
5795        else:
5796            self.vector = v
5797            assert ctx is not None
5798            self.ctx = ctx
5799        Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
5800
5801    def __del__(self):
5802        if self.vector is not None and self.ctx.ref() is not None:
5803            Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
5804
5805    def __len__(self):
5806        """Return the size of the vector `self`.
5807
5808        >>> A = AstVector()
5809        >>> len(A)
5810        0
5811        >>> A.push(Int('x'))
5812        >>> A.push(Int('x'))
5813        >>> len(A)
5814        2
5815        """
5816        return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
5817
5818    def __getitem__(self, i):
5819        """Return the AST at position `i`.
5820
5821        >>> A = AstVector()
5822        >>> A.push(Int('x') + 1)
5823        >>> A.push(Int('y'))
5824        >>> A[0]
5825        x + 1
5826        >>> A[1]
5827        y
5828        """
5829
5830        if isinstance(i, int):
5831            if i < 0:
5832                i += self.__len__()
5833
5834            if i >= self.__len__():
5835                raise IndexError
5836            return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
5837
5838        elif isinstance(i, slice):
5839            result = []
5840            for ii in range(*i.indices(self.__len__())):
5841                result.append(_to_ast_ref(
5842                    Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
5843                    self.ctx,
5844                ))
5845            return result
5846
5847    def __setitem__(self, i, v):
5848        """Update AST at position `i`.
5849
5850        >>> A = AstVector()
5851        >>> A.push(Int('x') + 1)
5852        >>> A.push(Int('y'))
5853        >>> A[0]
5854        x + 1
5855        >>> A[0] = Int('x')
5856        >>> A[0]
5857        x
5858        """
5859        if i >= self.__len__():
5860            raise IndexError
5861        Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
5862
5863    def push(self, v):
5864        """Add `v` in the end of the vector.
5865
5866        >>> A = AstVector()
5867        >>> len(A)
5868        0
5869        >>> A.push(Int('x'))
5870        >>> len(A)
5871        1
5872        """
5873        Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
5874
5875    def resize(self, sz):
5876        """Resize the vector to `sz` elements.
5877
5878        >>> A = AstVector()
5879        >>> A.resize(10)
5880        >>> len(A)
5881        10
5882        >>> for i in range(10): A[i] = Int('x')
5883        >>> A[5]
5884        x
5885        """
5886        Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
5887
5888    def __contains__(self, item):
5889        """Return `True` if the vector contains `item`.
5890
5891        >>> x = Int('x')
5892        >>> A = AstVector()
5893        >>> x in A
5894        False
5895        >>> A.push(x)
5896        >>> x in A
5897        True
5898        >>> (x+1) in A
5899        False
5900        >>> A.push(x+1)
5901        >>> (x+1) in A
5902        True
5903        >>> A
5904        [x, x + 1]
5905        """
5906        for elem in self:
5907            if elem.eq(item):
5908                return True
5909        return False
5910
5911    def translate(self, other_ctx):
5912        """Copy vector `self` to context `other_ctx`.
5913
5914        >>> x = Int('x')
5915        >>> A = AstVector()
5916        >>> A.push(x)
5917        >>> c2 = Context()
5918        >>> B = A.translate(c2)
5919        >>> B
5920        [x]
5921        """
5922        return AstVector(
5923            Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
5924            ctx=other_ctx,
5925        )
5926
5927    def __copy__(self):
5928        return self.translate(self.ctx)
5929
5930    def __deepcopy__(self, memo={}):
5931        return self.translate(self.ctx)
5932
5933    def __repr__(self):
5934        return obj_to_string(self)
5935
5936    def sexpr(self):
5937        """Return a textual representation of the s-expression representing the vector."""
5938        return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
5939
5940#########################################
5941#
5942# AST Map
5943#
5944#########################################
5945
5946
5947class AstMap:
5948    """A mapping from ASTs to ASTs."""
5949
5950    def __init__(self, m=None, ctx=None):
5951        self.map = None
5952        if m is None:
5953            self.ctx = _get_ctx(ctx)
5954            self.map = Z3_mk_ast_map(self.ctx.ref())
5955        else:
5956            self.map = m
5957            assert ctx is not None
5958            self.ctx = ctx
5959        Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
5960
5961    def __deepcopy__(self, memo={}):
5962        return AstMap(self.map, self.ctx)
5963
5964    def __del__(self):
5965        if self.map is not None and self.ctx.ref() is not None:
5966            Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
5967
5968    def __len__(self):
5969        """Return the size of the map.
5970
5971        >>> M = AstMap()
5972        >>> len(M)
5973        0
5974        >>> x = Int('x')
5975        >>> M[x] = IntVal(1)
5976        >>> len(M)
5977        1
5978        """
5979        return int(Z3_ast_map_size(self.ctx.ref(), self.map))
5980
5981    def __contains__(self, key):
5982        """Return `True` if the map contains key `key`.
5983
5984        >>> M = AstMap()
5985        >>> x = Int('x')
5986        >>> M[x] = x + 1
5987        >>> x in M
5988        True
5989        >>> x+1 in M
5990        False
5991        """
5992        return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
5993
5994    def __getitem__(self, key):
5995        """Retrieve the value associated with key `key`.
5996
5997        >>> M = AstMap()
5998        >>> x = Int('x')
5999        >>> M[x] = x + 1
6000        >>> M[x]
6001        x + 1
6002        """
6003        return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6004
6005    def __setitem__(self, k, v):
6006        """Add/Update key `k` with value `v`.
6007
6008        >>> M = AstMap()
6009        >>> x = Int('x')
6010        >>> M[x] = x + 1
6011        >>> len(M)
6012        1
6013        >>> M[x]
6014        x + 1
6015        >>> M[x] = IntVal(1)
6016        >>> M[x]
6017        1
6018        """
6019        Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6020
6021    def __repr__(self):
6022        return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6023
6024    def erase(self, k):
6025        """Remove the entry associated with key `k`.
6026
6027        >>> M = AstMap()
6028        >>> x = Int('x')
6029        >>> M[x] = x + 1
6030        >>> len(M)
6031        1
6032        >>> M.erase(x)
6033        >>> len(M)
6034        0
6035        """
6036        Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6037
6038    def reset(self):
6039        """Remove all entries from the map.
6040
6041        >>> M = AstMap()
6042        >>> x = Int('x')
6043        >>> M[x]   = x + 1
6044        >>> M[x+x] = IntVal(1)
6045        >>> len(M)
6046        2
6047        >>> M.reset()
6048        >>> len(M)
6049        0
6050        """
6051        Z3_ast_map_reset(self.ctx.ref(), self.map)
6052
6053    def keys(self):
6054        """Return an AstVector containing all keys in the map.
6055
6056        >>> M = AstMap()
6057        >>> x = Int('x')
6058        >>> M[x]   = x + 1
6059        >>> M[x+x] = IntVal(1)
6060        >>> M.keys()
6061        [x, x + x]
6062        """
6063        return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6064
6065#########################################
6066#
6067# Model
6068#
6069#########################################
6070
6071
6072class FuncEntry:
6073    """Store the value of the interpretation of a function in a particular point."""
6074
6075    def __init__(self, entry, ctx):
6076        self.entry = entry
6077        self.ctx = ctx
6078        Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6079
6080    def __deepcopy__(self, memo={}):
6081        return FuncEntry(self.entry, self.ctx)
6082
6083    def __del__(self):
6084        if self.ctx.ref() is not None:
6085            Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6086
6087    def num_args(self):
6088        """Return the number of arguments in the given entry.
6089
6090        >>> f = Function('f', IntSort(), IntSort(), IntSort())
6091        >>> s = Solver()
6092        >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6093        >>> s.check()
6094        sat
6095        >>> m = s.model()
6096        >>> f_i = m[f]
6097        >>> f_i.num_entries()
6098        1
6099        >>> e = f_i.entry(0)
6100        >>> e.num_args()
6101        2
6102        """
6103        return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6104
6105    def arg_value(self, idx):
6106        """Return the value of argument `idx`.
6107
6108        >>> f = Function('f', IntSort(), IntSort(), IntSort())
6109        >>> s = Solver()
6110        >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6111        >>> s.check()
6112        sat
6113        >>> m = s.model()
6114        >>> f_i = m[f]
6115        >>> f_i.num_entries()
6116        1
6117        >>> e = f_i.entry(0)
6118        >>> e
6119        [1, 2, 20]
6120        >>> e.num_args()
6121        2
6122        >>> e.arg_value(0)
6123        1
6124        >>> e.arg_value(1)
6125        2
6126        >>> try:
6127        ...   e.arg_value(2)
6128        ... except IndexError:
6129        ...   print("index error")
6130        index error
6131        """
6132        if idx >= self.num_args():
6133            raise IndexError
6134        return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6135
6136    def value(self):
6137        """Return the value of the function at point `self`.
6138
6139        >>> f = Function('f', IntSort(), IntSort(), IntSort())
6140        >>> s = Solver()
6141        >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6142        >>> s.check()
6143        sat
6144        >>> m = s.model()
6145        >>> f_i = m[f]
6146        >>> f_i.num_entries()
6147        1
6148        >>> e = f_i.entry(0)
6149        >>> e
6150        [1, 2, 20]
6151        >>> e.num_args()
6152        2
6153        >>> e.value()
6154        20
6155        """
6156        return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6157
6158    def as_list(self):
6159        """Return entry `self` as a Python list.
6160        >>> f = Function('f', IntSort(), IntSort(), IntSort())
6161        >>> s = Solver()
6162        >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6163        >>> s.check()
6164        sat
6165        >>> m = s.model()
6166        >>> f_i = m[f]
6167        >>> f_i.num_entries()
6168        1
6169        >>> e = f_i.entry(0)
6170        >>> e.as_list()
6171        [1, 2, 20]
6172        """
6173        args = [self.arg_value(i) for i in range(self.num_args())]
6174        args.append(self.value())
6175        return args
6176
6177    def __repr__(self):
6178        return repr(self.as_list())
6179
6180
6181class FuncInterp(Z3PPObject):
6182    """Stores the interpretation of a function in a Z3 model."""
6183
6184    def __init__(self, f, ctx):
6185        self.f = f
6186        self.ctx = ctx
6187        if self.f is not None:
6188            Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6189
6190    def __del__(self):
6191        if self.f is not None and self.ctx.ref() is not None:
6192            Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6193
6194    def else_value(self):
6195        """
6196        Return the `else` value for a function interpretation.
6197        Return None if Z3 did not specify the `else` value for
6198        this object.
6199
6200        >>> f = Function('f', IntSort(), IntSort())
6201        >>> s = Solver()
6202        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6203        >>> s.check()
6204        sat
6205        >>> m = s.model()
6206        >>> m[f]
6207        [2 -> 0, else -> 1]
6208        >>> m[f].else_value()
6209        1
6210        """
6211        r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6212        if r:
6213            return _to_expr_ref(r, self.ctx)
6214        else:
6215            return None
6216
6217    def num_entries(self):
6218        """Return the number of entries/points in the function interpretation `self`.
6219
6220        >>> f = Function('f', IntSort(), IntSort())
6221        >>> s = Solver()
6222        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6223        >>> s.check()
6224        sat
6225        >>> m = s.model()
6226        >>> m[f]
6227        [2 -> 0, else -> 1]
6228        >>> m[f].num_entries()
6229        1
6230        """
6231        return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6232
6233    def arity(self):
6234        """Return the number of arguments for each entry in the function interpretation `self`.
6235
6236        >>> f = Function('f', IntSort(), IntSort())
6237        >>> s = Solver()
6238        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6239        >>> s.check()
6240        sat
6241        >>> m = s.model()
6242        >>> m[f].arity()
6243        1
6244        """
6245        return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6246
6247    def entry(self, idx):
6248        """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6249
6250        >>> f = Function('f', IntSort(), IntSort())
6251        >>> s = Solver()
6252        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6253        >>> s.check()
6254        sat
6255        >>> m = s.model()
6256        >>> m[f]
6257        [2 -> 0, else -> 1]
6258        >>> m[f].num_entries()
6259        1
6260        >>> m[f].entry(0)
6261        [2, 0]
6262        """
6263        if idx >= self.num_entries():
6264            raise IndexError
6265        return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6266
6267    def translate(self, other_ctx):
6268        """Copy model 'self' to context 'other_ctx'.
6269        """
6270        return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6271
6272    def __copy__(self):
6273        return self.translate(self.ctx)
6274
6275    def __deepcopy__(self, memo={}):
6276        return self.translate(self.ctx)
6277
6278    def as_list(self):
6279        """Return the function interpretation as a Python list.
6280        >>> f = Function('f', IntSort(), IntSort())
6281        >>> s = Solver()
6282        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6283        >>> s.check()
6284        sat
6285        >>> m = s.model()
6286        >>> m[f]
6287        [2 -> 0, else -> 1]
6288        >>> m[f].as_list()
6289        [[2, 0], 1]
6290        """
6291        r = [self.entry(i).as_list() for i in range(self.num_entries())]
6292        r.append(self.else_value())
6293        return r
6294
6295    def __repr__(self):
6296        return obj_to_string(self)
6297
6298
6299class ModelRef(Z3PPObject):
6300    """Model/Solution of a satisfiability problem (aka system of constraints)."""
6301
6302    def __init__(self, m, ctx):
6303        assert ctx is not None
6304        self.model = m
6305        self.ctx = ctx
6306        Z3_model_inc_ref(self.ctx.ref(), self.model)
6307
6308    def __del__(self):
6309        if self.ctx.ref() is not None:
6310            Z3_model_dec_ref(self.ctx.ref(), self.model)
6311
6312    def __repr__(self):
6313        return obj_to_string(self)
6314
6315    def sexpr(self):
6316        """Return a textual representation of the s-expression representing the model."""
6317        return Z3_model_to_string(self.ctx.ref(), self.model)
6318
6319    def eval(self, t, model_completion=False):
6320        """Evaluate the expression `t` in the model `self`.
6321        If `model_completion` is enabled, then a default interpretation is automatically added
6322        for symbols that do not have an interpretation in the model `self`.
6323
6324        >>> x = Int('x')
6325        >>> s = Solver()
6326        >>> s.add(x > 0, x < 2)
6327        >>> s.check()
6328        sat
6329        >>> m = s.model()
6330        >>> m.eval(x + 1)
6331        2
6332        >>> m.eval(x == 1)
6333        True
6334        >>> y = Int('y')
6335        >>> m.eval(y + x)
6336        1 + y
6337        >>> m.eval(y)
6338        y
6339        >>> m.eval(y, model_completion=True)
6340        0
6341        >>> # Now, m contains an interpretation for y
6342        >>> m.eval(y + x)
6343        1
6344        """
6345        r = (Ast * 1)()
6346        if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6347            return _to_expr_ref(r[0], self.ctx)
6348        raise Z3Exception("failed to evaluate expression in the model")
6349
6350    def evaluate(self, t, model_completion=False):
6351        """Alias for `eval`.
6352
6353        >>> x = Int('x')
6354        >>> s = Solver()
6355        >>> s.add(x > 0, x < 2)
6356        >>> s.check()
6357        sat
6358        >>> m = s.model()
6359        >>> m.evaluate(x + 1)
6360        2
6361        >>> m.evaluate(x == 1)
6362        True
6363        >>> y = Int('y')
6364        >>> m.evaluate(y + x)
6365        1 + y
6366        >>> m.evaluate(y)
6367        y
6368        >>> m.evaluate(y, model_completion=True)
6369        0
6370        >>> # Now, m contains an interpretation for y
6371        >>> m.evaluate(y + x)
6372        1
6373        """
6374        return self.eval(t, model_completion)
6375
6376    def __len__(self):
6377        """Return the number of constant and function declarations in the model `self`.
6378
6379        >>> f = Function('f', IntSort(), IntSort())
6380        >>> x = Int('x')
6381        >>> s = Solver()
6382        >>> s.add(x > 0, f(x) != x)
6383        >>> s.check()
6384        sat
6385        >>> m = s.model()
6386        >>> len(m)
6387        2
6388        """
6389        num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6390        num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6391        return num_consts + num_funcs
6392
6393    def get_interp(self, decl):
6394        """Return the interpretation for a given declaration or constant.
6395
6396        >>> f = Function('f', IntSort(), IntSort())
6397        >>> x = Int('x')
6398        >>> s = Solver()
6399        >>> s.add(x > 0, x < 2, f(x) == 0)
6400        >>> s.check()
6401        sat
6402        >>> m = s.model()
6403        >>> m[x]
6404        1
6405        >>> m[f]
6406        [else -> 0]
6407        """
6408        if z3_debug():
6409            _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6410        if is_const(decl):
6411            decl = decl.decl()
6412        try:
6413            if decl.arity() == 0:
6414                _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6415                if _r.value is None:
6416                    return None
6417                r = _to_expr_ref(_r, self.ctx)
6418                if is_as_array(r):
6419                    return self.get_interp(get_as_array_func(r))
6420                else:
6421                    return r
6422            else:
6423                return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6424        except Z3Exception:
6425            return None
6426
6427    def num_sorts(self):
6428        """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6429
6430        >>> A = DeclareSort('A')
6431        >>> a, b = Consts('a b', A)
6432        >>> s = Solver()
6433        >>> s.add(a != b)
6434        >>> s.check()
6435        sat
6436        >>> m = s.model()
6437        >>> m.num_sorts()
6438        1
6439        """
6440        return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6441
6442    def get_sort(self, idx):
6443        """Return the uninterpreted sort at position `idx` < self.num_sorts().
6444
6445        >>> A = DeclareSort('A')
6446        >>> B = DeclareSort('B')
6447        >>> a1, a2 = Consts('a1 a2', A)
6448        >>> b1, b2 = Consts('b1 b2', B)
6449        >>> s = Solver()
6450        >>> s.add(a1 != a2, b1 != b2)
6451        >>> s.check()
6452        sat
6453        >>> m = s.model()
6454        >>> m.num_sorts()
6455        2
6456        >>> m.get_sort(0)
6457        A
6458        >>> m.get_sort(1)
6459        B
6460        """
6461        if idx >= self.num_sorts():
6462            raise IndexError
6463        return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6464
6465    def sorts(self):
6466        """Return all uninterpreted sorts that have an interpretation in the model `self`.
6467
6468        >>> A = DeclareSort('A')
6469        >>> B = DeclareSort('B')
6470        >>> a1, a2 = Consts('a1 a2', A)
6471        >>> b1, b2 = Consts('b1 b2', B)
6472        >>> s = Solver()
6473        >>> s.add(a1 != a2, b1 != b2)
6474        >>> s.check()
6475        sat
6476        >>> m = s.model()
6477        >>> m.sorts()
6478        [A, B]
6479        """
6480        return [self.get_sort(i) for i in range(self.num_sorts())]
6481
6482    def get_universe(self, s):
6483        """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6484
6485        >>> A = DeclareSort('A')
6486        >>> a, b = Consts('a b', A)
6487        >>> s = Solver()
6488        >>> s.add(a != b)
6489        >>> s.check()
6490        sat
6491        >>> m = s.model()
6492        >>> m.get_universe(A)
6493        [A!val!1, A!val!0]
6494        """
6495        if z3_debug():
6496            _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6497        try:
6498            return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6499        except Z3Exception:
6500            return None
6501
6502    def __getitem__(self, idx):
6503        """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6504        If `idx` is a declaration, then the actual interpretation is returned.
6505
6506        The elements can be retrieved using position or the actual declaration.
6507
6508        >>> f = Function('f', IntSort(), IntSort())
6509        >>> x = Int('x')
6510        >>> s = Solver()
6511        >>> s.add(x > 0, x < 2, f(x) == 0)
6512        >>> s.check()
6513        sat
6514        >>> m = s.model()
6515        >>> len(m)
6516        2
6517        >>> m[0]
6518        x
6519        >>> m[1]
6520        f
6521        >>> m[x]
6522        1
6523        >>> m[f]
6524        [else -> 0]
6525        >>> for d in m: print("%s -> %s" % (d, m[d]))
6526        x -> 1
6527        f -> [else -> 0]
6528        """
6529        if _is_int(idx):
6530            if idx >= len(self):
6531                raise IndexError
6532            num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6533            if (idx < num_consts):
6534                return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6535            else:
6536                return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6537        if isinstance(idx, FuncDeclRef):
6538            return self.get_interp(idx)
6539        if is_const(idx):
6540            return self.get_interp(idx.decl())
6541        if isinstance(idx, SortRef):
6542            return self.get_universe(idx)
6543        if z3_debug():
6544            _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6545        return None
6546
6547    def decls(self):
6548        """Return a list with all symbols that have an interpretation in the model `self`.
6549        >>> f = Function('f', IntSort(), IntSort())
6550        >>> x = Int('x')
6551        >>> s = Solver()
6552        >>> s.add(x > 0, x < 2, f(x) == 0)
6553        >>> s.check()
6554        sat
6555        >>> m = s.model()
6556        >>> m.decls()
6557        [x, f]
6558        """
6559        r = []
6560        for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6561            r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6562        for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6563            r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6564        return r
6565
6566    def update_value(self, x, value):
6567        """Update the interpretation of a constant"""
6568        if is_expr(x):
6569            x = x.decl()
6570        if not is_func_decl(x) or x.arity() != 0:
6571            raise Z3Exception("Expecting 0-ary function or constant expression")
6572        value = _py2expr(value)
6573        Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6574
6575    def translate(self, target):
6576        """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6577        """
6578        if z3_debug():
6579            _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6580        model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6581        return ModelRef(model, target)
6582
6583    def __copy__(self):
6584        return self.translate(self.ctx)
6585
6586    def __deepcopy__(self, memo={}):
6587        return self.translate(self.ctx)
6588
6589
6590def Model(ctx=None):
6591    ctx = _get_ctx(ctx)
6592    return ModelRef(Z3_mk_model(ctx.ref()), ctx)
6593
6594
6595def is_as_array(n):
6596    """Return true if n is a Z3 expression of the form (_ as-array f)."""
6597    return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6598
6599
6600def get_as_array_func(n):
6601    """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6602    if z3_debug():
6603        _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6604    return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6605
6606#########################################
6607#
6608# Statistics
6609#
6610#########################################
6611
6612
6613class Statistics:
6614    """Statistics for `Solver.check()`."""
6615
6616    def __init__(self, stats, ctx):
6617        self.stats = stats
6618        self.ctx = ctx
6619        Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6620
6621    def __deepcopy__(self, memo={}):
6622        return Statistics(self.stats, self.ctx)
6623
6624    def __del__(self):
6625        if self.ctx.ref() is not None:
6626            Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6627
6628    def __repr__(self):
6629        if in_html_mode():
6630            out = io.StringIO()
6631            even = True
6632            out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6633            for k, v in self:
6634                if even:
6635                    out.write(u('<tr style="background-color:#CFCFCF">'))
6636                    even = False
6637                else:
6638                    out.write(u("<tr>"))
6639                    even = True
6640                out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6641            out.write(u("</table>"))
6642            return out.getvalue()
6643        else:
6644            return Z3_stats_to_string(self.ctx.ref(), self.stats)
6645
6646    def __len__(self):
6647        """Return the number of statistical counters.
6648
6649        >>> x = Int('x')
6650        >>> s = Then('simplify', 'nlsat').solver()
6651        >>> s.add(x > 0)
6652        >>> s.check()
6653        sat
6654        >>> st = s.statistics()
6655        >>> len(st)
6656        6
6657        """
6658        return int(Z3_stats_size(self.ctx.ref(), self.stats))
6659
6660    def __getitem__(self, idx):
6661        """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6662
6663        >>> x = Int('x')
6664        >>> s = Then('simplify', 'nlsat').solver()
6665        >>> s.add(x > 0)
6666        >>> s.check()
6667        sat
6668        >>> st = s.statistics()
6669        >>> len(st)
6670        6
6671        >>> st[0]
6672        ('nlsat propagations', 2)
6673        >>> st[1]
6674        ('nlsat stages', 2)
6675        """
6676        if idx >= len(self):
6677            raise IndexError
6678        if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6679            val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6680        else:
6681            val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6682        return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
6683
6684    def keys(self):
6685        """Return the list of statistical counters.
6686
6687        >>> x = Int('x')
6688        >>> s = Then('simplify', 'nlsat').solver()
6689        >>> s.add(x > 0)
6690        >>> s.check()
6691        sat
6692        >>> st = s.statistics()
6693        """
6694        return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
6695
6696    def get_key_value(self, key):
6697        """Return the value of a particular statistical counter.
6698
6699        >>> x = Int('x')
6700        >>> s = Then('simplify', 'nlsat').solver()
6701        >>> s.add(x > 0)
6702        >>> s.check()
6703        sat
6704        >>> st = s.statistics()
6705        >>> st.get_key_value('nlsat propagations')
6706        2
6707        """
6708        for idx in range(len(self)):
6709            if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
6710                if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6711                    return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6712                else:
6713                    return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6714        raise Z3Exception("unknown key")
6715
6716    def __getattr__(self, name):
6717        """Access the value of statistical using attributes.
6718
6719        Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
6720        we should use '_' (e.g., 'nlsat_propagations').
6721
6722        >>> x = Int('x')
6723        >>> s = Then('simplify', 'nlsat').solver()
6724        >>> s.add(x > 0)
6725        >>> s.check()
6726        sat
6727        >>> st = s.statistics()
6728        >>> st.nlsat_propagations
6729        2
6730        >>> st.nlsat_stages
6731        2
6732        """
6733        key = name.replace("_", " ")
6734        try:
6735            return self.get_key_value(key)
6736        except Z3Exception:
6737            raise AttributeError
6738
6739#########################################
6740#
6741# Solver
6742#
6743#########################################
6744
6745
6746class CheckSatResult:
6747    """Represents the result of a satisfiability check: sat, unsat, unknown.
6748
6749    >>> s = Solver()
6750    >>> s.check()
6751    sat
6752    >>> r = s.check()
6753    >>> isinstance(r, CheckSatResult)
6754    True
6755    """
6756
6757    def __init__(self, r):
6758        self.r = r
6759
6760    def __deepcopy__(self, memo={}):
6761        return CheckSatResult(self.r)
6762
6763    def __eq__(self, other):
6764        return isinstance(other, CheckSatResult) and self.r == other.r
6765
6766    def __ne__(self, other):
6767        return not self.__eq__(other)
6768
6769    def __repr__(self):
6770        if in_html_mode():
6771            if self.r == Z3_L_TRUE:
6772                return "<b>sat</b>"
6773            elif self.r == Z3_L_FALSE:
6774                return "<b>unsat</b>"
6775            else:
6776                return "<b>unknown</b>"
6777        else:
6778            if self.r == Z3_L_TRUE:
6779                return "sat"
6780            elif self.r == Z3_L_FALSE:
6781                return "unsat"
6782            else:
6783                return "unknown"
6784
6785    def _repr_html_(self):
6786        in_html = in_html_mode()
6787        set_html_mode(True)
6788        res = repr(self)
6789        set_html_mode(in_html)
6790        return res
6791
6792
6793sat = CheckSatResult(Z3_L_TRUE)
6794unsat = CheckSatResult(Z3_L_FALSE)
6795unknown = CheckSatResult(Z3_L_UNDEF)
6796
6797
6798class Solver(Z3PPObject):
6799    """
6800    Solver API provides methods for implementing the main SMT 2.0 commands:
6801    push, pop, check, get-model, etc.
6802    """
6803
6804    def __init__(self, solver=None, ctx=None, logFile=None):
6805        assert solver is None or ctx is not None
6806        self.ctx = _get_ctx(ctx)
6807        self.backtrack_level = 4000000000
6808        self.solver = None
6809        if solver is None:
6810            self.solver = Z3_mk_solver(self.ctx.ref())
6811        else:
6812            self.solver = solver
6813        Z3_solver_inc_ref(self.ctx.ref(), self.solver)
6814        if logFile is not None:
6815            self.set("smtlib2_log", logFile)
6816
6817    def __del__(self):
6818        if self.solver is not None and self.ctx.ref() is not None:
6819            Z3_solver_dec_ref(self.ctx.ref(), self.solver)
6820
6821    def set(self, *args, **keys):
6822        """Set a configuration option.
6823        The method `help()` return a string containing all available options.
6824
6825        >>> s = Solver()
6826        >>> # The option MBQI can be set using three different approaches.
6827        >>> s.set(mbqi=True)
6828        >>> s.set('MBQI', True)
6829        >>> s.set(':mbqi', True)
6830        """
6831        p = args2params(args, keys, self.ctx)
6832        Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
6833
6834    def push(self):
6835        """Create a backtracking point.
6836
6837        >>> x = Int('x')
6838        >>> s = Solver()
6839        >>> s.add(x > 0)
6840        >>> s
6841        [x > 0]
6842        >>> s.push()
6843        >>> s.add(x < 1)
6844        >>> s
6845        [x > 0, x < 1]
6846        >>> s.check()
6847        unsat
6848        >>> s.pop()
6849        >>> s.check()
6850        sat
6851        >>> s
6852        [x > 0]
6853        """
6854        Z3_solver_push(self.ctx.ref(), self.solver)
6855
6856    def pop(self, num=1):
6857        """Backtrack \\c num backtracking points.
6858
6859        >>> x = Int('x')
6860        >>> s = Solver()
6861        >>> s.add(x > 0)
6862        >>> s
6863        [x > 0]
6864        >>> s.push()
6865        >>> s.add(x < 1)
6866        >>> s
6867        [x > 0, x < 1]
6868        >>> s.check()
6869        unsat
6870        >>> s.pop()
6871        >>> s.check()
6872        sat
6873        >>> s
6874        [x > 0]
6875        """
6876        Z3_solver_pop(self.ctx.ref(), self.solver, num)
6877
6878    def num_scopes(self):
6879        """Return the current number of backtracking points.
6880
6881        >>> s = Solver()
6882        >>> s.num_scopes()
6883        0
6884        >>> s.push()
6885        >>> s.num_scopes()
6886        1
6887        >>> s.push()
6888        >>> s.num_scopes()
6889        2
6890        >>> s.pop()
6891        >>> s.num_scopes()
6892        1
6893        """
6894        return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
6895
6896    def reset(self):
6897        """Remove all asserted constraints and backtracking points created using `push()`.
6898
6899        >>> x = Int('x')
6900        >>> s = Solver()
6901        >>> s.add(x > 0)
6902        >>> s
6903        [x > 0]
6904        >>> s.reset()
6905        >>> s
6906        []
6907        """
6908        Z3_solver_reset(self.ctx.ref(), self.solver)
6909
6910    def assert_exprs(self, *args):
6911        """Assert constraints into the solver.
6912
6913        >>> x = Int('x')
6914        >>> s = Solver()
6915        >>> s.assert_exprs(x > 0, x < 2)
6916        >>> s
6917        [x > 0, x < 2]
6918        """
6919        args = _get_args(args)
6920        s = BoolSort(self.ctx)
6921        for arg in args:
6922            if isinstance(arg, Goal) or isinstance(arg, AstVector):
6923                for f in arg:
6924                    Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
6925            else:
6926                arg = s.cast(arg)
6927                Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
6928
6929    def add(self, *args):
6930        """Assert constraints into the solver.
6931
6932        >>> x = Int('x')
6933        >>> s = Solver()
6934        >>> s.add(x > 0, x < 2)
6935        >>> s
6936        [x > 0, x < 2]
6937        """
6938        self.assert_exprs(*args)
6939
6940    def __iadd__(self, fml):
6941        self.add(fml)
6942        return self
6943
6944    def append(self, *args):
6945        """Assert constraints into the solver.
6946
6947        >>> x = Int('x')
6948        >>> s = Solver()
6949        >>> s.append(x > 0, x < 2)
6950        >>> s
6951        [x > 0, x < 2]
6952        """
6953        self.assert_exprs(*args)
6954
6955    def insert(self, *args):
6956        """Assert constraints into the solver.
6957
6958        >>> x = Int('x')
6959        >>> s = Solver()
6960        >>> s.insert(x > 0, x < 2)
6961        >>> s
6962        [x > 0, x < 2]
6963        """
6964        self.assert_exprs(*args)
6965
6966    def assert_and_track(self, a, p):
6967        """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
6968
6969        If `p` is a string, it will be automatically converted into a Boolean constant.
6970
6971        >>> x = Int('x')
6972        >>> p3 = Bool('p3')
6973        >>> s = Solver()
6974        >>> s.set(unsat_core=True)
6975        >>> s.assert_and_track(x > 0,  'p1')
6976        >>> s.assert_and_track(x != 1, 'p2')
6977        >>> s.assert_and_track(x < 0,  p3)
6978        >>> print(s.check())
6979        unsat
6980        >>> c = s.unsat_core()
6981        >>> len(c)
6982        2
6983        >>> Bool('p1') in c
6984        True
6985        >>> Bool('p2') in c
6986        False
6987        >>> p3 in c
6988        True
6989        """
6990        if isinstance(p, str):
6991            p = Bool(p, self.ctx)
6992        _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
6993        _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
6994        Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
6995
6996    def check(self, *assumptions):
6997        """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
6998
6999        >>> x = Int('x')
7000        >>> s = Solver()
7001        >>> s.check()
7002        sat
7003        >>> s.add(x > 0, x < 2)
7004        >>> s.check()
7005        sat
7006        >>> s.model().eval(x)
7007        1
7008        >>> s.add(x < 1)
7009        >>> s.check()
7010        unsat
7011        >>> s.reset()
7012        >>> s.add(2**x == 4)
7013        >>> s.check()
7014        unknown
7015        """
7016        s = BoolSort(self.ctx)
7017        assumptions = _get_args(assumptions)
7018        num = len(assumptions)
7019        _assumptions = (Ast * num)()
7020        for i in range(num):
7021            _assumptions[i] = s.cast(assumptions[i]).as_ast()
7022        r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7023        return CheckSatResult(r)
7024
7025    def model(self):
7026        """Return a model for the last `check()`.
7027
7028        This function raises an exception if
7029        a model is not available (e.g., last `check()` returned unsat).
7030
7031        >>> s = Solver()
7032        >>> a = Int('a')
7033        >>> s.add(a + 2 == 0)
7034        >>> s.check()
7035        sat
7036        >>> s.model()
7037        [a = -2]
7038        """
7039        try:
7040            return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7041        except Z3Exception:
7042            raise Z3Exception("model is not available")
7043
7044    def import_model_converter(self, other):
7045        """Import model converter from other into the current solver"""
7046        Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7047
7048    def unsat_core(self):
7049        """Return a subset (as an AST vector) of the assumptions provided to the last check().
7050
7051        These are the assumptions Z3 used in the unsatisfiability proof.
7052        Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7053        They may be also used to "retract" assumptions. Note that, assumptions are not really
7054        "soft constraints", but they can be used to implement them.
7055
7056        >>> p1, p2, p3 = Bools('p1 p2 p3')
7057        >>> x, y       = Ints('x y')
7058        >>> s          = Solver()
7059        >>> s.add(Implies(p1, x > 0))
7060        >>> s.add(Implies(p2, y > x))
7061        >>> s.add(Implies(p2, y < 1))
7062        >>> s.add(Implies(p3, y > -3))
7063        >>> s.check(p1, p2, p3)
7064        unsat
7065        >>> core = s.unsat_core()
7066        >>> len(core)
7067        2
7068        >>> p1 in core
7069        True
7070        >>> p2 in core
7071        True
7072        >>> p3 in core
7073        False
7074        >>> # "Retracting" p2
7075        >>> s.check(p1, p3)
7076        sat
7077        """
7078        return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7079
7080    def consequences(self, assumptions, variables):
7081        """Determine fixed values for the variables based on the solver state and assumptions.
7082        >>> s = Solver()
7083        >>> a, b, c, d = Bools('a b c d')
7084        >>> s.add(Implies(a,b), Implies(b, c))
7085        >>> s.consequences([a],[b,c,d])
7086        (sat, [Implies(a, b), Implies(a, c)])
7087        >>> s.consequences([Not(c),d],[a,b,c,d])
7088        (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7089        """
7090        if isinstance(assumptions, list):
7091            _asms = AstVector(None, self.ctx)
7092            for a in assumptions:
7093                _asms.push(a)
7094            assumptions = _asms
7095        if isinstance(variables, list):
7096            _vars = AstVector(None, self.ctx)
7097            for a in variables:
7098                _vars.push(a)
7099            variables = _vars
7100        _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7101        _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7102        consequences = AstVector(None, self.ctx)
7103        r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7104                                       variables.vector, consequences.vector)
7105        sz = len(consequences)
7106        consequences = [consequences[i] for i in range(sz)]
7107        return CheckSatResult(r), consequences
7108
7109    def from_file(self, filename):
7110        """Parse assertions from a file"""
7111        Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7112
7113    def from_string(self, s):
7114        """Parse assertions from a string"""
7115        Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7116
7117    def cube(self, vars=None):
7118        """Get set of cubes
7119        The method takes an optional set of variables that restrict which
7120        variables may be used as a starting point for cubing.
7121        If vars is not None, then the first case split is based on a variable in
7122        this set.
7123        """
7124        self.cube_vs = AstVector(None, self.ctx)
7125        if vars is not None:
7126            for v in vars:
7127                self.cube_vs.push(v)
7128        while True:
7129            lvl = self.backtrack_level
7130            self.backtrack_level = 4000000000
7131            r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7132            if (len(r) == 1 and is_false(r[0])):
7133                return
7134            yield r
7135            if (len(r) == 0):
7136                return
7137
7138    def cube_vars(self):
7139        """Access the set of variables that were touched by the most recently generated cube.
7140        This set of variables can be used as a starting point for additional cubes.
7141        The idea is that variables that appear in clauses that are reduced by the most recent
7142        cube are likely more useful to cube on."""
7143        return self.cube_vs
7144
7145    def proof(self):
7146        """Return a proof for the last `check()`. Proof construction must be enabled."""
7147        return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7148
7149    def assertions(self):
7150        """Return an AST vector containing all added constraints.
7151
7152        >>> s = Solver()
7153        >>> s.assertions()
7154        []
7155        >>> a = Int('a')
7156        >>> s.add(a > 0)
7157        >>> s.add(a < 10)
7158        >>> s.assertions()
7159        [a > 0, a < 10]
7160        """
7161        return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7162
7163    def units(self):
7164        """Return an AST vector containing all currently inferred units.
7165        """
7166        return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7167
7168    def non_units(self):
7169        """Return an AST vector containing all atomic formulas in solver state that are not units.
7170        """
7171        return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7172
7173    def trail_levels(self):
7174        """Return trail and decision levels of the solver state after a check() call.
7175        """
7176        trail = self.trail()
7177        levels = (ctypes.c_uint * len(trail))()
7178        Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7179        return trail, levels
7180
7181    def trail(self):
7182        """Return trail of the solver state after a check() call.
7183        """
7184        return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7185
7186    def statistics(self):
7187        """Return statistics for the last `check()`.
7188
7189        >>> s = SimpleSolver()
7190        >>> x = Int('x')
7191        >>> s.add(x > 0)
7192        >>> s.check()
7193        sat
7194        >>> st = s.statistics()
7195        >>> st.get_key_value('final checks')
7196        1
7197        >>> len(st) > 0
7198        True
7199        >>> st[0] != 0
7200        True
7201        """
7202        return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7203
7204    def reason_unknown(self):
7205        """Return a string describing why the last `check()` returned `unknown`.
7206
7207        >>> x = Int('x')
7208        >>> s = SimpleSolver()
7209        >>> s.add(2**x == 4)
7210        >>> s.check()
7211        unknown
7212        >>> s.reason_unknown()
7213        '(incomplete (theory arithmetic))'
7214        """
7215        return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7216
7217    def help(self):
7218        """Display a string describing all available options."""
7219        print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7220
7221    def param_descrs(self):
7222        """Return the parameter description set."""
7223        return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7224
7225    def __repr__(self):
7226        """Return a formatted string with all added constraints."""
7227        return obj_to_string(self)
7228
7229    def translate(self, target):
7230        """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7231
7232        >>> c1 = Context()
7233        >>> c2 = Context()
7234        >>> s1 = Solver(ctx=c1)
7235        >>> s2 = s1.translate(c2)
7236        """
7237        if z3_debug():
7238            _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7239        solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7240        return Solver(solver, target)
7241
7242    def __copy__(self):
7243        return self.translate(self.ctx)
7244
7245    def __deepcopy__(self, memo={}):
7246        return self.translate(self.ctx)
7247
7248    def sexpr(self):
7249        """Return a formatted string (in Lisp-like format) with all added constraints.
7250        We say the string is in s-expression format.
7251
7252        >>> x = Int('x')
7253        >>> s = Solver()
7254        >>> s.add(x > 0)
7255        >>> s.add(x < 2)
7256        >>> r = s.sexpr()
7257        """
7258        return Z3_solver_to_string(self.ctx.ref(), self.solver)
7259
7260    def dimacs(self, include_names=True):
7261        """Return a textual representation of the solver in DIMACS format."""
7262        return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7263
7264    def to_smt2(self):
7265        """return SMTLIB2 formatted benchmark for solver's assertions"""
7266        es = self.assertions()
7267        sz = len(es)
7268        sz1 = sz
7269        if sz1 > 0:
7270            sz1 -= 1
7271        v = (Ast * sz1)()
7272        for i in range(sz1):
7273            v[i] = es[i].as_ast()
7274        if sz > 0:
7275            e = es[sz1].as_ast()
7276        else:
7277            e = BoolVal(True, self.ctx).as_ast()
7278        return Z3_benchmark_to_smtlib_string(
7279            self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7280        )
7281
7282
7283def SolverFor(logic, ctx=None, logFile=None):
7284    """Create a solver customized for the given logic.
7285
7286    The parameter `logic` is a string. It should be contains
7287    the name of a SMT-LIB logic.
7288    See http://www.smtlib.org/ for the name of all available logics.
7289
7290    >>> s = SolverFor("QF_LIA")
7291    >>> x = Int('x')
7292    >>> s.add(x > 0)
7293    >>> s.add(x < 2)
7294    >>> s.check()
7295    sat
7296    >>> s.model()
7297    [x = 1]
7298    """
7299    ctx = _get_ctx(ctx)
7300    logic = to_symbol(logic)
7301    return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7302
7303
7304def SimpleSolver(ctx=None, logFile=None):
7305    """Return a simple general purpose solver with limited amount of preprocessing.
7306
7307    >>> s = SimpleSolver()
7308    >>> x = Int('x')
7309    >>> s.add(x > 0)
7310    >>> s.check()
7311    sat
7312    """
7313    ctx = _get_ctx(ctx)
7314    return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7315
7316#########################################
7317#
7318# Fixedpoint
7319#
7320#########################################
7321
7322
7323class Fixedpoint(Z3PPObject):
7324    """Fixedpoint API provides methods for solving with recursive predicates"""
7325
7326    def __init__(self, fixedpoint=None, ctx=None):
7327        assert fixedpoint is None or ctx is not None
7328        self.ctx = _get_ctx(ctx)
7329        self.fixedpoint = None
7330        if fixedpoint is None:
7331            self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7332        else:
7333            self.fixedpoint = fixedpoint
7334        Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7335        self.vars = []
7336
7337    def __deepcopy__(self, memo={}):
7338        return FixedPoint(self.fixedpoint, self.ctx)
7339
7340    def __del__(self):
7341        if self.fixedpoint is not None and self.ctx.ref() is not None:
7342            Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7343
7344    def set(self, *args, **keys):
7345        """Set a configuration option. The method `help()` return a string containing all available options.
7346        """
7347        p = args2params(args, keys, self.ctx)
7348        Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7349
7350    def help(self):
7351        """Display a string describing all available options."""
7352        print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7353
7354    def param_descrs(self):
7355        """Return the parameter description set."""
7356        return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7357
7358    def assert_exprs(self, *args):
7359        """Assert constraints as background axioms for the fixedpoint solver."""
7360        args = _get_args(args)
7361        s = BoolSort(self.ctx)
7362        for arg in args:
7363            if isinstance(arg, Goal) or isinstance(arg, AstVector):
7364                for f in arg:
7365                    f = self.abstract(f)
7366                    Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7367            else:
7368                arg = s.cast(arg)
7369                arg = self.abstract(arg)
7370                Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7371
7372    def add(self, *args):
7373        """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7374        self.assert_exprs(*args)
7375
7376    def __iadd__(self, fml):
7377        self.add(fml)
7378        return self
7379
7380    def append(self, *args):
7381        """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7382        self.assert_exprs(*args)
7383
7384    def insert(self, *args):
7385        """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7386        self.assert_exprs(*args)
7387
7388    def add_rule(self, head, body=None, name=None):
7389        """Assert rules defining recursive predicates to the fixedpoint solver.
7390        >>> a = Bool('a')
7391        >>> b = Bool('b')
7392        >>> s = Fixedpoint()
7393        >>> s.register_relation(a.decl())
7394        >>> s.register_relation(b.decl())
7395        >>> s.fact(a)
7396        >>> s.rule(b, a)
7397        >>> s.query(b)
7398        sat
7399        """
7400        if name is None:
7401            name = ""
7402        name = to_symbol(name, self.ctx)
7403        if body is None:
7404            head = self.abstract(head)
7405            Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7406        else:
7407            body = _get_args(body)
7408            f = self.abstract(Implies(And(body, self.ctx), head))
7409            Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7410
7411    def rule(self, head, body=None, name=None):
7412        """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7413        self.add_rule(head, body, name)
7414
7415    def fact(self, head, name=None):
7416        """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7417        self.add_rule(head, None, name)
7418
7419    def query(self, *query):
7420        """Query the fixedpoint engine whether formula is derivable.
7421           You can also pass an tuple or list of recursive predicates.
7422        """
7423        query = _get_args(query)
7424        sz = len(query)
7425        if sz >= 1 and isinstance(query[0], FuncDeclRef):
7426            _decls = (FuncDecl * sz)()
7427            i = 0
7428            for q in query:
7429                _decls[i] = q.ast
7430                i = i + 1
7431            r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7432        else:
7433            if sz == 1:
7434                query = query[0]
7435            else:
7436                query = And(query, self.ctx)
7437            query = self.abstract(query, False)
7438            r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7439        return CheckSatResult(r)
7440
7441    def query_from_lvl(self, lvl, *query):
7442        """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7443        """
7444        query = _get_args(query)
7445        sz = len(query)
7446        if sz >= 1 and isinstance(query[0], FuncDecl):
7447            _z3_assert(False, "unsupported")
7448        else:
7449            if sz == 1:
7450                query = query[0]
7451            else:
7452                query = And(query)
7453            query = self.abstract(query, False)
7454            r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7455        return CheckSatResult(r)
7456
7457    def update_rule(self, head, body, name):
7458        """update rule"""
7459        if name is None:
7460            name = ""
7461        name = to_symbol(name, self.ctx)
7462        body = _get_args(body)
7463        f = self.abstract(Implies(And(body, self.ctx), head))
7464        Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7465
7466    def get_answer(self):
7467        """Retrieve answer from last query call."""
7468        r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7469        return _to_expr_ref(r, self.ctx)
7470
7471    def get_ground_sat_answer(self):
7472        """Retrieve a ground cex from last query call."""
7473        r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7474        return _to_expr_ref(r, self.ctx)
7475
7476    def get_rules_along_trace(self):
7477        """retrieve rules along the counterexample trace"""
7478        return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7479
7480    def get_rule_names_along_trace(self):
7481        """retrieve rule names along the counterexample trace"""
7482        # this is a hack as I don't know how to return a list of symbols from C++;
7483        # obtain names as a single string separated by semicolons
7484        names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7485        # split into individual names
7486        return names.split(";")
7487
7488    def get_num_levels(self, predicate):
7489        """Retrieve number of levels used for predicate in PDR engine"""
7490        return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7491
7492    def get_cover_delta(self, level, predicate):
7493        """Retrieve properties known about predicate for the level'th unfolding.
7494        -1 is treated as the limit (infinity)
7495        """
7496        r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7497        return _to_expr_ref(r, self.ctx)
7498
7499    def add_cover(self, level, predicate, property):
7500        """Add property to predicate for the level'th unfolding.
7501        -1 is treated as infinity (infinity)
7502        """
7503        Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7504
7505    def register_relation(self, *relations):
7506        """Register relation as recursive"""
7507        relations = _get_args(relations)
7508        for f in relations:
7509            Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7510
7511    def set_predicate_representation(self, f, *representations):
7512        """Control how relation is represented"""
7513        representations = _get_args(representations)
7514        representations = [to_symbol(s) for s in representations]
7515        sz = len(representations)
7516        args = (Symbol * sz)()
7517        for i in range(sz):
7518            args[i] = representations[i]
7519        Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7520
7521    def parse_string(self, s):
7522        """Parse rules and queries from a string"""
7523        return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7524
7525    def parse_file(self, f):
7526        """Parse rules and queries from a file"""
7527        return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7528
7529    def get_rules(self):
7530        """retrieve rules that have been added to fixedpoint context"""
7531        return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7532
7533    def get_assertions(self):
7534        """retrieve assertions that have been added to fixedpoint context"""
7535        return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7536
7537    def __repr__(self):
7538        """Return a formatted string with all added rules and constraints."""
7539        return self.sexpr()
7540
7541    def sexpr(self):
7542        """Return a formatted string (in Lisp-like format) with all added constraints.
7543        We say the string is in s-expression format.
7544        """
7545        return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7546
7547    def to_string(self, queries):
7548        """Return a formatted string (in Lisp-like format) with all added constraints.
7549           We say the string is in s-expression format.
7550           Include also queries.
7551        """
7552        args, len = _to_ast_array(queries)
7553        return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7554
7555    def statistics(self):
7556        """Return statistics for the last `query()`.
7557        """
7558        return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7559
7560    def reason_unknown(self):
7561        """Return a string describing why the last `query()` returned `unknown`.
7562        """
7563        return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7564
7565    def declare_var(self, *vars):
7566        """Add variable or several variables.
7567        The added variable or variables will be bound in the rules
7568        and queries
7569        """
7570        vars = _get_args(vars)
7571        for v in vars:
7572            self.vars += [v]
7573
7574    def abstract(self, fml, is_forall=True):
7575        if self.vars == []:
7576            return fml
7577        if is_forall:
7578            return ForAll(self.vars, fml)
7579        else:
7580            return Exists(self.vars, fml)
7581
7582
7583#########################################
7584#
7585# Finite domains
7586#
7587#########################################
7588
7589class FiniteDomainSortRef(SortRef):
7590    """Finite domain sort."""
7591
7592    def size(self):
7593        """Return the size of the finite domain sort"""
7594        r = (ctypes.c_ulonglong * 1)()
7595        if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7596            return r[0]
7597        else:
7598            raise Z3Exception("Failed to retrieve finite domain sort size")
7599
7600
7601def FiniteDomainSort(name, sz, ctx=None):
7602    """Create a named finite domain sort of a given size sz"""
7603    if not isinstance(name, Symbol):
7604        name = to_symbol(name)
7605    ctx = _get_ctx(ctx)
7606    return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7607
7608
7609def is_finite_domain_sort(s):
7610    """Return True if `s` is a Z3 finite-domain sort.
7611
7612    >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7613    True
7614    >>> is_finite_domain_sort(IntSort())
7615    False
7616    """
7617    return isinstance(s, FiniteDomainSortRef)
7618
7619
7620class FiniteDomainRef(ExprRef):
7621    """Finite-domain expressions."""
7622
7623    def sort(self):
7624        """Return the sort of the finite-domain expression `self`."""
7625        return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7626
7627    def as_string(self):
7628        """Return a Z3 floating point expression as a Python string."""
7629        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7630
7631
7632def is_finite_domain(a):
7633    """Return `True` if `a` is a Z3 finite-domain expression.
7634
7635    >>> s = FiniteDomainSort('S', 100)
7636    >>> b = Const('b', s)
7637    >>> is_finite_domain(b)
7638    True
7639    >>> is_finite_domain(Int('x'))
7640    False
7641    """
7642    return isinstance(a, FiniteDomainRef)
7643
7644
7645class FiniteDomainNumRef(FiniteDomainRef):
7646    """Integer values."""
7647
7648    def as_long(self):
7649        """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7650
7651        >>> s = FiniteDomainSort('S', 100)
7652        >>> v = FiniteDomainVal(3, s)
7653        >>> v
7654        3
7655        >>> v.as_long() + 1
7656        4
7657        """
7658        return int(self.as_string())
7659
7660    def as_string(self):
7661        """Return a Z3 finite-domain numeral as a Python string.
7662
7663        >>> s = FiniteDomainSort('S', 100)
7664        >>> v = FiniteDomainVal(42, s)
7665        >>> v.as_string()
7666        '42'
7667        """
7668        return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
7669
7670
7671def FiniteDomainVal(val, sort, ctx=None):
7672    """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
7673
7674    >>> s = FiniteDomainSort('S', 256)
7675    >>> FiniteDomainVal(255, s)
7676    255
7677    >>> FiniteDomainVal('100', s)
7678    100
7679    """
7680    if z3_debug():
7681        _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
7682    ctx = sort.ctx
7683    return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
7684
7685
7686def is_finite_domain_value(a):
7687    """Return `True` if `a` is a Z3 finite-domain value.
7688
7689    >>> s = FiniteDomainSort('S', 100)
7690    >>> b = Const('b', s)
7691    >>> is_finite_domain_value(b)
7692    False
7693    >>> b = FiniteDomainVal(10, s)
7694    >>> b
7695    10
7696    >>> is_finite_domain_value(b)
7697    True
7698    """
7699    return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
7700
7701
7702#########################################
7703#
7704# Optimize
7705#
7706#########################################
7707
7708class OptimizeObjective:
7709    def __init__(self, opt, value, is_max):
7710        self._opt = opt
7711        self._value = value
7712        self._is_max = is_max
7713
7714    def lower(self):
7715        opt = self._opt
7716        return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7717
7718    def upper(self):
7719        opt = self._opt
7720        return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7721
7722    def lower_values(self):
7723        opt = self._opt
7724        return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7725
7726    def upper_values(self):
7727        opt = self._opt
7728        return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7729
7730    def value(self):
7731        if self._is_max:
7732            return self.upper()
7733        else:
7734            return self.lower()
7735
7736    def __str__(self):
7737        return "%s:%s" % (self._value, self._is_max)
7738
7739
7740_on_models = {}
7741
7742
7743def _global_on_model(ctx):
7744    (fn, mdl) = _on_models[ctx]
7745    fn(mdl)
7746
7747
7748_on_model_eh = on_model_eh_type(_global_on_model)
7749
7750
7751class Optimize(Z3PPObject):
7752    """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
7753
7754    def __init__(self, ctx=None):
7755        self.ctx = _get_ctx(ctx)
7756        self.optimize = Z3_mk_optimize(self.ctx.ref())
7757        self._on_models_id = None
7758        Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
7759
7760    def __deepcopy__(self, memo={}):
7761        return Optimize(self.optimize, self.ctx)
7762
7763    def __del__(self):
7764        if self.optimize is not None and self.ctx.ref() is not None:
7765            Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
7766        if self._on_models_id is not None:
7767            del _on_models[self._on_models_id]
7768
7769    def set(self, *args, **keys):
7770        """Set a configuration option.
7771        The method `help()` return a string containing all available options.
7772        """
7773        p = args2params(args, keys, self.ctx)
7774        Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
7775
7776    def help(self):
7777        """Display a string describing all available options."""
7778        print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
7779
7780    def param_descrs(self):
7781        """Return the parameter description set."""
7782        return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
7783
7784    def assert_exprs(self, *args):
7785        """Assert constraints as background axioms for the optimize solver."""
7786        args = _get_args(args)
7787        s = BoolSort(self.ctx)
7788        for arg in args:
7789            if isinstance(arg, Goal) or isinstance(arg, AstVector):
7790                for f in arg:
7791                    Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
7792            else:
7793                arg = s.cast(arg)
7794                Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
7795
7796    def add(self, *args):
7797        """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
7798        self.assert_exprs(*args)
7799
7800    def __iadd__(self, fml):
7801        self.add(fml)
7802        return self
7803
7804    def assert_and_track(self, a, p):
7805        """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7806
7807        If `p` is a string, it will be automatically converted into a Boolean constant.
7808
7809        >>> x = Int('x')
7810        >>> p3 = Bool('p3')
7811        >>> s = Optimize()
7812        >>> s.assert_and_track(x > 0,  'p1')
7813        >>> s.assert_and_track(x != 1, 'p2')
7814        >>> s.assert_and_track(x < 0,  p3)
7815        >>> print(s.check())
7816        unsat
7817        >>> c = s.unsat_core()
7818        >>> len(c)
7819        2
7820        >>> Bool('p1') in c
7821        True
7822        >>> Bool('p2') in c
7823        False
7824        >>> p3 in c
7825        True
7826        """
7827        if isinstance(p, str):
7828            p = Bool(p, self.ctx)
7829        _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7830        _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7831        Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
7832
7833    def add_soft(self, arg, weight="1", id=None):
7834        """Add soft constraint with optional weight and optional identifier.
7835           If no weight is supplied, then the penalty for violating the soft constraint
7836           is 1.
7837           Soft constraints are grouped by identifiers. Soft constraints that are
7838           added without identifiers are grouped by default.
7839        """
7840        if _is_int(weight):
7841            weight = "%d" % weight
7842        elif isinstance(weight, float):
7843            weight = "%f" % weight
7844        if not isinstance(weight, str):
7845            raise Z3Exception("weight should be a string or an integer")
7846        if id is None:
7847            id = ""
7848        id = to_symbol(id, self.ctx)
7849
7850        def asoft(a):
7851            v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
7852            return OptimizeObjective(self, v, False)
7853        if sys.version_info.major >= 3 and isinstance(arg, Iterable):
7854            return [asoft(a) for a in arg]
7855        return asoft(arg)
7856
7857    def maximize(self, arg):
7858        """Add objective function to maximize."""
7859        return OptimizeObjective(
7860            self,
7861            Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
7862            is_max=True,
7863        )
7864
7865    def minimize(self, arg):
7866        """Add objective function to minimize."""
7867        return OptimizeObjective(
7868            self,
7869            Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
7870            is_max=False,
7871        )
7872
7873    def push(self):
7874        """create a backtracking point for added rules, facts and assertions"""
7875        Z3_optimize_push(self.ctx.ref(), self.optimize)
7876
7877    def pop(self):
7878        """restore to previously created backtracking point"""
7879        Z3_optimize_pop(self.ctx.ref(), self.optimize)
7880
7881    def check(self, *assumptions):
7882        """Check satisfiability while optimizing objective functions."""
7883        assumptions = _get_args(assumptions)
7884        num = len(assumptions)
7885        _assumptions = (Ast * num)()
7886        for i in range(num):
7887            _assumptions[i] = assumptions[i].as_ast()
7888        return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
7889
7890    def reason_unknown(self):
7891        """Return a string that describes why the last `check()` returned `unknown`."""
7892        return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
7893
7894    def model(self):
7895        """Return a model for the last check()."""
7896        try:
7897            return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
7898        except Z3Exception:
7899            raise Z3Exception("model is not available")
7900
7901    def unsat_core(self):
7902        return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
7903
7904    def lower(self, obj):
7905        if not isinstance(obj, OptimizeObjective):
7906            raise Z3Exception("Expecting objective handle returned by maximize/minimize")
7907        return obj.lower()
7908
7909    def upper(self, obj):
7910        if not isinstance(obj, OptimizeObjective):
7911            raise Z3Exception("Expecting objective handle returned by maximize/minimize")
7912        return obj.upper()
7913
7914    def lower_values(self, obj):
7915        if not isinstance(obj, OptimizeObjective):
7916            raise Z3Exception("Expecting objective handle returned by maximize/minimize")
7917        return obj.lower_values()
7918
7919    def upper_values(self, obj):
7920        if not isinstance(obj, OptimizeObjective):
7921            raise Z3Exception("Expecting objective handle returned by maximize/minimize")
7922        return obj.upper_values()
7923
7924    def from_file(self, filename):
7925        """Parse assertions and objectives from a file"""
7926        Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
7927
7928    def from_string(self, s):
7929        """Parse assertions and objectives from a string"""
7930        Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
7931
7932    def assertions(self):
7933        """Return an AST vector containing all added constraints."""
7934        return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
7935
7936    def objectives(self):
7937        """returns set of objective functions"""
7938        return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
7939
7940    def __repr__(self):
7941        """Return a formatted string with all added rules and constraints."""
7942        return self.sexpr()
7943
7944    def sexpr(self):
7945        """Return a formatted string (in Lisp-like format) with all added constraints.
7946        We say the string is in s-expression format.
7947        """
7948        return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
7949
7950    def statistics(self):
7951        """Return statistics for the last check`.
7952        """
7953        return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
7954
7955    def set_on_model(self, on_model):
7956        """Register a callback that is invoked with every incremental improvement to
7957        objective values. The callback takes a model as argument.
7958        The life-time of the model is limited to the callback so the
7959        model has to be (deep) copied if it is to be used after the callback
7960        """
7961        id = len(_on_models) + 41
7962        mdl = Model(self.ctx)
7963        _on_models[id] = (on_model, mdl)
7964        self._on_models_id = id
7965        Z3_optimize_register_model_eh(
7966            self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
7967        )
7968
7969
7970#########################################
7971#
7972# ApplyResult
7973#
7974#########################################
7975class ApplyResult(Z3PPObject):
7976    """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
7977    It also contains model and proof converters.
7978    """
7979
7980    def __init__(self, result, ctx):
7981        self.result = result
7982        self.ctx = ctx
7983        Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
7984
7985    def __deepcopy__(self, memo={}):
7986        return ApplyResult(self.result, self.ctx)
7987
7988    def __del__(self):
7989        if self.ctx.ref() is not None:
7990            Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
7991
7992    def __len__(self):
7993        """Return the number of subgoals in `self`.
7994
7995        >>> a, b = Ints('a b')
7996        >>> g = Goal()
7997        >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
7998        >>> t = Tactic('split-clause')
7999        >>> r = t(g)
8000        >>> len(r)
8001        2
8002        >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8003        >>> len(t(g))
8004        4
8005        >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8006        >>> len(t(g))
8007        1
8008        """
8009        return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8010
8011    def __getitem__(self, idx):
8012        """Return one of the subgoals stored in ApplyResult object `self`.
8013
8014        >>> a, b = Ints('a b')
8015        >>> g = Goal()
8016        >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8017        >>> t = Tactic('split-clause')
8018        >>> r = t(g)
8019        >>> r[0]
8020        [a == 0, Or(b == 0, b == 1), a > b]
8021        >>> r[1]
8022        [a == 1, Or(b == 0, b == 1), a > b]
8023        """
8024        if idx >= len(self):
8025            raise IndexError
8026        return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8027
8028    def __repr__(self):
8029        return obj_to_string(self)
8030
8031    def sexpr(self):
8032        """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8033        return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8034
8035    def as_expr(self):
8036        """Return a Z3 expression consisting of all subgoals.
8037
8038        >>> x = Int('x')
8039        >>> g = Goal()
8040        >>> g.add(x > 1)
8041        >>> g.add(Or(x == 2, x == 3))
8042        >>> r = Tactic('simplify')(g)
8043        >>> r
8044        [[Not(x <= 1), Or(x == 2, x == 3)]]
8045        >>> r.as_expr()
8046        And(Not(x <= 1), Or(x == 2, x == 3))
8047        >>> r = Tactic('split-clause')(g)
8048        >>> r
8049        [[x > 1, x == 2], [x > 1, x == 3]]
8050        >>> r.as_expr()
8051        Or(And(x > 1, x == 2), And(x > 1, x == 3))
8052        """
8053        sz = len(self)
8054        if sz == 0:
8055            return BoolVal(False, self.ctx)
8056        elif sz == 1:
8057            return self[0].as_expr()
8058        else:
8059            return Or([self[i].as_expr() for i in range(len(self))])
8060
8061#########################################
8062#
8063# Tactics
8064#
8065#########################################
8066
8067
8068class Tactic:
8069    """Tactics transform, solver and/or simplify sets of constraints (Goal).
8070    A Tactic can be converted into a Solver using the method solver().
8071
8072    Several combinators are available for creating new tactics using the built-in ones:
8073    Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8074    """
8075
8076    def __init__(self, tactic, ctx=None):
8077        self.ctx = _get_ctx(ctx)
8078        self.tactic = None
8079        if isinstance(tactic, TacticObj):
8080            self.tactic = tactic
8081        else:
8082            if z3_debug():
8083                _z3_assert(isinstance(tactic, str), "tactic name expected")
8084            try:
8085                self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8086            except Z3Exception:
8087                raise Z3Exception("unknown tactic '%s'" % tactic)
8088        Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8089
8090    def __deepcopy__(self, memo={}):
8091        return Tactic(self.tactic, self.ctx)
8092
8093    def __del__(self):
8094        if self.tactic is not None and self.ctx.ref() is not None:
8095            Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8096
8097    def solver(self, logFile=None):
8098        """Create a solver using the tactic `self`.
8099
8100        The solver supports the methods `push()` and `pop()`, but it
8101        will always solve each `check()` from scratch.
8102
8103        >>> t = Then('simplify', 'nlsat')
8104        >>> s = t.solver()
8105        >>> x = Real('x')
8106        >>> s.add(x**2 == 2, x > 0)
8107        >>> s.check()
8108        sat
8109        >>> s.model()
8110        [x = 1.4142135623?]
8111        """
8112        return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8113
8114    def apply(self, goal, *arguments, **keywords):
8115        """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8116
8117        >>> x, y = Ints('x y')
8118        >>> t = Tactic('solve-eqs')
8119        >>> t.apply(And(x == 0, y >= x + 1))
8120        [[y >= 1]]
8121        """
8122        if z3_debug():
8123            _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8124        goal = _to_goal(goal)
8125        if len(arguments) > 0 or len(keywords) > 0:
8126            p = args2params(arguments, keywords, self.ctx)
8127            return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8128        else:
8129            return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8130
8131    def __call__(self, goal, *arguments, **keywords):
8132        """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8133
8134        >>> x, y = Ints('x y')
8135        >>> t = Tactic('solve-eqs')
8136        >>> t(And(x == 0, y >= x + 1))
8137        [[y >= 1]]
8138        """
8139        return self.apply(goal, *arguments, **keywords)
8140
8141    def help(self):
8142        """Display a string containing a description of the available options for the `self` tactic."""
8143        print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8144
8145    def param_descrs(self):
8146        """Return the parameter description set."""
8147        return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8148
8149
8150def _to_goal(a):
8151    if isinstance(a, BoolRef):
8152        goal = Goal(ctx=a.ctx)
8153        goal.add(a)
8154        return goal
8155    else:
8156        return a
8157
8158
8159def _to_tactic(t, ctx=None):
8160    if isinstance(t, Tactic):
8161        return t
8162    else:
8163        return Tactic(t, ctx)
8164
8165
8166def _and_then(t1, t2, ctx=None):
8167    t1 = _to_tactic(t1, ctx)
8168    t2 = _to_tactic(t2, ctx)
8169    if z3_debug():
8170        _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8171    return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8172
8173
8174def _or_else(t1, t2, ctx=None):
8175    t1 = _to_tactic(t1, ctx)
8176    t2 = _to_tactic(t2, ctx)
8177    if z3_debug():
8178        _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8179    return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8180
8181
8182def AndThen(*ts, **ks):
8183    """Return a tactic that applies the tactics in `*ts` in sequence.
8184
8185    >>> x, y = Ints('x y')
8186    >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8187    >>> t(And(x == 0, y > x + 1))
8188    [[Not(y <= 1)]]
8189    >>> t(And(x == 0, y > x + 1)).as_expr()
8190    Not(y <= 1)
8191    """
8192    if z3_debug():
8193        _z3_assert(len(ts) >= 2, "At least two arguments expected")
8194    ctx = ks.get("ctx", None)
8195    num = len(ts)
8196    r = ts[0]
8197    for i in range(num - 1):
8198        r = _and_then(r, ts[i + 1], ctx)
8199    return r
8200
8201
8202def Then(*ts, **ks):
8203    """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8204
8205    >>> x, y = Ints('x y')
8206    >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8207    >>> t(And(x == 0, y > x + 1))
8208    [[Not(y <= 1)]]
8209    >>> t(And(x == 0, y > x + 1)).as_expr()
8210    Not(y <= 1)
8211    """
8212    return AndThen(*ts, **ks)
8213
8214
8215def OrElse(*ts, **ks):
8216    """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8217
8218    >>> x = Int('x')
8219    >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8220    >>> # Tactic split-clause fails if there is no clause in the given goal.
8221    >>> t(x == 0)
8222    [[x == 0]]
8223    >>> t(Or(x == 0, x == 1))
8224    [[x == 0], [x == 1]]
8225    """
8226    if z3_debug():
8227        _z3_assert(len(ts) >= 2, "At least two arguments expected")
8228    ctx = ks.get("ctx", None)
8229    num = len(ts)
8230    r = ts[0]
8231    for i in range(num - 1):
8232        r = _or_else(r, ts[i + 1], ctx)
8233    return r
8234
8235
8236def ParOr(*ts, **ks):
8237    """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8238
8239    >>> x = Int('x')
8240    >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8241    >>> t(x + 1 == 2)
8242    [[x == 1]]
8243    """
8244    if z3_debug():
8245        _z3_assert(len(ts) >= 2, "At least two arguments expected")
8246    ctx = _get_ctx(ks.get("ctx", None))
8247    ts = [_to_tactic(t, ctx) for t in ts]
8248    sz = len(ts)
8249    _args = (TacticObj * sz)()
8250    for i in range(sz):
8251        _args[i] = ts[i].tactic
8252    return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8253
8254
8255def ParThen(t1, t2, ctx=None):
8256    """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8257    The subgoals are processed in parallel.
8258
8259    >>> x, y = Ints('x y')
8260    >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8261    >>> t(And(Or(x == 1, x == 2), y == x + 1))
8262    [[x == 1, y == 2], [x == 2, y == 3]]
8263    """
8264    t1 = _to_tactic(t1, ctx)
8265    t2 = _to_tactic(t2, ctx)
8266    if z3_debug():
8267        _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8268    return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8269
8270
8271def ParAndThen(t1, t2, ctx=None):
8272    """Alias for ParThen(t1, t2, ctx)."""
8273    return ParThen(t1, t2, ctx)
8274
8275
8276def With(t, *args, **keys):
8277    """Return a tactic that applies tactic `t` using the given configuration options.
8278
8279    >>> x, y = Ints('x y')
8280    >>> t = With(Tactic('simplify'), som=True)
8281    >>> t((x + 1)*(y + 2) == 0)
8282    [[2*x + y + x*y == -2]]
8283    """
8284    ctx = keys.pop("ctx", None)
8285    t = _to_tactic(t, ctx)
8286    p = args2params(args, keys, t.ctx)
8287    return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8288
8289
8290def WithParams(t, p):
8291    """Return a tactic that applies tactic `t` using the given configuration options.
8292
8293    >>> x, y = Ints('x y')
8294    >>> p = ParamsRef()
8295    >>> p.set("som", True)
8296    >>> t = WithParams(Tactic('simplify'), p)
8297    >>> t((x + 1)*(y + 2) == 0)
8298    [[2*x + y + x*y == -2]]
8299    """
8300    t = _to_tactic(t, None)
8301    return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8302
8303
8304def Repeat(t, max=4294967295, ctx=None):
8305    """Return a tactic that keeps applying `t` until the goal is not modified anymore
8306    or the maximum number of iterations `max` is reached.
8307
8308    >>> x, y = Ints('x y')
8309    >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8310    >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8311    >>> r = t(c)
8312    >>> for subgoal in r: print(subgoal)
8313    [x == 0, y == 0, x > y]
8314    [x == 0, y == 1, x > y]
8315    [x == 1, y == 0, x > y]
8316    [x == 1, y == 1, x > y]
8317    >>> t = Then(t, Tactic('propagate-values'))
8318    >>> t(c)
8319    [[x == 1, y == 0]]
8320    """
8321    t = _to_tactic(t, ctx)
8322    return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8323
8324
8325def TryFor(t, ms, ctx=None):
8326    """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8327
8328    If `t` does not terminate in `ms` milliseconds, then it fails.
8329    """
8330    t = _to_tactic(t, ctx)
8331    return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8332
8333
8334def tactics(ctx=None):
8335    """Return a list of all available tactics in Z3.
8336
8337    >>> l = tactics()
8338    >>> l.count('simplify') == 1
8339    True
8340    """
8341    ctx = _get_ctx(ctx)
8342    return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8343
8344
8345def tactic_description(name, ctx=None):
8346    """Return a short description for the tactic named `name`.
8347
8348    >>> d = tactic_description('simplify')
8349    """
8350    ctx = _get_ctx(ctx)
8351    return Z3_tactic_get_descr(ctx.ref(), name)
8352
8353
8354def describe_tactics():
8355    """Display a (tabular) description of all available tactics in Z3."""
8356    if in_html_mode():
8357        even = True
8358        print('<table border="1" cellpadding="2" cellspacing="0">')
8359        for t in tactics():
8360            if even:
8361                print('<tr style="background-color:#CFCFCF">')
8362                even = False
8363            else:
8364                print("<tr>")
8365                even = True
8366            print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8367        print("</table>")
8368    else:
8369        for t in tactics():
8370            print("%s : %s" % (t, tactic_description(t)))
8371
8372
8373class Probe:
8374    """Probes are used to inspect a goal (aka problem) and collect information that may be used
8375    to decide which solver and/or preprocessing step will be used.
8376    """
8377
8378    def __init__(self, probe, ctx=None):
8379        self.ctx = _get_ctx(ctx)
8380        self.probe = None
8381        if isinstance(probe, ProbeObj):
8382            self.probe = probe
8383        elif isinstance(probe, float):
8384            self.probe = Z3_probe_const(self.ctx.ref(), probe)
8385        elif _is_int(probe):
8386            self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8387        elif isinstance(probe, bool):
8388            if probe:
8389                self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8390            else:
8391                self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8392        else:
8393            if z3_debug():
8394                _z3_assert(isinstance(probe, str), "probe name expected")
8395            try:
8396                self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8397            except Z3Exception:
8398                raise Z3Exception("unknown probe '%s'" % probe)
8399        Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8400
8401    def __deepcopy__(self, memo={}):
8402        return Probe(self.probe, self.ctx)
8403
8404    def __del__(self):
8405        if self.probe is not None and self.ctx.ref() is not None:
8406            Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8407
8408    def __lt__(self, other):
8409        """Return a probe that evaluates to "true" when the value returned by `self`
8410        is less than the value returned by `other`.
8411
8412        >>> p = Probe('size') < 10
8413        >>> x = Int('x')
8414        >>> g = Goal()
8415        >>> g.add(x > 0)
8416        >>> g.add(x < 10)
8417        >>> p(g)
8418        1.0
8419        """
8420        return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8421
8422    def __gt__(self, other):
8423        """Return a probe that evaluates to "true" when the value returned by `self`
8424        is greater than the value returned by `other`.
8425
8426        >>> p = Probe('size') > 10
8427        >>> x = Int('x')
8428        >>> g = Goal()
8429        >>> g.add(x > 0)
8430        >>> g.add(x < 10)
8431        >>> p(g)
8432        0.0
8433        """
8434        return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8435
8436    def __le__(self, other):
8437        """Return a probe that evaluates to "true" when the value returned by `self`
8438        is less than or equal to the value returned by `other`.
8439
8440        >>> p = Probe('size') <= 2
8441        >>> x = Int('x')
8442        >>> g = Goal()
8443        >>> g.add(x > 0)
8444        >>> g.add(x < 10)
8445        >>> p(g)
8446        1.0
8447        """
8448        return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8449
8450    def __ge__(self, other):
8451        """Return a probe that evaluates to "true" when the value returned by `self`
8452        is greater than or equal to the value returned by `other`.
8453
8454        >>> p = Probe('size') >= 2
8455        >>> x = Int('x')
8456        >>> g = Goal()
8457        >>> g.add(x > 0)
8458        >>> g.add(x < 10)
8459        >>> p(g)
8460        1.0
8461        """
8462        return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8463
8464    def __eq__(self, other):
8465        """Return a probe that evaluates to "true" when the value returned by `self`
8466        is equal to the value returned by `other`.
8467
8468        >>> p = Probe('size') == 2
8469        >>> x = Int('x')
8470        >>> g = Goal()
8471        >>> g.add(x > 0)
8472        >>> g.add(x < 10)
8473        >>> p(g)
8474        1.0
8475        """
8476        return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8477
8478    def __ne__(self, other):
8479        """Return a probe that evaluates to "true" when the value returned by `self`
8480        is not equal to the value returned by `other`.
8481
8482        >>> p = Probe('size') != 2
8483        >>> x = Int('x')
8484        >>> g = Goal()
8485        >>> g.add(x > 0)
8486        >>> g.add(x < 10)
8487        >>> p(g)
8488        0.0
8489        """
8490        p = self.__eq__(other)
8491        return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8492
8493    def __call__(self, goal):
8494        """Evaluate the probe `self` in the given goal.
8495
8496        >>> p = Probe('size')
8497        >>> x = Int('x')
8498        >>> g = Goal()
8499        >>> g.add(x > 0)
8500        >>> g.add(x < 10)
8501        >>> p(g)
8502        2.0
8503        >>> g.add(x < 20)
8504        >>> p(g)
8505        3.0
8506        >>> p = Probe('num-consts')
8507        >>> p(g)
8508        1.0
8509        >>> p = Probe('is-propositional')
8510        >>> p(g)
8511        0.0
8512        >>> p = Probe('is-qflia')
8513        >>> p(g)
8514        1.0
8515        """
8516        if z3_debug():
8517            _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8518        goal = _to_goal(goal)
8519        return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8520
8521
8522def is_probe(p):
8523    """Return `True` if `p` is a Z3 probe.
8524
8525    >>> is_probe(Int('x'))
8526    False
8527    >>> is_probe(Probe('memory'))
8528    True
8529    """
8530    return isinstance(p, Probe)
8531
8532
8533def _to_probe(p, ctx=None):
8534    if is_probe(p):
8535        return p
8536    else:
8537        return Probe(p, ctx)
8538
8539
8540def probes(ctx=None):
8541    """Return a list of all available probes in Z3.
8542
8543    >>> l = probes()
8544    >>> l.count('memory') == 1
8545    True
8546    """
8547    ctx = _get_ctx(ctx)
8548    return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8549
8550
8551def probe_description(name, ctx=None):
8552    """Return a short description for the probe named `name`.
8553
8554    >>> d = probe_description('memory')
8555    """
8556    ctx = _get_ctx(ctx)
8557    return Z3_probe_get_descr(ctx.ref(), name)
8558
8559
8560def describe_probes():
8561    """Display a (tabular) description of all available probes in Z3."""
8562    if in_html_mode():
8563        even = True
8564        print('<table border="1" cellpadding="2" cellspacing="0">')
8565        for p in probes():
8566            if even:
8567                print('<tr style="background-color:#CFCFCF">')
8568                even = False
8569            else:
8570                print("<tr>")
8571                even = True
8572            print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
8573        print("</table>")
8574    else:
8575        for p in probes():
8576            print("%s : %s" % (p, probe_description(p)))
8577
8578
8579def _probe_nary(f, args, ctx):
8580    if z3_debug():
8581        _z3_assert(len(args) > 0, "At least one argument expected")
8582    num = len(args)
8583    r = _to_probe(args[0], ctx)
8584    for i in range(num - 1):
8585        r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
8586    return r
8587
8588
8589def _probe_and(args, ctx):
8590    return _probe_nary(Z3_probe_and, args, ctx)
8591
8592
8593def _probe_or(args, ctx):
8594    return _probe_nary(Z3_probe_or, args, ctx)
8595
8596
8597def FailIf(p, ctx=None):
8598    """Return a tactic that fails if the probe `p` evaluates to true.
8599    Otherwise, it returns the input goal unmodified.
8600
8601    In the following example, the tactic applies 'simplify' if and only if there are
8602    more than 2 constraints in the goal.
8603
8604    >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
8605    >>> x, y = Ints('x y')
8606    >>> g = Goal()
8607    >>> g.add(x > 0)
8608    >>> g.add(y > 0)
8609    >>> t(g)
8610    [[x > 0, y > 0]]
8611    >>> g.add(x == y + 1)
8612    >>> t(g)
8613    [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8614    """
8615    p = _to_probe(p, ctx)
8616    return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
8617
8618
8619def When(p, t, ctx=None):
8620    """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
8621    Otherwise, it returns the input goal unmodified.
8622
8623    >>> t = When(Probe('size') > 2, Tactic('simplify'))
8624    >>> x, y = Ints('x y')
8625    >>> g = Goal()
8626    >>> g.add(x > 0)
8627    >>> g.add(y > 0)
8628    >>> t(g)
8629    [[x > 0, y > 0]]
8630    >>> g.add(x == y + 1)
8631    >>> t(g)
8632    [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8633    """
8634    p = _to_probe(p, ctx)
8635    t = _to_tactic(t, ctx)
8636    return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
8637
8638
8639def Cond(p, t1, t2, ctx=None):
8640    """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
8641
8642    >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
8643    """
8644    p = _to_probe(p, ctx)
8645    t1 = _to_tactic(t1, ctx)
8646    t2 = _to_tactic(t2, ctx)
8647    return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
8648
8649#########################################
8650#
8651# Utils
8652#
8653#########################################
8654
8655
8656def simplify(a, *arguments, **keywords):
8657    """Simplify the expression `a` using the given options.
8658
8659    This function has many options. Use `help_simplify` to obtain the complete list.
8660
8661    >>> x = Int('x')
8662    >>> y = Int('y')
8663    >>> simplify(x + 1 + y + x + 1)
8664    2 + 2*x + y
8665    >>> simplify((x + 1)*(y + 1), som=True)
8666    1 + x + y + x*y
8667    >>> simplify(Distinct(x, y, 1), blast_distinct=True)
8668    And(Not(x == y), Not(x == 1), Not(y == 1))
8669    >>> simplify(And(x == 0, y == 1), elim_and=True)
8670    Not(Or(Not(x == 0), Not(y == 1)))
8671    """
8672    if z3_debug():
8673        _z3_assert(is_expr(a), "Z3 expression expected")
8674    if len(arguments) > 0 or len(keywords) > 0:
8675        p = args2params(arguments, keywords, a.ctx)
8676        return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
8677    else:
8678        return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
8679
8680
8681def help_simplify():
8682    """Return a string describing all options available for Z3 `simplify` procedure."""
8683    print(Z3_simplify_get_help(main_ctx().ref()))
8684
8685
8686def simplify_param_descrs():
8687    """Return the set of parameter descriptions for Z3 `simplify` procedure."""
8688    return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
8689
8690
8691def substitute(t, *m):
8692    """Apply substitution m on t, m is a list of pairs of the form (from, to).
8693    Every occurrence in t of from is replaced with to.
8694
8695    >>> x = Int('x')
8696    >>> y = Int('y')
8697    >>> substitute(x + 1, (x, y + 1))
8698    y + 1 + 1
8699    >>> f = Function('f', IntSort(), IntSort())
8700    >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
8701    1 + 1
8702    """
8703    if isinstance(m, tuple):
8704        m1 = _get_args(m)
8705        if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
8706            m = m1
8707    if z3_debug():
8708        _z3_assert(is_expr(t), "Z3 expression expected")
8709        _z3_assert(all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) and p[0].sort().eq(
8710            p[1].sort()) for p in m]), "Z3 invalid substitution, expression pairs expected.")
8711    num = len(m)
8712    _from = (Ast * num)()
8713    _to = (Ast * num)()
8714    for i in range(num):
8715        _from[i] = m[i][0].as_ast()
8716        _to[i] = m[i][1].as_ast()
8717    return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
8718
8719
8720def substitute_vars(t, *m):
8721    """Substitute the free variables in t with the expression in m.
8722
8723    >>> v0 = Var(0, IntSort())
8724    >>> v1 = Var(1, IntSort())
8725    >>> x  = Int('x')
8726    >>> f  = Function('f', IntSort(), IntSort(), IntSort())
8727    >>> # replace v0 with x+1 and v1 with x
8728    >>> substitute_vars(f(v0, v1), x + 1, x)
8729    f(x + 1, x)
8730    """
8731    if z3_debug():
8732        _z3_assert(is_expr(t), "Z3 expression expected")
8733        _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
8734    num = len(m)
8735    _to = (Ast * num)()
8736    for i in range(num):
8737        _to[i] = m[i].as_ast()
8738    return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
8739
8740
8741def Sum(*args):
8742    """Create the sum of the Z3 expressions.
8743
8744    >>> a, b, c = Ints('a b c')
8745    >>> Sum(a, b, c)
8746    a + b + c
8747    >>> Sum([a, b, c])
8748    a + b + c
8749    >>> A = IntVector('a', 5)
8750    >>> Sum(A)
8751    a__0 + a__1 + a__2 + a__3 + a__4
8752    """
8753    args = _get_args(args)
8754    if len(args) == 0:
8755        return 0
8756    ctx = _ctx_from_ast_arg_list(args)
8757    if ctx is None:
8758        return _reduce(lambda a, b: a + b, args, 0)
8759    args = _coerce_expr_list(args, ctx)
8760    if is_bv(args[0]):
8761        return _reduce(lambda a, b: a + b, args, 0)
8762    else:
8763        _args, sz = _to_ast_array(args)
8764        return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
8765
8766
8767def Product(*args):
8768    """Create the product of the Z3 expressions.
8769
8770    >>> a, b, c = Ints('a b c')
8771    >>> Product(a, b, c)
8772    a*b*c
8773    >>> Product([a, b, c])
8774    a*b*c
8775    >>> A = IntVector('a', 5)
8776    >>> Product(A)
8777    a__0*a__1*a__2*a__3*a__4
8778    """
8779    args = _get_args(args)
8780    if len(args) == 0:
8781        return 1
8782    ctx = _ctx_from_ast_arg_list(args)
8783    if ctx is None:
8784        return _reduce(lambda a, b: a * b, args, 1)
8785    args = _coerce_expr_list(args, ctx)
8786    if is_bv(args[0]):
8787        return _reduce(lambda a, b: a * b, args, 1)
8788    else:
8789        _args, sz = _to_ast_array(args)
8790        return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
8791
8792
8793def AtMost(*args):
8794    """Create an at-most Pseudo-Boolean k constraint.
8795
8796    >>> a, b, c = Bools('a b c')
8797    >>> f = AtMost(a, b, c, 2)
8798    """
8799    args = _get_args(args)
8800    if z3_debug():
8801        _z3_assert(len(args) > 1, "Non empty list of arguments expected")
8802    ctx = _ctx_from_ast_arg_list(args)
8803    if z3_debug():
8804        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
8805    args1 = _coerce_expr_list(args[:-1], ctx)
8806    k = args[-1]
8807    _args, sz = _to_ast_array(args1)
8808    return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
8809
8810
8811def AtLeast(*args):
8812    """Create an at-most Pseudo-Boolean k constraint.
8813
8814    >>> a, b, c = Bools('a b c')
8815    >>> f = AtLeast(a, b, c, 2)
8816    """
8817    args = _get_args(args)
8818    if z3_debug():
8819        _z3_assert(len(args) > 1, "Non empty list of arguments expected")
8820    ctx = _ctx_from_ast_arg_list(args)
8821    if z3_debug():
8822        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
8823    args1 = _coerce_expr_list(args[:-1], ctx)
8824    k = args[-1]
8825    _args, sz = _to_ast_array(args1)
8826    return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
8827
8828
8829def _reorder_pb_arg(arg):
8830    a, b = arg
8831    if not _is_int(b) and _is_int(a):
8832        return b, a
8833    return arg
8834
8835
8836def _pb_args_coeffs(args, default_ctx=None):
8837    args = _get_args_ast_list(args)
8838    if len(args) == 0:
8839        return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
8840    args = [_reorder_pb_arg(arg) for arg in args]
8841    args, coeffs = zip(*args)
8842    if z3_debug():
8843        _z3_assert(len(args) > 0, "Non empty list of arguments expected")
8844    ctx = _ctx_from_ast_arg_list(args)
8845    if z3_debug():
8846        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
8847    args = _coerce_expr_list(args, ctx)
8848    _args, sz = _to_ast_array(args)
8849    _coeffs = (ctypes.c_int * len(coeffs))()
8850    for i in range(len(coeffs)):
8851        _z3_check_cint_overflow(coeffs[i], "coefficient")
8852        _coeffs[i] = coeffs[i]
8853    return ctx, sz, _args, _coeffs
8854
8855
8856def PbLe(args, k):
8857    """Create a Pseudo-Boolean inequality k constraint.
8858
8859    >>> a, b, c = Bools('a b c')
8860    >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
8861    """
8862    _z3_check_cint_overflow(k, "k")
8863    ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
8864    return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
8865
8866
8867def PbGe(args, k):
8868    """Create a Pseudo-Boolean inequality k constraint.
8869
8870    >>> a, b, c = Bools('a b c')
8871    >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
8872    """
8873    _z3_check_cint_overflow(k, "k")
8874    ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
8875    return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
8876
8877
8878def PbEq(args, k, ctx=None):
8879    """Create a Pseudo-Boolean inequality k constraint.
8880
8881    >>> a, b, c = Bools('a b c')
8882    >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
8883    """
8884    _z3_check_cint_overflow(k, "k")
8885    ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
8886    return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
8887
8888
8889def solve(*args, **keywords):
8890    """Solve the constraints `*args`.
8891
8892    This is a simple function for creating demonstrations. It creates a solver,
8893    configure it using the options in `keywords`, adds the constraints
8894    in `args`, and invokes check.
8895
8896    >>> a = Int('a')
8897    >>> solve(a > 0, a < 2)
8898    [a = 1]
8899    """
8900    show = keywords.pop("show", False)
8901    s = Solver()
8902    s.set(**keywords)
8903    s.add(*args)
8904    if show:
8905        print(s)
8906    r = s.check()
8907    if r == unsat:
8908        print("no solution")
8909    elif r == unknown:
8910        print("failed to solve")
8911        try:
8912            print(s.model())
8913        except Z3Exception:
8914            return
8915    else:
8916        print(s.model())
8917
8918
8919def solve_using(s, *args, **keywords):
8920    """Solve the constraints `*args` using solver `s`.
8921
8922    This is a simple function for creating demonstrations. It is similar to `solve`,
8923    but it uses the given solver `s`.
8924    It configures solver `s` using the options in `keywords`, adds the constraints
8925    in `args`, and invokes check.
8926    """
8927    show = keywords.pop("show", False)
8928    if z3_debug():
8929        _z3_assert(isinstance(s, Solver), "Solver object expected")
8930    s.set(**keywords)
8931    s.add(*args)
8932    if show:
8933        print("Problem:")
8934        print(s)
8935    r = s.check()
8936    if r == unsat:
8937        print("no solution")
8938    elif r == unknown:
8939        print("failed to solve")
8940        try:
8941            print(s.model())
8942        except Z3Exception:
8943            return
8944    else:
8945        if show:
8946            print("Solution:")
8947        print(s.model())
8948
8949
8950def prove(claim, show=False, **keywords):
8951    """Try to prove the given claim.
8952
8953    This is a simple function for creating demonstrations.  It tries to prove
8954    `claim` by showing the negation is unsatisfiable.
8955
8956    >>> p, q = Bools('p q')
8957    >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
8958    proved
8959    """
8960    if z3_debug():
8961        _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
8962    s = Solver()
8963    s.set(**keywords)
8964    s.add(Not(claim))
8965    if show:
8966        print(s)
8967    r = s.check()
8968    if r == unsat:
8969        print("proved")
8970    elif r == unknown:
8971        print("failed to prove")
8972        print(s.model())
8973    else:
8974        print("counterexample")
8975        print(s.model())
8976
8977
8978def _solve_html(*args, **keywords):
8979    """Version of function `solve` used in RiSE4Fun."""
8980    show = keywords.pop("show", False)
8981    s = Solver()
8982    s.set(**keywords)
8983    s.add(*args)
8984    if show:
8985        print("<b>Problem:</b>")
8986        print(s)
8987    r = s.check()
8988    if r == unsat:
8989        print("<b>no solution</b>")
8990    elif r == unknown:
8991        print("<b>failed to solve</b>")
8992        try:
8993            print(s.model())
8994        except Z3Exception:
8995            return
8996    else:
8997        if show:
8998            print("<b>Solution:</b>")
8999        print(s.model())
9000
9001
9002def _solve_using_html(s, *args, **keywords):
9003    """Version of function `solve_using` used in RiSE4Fun."""
9004    show = keywords.pop("show", False)
9005    if z3_debug():
9006        _z3_assert(isinstance(s, Solver), "Solver object expected")
9007    s.set(**keywords)
9008    s.add(*args)
9009    if show:
9010        print("<b>Problem:</b>")
9011        print(s)
9012    r = s.check()
9013    if r == unsat:
9014        print("<b>no solution</b>")
9015    elif r == unknown:
9016        print("<b>failed to solve</b>")
9017        try:
9018            print(s.model())
9019        except Z3Exception:
9020            return
9021    else:
9022        if show:
9023            print("<b>Solution:</b>")
9024        print(s.model())
9025
9026
9027def _prove_html(claim, show=False, **keywords):
9028    """Version of function `prove` used in RiSE4Fun."""
9029    if z3_debug():
9030        _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9031    s = Solver()
9032    s.set(**keywords)
9033    s.add(Not(claim))
9034    if show:
9035        print(s)
9036    r = s.check()
9037    if r == unsat:
9038        print("<b>proved</b>")
9039    elif r == unknown:
9040        print("<b>failed to prove</b>")
9041        print(s.model())
9042    else:
9043        print("<b>counterexample</b>")
9044        print(s.model())
9045
9046
9047def _dict2sarray(sorts, ctx):
9048    sz = len(sorts)
9049    _names = (Symbol * sz)()
9050    _sorts = (Sort * sz)()
9051    i = 0
9052    for k in sorts:
9053        v = sorts[k]
9054        if z3_debug():
9055            _z3_assert(isinstance(k, str), "String expected")
9056            _z3_assert(is_sort(v), "Z3 sort expected")
9057        _names[i] = to_symbol(k, ctx)
9058        _sorts[i] = v.ast
9059        i = i + 1
9060    return sz, _names, _sorts
9061
9062
9063def _dict2darray(decls, ctx):
9064    sz = len(decls)
9065    _names = (Symbol * sz)()
9066    _decls = (FuncDecl * sz)()
9067    i = 0
9068    for k in decls:
9069        v = decls[k]
9070        if z3_debug():
9071            _z3_assert(isinstance(k, str), "String expected")
9072            _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9073        _names[i] = to_symbol(k, ctx)
9074        if is_const(v):
9075            _decls[i] = v.decl().ast
9076        else:
9077            _decls[i] = v.ast
9078        i = i + 1
9079    return sz, _names, _decls
9080
9081
9082def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9083    """Parse a string in SMT 2.0 format using the given sorts and decls.
9084
9085    The arguments sorts and decls are Python dictionaries used to initialize
9086    the symbol table used for the SMT 2.0 parser.
9087
9088    >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9089    [x > 0, x < 10]
9090    >>> x, y = Ints('x y')
9091    >>> f = Function('f', IntSort(), IntSort())
9092    >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9093    [x + f(y) > 0]
9094    >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9095    [a > 0]
9096    """
9097    ctx = _get_ctx(ctx)
9098    ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9099    dsz, dnames, ddecls = _dict2darray(decls, ctx)
9100    return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9101
9102
9103def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9104    """Parse a file in SMT 2.0 format using the given sorts and decls.
9105
9106    This function is similar to parse_smt2_string().
9107    """
9108    ctx = _get_ctx(ctx)
9109    ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9110    dsz, dnames, ddecls = _dict2darray(decls, ctx)
9111    return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9112
9113
9114#########################################
9115#
9116# Floating-Point Arithmetic
9117#
9118#########################################
9119
9120
9121# Global default rounding mode
9122_dflt_rounding_mode = Z3_OP_FPA_RM_TOWARD_ZERO
9123_dflt_fpsort_ebits = 11
9124_dflt_fpsort_sbits = 53
9125
9126
9127def get_default_rounding_mode(ctx=None):
9128    """Retrieves the global default rounding mode."""
9129    global _dflt_rounding_mode
9130    if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9131        return RTZ(ctx)
9132    elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9133        return RTN(ctx)
9134    elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9135        return RTP(ctx)
9136    elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9137        return RNE(ctx)
9138    elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9139        return RNA(ctx)
9140
9141
9142_ROUNDING_MODES = frozenset({
9143    Z3_OP_FPA_RM_TOWARD_ZERO,
9144    Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9145    Z3_OP_FPA_RM_TOWARD_POSITIVE,
9146    Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9147    Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9148})
9149
9150
9151def set_default_rounding_mode(rm, ctx=None):
9152    global _dflt_rounding_mode
9153    if is_fprm_value(rm):
9154        _dflt_rounding_mode = rm.decl().kind()
9155    else:
9156        _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9157        _dflt_rounding_mode = rm
9158
9159
9160def get_default_fp_sort(ctx=None):
9161    return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9162
9163
9164def set_default_fp_sort(ebits, sbits, ctx=None):
9165    global _dflt_fpsort_ebits
9166    global _dflt_fpsort_sbits
9167    _dflt_fpsort_ebits = ebits
9168    _dflt_fpsort_sbits = sbits
9169
9170
9171def _dflt_rm(ctx=None):
9172    return get_default_rounding_mode(ctx)
9173
9174
9175def _dflt_fps(ctx=None):
9176    return get_default_fp_sort(ctx)
9177
9178
9179def _coerce_fp_expr_list(alist, ctx):
9180    first_fp_sort = None
9181    for a in alist:
9182        if is_fp(a):
9183            if first_fp_sort is None:
9184                first_fp_sort = a.sort()
9185            elif first_fp_sort == a.sort():
9186                pass  # OK, same as before
9187            else:
9188                # we saw at least 2 different float sorts; something will
9189                # throw a sort mismatch later, for now assume None.
9190                first_fp_sort = None
9191                break
9192
9193    r = []
9194    for i in range(len(alist)):
9195        a = alist[i]
9196        is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9197        if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9198            r.append(FPVal(a, None, first_fp_sort, ctx))
9199        else:
9200            r.append(a)
9201    return _coerce_expr_list(r, ctx)
9202
9203
9204# FP Sorts
9205
9206class FPSortRef(SortRef):
9207    """Floating-point sort."""
9208
9209    def ebits(self):
9210        """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9211        >>> b = FPSort(8, 24)
9212        >>> b.ebits()
9213        8
9214        """
9215        return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9216
9217    def sbits(self):
9218        """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9219        >>> b = FPSort(8, 24)
9220        >>> b.sbits()
9221        24
9222        """
9223        return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9224
9225    def cast(self, val):
9226        """Try to cast `val` as a floating-point expression.
9227        >>> b = FPSort(8, 24)
9228        >>> b.cast(1.0)
9229        1
9230        >>> b.cast(1.0).sexpr()
9231        '(fp #b0 #x7f #b00000000000000000000000)'
9232        """
9233        if is_expr(val):
9234            if z3_debug():
9235                _z3_assert(self.ctx == val.ctx, "Context mismatch")
9236            return val
9237        else:
9238            return FPVal(val, None, self, self.ctx)
9239
9240
9241def Float16(ctx=None):
9242    """Floating-point 16-bit (half) sort."""
9243    ctx = _get_ctx(ctx)
9244    return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9245
9246
9247def FloatHalf(ctx=None):
9248    """Floating-point 16-bit (half) sort."""
9249    ctx = _get_ctx(ctx)
9250    return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9251
9252
9253def Float32(ctx=None):
9254    """Floating-point 32-bit (single) sort."""
9255    ctx = _get_ctx(ctx)
9256    return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9257
9258
9259def FloatSingle(ctx=None):
9260    """Floating-point 32-bit (single) sort."""
9261    ctx = _get_ctx(ctx)
9262    return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9263
9264
9265def Float64(ctx=None):
9266    """Floating-point 64-bit (double) sort."""
9267    ctx = _get_ctx(ctx)
9268    return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9269
9270
9271def FloatDouble(ctx=None):
9272    """Floating-point 64-bit (double) sort."""
9273    ctx = _get_ctx(ctx)
9274    return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9275
9276
9277def Float128(ctx=None):
9278    """Floating-point 128-bit (quadruple) sort."""
9279    ctx = _get_ctx(ctx)
9280    return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9281
9282
9283def FloatQuadruple(ctx=None):
9284    """Floating-point 128-bit (quadruple) sort."""
9285    ctx = _get_ctx(ctx)
9286    return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9287
9288
9289class FPRMSortRef(SortRef):
9290    """"Floating-point rounding mode sort."""
9291
9292
9293def is_fp_sort(s):
9294    """Return True if `s` is a Z3 floating-point sort.
9295
9296    >>> is_fp_sort(FPSort(8, 24))
9297    True
9298    >>> is_fp_sort(IntSort())
9299    False
9300    """
9301    return isinstance(s, FPSortRef)
9302
9303
9304def is_fprm_sort(s):
9305    """Return True if `s` is a Z3 floating-point rounding mode sort.
9306
9307    >>> is_fprm_sort(FPSort(8, 24))
9308    False
9309    >>> is_fprm_sort(RNE().sort())
9310    True
9311    """
9312    return isinstance(s, FPRMSortRef)
9313
9314# FP Expressions
9315
9316
9317class FPRef(ExprRef):
9318    """Floating-point expressions."""
9319
9320    def sort(self):
9321        """Return the sort of the floating-point expression `self`.
9322
9323        >>> x = FP('1.0', FPSort(8, 24))
9324        >>> x.sort()
9325        FPSort(8, 24)
9326        >>> x.sort() == FPSort(8, 24)
9327        True
9328        """
9329        return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9330
9331    def ebits(self):
9332        """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9333        >>> b = FPSort(8, 24)
9334        >>> b.ebits()
9335        8
9336        """
9337        return self.sort().ebits()
9338
9339    def sbits(self):
9340        """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9341        >>> b = FPSort(8, 24)
9342        >>> b.sbits()
9343        24
9344        """
9345        return self.sort().sbits()
9346
9347    def as_string(self):
9348        """Return a Z3 floating point expression as a Python string."""
9349        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9350
9351    def __le__(self, other):
9352        return fpLEQ(self, other, self.ctx)
9353
9354    def __lt__(self, other):
9355        return fpLT(self, other, self.ctx)
9356
9357    def __ge__(self, other):
9358        return fpGEQ(self, other, self.ctx)
9359
9360    def __gt__(self, other):
9361        return fpGT(self, other, self.ctx)
9362
9363    def __add__(self, other):
9364        """Create the Z3 expression `self + other`.
9365
9366        >>> x = FP('x', FPSort(8, 24))
9367        >>> y = FP('y', FPSort(8, 24))
9368        >>> x + y
9369        x + y
9370        >>> (x + y).sort()
9371        FPSort(8, 24)
9372        """
9373        [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9374        return fpAdd(_dflt_rm(), a, b, self.ctx)
9375
9376    def __radd__(self, other):
9377        """Create the Z3 expression `other + self`.
9378
9379        >>> x = FP('x', FPSort(8, 24))
9380        >>> 10 + x
9381        1.25*(2**3) + x
9382        """
9383        [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9384        return fpAdd(_dflt_rm(), a, b, self.ctx)
9385
9386    def __sub__(self, other):
9387        """Create the Z3 expression `self - other`.
9388
9389        >>> x = FP('x', FPSort(8, 24))
9390        >>> y = FP('y', FPSort(8, 24))
9391        >>> x - y
9392        x - y
9393        >>> (x - y).sort()
9394        FPSort(8, 24)
9395        """
9396        [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9397        return fpSub(_dflt_rm(), a, b, self.ctx)
9398
9399    def __rsub__(self, other):
9400        """Create the Z3 expression `other - self`.
9401
9402        >>> x = FP('x', FPSort(8, 24))
9403        >>> 10 - x
9404        1.25*(2**3) - x
9405        """
9406        [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9407        return fpSub(_dflt_rm(), a, b, self.ctx)
9408
9409    def __mul__(self, other):
9410        """Create the Z3 expression `self * other`.
9411
9412        >>> x = FP('x', FPSort(8, 24))
9413        >>> y = FP('y', FPSort(8, 24))
9414        >>> x * y
9415        x * y
9416        >>> (x * y).sort()
9417        FPSort(8, 24)
9418        >>> 10 * y
9419        1.25*(2**3) * y
9420        """
9421        [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9422        return fpMul(_dflt_rm(), a, b, self.ctx)
9423
9424    def __rmul__(self, other):
9425        """Create the Z3 expression `other * self`.
9426
9427        >>> x = FP('x', FPSort(8, 24))
9428        >>> y = FP('y', FPSort(8, 24))
9429        >>> x * y
9430        x * y
9431        >>> x * 10
9432        x * 1.25*(2**3)
9433        """
9434        [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9435        return fpMul(_dflt_rm(), a, b, self.ctx)
9436
9437    def __pos__(self):
9438        """Create the Z3 expression `+self`."""
9439        return self
9440
9441    def __neg__(self):
9442        """Create the Z3 expression `-self`.
9443
9444        >>> x = FP('x', Float32())
9445        >>> -x
9446        -x
9447        """
9448        return fpNeg(self)
9449
9450    def __div__(self, other):
9451        """Create the Z3 expression `self / other`.
9452
9453        >>> x = FP('x', FPSort(8, 24))
9454        >>> y = FP('y', FPSort(8, 24))
9455        >>> x / y
9456        x / y
9457        >>> (x / y).sort()
9458        FPSort(8, 24)
9459        >>> 10 / y
9460        1.25*(2**3) / y
9461        """
9462        [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9463        return fpDiv(_dflt_rm(), a, b, self.ctx)
9464
9465    def __rdiv__(self, other):
9466        """Create the Z3 expression `other / self`.
9467
9468        >>> x = FP('x', FPSort(8, 24))
9469        >>> y = FP('y', FPSort(8, 24))
9470        >>> x / y
9471        x / y
9472        >>> x / 10
9473        x / 1.25*(2**3)
9474        """
9475        [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9476        return fpDiv(_dflt_rm(), a, b, self.ctx)
9477
9478    def __truediv__(self, other):
9479        """Create the Z3 expression division `self / other`."""
9480        return self.__div__(other)
9481
9482    def __rtruediv__(self, other):
9483        """Create the Z3 expression division `other / self`."""
9484        return self.__rdiv__(other)
9485
9486    def __mod__(self, other):
9487        """Create the Z3 expression mod `self % other`."""
9488        return fpRem(self, other)
9489
9490    def __rmod__(self, other):
9491        """Create the Z3 expression mod `other % self`."""
9492        return fpRem(other, self)
9493
9494
9495class FPRMRef(ExprRef):
9496    """Floating-point rounding mode expressions"""
9497
9498    def as_string(self):
9499        """Return a Z3 floating point expression as a Python string."""
9500        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9501
9502
9503def RoundNearestTiesToEven(ctx=None):
9504    ctx = _get_ctx(ctx)
9505    return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9506
9507
9508def RNE(ctx=None):
9509    ctx = _get_ctx(ctx)
9510    return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9511
9512
9513def RoundNearestTiesToAway(ctx=None):
9514    ctx = _get_ctx(ctx)
9515    return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9516
9517
9518def RNA(ctx=None):
9519    ctx = _get_ctx(ctx)
9520    return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9521
9522
9523def RoundTowardPositive(ctx=None):
9524    ctx = _get_ctx(ctx)
9525    return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9526
9527
9528def RTP(ctx=None):
9529    ctx = _get_ctx(ctx)
9530    return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9531
9532
9533def RoundTowardNegative(ctx=None):
9534    ctx = _get_ctx(ctx)
9535    return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9536
9537
9538def RTN(ctx=None):
9539    ctx = _get_ctx(ctx)
9540    return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9541
9542
9543def RoundTowardZero(ctx=None):
9544    ctx = _get_ctx(ctx)
9545    return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9546
9547
9548def RTZ(ctx=None):
9549    ctx = _get_ctx(ctx)
9550    return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9551
9552
9553def is_fprm(a):
9554    """Return `True` if `a` is a Z3 floating-point rounding mode expression.
9555
9556    >>> rm = RNE()
9557    >>> is_fprm(rm)
9558    True
9559    >>> rm = 1.0
9560    >>> is_fprm(rm)
9561    False
9562    """
9563    return isinstance(a, FPRMRef)
9564
9565
9566def is_fprm_value(a):
9567    """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
9568    return is_fprm(a) and _is_numeral(a.ctx, a.ast)
9569
9570# FP Numerals
9571
9572
9573class FPNumRef(FPRef):
9574    """The sign of the numeral.
9575
9576    >>> x = FPVal(+1.0, FPSort(8, 24))
9577    >>> x.sign()
9578    False
9579    >>> x = FPVal(-1.0, FPSort(8, 24))
9580    >>> x.sign()
9581    True
9582    """
9583
9584    def sign(self):
9585        num = (ctypes.c_int)()
9586        nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
9587        if nsign is False:
9588            raise Z3Exception("error retrieving the sign of a numeral.")
9589        return num.value != 0
9590
9591    """The sign of a floating-point numeral as a bit-vector expression.
9592
9593    Remark: NaN's are invalid arguments.
9594    """
9595
9596    def sign_as_bv(self):
9597        return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9598
9599    """The significand of the numeral.
9600
9601    >>> x = FPVal(2.5, FPSort(8, 24))
9602    >>> x.significand()
9603    1.25
9604    """
9605
9606    def significand(self):
9607        return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
9608
9609    """The significand of the numeral as a long.
9610
9611    >>> x = FPVal(2.5, FPSort(8, 24))
9612    >>> x.significand_as_long()
9613    1.25
9614    """
9615
9616    def significand_as_long(self):
9617        ptr = (ctypes.c_ulonglong * 1)()
9618        if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
9619            raise Z3Exception("error retrieving the significand of a numeral.")
9620        return ptr[0]
9621
9622    """The significand of the numeral as a bit-vector expression.
9623
9624    Remark: NaN are invalid arguments.
9625    """
9626
9627    def significand_as_bv(self):
9628        return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9629
9630    """The exponent of the numeral.
9631
9632    >>> x = FPVal(2.5, FPSort(8, 24))
9633    >>> x.exponent()
9634    1
9635    """
9636
9637    def exponent(self, biased=True):
9638        return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
9639
9640    """The exponent of the numeral as a long.
9641
9642    >>> x = FPVal(2.5, FPSort(8, 24))
9643    >>> x.exponent_as_long()
9644    1
9645    """
9646
9647    def exponent_as_long(self, biased=True):
9648        ptr = (ctypes.c_longlong * 1)()
9649        if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
9650            raise Z3Exception("error retrieving the exponent of a numeral.")
9651        return ptr[0]
9652
9653    """The exponent of the numeral as a bit-vector expression.
9654
9655    Remark: NaNs are invalid arguments.
9656    """
9657
9658    def exponent_as_bv(self, biased=True):
9659        return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
9660
9661    """Indicates whether the numeral is a NaN."""
9662
9663    def isNaN(self):
9664        return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
9665
9666    """Indicates whether the numeral is +oo or -oo."""
9667
9668    def isInf(self):
9669        return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
9670
9671    """Indicates whether the numeral is +zero or -zero."""
9672
9673    def isZero(self):
9674        return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
9675
9676    """Indicates whether the numeral is normal."""
9677
9678    def isNormal(self):
9679        return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
9680
9681    """Indicates whether the numeral is subnormal."""
9682
9683    def isSubnormal(self):
9684        return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
9685
9686    """Indicates whether the numeral is positive."""
9687
9688    def isPositive(self):
9689        return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
9690
9691    """Indicates whether the numeral is negative."""
9692
9693    def isNegative(self):
9694        return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
9695
9696    """
9697    The string representation of the numeral.
9698
9699    >>> x = FPVal(20, FPSort(8, 24))
9700    >>> x.as_string()
9701    1.25*(2**4)
9702    """
9703
9704    def as_string(self):
9705        s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
9706        return ("FPVal(%s, %s)" % (s, self.sort()))
9707
9708
9709def is_fp(a):
9710    """Return `True` if `a` is a Z3 floating-point expression.
9711
9712    >>> b = FP('b', FPSort(8, 24))
9713    >>> is_fp(b)
9714    True
9715    >>> is_fp(b + 1.0)
9716    True
9717    >>> is_fp(Int('x'))
9718    False
9719    """
9720    return isinstance(a, FPRef)
9721
9722
9723def is_fp_value(a):
9724    """Return `True` if `a` is a Z3 floating-point numeral value.
9725
9726    >>> b = FP('b', FPSort(8, 24))
9727    >>> is_fp_value(b)
9728    False
9729    >>> b = FPVal(1.0, FPSort(8, 24))
9730    >>> b
9731    1
9732    >>> is_fp_value(b)
9733    True
9734    """
9735    return is_fp(a) and _is_numeral(a.ctx, a.ast)
9736
9737
9738def FPSort(ebits, sbits, ctx=None):
9739    """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
9740
9741    >>> Single = FPSort(8, 24)
9742    >>> Double = FPSort(11, 53)
9743    >>> Single
9744    FPSort(8, 24)
9745    >>> x = Const('x', Single)
9746    >>> eq(x, FP('x', FPSort(8, 24)))
9747    True
9748    """
9749    ctx = _get_ctx(ctx)
9750    return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
9751
9752
9753def _to_float_str(val, exp=0):
9754    if isinstance(val, float):
9755        if math.isnan(val):
9756            res = "NaN"
9757        elif val == 0.0:
9758            sone = math.copysign(1.0, val)
9759            if sone < 0.0:
9760                return "-0.0"
9761            else:
9762                return "+0.0"
9763        elif val == float("+inf"):
9764            res = "+oo"
9765        elif val == float("-inf"):
9766            res = "-oo"
9767        else:
9768            v = val.as_integer_ratio()
9769            num = v[0]
9770            den = v[1]
9771            rvs = str(num) + "/" + str(den)
9772            res = rvs + "p" + _to_int_str(exp)
9773    elif isinstance(val, bool):
9774        if val:
9775            res = "1.0"
9776        else:
9777            res = "0.0"
9778    elif _is_int(val):
9779        res = str(val)
9780    elif isinstance(val, str):
9781        inx = val.find("*(2**")
9782        if inx == -1:
9783            res = val
9784        elif val[-1] == ")":
9785            res = val[0:inx]
9786            exp = str(int(val[inx + 5:-1]) + int(exp))
9787        else:
9788            _z3_assert(False, "String does not have floating-point numeral form.")
9789    elif z3_debug():
9790        _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
9791    if exp == 0:
9792        return res
9793    else:
9794        return res + "p" + exp
9795
9796
9797def fpNaN(s):
9798    """Create a Z3 floating-point NaN term.
9799
9800    >>> s = FPSort(8, 24)
9801    >>> set_fpa_pretty(True)
9802    >>> fpNaN(s)
9803    NaN
9804    >>> pb = get_fpa_pretty()
9805    >>> set_fpa_pretty(False)
9806    >>> fpNaN(s)
9807    fpNaN(FPSort(8, 24))
9808    >>> set_fpa_pretty(pb)
9809    """
9810    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9811    return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
9812
9813
9814def fpPlusInfinity(s):
9815    """Create a Z3 floating-point +oo term.
9816
9817    >>> s = FPSort(8, 24)
9818    >>> pb = get_fpa_pretty()
9819    >>> set_fpa_pretty(True)
9820    >>> fpPlusInfinity(s)
9821    +oo
9822    >>> set_fpa_pretty(False)
9823    >>> fpPlusInfinity(s)
9824    fpPlusInfinity(FPSort(8, 24))
9825    >>> set_fpa_pretty(pb)
9826    """
9827    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9828    return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
9829
9830
9831def fpMinusInfinity(s):
9832    """Create a Z3 floating-point -oo term."""
9833    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9834    return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
9835
9836
9837def fpInfinity(s, negative):
9838    """Create a Z3 floating-point +oo or -oo term."""
9839    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9840    _z3_assert(isinstance(negative, bool), "expected Boolean flag")
9841    return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
9842
9843
9844def fpPlusZero(s):
9845    """Create a Z3 floating-point +0.0 term."""
9846    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9847    return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
9848
9849
9850def fpMinusZero(s):
9851    """Create a Z3 floating-point -0.0 term."""
9852    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9853    return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
9854
9855
9856def fpZero(s, negative):
9857    """Create a Z3 floating-point +0.0 or -0.0 term."""
9858    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9859    _z3_assert(isinstance(negative, bool), "expected Boolean flag")
9860    return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
9861
9862
9863def FPVal(sig, exp=None, fps=None, ctx=None):
9864    """Return a floating-point value of value `val` and sort `fps`.
9865    If `ctx=None`, then the global context is used.
9866
9867    >>> v = FPVal(20.0, FPSort(8, 24))
9868    >>> v
9869    1.25*(2**4)
9870    >>> print("0x%.8x" % v.exponent_as_long(False))
9871    0x00000004
9872    >>> v = FPVal(2.25, FPSort(8, 24))
9873    >>> v
9874    1.125*(2**1)
9875    >>> v = FPVal(-2.25, FPSort(8, 24))
9876    >>> v
9877    -1.125*(2**1)
9878    >>> FPVal(-0.0, FPSort(8, 24))
9879    -0.0
9880    >>> FPVal(0.0, FPSort(8, 24))
9881    +0.0
9882    >>> FPVal(+0.0, FPSort(8, 24))
9883    +0.0
9884    """
9885    ctx = _get_ctx(ctx)
9886    if is_fp_sort(exp):
9887        fps = exp
9888        exp = None
9889    elif fps is None:
9890        fps = _dflt_fps(ctx)
9891    _z3_assert(is_fp_sort(fps), "sort mismatch")
9892    if exp is None:
9893        exp = 0
9894    val = _to_float_str(sig)
9895    if val == "NaN" or val == "nan":
9896        return fpNaN(fps)
9897    elif val == "-0.0":
9898        return fpMinusZero(fps)
9899    elif val == "0.0" or val == "+0.0":
9900        return fpPlusZero(fps)
9901    elif val == "+oo" or val == "+inf" or val == "+Inf":
9902        return fpPlusInfinity(fps)
9903    elif val == "-oo" or val == "-inf" or val == "-Inf":
9904        return fpMinusInfinity(fps)
9905    else:
9906        return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
9907
9908
9909def FP(name, fpsort, ctx=None):
9910    """Return a floating-point constant named `name`.
9911    `fpsort` is the floating-point sort.
9912    If `ctx=None`, then the global context is used.
9913
9914    >>> x  = FP('x', FPSort(8, 24))
9915    >>> is_fp(x)
9916    True
9917    >>> x.ebits()
9918    8
9919    >>> x.sort()
9920    FPSort(8, 24)
9921    >>> word = FPSort(8, 24)
9922    >>> x2 = FP('x', word)
9923    >>> eq(x, x2)
9924    True
9925    """
9926    if isinstance(fpsort, FPSortRef) and ctx is None:
9927        ctx = fpsort.ctx
9928    else:
9929        ctx = _get_ctx(ctx)
9930    return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
9931
9932
9933def FPs(names, fpsort, ctx=None):
9934    """Return an array of floating-point constants.
9935
9936    >>> x, y, z = FPs('x y z', FPSort(8, 24))
9937    >>> x.sort()
9938    FPSort(8, 24)
9939    >>> x.sbits()
9940    24
9941    >>> x.ebits()
9942    8
9943    >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
9944    fpMul(RNE(), fpAdd(RNE(), x, y), z)
9945    """
9946    ctx = _get_ctx(ctx)
9947    if isinstance(names, str):
9948        names = names.split(" ")
9949    return [FP(name, fpsort, ctx) for name in names]
9950
9951
9952def fpAbs(a, ctx=None):
9953    """Create a Z3 floating-point absolute value expression.
9954
9955    >>> s = FPSort(8, 24)
9956    >>> rm = RNE()
9957    >>> x = FPVal(1.0, s)
9958    >>> fpAbs(x)
9959    fpAbs(1)
9960    >>> y = FPVal(-20.0, s)
9961    >>> y
9962    -1.25*(2**4)
9963    >>> fpAbs(y)
9964    fpAbs(-1.25*(2**4))
9965    >>> fpAbs(-1.25*(2**4))
9966    fpAbs(-1.25*(2**4))
9967    >>> fpAbs(x).sort()
9968    FPSort(8, 24)
9969    """
9970    ctx = _get_ctx(ctx)
9971    [a] = _coerce_fp_expr_list([a], ctx)
9972    return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
9973
9974
9975def fpNeg(a, ctx=None):
9976    """Create a Z3 floating-point addition expression.
9977
9978    >>> s = FPSort(8, 24)
9979    >>> rm = RNE()
9980    >>> x = FP('x', s)
9981    >>> fpNeg(x)
9982    -x
9983    >>> fpNeg(x).sort()
9984    FPSort(8, 24)
9985    """
9986    ctx = _get_ctx(ctx)
9987    [a] = _coerce_fp_expr_list([a], ctx)
9988    return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
9989
9990
9991def _mk_fp_unary(f, rm, a, ctx):
9992    ctx = _get_ctx(ctx)
9993    [a] = _coerce_fp_expr_list([a], ctx)
9994    if z3_debug():
9995        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
9996        _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
9997    return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
9998
9999
10000def _mk_fp_unary_pred(f, a, ctx):
10001    ctx = _get_ctx(ctx)
10002    [a] = _coerce_fp_expr_list([a], ctx)
10003    if z3_debug():
10004        _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10005    return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10006
10007
10008def _mk_fp_bin(f, rm, a, b, ctx):
10009    ctx = _get_ctx(ctx)
10010    [a, b] = _coerce_fp_expr_list([a, b], ctx)
10011    if z3_debug():
10012        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10013        _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10014    return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10015
10016
10017def _mk_fp_bin_norm(f, a, b, ctx):
10018    ctx = _get_ctx(ctx)
10019    [a, b] = _coerce_fp_expr_list([a, b], ctx)
10020    if z3_debug():
10021        _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10022    return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10023
10024
10025def _mk_fp_bin_pred(f, a, b, ctx):
10026    ctx = _get_ctx(ctx)
10027    [a, b] = _coerce_fp_expr_list([a, b], ctx)
10028    if z3_debug():
10029        _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10030    return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10031
10032
10033def _mk_fp_tern(f, rm, a, b, c, ctx):
10034    ctx = _get_ctx(ctx)
10035    [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10036    if z3_debug():
10037        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10038        _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10039            c), "Second, third or fourth argument must be a Z3 floating-point expression")
10040    return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10041
10042
10043def fpAdd(rm, a, b, ctx=None):
10044    """Create a Z3 floating-point addition expression.
10045
10046    >>> s = FPSort(8, 24)
10047    >>> rm = RNE()
10048    >>> x = FP('x', s)
10049    >>> y = FP('y', s)
10050    >>> fpAdd(rm, x, y)
10051    fpAdd(RNE(), x, y)
10052    >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10053    x + y
10054    >>> fpAdd(rm, x, y).sort()
10055    FPSort(8, 24)
10056    """
10057    return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10058
10059
10060def fpSub(rm, a, b, ctx=None):
10061    """Create a Z3 floating-point subtraction expression.
10062
10063    >>> s = FPSort(8, 24)
10064    >>> rm = RNE()
10065    >>> x = FP('x', s)
10066    >>> y = FP('y', s)
10067    >>> fpSub(rm, x, y)
10068    fpSub(RNE(), x, y)
10069    >>> fpSub(rm, x, y).sort()
10070    FPSort(8, 24)
10071    """
10072    return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10073
10074
10075def fpMul(rm, a, b, ctx=None):
10076    """Create a Z3 floating-point multiplication expression.
10077
10078    >>> s = FPSort(8, 24)
10079    >>> rm = RNE()
10080    >>> x = FP('x', s)
10081    >>> y = FP('y', s)
10082    >>> fpMul(rm, x, y)
10083    fpMul(RNE(), x, y)
10084    >>> fpMul(rm, x, y).sort()
10085    FPSort(8, 24)
10086    """
10087    return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10088
10089
10090def fpDiv(rm, a, b, ctx=None):
10091    """Create a Z3 floating-point division expression.
10092
10093    >>> s = FPSort(8, 24)
10094    >>> rm = RNE()
10095    >>> x = FP('x', s)
10096    >>> y = FP('y', s)
10097    >>> fpDiv(rm, x, y)
10098    fpDiv(RNE(), x, y)
10099    >>> fpDiv(rm, x, y).sort()
10100    FPSort(8, 24)
10101    """
10102    return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10103
10104
10105def fpRem(a, b, ctx=None):
10106    """Create a Z3 floating-point remainder expression.
10107
10108    >>> s = FPSort(8, 24)
10109    >>> x = FP('x', s)
10110    >>> y = FP('y', s)
10111    >>> fpRem(x, y)
10112    fpRem(x, y)
10113    >>> fpRem(x, y).sort()
10114    FPSort(8, 24)
10115    """
10116    return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10117
10118
10119def fpMin(a, b, ctx=None):
10120    """Create a Z3 floating-point minimum expression.
10121
10122    >>> s = FPSort(8, 24)
10123    >>> rm = RNE()
10124    >>> x = FP('x', s)
10125    >>> y = FP('y', s)
10126    >>> fpMin(x, y)
10127    fpMin(x, y)
10128    >>> fpMin(x, y).sort()
10129    FPSort(8, 24)
10130    """
10131    return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10132
10133
10134def fpMax(a, b, ctx=None):
10135    """Create a Z3 floating-point maximum expression.
10136
10137    >>> s = FPSort(8, 24)
10138    >>> rm = RNE()
10139    >>> x = FP('x', s)
10140    >>> y = FP('y', s)
10141    >>> fpMax(x, y)
10142    fpMax(x, y)
10143    >>> fpMax(x, y).sort()
10144    FPSort(8, 24)
10145    """
10146    return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10147
10148
10149def fpFMA(rm, a, b, c, ctx=None):
10150    """Create a Z3 floating-point fused multiply-add expression.
10151    """
10152    return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10153
10154
10155def fpSqrt(rm, a, ctx=None):
10156    """Create a Z3 floating-point square root expression.
10157    """
10158    return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10159
10160
10161def fpRoundToIntegral(rm, a, ctx=None):
10162    """Create a Z3 floating-point roundToIntegral expression.
10163    """
10164    return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10165
10166
10167def fpIsNaN(a, ctx=None):
10168    """Create a Z3 floating-point isNaN expression.
10169
10170    >>> s = FPSort(8, 24)
10171    >>> x = FP('x', s)
10172    >>> y = FP('y', s)
10173    >>> fpIsNaN(x)
10174    fpIsNaN(x)
10175    """
10176    return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10177
10178
10179def fpIsInf(a, ctx=None):
10180    """Create a Z3 floating-point isInfinite expression.
10181
10182    >>> s = FPSort(8, 24)
10183    >>> x = FP('x', s)
10184    >>> fpIsInf(x)
10185    fpIsInf(x)
10186    """
10187    return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10188
10189
10190def fpIsZero(a, ctx=None):
10191    """Create a Z3 floating-point isZero expression.
10192    """
10193    return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10194
10195
10196def fpIsNormal(a, ctx=None):
10197    """Create a Z3 floating-point isNormal expression.
10198    """
10199    return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10200
10201
10202def fpIsSubnormal(a, ctx=None):
10203    """Create a Z3 floating-point isSubnormal expression.
10204    """
10205    return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10206
10207
10208def fpIsNegative(a, ctx=None):
10209    """Create a Z3 floating-point isNegative expression.
10210    """
10211    return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10212
10213
10214def fpIsPositive(a, ctx=None):
10215    """Create a Z3 floating-point isPositive expression.
10216    """
10217    return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10218
10219
10220def _check_fp_args(a, b):
10221    if z3_debug():
10222        _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10223
10224
10225def fpLT(a, b, ctx=None):
10226    """Create the Z3 floating-point expression `other < self`.
10227
10228    >>> x, y = FPs('x y', FPSort(8, 24))
10229    >>> fpLT(x, y)
10230    x < y
10231    >>> (x < y).sexpr()
10232    '(fp.lt x y)'
10233    """
10234    return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10235
10236
10237def fpLEQ(a, b, ctx=None):
10238    """Create the Z3 floating-point expression `other <= self`.
10239
10240    >>> x, y = FPs('x y', FPSort(8, 24))
10241    >>> fpLEQ(x, y)
10242    x <= y
10243    >>> (x <= y).sexpr()
10244    '(fp.leq x y)'
10245    """
10246    return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10247
10248
10249def fpGT(a, b, ctx=None):
10250    """Create the Z3 floating-point expression `other > self`.
10251
10252    >>> x, y = FPs('x y', FPSort(8, 24))
10253    >>> fpGT(x, y)
10254    x > y
10255    >>> (x > y).sexpr()
10256    '(fp.gt x y)'
10257    """
10258    return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10259
10260
10261def fpGEQ(a, b, ctx=None):
10262    """Create the Z3 floating-point expression `other >= self`.
10263
10264    >>> x, y = FPs('x y', FPSort(8, 24))
10265    >>> fpGEQ(x, y)
10266    x >= y
10267    >>> (x >= y).sexpr()
10268    '(fp.geq x y)'
10269    """
10270    return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10271
10272
10273def fpEQ(a, b, ctx=None):
10274    """Create the Z3 floating-point expression `fpEQ(other, self)`.
10275
10276    >>> x, y = FPs('x y', FPSort(8, 24))
10277    >>> fpEQ(x, y)
10278    fpEQ(x, y)
10279    >>> fpEQ(x, y).sexpr()
10280    '(fp.eq x y)'
10281    """
10282    return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10283
10284
10285def fpNEQ(a, b, ctx=None):
10286    """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10287
10288    >>> x, y = FPs('x y', FPSort(8, 24))
10289    >>> fpNEQ(x, y)
10290    Not(fpEQ(x, y))
10291    >>> (x != y).sexpr()
10292    '(distinct x y)'
10293    """
10294    return Not(fpEQ(a, b, ctx))
10295
10296
10297def fpFP(sgn, exp, sig, ctx=None):
10298    """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10299
10300    >>> s = FPSort(8, 24)
10301    >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10302    >>> print(x)
10303    fpFP(1, 127, 4194304)
10304    >>> xv = FPVal(-1.5, s)
10305    >>> print(xv)
10306    -1.5
10307    >>> slvr = Solver()
10308    >>> slvr.add(fpEQ(x, xv))
10309    >>> slvr.check()
10310    sat
10311    >>> xv = FPVal(+1.5, s)
10312    >>> print(xv)
10313    1.5
10314    >>> slvr = Solver()
10315    >>> slvr.add(fpEQ(x, xv))
10316    >>> slvr.check()
10317    unsat
10318    """
10319    _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10320    _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10321    ctx = _get_ctx(ctx)
10322    _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10323    return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10324
10325
10326def fpToFP(a1, a2=None, a3=None, ctx=None):
10327    """Create a Z3 floating-point conversion expression from other term sorts
10328    to floating-point.
10329
10330    From a bit-vector term in IEEE 754-2008 format:
10331    >>> x = FPVal(1.0, Float32())
10332    >>> x_bv = fpToIEEEBV(x)
10333    >>> simplify(fpToFP(x_bv, Float32()))
10334    1
10335
10336    From a floating-point term with different precision:
10337    >>> x = FPVal(1.0, Float32())
10338    >>> x_db = fpToFP(RNE(), x, Float64())
10339    >>> x_db.sort()
10340    FPSort(11, 53)
10341
10342    From a real term:
10343    >>> x_r = RealVal(1.5)
10344    >>> simplify(fpToFP(RNE(), x_r, Float32()))
10345    1.5
10346
10347    From a signed bit-vector term:
10348    >>> x_signed = BitVecVal(-5, BitVecSort(32))
10349    >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10350    -1.25*(2**2)
10351    """
10352    ctx = _get_ctx(ctx)
10353    if is_bv(a1) and is_fp_sort(a2):
10354        return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10355    elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10356        return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10357    elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10358        return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10359    elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10360        return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10361    else:
10362        raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10363
10364
10365def fpBVToFP(v, sort, ctx=None):
10366    """Create a Z3 floating-point conversion expression that represents the
10367    conversion from a bit-vector term to a floating-point term.
10368
10369    >>> x_bv = BitVecVal(0x3F800000, 32)
10370    >>> x_fp = fpBVToFP(x_bv, Float32())
10371    >>> x_fp
10372    fpToFP(1065353216)
10373    >>> simplify(x_fp)
10374    1
10375    """
10376    _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10377    _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10378    ctx = _get_ctx(ctx)
10379    return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10380
10381
10382def fpFPToFP(rm, v, sort, ctx=None):
10383    """Create a Z3 floating-point conversion expression that represents the
10384    conversion from a floating-point term to a floating-point term of different precision.
10385
10386    >>> x_sgl = FPVal(1.0, Float32())
10387    >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10388    >>> x_dbl
10389    fpToFP(RNE(), 1)
10390    >>> simplify(x_dbl)
10391    1
10392    >>> x_dbl.sort()
10393    FPSort(11, 53)
10394    """
10395    _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10396    _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10397    _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10398    ctx = _get_ctx(ctx)
10399    return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10400
10401
10402def fpRealToFP(rm, v, sort, ctx=None):
10403    """Create a Z3 floating-point conversion expression that represents the
10404    conversion from a real term to a floating-point term.
10405
10406    >>> x_r = RealVal(1.5)
10407    >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10408    >>> x_fp
10409    fpToFP(RNE(), 3/2)
10410    >>> simplify(x_fp)
10411    1.5
10412    """
10413    _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10414    _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10415    _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10416    ctx = _get_ctx(ctx)
10417    return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10418
10419
10420def fpSignedToFP(rm, v, sort, ctx=None):
10421    """Create a Z3 floating-point conversion expression that represents the
10422    conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10423
10424    >>> x_signed = BitVecVal(-5, BitVecSort(32))
10425    >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10426    >>> x_fp
10427    fpToFP(RNE(), 4294967291)
10428    >>> simplify(x_fp)
10429    -1.25*(2**2)
10430    """
10431    _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10432    _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10433    _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10434    ctx = _get_ctx(ctx)
10435    return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10436
10437
10438def fpUnsignedToFP(rm, v, sort, ctx=None):
10439    """Create a Z3 floating-point conversion expression that represents the
10440    conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10441
10442    >>> x_signed = BitVecVal(-5, BitVecSort(32))
10443    >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10444    >>> x_fp
10445    fpToFPUnsigned(RNE(), 4294967291)
10446    >>> simplify(x_fp)
10447    1*(2**32)
10448    """
10449    _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10450    _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10451    _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10452    ctx = _get_ctx(ctx)
10453    return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10454
10455
10456def fpToFPUnsigned(rm, x, s, ctx=None):
10457    """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10458    if z3_debug():
10459        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10460        _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10461        _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10462    ctx = _get_ctx(ctx)
10463    return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10464
10465
10466def fpToSBV(rm, x, s, ctx=None):
10467    """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10468
10469    >>> x = FP('x', FPSort(8, 24))
10470    >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10471    >>> print(is_fp(x))
10472    True
10473    >>> print(is_bv(y))
10474    True
10475    >>> print(is_fp(y))
10476    False
10477    >>> print(is_bv(x))
10478    False
10479    """
10480    if z3_debug():
10481        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10482        _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10483        _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10484    ctx = _get_ctx(ctx)
10485    return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10486
10487
10488def fpToUBV(rm, x, s, ctx=None):
10489    """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10490
10491    >>> x = FP('x', FPSort(8, 24))
10492    >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10493    >>> print(is_fp(x))
10494    True
10495    >>> print(is_bv(y))
10496    True
10497    >>> print(is_fp(y))
10498    False
10499    >>> print(is_bv(x))
10500    False
10501    """
10502    if z3_debug():
10503        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10504        _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10505        _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10506    ctx = _get_ctx(ctx)
10507    return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10508
10509
10510def fpToReal(x, ctx=None):
10511    """Create a Z3 floating-point conversion expression, from floating-point expression to real.
10512
10513    >>> x = FP('x', FPSort(8, 24))
10514    >>> y = fpToReal(x)
10515    >>> print(is_fp(x))
10516    True
10517    >>> print(is_real(y))
10518    True
10519    >>> print(is_fp(y))
10520    False
10521    >>> print(is_real(x))
10522    False
10523    """
10524    if z3_debug():
10525        _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10526    ctx = _get_ctx(ctx)
10527    return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
10528
10529
10530def fpToIEEEBV(x, ctx=None):
10531    """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
10532
10533    The size of the resulting bit-vector is automatically determined.
10534
10535    Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
10536    knows only one NaN and it will always produce the same bit-vector representation of
10537    that NaN.
10538
10539    >>> x = FP('x', FPSort(8, 24))
10540    >>> y = fpToIEEEBV(x)
10541    >>> print(is_fp(x))
10542    True
10543    >>> print(is_bv(y))
10544    True
10545    >>> print(is_fp(y))
10546    False
10547    >>> print(is_bv(x))
10548    False
10549    """
10550    if z3_debug():
10551        _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10552    ctx = _get_ctx(ctx)
10553    return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
10554
10555
10556#########################################
10557#
10558# Strings, Sequences and Regular expressions
10559#
10560#########################################
10561
10562class SeqSortRef(SortRef):
10563    """Sequence sort."""
10564
10565    def is_string(self):
10566        """Determine if sort is a string
10567        >>> s = StringSort()
10568        >>> s.is_string()
10569        True
10570        >>> s = SeqSort(IntSort())
10571        >>> s.is_string()
10572        False
10573        """
10574        return Z3_is_string_sort(self.ctx_ref(), self.ast)
10575
10576    def basis(self):
10577        return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10578
10579class CharSortRef(SortRef):
10580    """Character sort."""
10581
10582
10583
10584def StringSort(ctx=None):
10585    """Create a string sort
10586    >>> s = StringSort()
10587    >>> print(s)
10588    String
10589    """
10590    ctx = _get_ctx(ctx)
10591    return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
10592
10593def CharSort(ctx=None):
10594    """Create a character sort
10595    >>> ch = CharSort()
10596    >>> print(ch)
10597    Char
10598    """
10599    ctx = _get_ctx(ctx)
10600    return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
10601
10602
10603def SeqSort(s):
10604    """Create a sequence sort over elements provided in the argument
10605    >>> s = SeqSort(IntSort())
10606    >>> s == Unit(IntVal(1)).sort()
10607    True
10608    """
10609    return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
10610
10611
10612class SeqRef(ExprRef):
10613    """Sequence expression."""
10614
10615    def sort(self):
10616        return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
10617
10618    def __add__(self, other):
10619        return Concat(self, other)
10620
10621    def __radd__(self, other):
10622        return Concat(other, self)
10623
10624    def __getitem__(self, i):
10625        if _is_int(i):
10626            i = IntVal(i, self.ctx)
10627        return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
10628
10629    def at(self, i):
10630        if _is_int(i):
10631            i = IntVal(i, self.ctx)
10632        return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
10633
10634    def is_string(self):
10635        return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
10636
10637    def is_string_value(self):
10638        return Z3_is_string(self.ctx_ref(), self.as_ast())
10639
10640    def as_string(self):
10641        """Return a string representation of sequence expression."""
10642        if self.is_string_value():
10643            string_length = ctypes.c_uint()
10644            chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
10645            return string_at(chars, size=string_length.value).decode("latin-1")
10646        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10647
10648    def __le__(self, other):
10649        return SeqRef(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10650
10651    def __lt__(self, other):
10652        return SeqRef(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10653
10654    def __ge__(self, other):
10655        return SeqRef(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
10656
10657    def __gt__(self, other):
10658        return SeqRef(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
10659
10660
10661def _coerce_seq(s, ctx=None):
10662    if isinstance(s, str):
10663        ctx = _get_ctx(ctx)
10664        s = StringVal(s, ctx)
10665    if not is_expr(s):
10666        raise Z3Exception("Non-expression passed as a sequence")
10667    if not is_seq(s):
10668        raise Z3Exception("Non-sequence passed as a sequence")
10669    return s
10670
10671
10672def _get_ctx2(a, b, ctx=None):
10673    if is_expr(a):
10674        return a.ctx
10675    if is_expr(b):
10676        return b.ctx
10677    if ctx is None:
10678        ctx = main_ctx()
10679    return ctx
10680
10681
10682def is_seq(a):
10683    """Return `True` if `a` is a Z3 sequence expression.
10684    >>> print (is_seq(Unit(IntVal(0))))
10685    True
10686    >>> print (is_seq(StringVal("abc")))
10687    True
10688    """
10689    return isinstance(a, SeqRef)
10690
10691
10692def is_string(a):
10693    """Return `True` if `a` is a Z3 string expression.
10694    >>> print (is_string(StringVal("ab")))
10695    True
10696    """
10697    return isinstance(a, SeqRef) and a.is_string()
10698
10699
10700def is_string_value(a):
10701    """return 'True' if 'a' is a Z3 string constant expression.
10702    >>> print (is_string_value(StringVal("a")))
10703    True
10704    >>> print (is_string_value(StringVal("a") + StringVal("b")))
10705    False
10706    """
10707    return isinstance(a, SeqRef) and a.is_string_value()
10708
10709def StringVal(s, ctx=None):
10710    """create a string expression"""
10711    s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
10712    ctx = _get_ctx(ctx)
10713    return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
10714
10715
10716def String(name, ctx=None):
10717    """Return a string constant named `name`. If `ctx=None`, then the global context is used.
10718
10719    >>> x = String('x')
10720    """
10721    ctx = _get_ctx(ctx)
10722    return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
10723
10724
10725def Strings(names, ctx=None):
10726    """Return a tuple of String constants. """
10727    ctx = _get_ctx(ctx)
10728    if isinstance(names, str):
10729        names = names.split(" ")
10730    return [String(name, ctx) for name in names]
10731
10732
10733def SubString(s, offset, length):
10734    """Extract substring or subsequence starting at offset"""
10735    return Extract(s, offset, length)
10736
10737
10738def SubSeq(s, offset, length):
10739    """Extract substring or subsequence starting at offset"""
10740    return Extract(s, offset, length)
10741
10742
10743def Empty(s):
10744    """Create the empty sequence of the given sort
10745    >>> e = Empty(StringSort())
10746    >>> e2 = StringVal("")
10747    >>> print(e.eq(e2))
10748    True
10749    >>> e3 = Empty(SeqSort(IntSort()))
10750    >>> print(e3)
10751    Empty(Seq(Int))
10752    >>> e4 = Empty(ReSort(SeqSort(IntSort())))
10753    >>> print(e4)
10754    Empty(ReSort(Seq(Int)))
10755    """
10756    if isinstance(s, SeqSortRef):
10757        return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
10758    if isinstance(s, ReSortRef):
10759        return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
10760    raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
10761
10762
10763def Full(s):
10764    """Create the regular expression that accepts the universal language
10765    >>> e = Full(ReSort(SeqSort(IntSort())))
10766    >>> print(e)
10767    Full(ReSort(Seq(Int)))
10768    >>> e1 = Full(ReSort(StringSort()))
10769    >>> print(e1)
10770    Full(ReSort(String))
10771    """
10772    if isinstance(s, ReSortRef):
10773        return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
10774    raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
10775
10776
10777def Unit(a):
10778    """Create a singleton sequence"""
10779    return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
10780
10781
10782def PrefixOf(a, b):
10783    """Check if 'a' is a prefix of 'b'
10784    >>> s1 = PrefixOf("ab", "abc")
10785    >>> simplify(s1)
10786    True
10787    >>> s2 = PrefixOf("bc", "abc")
10788    >>> simplify(s2)
10789    False
10790    """
10791    ctx = _get_ctx2(a, b)
10792    a = _coerce_seq(a, ctx)
10793    b = _coerce_seq(b, ctx)
10794    return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
10795
10796
10797def SuffixOf(a, b):
10798    """Check if 'a' is a suffix of 'b'
10799    >>> s1 = SuffixOf("ab", "abc")
10800    >>> simplify(s1)
10801    False
10802    >>> s2 = SuffixOf("bc", "abc")
10803    >>> simplify(s2)
10804    True
10805    """
10806    ctx = _get_ctx2(a, b)
10807    a = _coerce_seq(a, ctx)
10808    b = _coerce_seq(b, ctx)
10809    return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
10810
10811
10812def Contains(a, b):
10813    """Check if 'a' contains 'b'
10814    >>> s1 = Contains("abc", "ab")
10815    >>> simplify(s1)
10816    True
10817    >>> s2 = Contains("abc", "bc")
10818    >>> simplify(s2)
10819    True
10820    >>> x, y, z = Strings('x y z')
10821    >>> s3 = Contains(Concat(x,y,z), y)
10822    >>> simplify(s3)
10823    True
10824    """
10825    ctx = _get_ctx2(a, b)
10826    a = _coerce_seq(a, ctx)
10827    b = _coerce_seq(b, ctx)
10828    return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
10829
10830
10831def Replace(s, src, dst):
10832    """Replace the first occurrence of 'src' by 'dst' in 's'
10833    >>> r = Replace("aaa", "a", "b")
10834    >>> simplify(r)
10835    "baa"
10836    """
10837    ctx = _get_ctx2(dst, s)
10838    if ctx is None and is_expr(src):
10839        ctx = src.ctx
10840    src = _coerce_seq(src, ctx)
10841    dst = _coerce_seq(dst, ctx)
10842    s = _coerce_seq(s, ctx)
10843    return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
10844
10845
10846def IndexOf(s, substr, offset=None):
10847    """Retrieve the index of substring within a string starting at a specified offset.
10848    >>> simplify(IndexOf("abcabc", "bc", 0))
10849    1
10850    >>> simplify(IndexOf("abcabc", "bc", 2))
10851    4
10852    """
10853    if offset is None:
10854        offset = IntVal(0)
10855    ctx = None
10856    if is_expr(offset):
10857        ctx = offset.ctx
10858    ctx = _get_ctx2(s, substr, ctx)
10859    s = _coerce_seq(s, ctx)
10860    substr = _coerce_seq(substr, ctx)
10861    if _is_int(offset):
10862        offset = IntVal(offset, ctx)
10863    return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
10864
10865
10866def LastIndexOf(s, substr):
10867    """Retrieve the last index of substring within a string"""
10868    ctx = None
10869    ctx = _get_ctx2(s, substr, ctx)
10870    s = _coerce_seq(s, ctx)
10871    substr = _coerce_seq(substr, ctx)
10872    return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
10873
10874
10875def Length(s):
10876    """Obtain the length of a sequence 's'
10877    >>> l = Length(StringVal("abc"))
10878    >>> simplify(l)
10879    3
10880    """
10881    s = _coerce_seq(s)
10882    return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
10883
10884
10885def StrToInt(s):
10886    """Convert string expression to integer
10887    >>> a = StrToInt("1")
10888    >>> simplify(1 == a)
10889    True
10890    >>> b = StrToInt("2")
10891    >>> simplify(1 == b)
10892    False
10893    >>> c = StrToInt(IntToStr(2))
10894    >>> simplify(1 == c)
10895    False
10896    """
10897    s = _coerce_seq(s)
10898    return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
10899
10900
10901def IntToStr(s):
10902    """Convert integer expression to string"""
10903    if not is_expr(s):
10904        s = _py2expr(s)
10905    return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
10906
10907
10908def Re(s, ctx=None):
10909    """The regular expression that accepts sequence 's'
10910    >>> s1 = Re("ab")
10911    >>> s2 = Re(StringVal("ab"))
10912    >>> s3 = Re(Unit(BoolVal(True)))
10913    """
10914    s = _coerce_seq(s, ctx)
10915    return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
10916
10917
10918# Regular expressions
10919
10920class ReSortRef(SortRef):
10921    """Regular expression sort."""
10922
10923    def basis(self):
10924        return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10925
10926
10927def ReSort(s):
10928    if is_ast(s):
10929        return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
10930    if s is None or isinstance(s, Context):
10931        ctx = _get_ctx(s)
10932        return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
10933    raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
10934
10935
10936class ReRef(ExprRef):
10937    """Regular expressions."""
10938
10939    def __add__(self, other):
10940        return Union(self, other)
10941
10942
10943def is_re(s):
10944    return isinstance(s, ReRef)
10945
10946
10947def InRe(s, re):
10948    """Create regular expression membership test
10949    >>> re = Union(Re("a"),Re("b"))
10950    >>> print (simplify(InRe("a", re)))
10951    True
10952    >>> print (simplify(InRe("b", re)))
10953    True
10954    >>> print (simplify(InRe("c", re)))
10955    False
10956    """
10957    s = _coerce_seq(s, re.ctx)
10958    return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
10959
10960
10961def Union(*args):
10962    """Create union of regular expressions.
10963    >>> re = Union(Re("a"), Re("b"), Re("c"))
10964    >>> print (simplify(InRe("d", re)))
10965    False
10966    """
10967    args = _get_args(args)
10968    sz = len(args)
10969    if z3_debug():
10970        _z3_assert(sz > 0, "At least one argument expected.")
10971        _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
10972    if sz == 1:
10973        return args[0]
10974    ctx = args[0].ctx
10975    v = (Ast * sz)()
10976    for i in range(sz):
10977        v[i] = args[i].as_ast()
10978    return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
10979
10980
10981def Intersect(*args):
10982    """Create intersection of regular expressions.
10983    >>> re = Intersect(Re("a"), Re("b"), Re("c"))
10984    """
10985    args = _get_args(args)
10986    sz = len(args)
10987    if z3_debug():
10988        _z3_assert(sz > 0, "At least one argument expected.")
10989        _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
10990    if sz == 1:
10991        return args[0]
10992    ctx = args[0].ctx
10993    v = (Ast * sz)()
10994    for i in range(sz):
10995        v[i] = args[i].as_ast()
10996    return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
10997
10998
10999def Plus(re):
11000    """Create the regular expression accepting one or more repetitions of argument.
11001    >>> re = Plus(Re("a"))
11002    >>> print(simplify(InRe("aa", re)))
11003    True
11004    >>> print(simplify(InRe("ab", re)))
11005    False
11006    >>> print(simplify(InRe("", re)))
11007    False
11008    """
11009    return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11010
11011
11012def Option(re):
11013    """Create the regular expression that optionally accepts the argument.
11014    >>> re = Option(Re("a"))
11015    >>> print(simplify(InRe("a", re)))
11016    True
11017    >>> print(simplify(InRe("", re)))
11018    True
11019    >>> print(simplify(InRe("aa", re)))
11020    False
11021    """
11022    return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11023
11024
11025def Complement(re):
11026    """Create the complement regular expression."""
11027    return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11028
11029
11030def Star(re):
11031    """Create the regular expression accepting zero or more repetitions of argument.
11032    >>> re = Star(Re("a"))
11033    >>> print(simplify(InRe("aa", re)))
11034    True
11035    >>> print(simplify(InRe("ab", re)))
11036    False
11037    >>> print(simplify(InRe("", re)))
11038    True
11039    """
11040    return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11041
11042
11043def Loop(re, lo, hi=0):
11044    """Create the regular expression accepting between a lower and upper bound repetitions
11045    >>> re = Loop(Re("a"), 1, 3)
11046    >>> print(simplify(InRe("aa", re)))
11047    True
11048    >>> print(simplify(InRe("aaaa", re)))
11049    False
11050    >>> print(simplify(InRe("", re)))
11051    False
11052    """
11053    return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11054
11055
11056def Range(lo, hi, ctx=None):
11057    """Create the range regular expression over two sequences of length 1
11058    >>> range = Range("a","z")
11059    >>> print(simplify(InRe("b", range)))
11060    True
11061    >>> print(simplify(InRe("bb", range)))
11062    False
11063    """
11064    lo = _coerce_seq(lo, ctx)
11065    hi = _coerce_seq(hi, ctx)
11066    return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11067
11068def AllChar(regex_sort, ctx=None):
11069    """Create a regular expression that accepts all single character strings
11070    """
11071    return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11072
11073# Special Relations
11074
11075
11076def PartialOrder(a, index):
11077    return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11078
11079
11080def LinearOrder(a, index):
11081    return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11082
11083
11084def TreeOrder(a, index):
11085    return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11086
11087
11088def PiecewiseLinearOrder(a, index):
11089    return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11090
11091
11092def TransitiveClosure(f):
11093    """Given a binary relation R, such that the two arguments have the same sort
11094    create the transitive closure relation R+.
11095    The transitive closure R+ is a new relation.
11096    """
11097    return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11098
11099
11100class PropClosures:
11101    def __init__(self):
11102        self.bases = {}
11103        self.lock = None
11104
11105    def set_threaded(self):
11106        if self.lock is None:
11107            import threading
11108            self.lock = threading.Lock()
11109
11110    def get(self, ctx):
11111        if self.lock:
11112            with self.lock:
11113                r = self.bases[ctx]
11114        else:
11115            r = self.bases[ctx]
11116        return r
11117
11118    def set(self, ctx, r):
11119        if self.lock:
11120            with self.lock:
11121                self.bases[ctx] = r
11122        else:
11123            self.bases[ctx] = r
11124
11125    def insert(self, r):
11126        if self.lock:
11127            with self.lock:
11128                id = len(self.bases) + 3
11129                self.bases[id] = r
11130        else:
11131            id = len(self.bases) + 3
11132            self.bases[id] = r
11133        return id
11134
11135
11136_prop_closures = None
11137
11138
11139def ensure_prop_closures():
11140    global _prop_closures
11141    if _prop_closures is None:
11142        _prop_closures = PropClosures()
11143
11144
11145def user_prop_push(ctx):
11146    _prop_closures.get(ctx).push()
11147
11148
11149def user_prop_pop(ctx, num_scopes):
11150    _prop_closures.get(ctx).pop(num_scopes)
11151
11152
11153def user_prop_fresh(id, ctx):
11154    _prop_closures.set_threaded()
11155    prop = _prop_closures.get(id)
11156    new_prop = prop.fresh()
11157    _prop_closures.set(new_prop.id, new_prop)
11158    return ctypes.c_void_p(new_prop.id)
11159
11160
11161def user_prop_fixed(ctx, cb, id, value):
11162    prop = _prop_closures.get(ctx)
11163    prop.cb = cb
11164    prop.fixed(id, _to_expr_ref(ctypes.c_void_p(value), prop.ctx()))
11165    prop.cb = None
11166
11167
11168def user_prop_final(ctx, cb):
11169    prop = _prop_closures.get(ctx)
11170    prop.cb = cb
11171    prop.final()
11172    prop.cb = None
11173
11174
11175def user_prop_eq(ctx, cb, x, y):
11176    prop = _prop_closures.get(ctx)
11177    prop.cb = cb
11178    prop.eq(x, y)
11179    prop.cb = None
11180
11181
11182def user_prop_diseq(ctx, cb, x, y):
11183    prop = _prop_closures.get(ctx)
11184    prop.cb = cb
11185    prop.diseq(x, y)
11186    prop.cb = None
11187
11188
11189_user_prop_push = push_eh_type(user_prop_push)
11190_user_prop_pop = pop_eh_type(user_prop_pop)
11191_user_prop_fresh = fresh_eh_type(user_prop_fresh)
11192_user_prop_fixed = fixed_eh_type(user_prop_fixed)
11193_user_prop_final = final_eh_type(user_prop_final)
11194_user_prop_eq = eq_eh_type(user_prop_eq)
11195_user_prop_diseq = eq_eh_type(user_prop_diseq)
11196
11197
11198class UserPropagateBase:
11199
11200    #
11201    # Either solver is set or ctx is set.
11202    # Propagators that are created throuh callbacks
11203    # to "fresh" inherit the context of that is supplied
11204    # as argument to the callback.
11205    # This context should not be deleted. It is owned by the solver.
11206    #
11207    def __init__(self, s, ctx=None):
11208        assert s is None or ctx is None
11209        ensure_prop_closures()
11210        self.solver = s
11211        self._ctx = None
11212        self.cb = None
11213        self.id = _prop_closures.insert(self)
11214        self.fixed = None
11215        self.final = None
11216        self.eq = None
11217        self.diseq = None
11218        if ctx:
11219            # TBD fresh is broken: ctx is not of the right type when we reach here.
11220            self._ctx = Context()
11221            #Z3_del_context(self._ctx.ctx)
11222            #self._ctx.ctx = ctx
11223            #self._ctx.eh = Z3_set_error_handler(ctx, z3_error_handler)
11224            #Z3_set_ast_print_mode(ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
11225        if s:
11226            Z3_solver_propagate_init(self.ctx_ref(),
11227                                     s.solver,
11228                                     ctypes.c_void_p(self.id),
11229                                     _user_prop_push,
11230                                     _user_prop_pop,
11231                                     _user_prop_fresh)
11232
11233    def __del__(self):
11234        if self._ctx:
11235            self._ctx.ctx = None
11236
11237    def ctx(self):
11238        if self._ctx:
11239            return self._ctx
11240        else:
11241            return self.solver.ctx
11242
11243    def ctx_ref(self):
11244        return self.ctx().ref()
11245
11246    def add_fixed(self, fixed):
11247        assert not self.fixed
11248        assert not self._ctx
11249        Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11250        self.fixed = fixed
11251
11252    def add_final(self, final):
11253        assert not self.final
11254        assert not self._ctx
11255        Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
11256        self.final = final
11257
11258    def add_eq(self, eq):
11259        assert not self.eq
11260        assert not self._ctx
11261        Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
11262        self.eq = eq
11263
11264    def add_diseq(self, diseq):
11265        assert not self.diseq
11266        assert not self._ctx
11267        Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
11268        self.diseq = diseq
11269
11270    def push(self):
11271        raise Z3Exception("push needs to be overwritten")
11272
11273    def pop(self, num_scopes):
11274        raise Z3Exception("pop needs to be overwritten")
11275
11276    def fresh(self):
11277        raise Z3Exception("fresh needs to be overwritten")
11278
11279    def add(self, e):
11280        assert self.solver
11281        assert not self._ctx
11282        return Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
11283
11284    #
11285    # Propagation can only be invoked as during a fixed or final callback.
11286    #
11287    def propagate(self, e, ids, eqs=[]):
11288        num_fixed = len(ids)
11289        _ids = (ctypes.c_uint * num_fixed)()
11290        for i in range(num_fixed):
11291            _ids[i] = ids[i]
11292        num_eqs = len(eqs)
11293        _lhs = (ctypes.c_uint * num_eqs)()
11294        _rhs = (ctypes.c_uint * num_eqs)()
11295        for i in range(num_eqs):
11296            _lhs[i] = eqs[i][0]
11297            _rhs[i] = eqs[i][1]
11298        Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
11299            self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
11300
11301    def conflict(self, ids):
11302        self.propagate(BoolVal(False, self.ctx()), ids, eqs=[])
11303