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. Z3 is used in many applications such as: software/hardware verification and testing, constraint solving, analysis of hybrid systems, security, biology (in silico analysis), and geometrical problems.
10
11Several online tutorials for Z3Py are available at:
12http://rise4fun.com/Z3Py/tutorial/guide
13
14Please send feedback, comments and/or corrections on the Issue tracker for https://github.com/Z3prover/z3.git. Your comments are very valuable.
15
16Small example:
17
18>>> x = Int('x')
19>>> y = Int('y')
20>>> s = Solver()
21>>> s.add(x > 0)
22>>> s.add(x < 2)
23>>> s.add(y == x + 1)
24>>> s.check()
25sat
26>>> m = s.model()
27>>> m[x]
281
29>>> m[y]
302
31
32Z3 exceptions:
33
34>>> try:
35...   x = BitVec('x', 32)
36...   y = Bool('y')
37...   # the expression x + y is type incorrect
38...   n = x + y
39... except Z3Exception as ex:
40...   print("failed: %s" % ex)
41failed: sort mismatch
42"""
43from . import z3core
44from .z3core import *
45from .z3types import *
46from .z3consts import *
47from .z3printer import *
48from fractions import Fraction
49import sys
50import io
51import math
52import copy
53
54Z3_DEBUG = __debug__
55
56def z3_debug():
57    global Z3_DEBUG
58    return Z3_DEBUG
59
60if sys.version < '3':
61    def _is_int(v):
62        return isinstance(v, (int, long))
63else:
64    def _is_int(v):
65        return isinstance(v, int)
66
67def enable_trace(msg):
68    Z3_enable_trace(msg)
69
70def disable_trace(msg):
71    Z3_disable_trace(msg)
72
73def get_version_string():
74  major = ctypes.c_uint(0)
75  minor = ctypes.c_uint(0)
76  build = ctypes.c_uint(0)
77  rev = ctypes.c_uint(0)
78  Z3_get_version(major, minor, build, rev)
79  return "%s.%s.%s" % (major.value, minor.value, build.value)
80
81def get_version():
82  major = ctypes.c_uint(0)
83  minor = ctypes.c_uint(0)
84  build = ctypes.c_uint(0)
85  rev = ctypes.c_uint(0)
86  Z3_get_version(major, minor, build, rev)
87  return (major.value, minor.value, build.value, rev.value)
88
89def get_full_version():
90  return Z3_get_full_version()
91
92# We use _z3_assert instead of the assert command because we want to
93# produce nice error messages in Z3Py at rise4fun.com
94def _z3_assert(cond, msg):
95    if not cond:
96        raise Z3Exception(msg)
97
98def _z3_check_cint_overflow(n, name):
99    _z3_assert(ctypes.c_int(n).value == n, name + " is too large")
100
101def open_log(fname):
102    """Log interaction to a file. This function must be invoked immediately after init(). """
103    Z3_open_log(fname)
104
105def append_log(s):
106    """Append user-defined string to interaction log. """
107    Z3_append_log(s)
108
109def to_symbol(s, ctx=None):
110    """Convert an integer or string into a Z3 symbol."""
111    if _is_int(s):
112        return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
113    else:
114        return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
115
116def _symbol2py(ctx, s):
117    """Convert a Z3 symbol back into a Python object. """
118    if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
119        return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
120    else:
121        return Z3_get_symbol_string(ctx.ref(), s)
122
123# Hack for having nary functions that can receive one argument that is the
124# list of arguments.
125# Use this when function takes a single list of arguments
126def _get_args(args):
127     try:
128       if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
129            return args[0]
130       elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)):
131            return [arg for arg in args[0]]
132       else:
133            return args
134     except:  # len is not necessarily defined when args is not a sequence (use reflection?)
135        return args
136
137# Use this when function takes multiple arguments
138def _get_args_ast_list(args):
139    try:
140        if isinstance(args, set) or isinstance(args, AstVector) or isinstance(args, tuple):
141            return [arg for arg in args]
142        else:
143            return args
144    except:
145        return args
146
147def _to_param_value(val):
148    if isinstance(val, bool):
149        if val == True:
150            return "true"
151        else:
152            return "false"
153    else:
154        return str(val)
155
156def z3_error_handler(c, e):
157    # Do nothing error handler, just avoid exit(0)
158    # The wrappers in z3core.py will raise a Z3Exception if an error is detected
159    return
160
161class Context:
162    """A Context manages all other Z3 objects, global configuration options, etc.
163
164    Z3Py uses a default global context. For most applications this is sufficient.
165    An application may use multiple Z3 contexts. Objects created in one context
166    cannot be used in another one. However, several objects may be "translated" from
167    one context to another. It is not safe to access Z3 objects from multiple threads.
168    The only exception is the method `interrupt()` that can be used to interrupt() a long
169    computation.
170    The initialization method receives global configuration options for the new context.
171    """
172    def __init__(self, *args, **kws):
173        if z3_debug():
174            _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
175        conf = Z3_mk_config()
176        for key in kws:
177            value = kws[key]
178            Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
179        prev = None
180        for a in args:
181            if prev is None:
182                prev = a
183            else:
184                Z3_set_param_value(conf, str(prev), _to_param_value(a))
185                prev = None
186        self.ctx = Z3_mk_context_rc(conf)
187        self.eh = Z3_set_error_handler(self.ctx, z3_error_handler)
188        Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
189        Z3_del_config(conf)
190
191    def __del__(self):
192        Z3_del_context(self.ctx)
193        self.ctx = None
194        self.eh = None
195
196    def ref(self):
197        """Return a reference to the actual C pointer to the Z3 context."""
198        return self.ctx
199
200    def interrupt(self):
201        """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
202
203        This method can be invoked from a thread different from the one executing the
204        interruptible procedure.
205        """
206        Z3_interrupt(self.ref())
207
208
209# Global Z3 context
210_main_ctx = None
211def main_ctx():
212    """Return a reference to the global Z3 context.
213
214    >>> x = Real('x')
215    >>> x.ctx == main_ctx()
216    True
217    >>> c = Context()
218    >>> c == main_ctx()
219    False
220    >>> x2 = Real('x', c)
221    >>> x2.ctx == c
222    True
223    >>> eq(x, x2)
224    False
225    """
226    global _main_ctx
227    if _main_ctx is None:
228        _main_ctx = Context()
229    return _main_ctx
230
231def _get_ctx(ctx):
232    if ctx is None:
233        return main_ctx()
234    else:
235        return ctx
236
237def get_ctx(ctx):
238    return _get_ctx(ctx)
239
240def set_param(*args, **kws):
241    """Set Z3 global (or module) parameters.
242
243    >>> set_param(precision=10)
244    """
245    if z3_debug():
246        _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
247    new_kws = {}
248    for k in kws:
249        v = kws[k]
250        if not set_pp_option(k, v):
251            new_kws[k] = v
252    for key in new_kws:
253        value = new_kws[key]
254        Z3_global_param_set(str(key).upper(), _to_param_value(value))
255    prev = None
256    for a in args:
257        if prev is None:
258            prev = a
259        else:
260            Z3_global_param_set(str(prev), _to_param_value(a))
261            prev = None
262
263def reset_params():
264    """Reset all global (or module) parameters.
265    """
266    Z3_global_param_reset_all()
267
268def set_option(*args, **kws):
269    """Alias for 'set_param' for backward compatibility.
270    """
271    return set_param(*args, **kws)
272
273def get_param(name):
274    """Return the value of a Z3 global (or module) parameter
275
276    >>> get_param('nlsat.reorder')
277    'true'
278    """
279    ptr = (ctypes.c_char_p * 1)()
280    if Z3_global_param_get(str(name), ptr):
281        r = z3core._to_pystr(ptr[0])
282        return r
283    raise Z3Exception("failed to retrieve value for '%s'" % name)
284
285#########################################
286#
287# ASTs base class
288#
289#########################################
290
291# Mark objects that use pretty printer
292class Z3PPObject:
293    """Superclass for all Z3 objects that have support for pretty printing."""
294    def use_pp(self):
295        return True
296
297    def _repr_html_(self):
298        in_html = in_html_mode()
299        set_html_mode(True)
300        res = repr(self)
301        set_html_mode(in_html)
302        return res
303
304
305class AstRef(Z3PPObject):
306    """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
307    def __init__(self, ast, ctx=None):
308        self.ast  = ast
309        self.ctx  = _get_ctx(ctx)
310        Z3_inc_ref(self.ctx.ref(), self.as_ast())
311
312    def __del__(self):
313        if self.ctx.ref() is not None and self.ast is not None:
314           Z3_dec_ref(self.ctx.ref(), self.as_ast())
315           self.ast = None
316
317    def __deepcopy__(self, memo={}):
318        return _to_ast_ref(self.ast, self.ctx)
319
320    def __str__(self):
321        return obj_to_string(self)
322
323    def __repr__(self):
324        return obj_to_string(self)
325
326    def __eq__(self, other):
327        return self.eq(other)
328
329    def __hash__(self):
330        return self.hash()
331
332    def __nonzero__(self):
333        return self.__bool__()
334
335    def __bool__(self):
336        if is_true(self):
337            return True
338        elif is_false(self):
339            return False
340        elif is_eq(self) and self.num_args() == 2:
341           return self.arg(0).eq(self.arg(1))
342        else:
343            raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
344
345    def sexpr(self):
346        """Return a string representing the AST node in s-expression notation.
347
348        >>> x = Int('x')
349        >>> ((x + 1)*x).sexpr()
350        '(* (+ x 1) x)'
351        """
352        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
353
354    def as_ast(self):
355        """Return a pointer to the corresponding C Z3_ast object."""
356        return self.ast
357
358    def get_id(self):
359        """Return unique identifier for object. It can be used for hash-tables and maps."""
360        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
361
362    def ctx_ref(self):
363        """Return a reference to the C context where this AST node is stored."""
364        return self.ctx.ref()
365
366    def eq(self, other):
367        """Return `True` if `self` and `other` are structurally identical.
368
369        >>> x = Int('x')
370        >>> n1 = x + 1
371        >>> n2 = 1 + x
372        >>> n1.eq(n2)
373        False
374        >>> n1 = simplify(n1)
375        >>> n2 = simplify(n2)
376        >>> n1.eq(n2)
377        True
378        """
379        if z3_debug():
380            _z3_assert(is_ast(other), "Z3 AST expected")
381        return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
382
383    def translate(self, target):
384        """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
385
386        >>> c1 = Context()
387        >>> c2 = Context()
388        >>> x  = Int('x', c1)
389        >>> y  = Int('y', c2)
390        >>> # Nodes in different contexts can't be mixed.
391        >>> # However, we can translate nodes from one context to another.
392        >>> x.translate(c2) + y
393        x + y
394        """
395        if z3_debug():
396            _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
397        return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
398
399    def __copy__(self):
400        return self.translate(self.ctx)
401
402    def hash(self):
403        """Return a hashcode for the `self`.
404
405        >>> n1 = simplify(Int('x') + 1)
406        >>> n2 = simplify(2 + Int('x') - 1)
407        >>> n1.hash() == n2.hash()
408        True
409        """
410        return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
411
412def is_ast(a):
413    """Return `True` if `a` is an AST node.
414
415    >>> is_ast(10)
416    False
417    >>> is_ast(IntVal(10))
418    True
419    >>> is_ast(Int('x'))
420    True
421    >>> is_ast(BoolSort())
422    True
423    >>> is_ast(Function('f', IntSort(), IntSort()))
424    True
425    >>> is_ast("x")
426    False
427    >>> is_ast(Solver())
428    False
429    """
430    return isinstance(a, AstRef)
431
432def eq(a, b):
433    """Return `True` if `a` and `b` are structurally identical AST nodes.
434
435    >>> x = Int('x')
436    >>> y = Int('y')
437    >>> eq(x, y)
438    False
439    >>> eq(x + 1, x + 1)
440    True
441    >>> eq(x + 1, 1 + x)
442    False
443    >>> eq(simplify(x + 1), simplify(1 + x))
444    True
445    """
446    if z3_debug():
447        _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
448    return a.eq(b)
449
450def _ast_kind(ctx, a):
451    if is_ast(a):
452        a = a.as_ast()
453    return Z3_get_ast_kind(ctx.ref(), a)
454
455def _ctx_from_ast_arg_list(args, default_ctx=None):
456    ctx = None
457    for a in args:
458        if is_ast(a) or is_probe(a):
459            if ctx is None:
460                ctx = a.ctx
461            else:
462                if z3_debug():
463                    _z3_assert(ctx == a.ctx, "Context mismatch")
464    if ctx is None:
465        ctx = default_ctx
466    return ctx
467
468def _ctx_from_ast_args(*args):
469    return _ctx_from_ast_arg_list(args)
470
471def _to_func_decl_array(args):
472    sz = len(args)
473    _args = (FuncDecl * sz)()
474    for i in range(sz):
475        _args[i] = args[i].as_func_decl()
476    return _args, sz
477
478def _to_ast_array(args):
479    sz = len(args)
480    _args = (Ast * sz)()
481    for i in range(sz):
482        _args[i] = args[i].as_ast()
483    return _args, sz
484
485def _to_ref_array(ref, args):
486    sz = len(args)
487    _args = (ref * sz)()
488    for i in range(sz):
489        _args[i] = args[i].as_ast()
490    return _args, sz
491
492def _to_ast_ref(a, ctx):
493    k = _ast_kind(ctx, a)
494    if k == Z3_SORT_AST:
495        return _to_sort_ref(a, ctx)
496    elif k == Z3_FUNC_DECL_AST:
497        return _to_func_decl_ref(a, ctx)
498    else:
499        return _to_expr_ref(a, ctx)
500
501
502#########################################
503#
504# Sorts
505#
506#########################################
507
508def _sort_kind(ctx, s):
509    return Z3_get_sort_kind(ctx.ref(), s)
510
511class SortRef(AstRef):
512    """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
513    def as_ast(self):
514        return Z3_sort_to_ast(self.ctx_ref(), self.ast)
515
516    def get_id(self):
517        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
518
519    def kind(self):
520        """Return the Z3 internal kind of a sort. This method can be used to test if `self` is one of the Z3 builtin sorts.
521
522        >>> b = BoolSort()
523        >>> b.kind() == Z3_BOOL_SORT
524        True
525        >>> b.kind() == Z3_INT_SORT
526        False
527        >>> A = ArraySort(IntSort(), IntSort())
528        >>> A.kind() == Z3_ARRAY_SORT
529        True
530        >>> A.kind() == Z3_INT_SORT
531        False
532        """
533        return _sort_kind(self.ctx, self.ast)
534
535    def subsort(self, other):
536        """Return `True` if `self` is a subsort of `other`.
537
538        >>> IntSort().subsort(RealSort())
539        True
540        """
541        return False
542
543    def cast(self, val):
544        """Try to cast `val` as an element of sort `self`.
545
546        This method is used in Z3Py to convert Python objects such as integers,
547        floats, longs and strings into Z3 expressions.
548
549        >>> x = Int('x')
550        >>> RealSort().cast(x)
551        ToReal(x)
552        """
553        if z3_debug():
554            _z3_assert(is_expr(val), "Z3 expression expected")
555            _z3_assert(self.eq(val.sort()), "Sort mismatch")
556        return val
557
558    def name(self):
559        """Return the name (string) of sort `self`.
560
561        >>> BoolSort().name()
562        'Bool'
563        >>> ArraySort(IntSort(), IntSort()).name()
564        'Array'
565        """
566        return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
567
568    def __eq__(self, other):
569        """Return `True` if `self` and `other` are the same Z3 sort.
570
571        >>> p = Bool('p')
572        >>> p.sort() == BoolSort()
573        True
574        >>> p.sort() == IntSort()
575        False
576        """
577        if other is None:
578            return False
579        return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
580
581    def __ne__(self, other):
582        """Return `True` if `self` and `other` are not the same Z3 sort.
583
584        >>> p = Bool('p')
585        >>> p.sort() != BoolSort()
586        False
587        >>> p.sort() != IntSort()
588        True
589        """
590        return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
591
592    def __hash__(self):
593        """ Hash code. """
594        return AstRef.__hash__(self)
595
596def is_sort(s):
597    """Return `True` if `s` is a Z3 sort.
598
599    >>> is_sort(IntSort())
600    True
601    >>> is_sort(Int('x'))
602    False
603    >>> is_expr(Int('x'))
604    True
605    """
606    return isinstance(s, SortRef)
607
608def _to_sort_ref(s, ctx):
609    if z3_debug():
610        _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
611    k = _sort_kind(ctx, s)
612    if k == Z3_BOOL_SORT:
613        return BoolSortRef(s, ctx)
614    elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
615        return ArithSortRef(s, ctx)
616    elif k == Z3_BV_SORT:
617        return BitVecSortRef(s, ctx)
618    elif k == Z3_ARRAY_SORT:
619        return ArraySortRef(s, ctx)
620    elif k == Z3_DATATYPE_SORT:
621        return DatatypeSortRef(s, ctx)
622    elif k == Z3_FINITE_DOMAIN_SORT:
623        return FiniteDomainSortRef(s, ctx)
624    elif k == Z3_FLOATING_POINT_SORT:
625        return FPSortRef(s, ctx)
626    elif k == Z3_ROUNDING_MODE_SORT:
627        return FPRMSortRef(s, ctx)
628    elif k == Z3_RE_SORT:
629        return ReSortRef(s, ctx)
630    elif k == Z3_SEQ_SORT:
631        return SeqSortRef(s, ctx)
632    return SortRef(s, ctx)
633
634def _sort(ctx, a):
635    return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
636
637def DeclareSort(name, ctx=None):
638    """Create a new uninterpreted sort named `name`.
639
640    If `ctx=None`, then the new sort is declared in the global Z3Py context.
641
642    >>> A = DeclareSort('A')
643    >>> a = Const('a', A)
644    >>> b = Const('b', A)
645    >>> a.sort() == A
646    True
647    >>> b.sort() == A
648    True
649    >>> a == b
650    a == b
651    """
652    ctx = _get_ctx(ctx)
653    return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
654
655#########################################
656#
657# Function Declarations
658#
659#########################################
660
661class FuncDeclRef(AstRef):
662    """Function declaration. Every constant and function have an associated declaration.
663
664    The declaration assigns a name, a sort (i.e., type), and for function
665    the sort (i.e., type) of each of its arguments. Note that, in Z3,
666    a constant is a function with 0 arguments.
667    """
668    def as_ast(self):
669        return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
670
671    def get_id(self):
672        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
673
674    def as_func_decl(self):
675        return self.ast
676
677    def name(self):
678        """Return the name of the function declaration `self`.
679
680        >>> f = Function('f', IntSort(), IntSort())
681        >>> f.name()
682        'f'
683        >>> isinstance(f.name(), str)
684        True
685        """
686        return _symbol2py(self.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
687
688    def arity(self):
689        """Return the number of arguments of a function declaration. If `self` is a constant, then `self.arity()` is 0.
690
691        >>> f = Function('f', IntSort(), RealSort(), BoolSort())
692        >>> f.arity()
693        2
694        """
695        return int(Z3_get_arity(self.ctx_ref(), self.ast))
696
697    def domain(self, i):
698        """Return the sort of the argument `i` of a function declaration. This method assumes that `0 <= i < self.arity()`.
699
700        >>> f = Function('f', IntSort(), RealSort(), BoolSort())
701        >>> f.domain(0)
702        Int
703        >>> f.domain(1)
704        Real
705        """
706        if z3_debug():
707            _z3_assert(i < self.arity(), "Index out of bounds")
708        return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
709
710    def range(self):
711        """Return the sort of the range of a function declaration. For constants, this is the sort of the constant.
712
713        >>> f = Function('f', IntSort(), RealSort(), BoolSort())
714        >>> f.range()
715        Bool
716        """
717        return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.ast), self.ctx)
718
719    def kind(self):
720        """Return the internal kind of a function declaration. It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
721
722        >>> x = Int('x')
723        >>> d = (x + 1).decl()
724        >>> d.kind() == Z3_OP_ADD
725        True
726        >>> d.kind() == Z3_OP_MUL
727        False
728        """
729        return Z3_get_decl_kind(self.ctx_ref(), self.ast)
730
731    def params(self):
732        ctx = self.ctx
733        n = Z3_get_decl_num_parameters(self.ctx_ref(), self.ast)
734        result = [ None for i in range(n) ]
735        for i in range(n):
736            k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.ast, i)
737            if k == Z3_PARAMETER_INT:
738               result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.ast, i)
739            elif k == Z3_PARAMETER_DOUBLE:
740               result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.ast, i)
741            elif k == Z3_PARAMETER_RATIONAL:
742               result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.ast, i)
743            elif k == Z3_PARAMETER_SYMBOL:
744               result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.ast, i)
745            elif k == Z3_PARAMETER_SORT:
746               result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.ast, i), ctx)
747            elif k == Z3_PARAMETER_AST:
748               result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.ast, i), ctx)
749            elif k == Z3_PARAMETER_FUNC_DECL:
750               result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.ast, i), ctx)
751            else:
752               assert(False)
753        return result
754
755    def __call__(self, *args):
756        """Create a Z3 application expression using the function `self`, and the given arguments.
757
758        The arguments must be Z3 expressions. This method assumes that
759        the sorts of the elements in `args` match the sorts of the
760        domain. Limited coercion is supported.  For example, if
761        args[0] is a Python integer, and the function expects a Z3
762        integer, then the argument is automatically converted into a
763        Z3 integer.
764
765        >>> f = Function('f', IntSort(), RealSort(), BoolSort())
766        >>> x = Int('x')
767        >>> y = Real('y')
768        >>> f(x, y)
769        f(x, y)
770        >>> f(x, x)
771        f(x, ToReal(x))
772        """
773        args = _get_args(args)
774        num = len(args)
775        if z3_debug():
776            _z3_assert(num == self.arity(), "Incorrect number of arguments to %s" % self)
777        _args = (Ast * num)()
778        saved = []
779        for i in range(num):
780            # self.domain(i).cast(args[i]) may create a new Z3 expression,
781            # then we must save in 'saved' to prevent it from being garbage collected.
782            tmp      = self.domain(i).cast(args[i])
783            saved.append(tmp)
784            _args[i] = tmp.as_ast()
785        return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
786
787def is_func_decl(a):
788    """Return `True` if `a` is a Z3 function declaration.
789
790    >>> f = Function('f', IntSort(), IntSort())
791    >>> is_func_decl(f)
792    True
793    >>> x = Real('x')
794    >>> is_func_decl(x)
795    False
796    """
797    return isinstance(a, FuncDeclRef)
798
799def Function(name, *sig):
800    """Create a new Z3 uninterpreted function with the given sorts.
801
802    >>> f = Function('f', IntSort(), IntSort())
803    >>> f(f(0))
804    f(f(0))
805    """
806    sig = _get_args(sig)
807    if z3_debug():
808        _z3_assert(len(sig) > 0, "At least two arguments expected")
809    arity = len(sig) - 1
810    rng   = sig[arity]
811    if z3_debug():
812        _z3_assert(is_sort(rng), "Z3 sort expected")
813    dom   = (Sort * arity)()
814    for i in range(arity):
815        if z3_debug():
816            _z3_assert(is_sort(sig[i]), "Z3 sort expected")
817        dom[i] = sig[i].ast
818    ctx = rng.ctx
819    return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
820
821def FreshFunction(*sig):
822    """Create a new fresh Z3 uninterpreted function with the given sorts.
823    """
824    sig = _get_args(sig)
825    if z3_debug():
826        _z3_assert(len(sig) > 0, "At least two arguments expected")
827    arity = len(sig) - 1
828    rng = sig[arity]
829    if z3_debug():
830        _z3_assert(is_sort(rng), "Z3 sort expected")
831    dom = (z3.Sort * arity)()
832    for i in range(arity):
833        if z3_debug():
834            _z3_assert(is_sort(sig[i]), "Z3 sort expected")
835        dom[i] = sig[i].ast
836    ctx = rng.ctx
837    return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), 'f', arity, dom, rng.ast), ctx)
838
839
840def _to_func_decl_ref(a, ctx):
841    return FuncDeclRef(a, ctx)
842
843def RecFunction(name, *sig):
844    """Create a new Z3 recursive with the given sorts."""
845    sig = _get_args(sig)
846    if z3_debug():
847        _z3_assert(len(sig) > 0, "At least two arguments expected")
848    arity = len(sig) - 1
849    rng   = sig[arity]
850    if z3_debug():
851        _z3_assert(is_sort(rng), "Z3 sort expected")
852    dom   = (Sort * arity)()
853    for i in range(arity):
854        if z3_debug():
855            _z3_assert(is_sort(sig[i]), "Z3 sort expected")
856        dom[i] = sig[i].ast
857    ctx = rng.ctx
858    return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
859
860def RecAddDefinition(f, args, body):
861    """Set the body of a recursive function.
862       Recursive definitions can be simplified if they are applied to ground
863       arguments.
864    >>> ctx = Context()
865    >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
866    >>> n = Int('n', ctx)
867    >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
868    >>> simplify(fac(5))
869    120
870    >>> s = Solver(ctx=ctx)
871    >>> s.add(fac(n) < 3)
872    >>> s.check()
873    sat
874    >>> s.model().eval(fac(5))
875    120
876    """
877    if is_app(args):
878       args = [args]
879    ctx = body.ctx
880    args = _get_args(args)
881    n = len(args)
882    _args = (Ast * n)()
883    for i in range(n):
884        _args[i] = args[i].ast
885    Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
886
887#########################################
888#
889# Expressions
890#
891#########################################
892
893class ExprRef(AstRef):
894    """Constraints, formulas and terms are expressions in Z3.
895
896    Expressions are ASTs. Every expression has a sort.
897    There are three main kinds of expressions:
898    function applications, quantifiers and bounded variables.
899    A constant is a function application with 0 arguments.
900    For quantifier free problems, all expressions are
901    function applications.
902    """
903    def as_ast(self):
904        return self.ast
905
906    def get_id(self):
907        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
908
909    def sort(self):
910        """Return the sort of expression `self`.
911
912        >>> x = Int('x')
913        >>> (x + 1).sort()
914        Int
915        >>> y = Real('y')
916        >>> (x + y).sort()
917        Real
918        """
919        return _sort(self.ctx, self.as_ast())
920
921    def sort_kind(self):
922        """Shorthand for `self.sort().kind()`.
923
924        >>> a = Array('a', IntSort(), IntSort())
925        >>> a.sort_kind() == Z3_ARRAY_SORT
926        True
927        >>> a.sort_kind() == Z3_INT_SORT
928        False
929        """
930        return self.sort().kind()
931
932    def __eq__(self, other):
933        """Return a Z3 expression that represents the constraint `self == other`.
934
935        If `other` is `None`, then this method simply returns `False`.
936
937        >>> a = Int('a')
938        >>> b = Int('b')
939        >>> a == b
940        a == b
941        >>> a is None
942        False
943        """
944        if other is None:
945            return False
946        a, b = _coerce_exprs(self, other)
947        return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
948
949    def __hash__(self):
950        """ Hash code. """
951        return AstRef.__hash__(self)
952
953    def __ne__(self, other):
954        """Return a Z3 expression that represents the constraint `self != other`.
955
956        If `other` is `None`, then this method simply returns `True`.
957
958        >>> a = Int('a')
959        >>> b = Int('b')
960        >>> a != b
961        a != b
962        >>> a is not None
963        True
964        """
965        if other is None:
966            return True
967        a, b = _coerce_exprs(self, other)
968        _args, sz = _to_ast_array((a, b))
969        return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
970
971    def params(self):
972        return self.decl().params()
973
974    def decl(self):
975        """Return the Z3 function declaration associated with a Z3 application.
976
977        >>> f = Function('f', IntSort(), IntSort())
978        >>> a = Int('a')
979        >>> t = f(a)
980        >>> eq(t.decl(), f)
981        True
982        >>> (a + 1).decl()
983        +
984        """
985        if z3_debug():
986            _z3_assert(is_app(self), "Z3 application expected")
987        return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_ast()), self.ctx)
988
989    def num_args(self):
990        """Return the number of arguments of a Z3 application.
991
992        >>> a = Int('a')
993        >>> b = Int('b')
994        >>> (a + b).num_args()
995        2
996        >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
997        >>> t = f(a, b, 0)
998        >>> t.num_args()
999        3
1000        """
1001        if z3_debug():
1002            _z3_assert(is_app(self), "Z3 application expected")
1003        return int(Z3_get_app_num_args(self.ctx_ref(), self.as_ast()))
1004
1005    def arg(self, idx):
1006        """Return argument `idx` of the application `self`.
1007
1008        This method assumes that `self` is a function application with at least `idx+1` arguments.
1009
1010        >>> a = Int('a')
1011        >>> b = Int('b')
1012        >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1013        >>> t = f(a, b, 0)
1014        >>> t.arg(0)
1015        a
1016        >>> t.arg(1)
1017        b
1018        >>> t.arg(2)
1019        0
1020        """
1021        if z3_debug():
1022            _z3_assert(is_app(self), "Z3 application expected")
1023            _z3_assert(idx < self.num_args(), "Invalid argument index")
1024        return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_ast(), idx), self.ctx)
1025
1026    def children(self):
1027        """Return a list containing the children of the given expression
1028
1029        >>> a = Int('a')
1030        >>> b = Int('b')
1031        >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1032        >>> t = f(a, b, 0)
1033        >>> t.children()
1034        [a, b, 0]
1035        """
1036        if is_app(self):
1037            return [self.arg(i) for i in range(self.num_args())]
1038        else:
1039            return []
1040
1041def _to_expr_ref(a, ctx):
1042    if isinstance(a, Pattern):
1043        return PatternRef(a, ctx)
1044    ctx_ref = ctx.ref()
1045    k = Z3_get_ast_kind(ctx_ref, a)
1046    if k == Z3_QUANTIFIER_AST:
1047        return QuantifierRef(a, ctx)
1048    sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1049    if sk == Z3_BOOL_SORT:
1050        return BoolRef(a, ctx)
1051    if sk == Z3_INT_SORT:
1052        if k == Z3_NUMERAL_AST:
1053            return IntNumRef(a, ctx)
1054        return ArithRef(a, ctx)
1055    if sk == Z3_REAL_SORT:
1056        if k == Z3_NUMERAL_AST:
1057            return RatNumRef(a, ctx)
1058        if _is_algebraic(ctx, a):
1059            return AlgebraicNumRef(a, ctx)
1060        return ArithRef(a, ctx)
1061    if sk == Z3_BV_SORT:
1062        if k == Z3_NUMERAL_AST:
1063            return BitVecNumRef(a, ctx)
1064        else:
1065            return BitVecRef(a, ctx)
1066    if sk == Z3_ARRAY_SORT:
1067        return ArrayRef(a, ctx)
1068    if sk == Z3_DATATYPE_SORT:
1069        return DatatypeRef(a, ctx)
1070    if sk == Z3_FLOATING_POINT_SORT:
1071        if k == Z3_APP_AST and _is_numeral(ctx, a):
1072            return FPNumRef(a, ctx)
1073        else:
1074            return FPRef(a, ctx)
1075    if sk == Z3_FINITE_DOMAIN_SORT:
1076        if k == Z3_NUMERAL_AST:
1077            return FiniteDomainNumRef(a, ctx)
1078        else:
1079            return FiniteDomainRef(a, ctx)
1080    if sk == Z3_ROUNDING_MODE_SORT:
1081        return FPRMRef(a, ctx)
1082    if sk == Z3_SEQ_SORT:
1083        return SeqRef(a, ctx)
1084    if sk == Z3_RE_SORT:
1085        return ReRef(a, ctx)
1086    return ExprRef(a, ctx)
1087
1088def _coerce_expr_merge(s, a):
1089    if is_expr(a):
1090        s1 = a.sort()
1091        if s is None:
1092            return s1
1093        if s1.eq(s):
1094            return s
1095        elif s.subsort(s1):
1096            return s1
1097        elif s1.subsort(s):
1098            return s
1099        else:
1100            if z3_debug():
1101                _z3_assert(s1.ctx == s.ctx, "context mismatch")
1102                _z3_assert(False, "sort mismatch")
1103    else:
1104        return s
1105
1106def _coerce_exprs(a, b, ctx=None):
1107    if not is_expr(a) and not is_expr(b):
1108        a = _py2expr(a, ctx)
1109        b = _py2expr(b, ctx)
1110    s = None
1111    s = _coerce_expr_merge(s, a)
1112    s = _coerce_expr_merge(s, b)
1113    a = s.cast(a)
1114    b = s.cast(b)
1115    return (a, b)
1116
1117
1118def _reduce(f, l, a):
1119    r = a
1120    for e in l:
1121        r = f(r, e)
1122    return r
1123
1124def _coerce_expr_list(alist, ctx=None):
1125    has_expr = False
1126    for a in alist:
1127        if is_expr(a):
1128            has_expr = True
1129            break
1130    if not has_expr:
1131        alist = [ _py2expr(a, ctx) for a in alist ]
1132    s = _reduce(_coerce_expr_merge, alist, None)
1133    return [ s.cast(a) for a in alist ]
1134
1135def is_expr(a):
1136    """Return `True` if `a` is a Z3 expression.
1137
1138    >>> a = Int('a')
1139    >>> is_expr(a)
1140    True
1141    >>> is_expr(a + 1)
1142    True
1143    >>> is_expr(IntSort())
1144    False
1145    >>> is_expr(1)
1146    False
1147    >>> is_expr(IntVal(1))
1148    True
1149    >>> x = Int('x')
1150    >>> is_expr(ForAll(x, x >= 0))
1151    True
1152    >>> is_expr(FPVal(1.0))
1153    True
1154    """
1155    return isinstance(a, ExprRef)
1156
1157def is_app(a):
1158    """Return `True` if `a` is a Z3 function application.
1159
1160    Note that, constants are function applications with 0 arguments.
1161
1162    >>> a = Int('a')
1163    >>> is_app(a)
1164    True
1165    >>> is_app(a + 1)
1166    True
1167    >>> is_app(IntSort())
1168    False
1169    >>> is_app(1)
1170    False
1171    >>> is_app(IntVal(1))
1172    True
1173    >>> x = Int('x')
1174    >>> is_app(ForAll(x, x >= 0))
1175    False
1176    """
1177    if not isinstance(a, ExprRef):
1178        return False
1179    k = _ast_kind(a.ctx, a)
1180    return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1181
1182def is_const(a):
1183    """Return `True` if `a` is Z3 constant/variable expression.
1184
1185    >>> a = Int('a')
1186    >>> is_const(a)
1187    True
1188    >>> is_const(a + 1)
1189    False
1190    >>> is_const(1)
1191    False
1192    >>> is_const(IntVal(1))
1193    True
1194    >>> x = Int('x')
1195    >>> is_const(ForAll(x, x >= 0))
1196    False
1197    """
1198    return is_app(a) and a.num_args() == 0
1199
1200def is_var(a):
1201    """Return `True` if `a` is variable.
1202
1203    Z3 uses de-Bruijn indices for representing bound variables in
1204    quantifiers.
1205
1206    >>> x = Int('x')
1207    >>> is_var(x)
1208    False
1209    >>> is_const(x)
1210    True
1211    >>> f = Function('f', IntSort(), IntSort())
1212    >>> # Z3 replaces x with bound variables when ForAll is executed.
1213    >>> q = ForAll(x, f(x) == x)
1214    >>> b = q.body()
1215    >>> b
1216    f(Var(0)) == Var(0)
1217    >>> b.arg(1)
1218    Var(0)
1219    >>> is_var(b.arg(1))
1220    True
1221    """
1222    return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1223
1224def get_var_index(a):
1225    """Return the de-Bruijn index of the Z3 bounded variable `a`.
1226
1227    >>> x = Int('x')
1228    >>> y = Int('y')
1229    >>> is_var(x)
1230    False
1231    >>> is_const(x)
1232    True
1233    >>> f = Function('f', IntSort(), IntSort(), IntSort())
1234    >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1235    >>> q = ForAll([x, y], f(x, y) == x + y)
1236    >>> q.body()
1237    f(Var(1), Var(0)) == Var(1) + Var(0)
1238    >>> b = q.body()
1239    >>> b.arg(0)
1240    f(Var(1), Var(0))
1241    >>> v1 = b.arg(0).arg(0)
1242    >>> v2 = b.arg(0).arg(1)
1243    >>> v1
1244    Var(1)
1245    >>> v2
1246    Var(0)
1247    >>> get_var_index(v1)
1248    1
1249    >>> get_var_index(v2)
1250    0
1251    """
1252    if z3_debug():
1253        _z3_assert(is_var(a), "Z3 bound variable expected")
1254    return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1255
1256def is_app_of(a, k):
1257    """Return `True` if `a` is an application of the given kind `k`.
1258
1259    >>> x = Int('x')
1260    >>> n = x + 1
1261    >>> is_app_of(n, Z3_OP_ADD)
1262    True
1263    >>> is_app_of(n, Z3_OP_MUL)
1264    False
1265    """
1266    return is_app(a) and a.decl().kind() == k
1267
1268def If(a, b, c, ctx=None):
1269    """Create a Z3 if-then-else expression.
1270
1271    >>> x = Int('x')
1272    >>> y = Int('y')
1273    >>> max = If(x > y, x, y)
1274    >>> max
1275    If(x > y, x, y)
1276    >>> simplify(max)
1277    If(x <= y, y, x)
1278    """
1279    if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1280        return Cond(a, b, c, ctx)
1281    else:
1282        ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1283        s = BoolSort(ctx)
1284        a = s.cast(a)
1285        b, c = _coerce_exprs(b, c, ctx)
1286        if z3_debug():
1287            _z3_assert(a.ctx == b.ctx, "Context mismatch")
1288        return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1289
1290def Distinct(*args):
1291    """Create a Z3 distinct expression.
1292
1293    >>> x = Int('x')
1294    >>> y = Int('y')
1295    >>> Distinct(x, y)
1296    x != y
1297    >>> z = Int('z')
1298    >>> Distinct(x, y, z)
1299    Distinct(x, y, z)
1300    >>> simplify(Distinct(x, y, z))
1301    Distinct(x, y, z)
1302    >>> simplify(Distinct(x, y, z), blast_distinct=True)
1303    And(Not(x == y), Not(x == z), Not(y == z))
1304    """
1305    args  = _get_args(args)
1306    ctx   = _ctx_from_ast_arg_list(args)
1307    if z3_debug():
1308        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1309    args  = _coerce_expr_list(args, ctx)
1310    _args, sz = _to_ast_array(args)
1311    return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1312
1313def _mk_bin(f, a, b):
1314    args = (Ast * 2)()
1315    if z3_debug():
1316        _z3_assert(a.ctx == b.ctx, "Context mismatch")
1317    args[0] = a.as_ast()
1318    args[1] = b.as_ast()
1319    return f(a.ctx.ref(), 2, args)
1320
1321def Const(name, sort):
1322    """Create a constant of the given sort.
1323
1324    >>> Const('x', IntSort())
1325    x
1326    """
1327    if z3_debug():
1328        _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1329    ctx = sort.ctx
1330    return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1331
1332def Consts(names, sort):
1333    """Create several constants of the given sort.
1334
1335    `names` is a string containing the names of all constants to be created.
1336    Blank spaces separate the names of different constants.
1337
1338    >>> x, y, z = Consts('x y z', IntSort())
1339    >>> x + y + z
1340    x + y + z
1341    """
1342    if isinstance(names, str):
1343        names = names.split(" ")
1344    return [Const(name, sort) for name in names]
1345
1346def FreshConst(sort, prefix='c'):
1347    """Create a fresh constant of a specified sort"""
1348    ctx = _get_ctx(sort.ctx)
1349    return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1350
1351def Var(idx, s):
1352    """Create a Z3 free variable. Free variables are used to create quantified formulas.
1353
1354    >>> Var(0, IntSort())
1355    Var(0)
1356    >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1357    False
1358    """
1359    if z3_debug():
1360        _z3_assert(is_sort(s), "Z3 sort expected")
1361    return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1362
1363def RealVar(idx, ctx=None):
1364    """
1365    Create a real free variable. Free variables are used to create quantified formulas.
1366    They are also used to create polynomials.
1367
1368    >>> RealVar(0)
1369    Var(0)
1370    """
1371    return Var(idx, RealSort(ctx))
1372
1373def RealVarVector(n, ctx=None):
1374    """
1375    Create a list of Real free variables.
1376    The variables have ids: 0, 1, ..., n-1
1377
1378    >>> x0, x1, x2, x3 = RealVarVector(4)
1379    >>> x2
1380    Var(2)
1381    """
1382    return [ RealVar(i, ctx) for i in range(n) ]
1383
1384#########################################
1385#
1386# Booleans
1387#
1388#########################################
1389
1390class BoolSortRef(SortRef):
1391    """Boolean sort."""
1392    def cast(self, val):
1393        """Try to cast `val` as a Boolean.
1394
1395        >>> x = BoolSort().cast(True)
1396        >>> x
1397        True
1398        >>> is_expr(x)
1399        True
1400        >>> is_expr(True)
1401        False
1402        >>> x.sort()
1403        Bool
1404        """
1405        if isinstance(val, bool):
1406            return BoolVal(val, self.ctx)
1407        if z3_debug():
1408            if not is_expr(val):
1409               _z3_assert(is_expr(val), "True, False or Z3 Boolean expression expected. Received %s of type %s" % (val, type(val)))
1410            if not self.eq(val.sort()):
1411               _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1412        return val
1413
1414    def subsort(self, other):
1415        return isinstance(other, ArithSortRef)
1416
1417    def is_int(self):
1418        return True
1419
1420    def is_bool(self):
1421        return True
1422
1423
1424class BoolRef(ExprRef):
1425    """All Boolean expressions are instances of this class."""
1426    def sort(self):
1427        return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
1428
1429    def __rmul__(self, other):
1430        return self * other
1431
1432    def __mul__(self, other):
1433        """Create the Z3 expression `self * other`.
1434        """
1435        if other == 1:
1436            return self
1437        if other == 0:
1438            return 0
1439        return If(self, other, 0)
1440
1441
1442def is_bool(a):
1443    """Return `True` if `a` is a Z3 Boolean expression.
1444
1445    >>> p = Bool('p')
1446    >>> is_bool(p)
1447    True
1448    >>> q = Bool('q')
1449    >>> is_bool(And(p, q))
1450    True
1451    >>> x = Real('x')
1452    >>> is_bool(x)
1453    False
1454    >>> is_bool(x == 0)
1455    True
1456    """
1457    return isinstance(a, BoolRef)
1458
1459def is_true(a):
1460    """Return `True` if `a` is the Z3 true expression.
1461
1462    >>> p = Bool('p')
1463    >>> is_true(p)
1464    False
1465    >>> is_true(simplify(p == p))
1466    True
1467    >>> x = Real('x')
1468    >>> is_true(x == 0)
1469    False
1470    >>> # True is a Python Boolean expression
1471    >>> is_true(True)
1472    False
1473    """
1474    return is_app_of(a, Z3_OP_TRUE)
1475
1476def is_false(a):
1477    """Return `True` if `a` is the Z3 false expression.
1478
1479    >>> p = Bool('p')
1480    >>> is_false(p)
1481    False
1482    >>> is_false(False)
1483    False
1484    >>> is_false(BoolVal(False))
1485    True
1486    """
1487    return is_app_of(a, Z3_OP_FALSE)
1488
1489def is_and(a):
1490    """Return `True` if `a` is a Z3 and expression.
1491
1492    >>> p, q = Bools('p q')
1493    >>> is_and(And(p, q))
1494    True
1495    >>> is_and(Or(p, q))
1496    False
1497    """
1498    return is_app_of(a, Z3_OP_AND)
1499
1500def is_or(a):
1501    """Return `True` if `a` is a Z3 or expression.
1502
1503    >>> p, q = Bools('p q')
1504    >>> is_or(Or(p, q))
1505    True
1506    >>> is_or(And(p, q))
1507    False
1508    """
1509    return is_app_of(a, Z3_OP_OR)
1510
1511def is_implies(a):
1512    """Return `True` if `a` is a Z3 implication expression.
1513
1514    >>> p, q = Bools('p q')
1515    >>> is_implies(Implies(p, q))
1516    True
1517    >>> is_implies(And(p, q))
1518    False
1519    """
1520    return is_app_of(a, Z3_OP_IMPLIES)
1521
1522def is_not(a):
1523    """Return `True` if `a` is a Z3 not expression.
1524
1525    >>> p = Bool('p')
1526    >>> is_not(p)
1527    False
1528    >>> is_not(Not(p))
1529    True
1530    """
1531    return is_app_of(a, Z3_OP_NOT)
1532
1533def is_eq(a):
1534    """Return `True` if `a` is a Z3 equality expression.
1535
1536    >>> x, y = Ints('x y')
1537    >>> is_eq(x == y)
1538    True
1539    """
1540    return is_app_of(a, Z3_OP_EQ)
1541
1542def is_distinct(a):
1543    """Return `True` if `a` is a Z3 distinct expression.
1544
1545    >>> x, y, z = Ints('x y z')
1546    >>> is_distinct(x == y)
1547    False
1548    >>> is_distinct(Distinct(x, y, z))
1549    True
1550    """
1551    return is_app_of(a, Z3_OP_DISTINCT)
1552
1553def BoolSort(ctx=None):
1554    """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1555
1556    >>> BoolSort()
1557    Bool
1558    >>> p = Const('p', BoolSort())
1559    >>> is_bool(p)
1560    True
1561    >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1562    >>> r(0, 1)
1563    r(0, 1)
1564    >>> is_bool(r(0, 1))
1565    True
1566    """
1567    ctx = _get_ctx(ctx)
1568    return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1569
1570def BoolVal(val, ctx=None):
1571    """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1572
1573    >>> BoolVal(True)
1574    True
1575    >>> is_true(BoolVal(True))
1576    True
1577    >>> is_true(True)
1578    False
1579    >>> is_false(BoolVal(False))
1580    True
1581    """
1582    ctx = _get_ctx(ctx)
1583    if val == False:
1584        return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1585    else:
1586        return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1587
1588def Bool(name, ctx=None):
1589    """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1590
1591    >>> p = Bool('p')
1592    >>> q = Bool('q')
1593    >>> And(p, q)
1594    And(p, q)
1595    """
1596    ctx = _get_ctx(ctx)
1597    return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1598
1599def Bools(names, ctx=None):
1600    """Return a tuple of Boolean constants.
1601
1602    `names` is a single string containing all names separated by blank spaces.
1603    If `ctx=None`, then the global context is used.
1604
1605    >>> p, q, r = Bools('p q r')
1606    >>> And(p, Or(q, r))
1607    And(p, Or(q, r))
1608    """
1609    ctx = _get_ctx(ctx)
1610    if isinstance(names, str):
1611        names = names.split(" ")
1612    return [Bool(name, ctx) for name in names]
1613
1614def BoolVector(prefix, sz, ctx=None):
1615    """Return a list of Boolean constants of size `sz`.
1616
1617    The constants are named using the given prefix.
1618    If `ctx=None`, then the global context is used.
1619
1620    >>> P = BoolVector('p', 3)
1621    >>> P
1622    [p__0, p__1, p__2]
1623    >>> And(P)
1624    And(p__0, p__1, p__2)
1625    """
1626    return [ Bool('%s__%s' % (prefix, i)) for i in range(sz) ]
1627
1628def FreshBool(prefix='b', ctx=None):
1629    """Return a fresh Boolean constant in the given context using the given prefix.
1630
1631    If `ctx=None`, then the global context is used.
1632
1633    >>> b1 = FreshBool()
1634    >>> b2 = FreshBool()
1635    >>> eq(b1, b2)
1636    False
1637    """
1638    ctx = _get_ctx(ctx)
1639    return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1640
1641def Implies(a, b, ctx=None):
1642    """Create a Z3 implies expression.
1643
1644    >>> p, q = Bools('p q')
1645    >>> Implies(p, q)
1646    Implies(p, q)
1647    """
1648    ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1649    s = BoolSort(ctx)
1650    a = s.cast(a)
1651    b = s.cast(b)
1652    return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1653
1654def Xor(a, b, ctx=None):
1655    """Create a Z3 Xor expression.
1656
1657    >>> p, q = Bools('p q')
1658    >>> Xor(p, q)
1659    Xor(p, q)
1660    >>> simplify(Xor(p, q))
1661    Not(p) == q
1662    """
1663    ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1664    s = BoolSort(ctx)
1665    a = s.cast(a)
1666    b = s.cast(b)
1667    return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1668
1669def Not(a, ctx=None):
1670    """Create a Z3 not expression or probe.
1671
1672    >>> p = Bool('p')
1673    >>> Not(Not(p))
1674    Not(Not(p))
1675    >>> simplify(Not(Not(p)))
1676    p
1677    """
1678    ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1679    if is_probe(a):
1680        # Not is also used to build probes
1681        return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1682    else:
1683        s = BoolSort(ctx)
1684        a = s.cast(a)
1685        return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1686
1687def mk_not(a):
1688    if is_not(a):
1689        return a.arg(0)
1690    else:
1691        return Not(a)
1692
1693def _has_probe(args):
1694    """Return `True` if one of the elements of the given collection is a Z3 probe."""
1695    for arg in args:
1696        if is_probe(arg):
1697            return True
1698    return False
1699
1700def And(*args):
1701    """Create a Z3 and-expression or and-probe.
1702
1703    >>> p, q, r = Bools('p q r')
1704    >>> And(p, q, r)
1705    And(p, q, r)
1706    >>> P = BoolVector('p', 5)
1707    >>> And(P)
1708    And(p__0, p__1, p__2, p__3, p__4)
1709    """
1710    last_arg = None
1711    if len(args) > 0:
1712        last_arg = args[len(args)-1]
1713    if isinstance(last_arg, Context):
1714        ctx = args[len(args)-1]
1715        args = args[:len(args)-1]
1716    elif len(args) == 1 and isinstance(args[0], AstVector):
1717        ctx = args[0].ctx
1718        args = [a for a in args[0]]
1719    else:
1720        ctx = None
1721    args = _get_args(args)
1722    ctx  = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1723    if z3_debug():
1724        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1725    if _has_probe(args):
1726        return _probe_and(args, ctx)
1727    else:
1728        args  = _coerce_expr_list(args, ctx)
1729        _args, sz = _to_ast_array(args)
1730        return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
1731
1732def Or(*args):
1733    """Create a Z3 or-expression or or-probe.
1734
1735    >>> p, q, r = Bools('p q r')
1736    >>> Or(p, q, r)
1737    Or(p, q, r)
1738    >>> P = BoolVector('p', 5)
1739    >>> Or(P)
1740    Or(p__0, p__1, p__2, p__3, p__4)
1741    """
1742    last_arg = None
1743    if len(args) > 0:
1744        last_arg = args[len(args)-1]
1745    if isinstance(last_arg, Context):
1746        ctx = args[len(args)-1]
1747        args = args[:len(args)-1]
1748    elif len(args) == 1 and isinstance(args[0], AstVector):
1749        ctx = args[0].ctx
1750        args = [a for a in args[0]]
1751    else:
1752        ctx = None
1753    args = _get_args(args)
1754    ctx  = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1755    if z3_debug():
1756        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1757    if _has_probe(args):
1758        return _probe_or(args, ctx)
1759    else:
1760        args  = _coerce_expr_list(args, ctx)
1761        _args, sz = _to_ast_array(args)
1762        return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
1763
1764#########################################
1765#
1766# Patterns
1767#
1768#########################################
1769
1770class PatternRef(ExprRef):
1771    """Patterns are hints for quantifier instantiation.
1772
1773    """
1774    def as_ast(self):
1775        return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
1776
1777    def get_id(self):
1778        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1779
1780def is_pattern(a):
1781    """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
1782
1783    >>> f = Function('f', IntSort(), IntSort())
1784    >>> x = Int('x')
1785    >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
1786    >>> q
1787    ForAll(x, f(x) == 0)
1788    >>> q.num_patterns()
1789    1
1790    >>> is_pattern(q.pattern(0))
1791    True
1792    >>> q.pattern(0)
1793    f(Var(0))
1794    """
1795    return isinstance(a, PatternRef)
1796
1797def MultiPattern(*args):
1798    """Create a Z3 multi-pattern using the given expressions `*args`
1799
1800    >>> f = Function('f', IntSort(), IntSort())
1801    >>> g = Function('g', IntSort(), IntSort())
1802    >>> x = Int('x')
1803    >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
1804    >>> q
1805    ForAll(x, f(x) != g(x))
1806    >>> q.num_patterns()
1807    1
1808    >>> is_pattern(q.pattern(0))
1809    True
1810    >>> q.pattern(0)
1811    MultiPattern(f(Var(0)), g(Var(0)))
1812    """
1813    if z3_debug():
1814        _z3_assert(len(args) > 0, "At least one argument expected")
1815        _z3_assert(all([ is_expr(a) for a in args ]), "Z3 expressions expected")
1816    ctx = args[0].ctx
1817    args, sz = _to_ast_array(args)
1818    return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
1819
1820def _to_pattern(arg):
1821    if is_pattern(arg):
1822        return arg
1823    else:
1824        return MultiPattern(arg)
1825
1826#########################################
1827#
1828# Quantifiers
1829#
1830#########################################
1831
1832class QuantifierRef(BoolRef):
1833    """Universally and Existentially quantified formulas."""
1834
1835    def as_ast(self):
1836        return self.ast
1837
1838    def get_id(self):
1839        return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1840
1841    def sort(self):
1842        """Return the Boolean sort or sort of Lambda."""
1843        if self.is_lambda():
1844            return _sort(self.ctx, self.as_ast())
1845        return BoolSort(self.ctx)
1846
1847    def is_forall(self):
1848        """Return `True` if `self` is a universal quantifier.
1849
1850        >>> f = Function('f', IntSort(), IntSort())
1851        >>> x = Int('x')
1852        >>> q = ForAll(x, f(x) == 0)
1853        >>> q.is_forall()
1854        True
1855        >>> q = Exists(x, f(x) != 0)
1856        >>> q.is_forall()
1857        False
1858        """
1859        return Z3_is_quantifier_forall(self.ctx_ref(), self.ast)
1860
1861    def is_exists(self):
1862        """Return `True` if `self` is an existential quantifier.
1863
1864        >>> f = Function('f', IntSort(), IntSort())
1865        >>> x = Int('x')
1866        >>> q = ForAll(x, f(x) == 0)
1867        >>> q.is_exists()
1868        False
1869        >>> q = Exists(x, f(x) != 0)
1870        >>> q.is_exists()
1871        True
1872        """
1873        return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
1874
1875    def is_lambda(self):
1876        """Return `True` if `self` is a lambda expression.
1877
1878        >>> f = Function('f', IntSort(), IntSort())
1879        >>> x = Int('x')
1880        >>> q = Lambda(x, f(x))
1881        >>> q.is_lambda()
1882        True
1883        >>> q = Exists(x, f(x) != 0)
1884        >>> q.is_lambda()
1885        False
1886        """
1887        return Z3_is_lambda(self.ctx_ref(), self.ast)
1888
1889    def __getitem__(self, arg):
1890        """Return the Z3 expression `self[arg]`.
1891        """
1892        if z3_debug():
1893            _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
1894        arg = self.sort().domain().cast(arg)
1895        return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx)
1896
1897
1898    def weight(self):
1899        """Return the weight annotation of `self`.
1900
1901        >>> f = Function('f', IntSort(), IntSort())
1902        >>> x = Int('x')
1903        >>> q = ForAll(x, f(x) == 0)
1904        >>> q.weight()
1905        1
1906        >>> q = ForAll(x, f(x) == 0, weight=10)
1907        >>> q.weight()
1908        10
1909        """
1910        return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
1911
1912    def num_patterns(self):
1913        """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
1914
1915        >>> f = Function('f', IntSort(), IntSort())
1916        >>> g = Function('g', IntSort(), IntSort())
1917        >>> x = Int('x')
1918        >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
1919        >>> q.num_patterns()
1920        2
1921        """
1922        return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
1923
1924    def pattern(self, idx):
1925        """Return a pattern (i.e., quantifier instantiation hints) in `self`.
1926
1927        >>> f = Function('f', IntSort(), IntSort())
1928        >>> g = Function('g', IntSort(), IntSort())
1929        >>> x = Int('x')
1930        >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
1931        >>> q.num_patterns()
1932        2
1933        >>> q.pattern(0)
1934        f(Var(0))
1935        >>> q.pattern(1)
1936        g(Var(0))
1937        """
1938        if z3_debug():
1939            _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
1940        return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
1941
1942    def num_no_patterns(self):
1943        """Return the number of no-patterns."""
1944        return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
1945
1946    def no_pattern(self, idx):
1947        """Return a no-pattern."""
1948        if z3_debug():
1949            _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
1950        return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
1951
1952    def body(self):
1953        """Return the expression being quantified.
1954
1955        >>> f = Function('f', IntSort(), IntSort())
1956        >>> x = Int('x')
1957        >>> q = ForAll(x, f(x) == 0)
1958        >>> q.body()
1959        f(Var(0)) == 0
1960        """
1961        return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
1962
1963    def num_vars(self):
1964        """Return the number of variables bounded by this quantifier.
1965
1966        >>> f = Function('f', IntSort(), IntSort(), IntSort())
1967        >>> x = Int('x')
1968        >>> y = Int('y')
1969        >>> q = ForAll([x, y], f(x, y) >= x)
1970        >>> q.num_vars()
1971        2
1972        """
1973        return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
1974
1975    def var_name(self, idx):
1976        """Return a string representing a name used when displaying the quantifier.
1977
1978        >>> f = Function('f', IntSort(), IntSort(), IntSort())
1979        >>> x = Int('x')
1980        >>> y = Int('y')
1981        >>> q = ForAll([x, y], f(x, y) >= x)
1982        >>> q.var_name(0)
1983        'x'
1984        >>> q.var_name(1)
1985        'y'
1986        """
1987        if z3_debug():
1988            _z3_assert(idx < self.num_vars(), "Invalid variable idx")
1989        return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
1990
1991    def var_sort(self, idx):
1992        """Return the sort of a bound variable.
1993
1994        >>> f = Function('f', IntSort(), RealSort(), IntSort())
1995        >>> x = Int('x')
1996        >>> y = Real('y')
1997        >>> q = ForAll([x, y], f(x, y) >= x)
1998        >>> q.var_sort(0)
1999        Int
2000        >>> q.var_sort(1)
2001        Real
2002        """
2003        if z3_debug():
2004            _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2005        return _to_sort_ref(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
2006
2007    def children(self):
2008        """Return a list containing a single element self.body()
2009
2010        >>> f = Function('f', IntSort(), IntSort())
2011        >>> x = Int('x')
2012        >>> q = ForAll(x, f(x) == 0)
2013        >>> q.children()
2014        [f(Var(0)) == 0]
2015        """
2016        return [ self.body() ]
2017
2018def is_quantifier(a):
2019    """Return `True` if `a` is a Z3 quantifier.
2020
2021    >>> f = Function('f', IntSort(), IntSort())
2022    >>> x = Int('x')
2023    >>> q = ForAll(x, f(x) == 0)
2024    >>> is_quantifier(q)
2025    True
2026    >>> is_quantifier(f(x))
2027    False
2028    """
2029    return isinstance(a, QuantifierRef)
2030
2031def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2032    if z3_debug():
2033        _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2034        _z3_assert(is_const(vs) or (len(vs) > 0 and all([ is_const(v) for v in vs])), "Invalid bounded variable(s)")
2035        _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2036        _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2037    if is_app(vs):
2038        ctx = vs.ctx
2039        vs = [vs]
2040    else:
2041        ctx = vs[0].ctx
2042    if not is_expr(body):
2043       body = BoolVal(body, ctx)
2044    num_vars = len(vs)
2045    if num_vars == 0:
2046        return body
2047    _vs = (Ast * num_vars)()
2048    for i in range(num_vars):
2049        ## TODO: Check if is constant
2050        _vs[i] = vs[i].as_ast()
2051    patterns = [ _to_pattern(p) for p in patterns ]
2052    num_pats = len(patterns)
2053    _pats = (Pattern * num_pats)()
2054    for i in range(num_pats):
2055        _pats[i] = patterns[i].ast
2056    _no_pats, num_no_pats = _to_ast_array(no_patterns)
2057    qid  = to_symbol(qid, ctx)
2058    skid = to_symbol(skid, ctx)
2059    return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2060                                                   num_vars, _vs,
2061                                                   num_pats, _pats,
2062                                                   num_no_pats, _no_pats,
2063                                                   body.as_ast()), ctx)
2064
2065def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2066    """Create a Z3 forall formula.
2067
2068    The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2069
2070    >>> f = Function('f', IntSort(), IntSort(), IntSort())
2071    >>> x = Int('x')
2072    >>> y = Int('y')
2073    >>> ForAll([x, y], f(x, y) >= x)
2074    ForAll([x, y], f(x, y) >= x)
2075    >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2076    ForAll([x, y], f(x, y) >= x)
2077    >>> ForAll([x, y], f(x, y) >= x, weight=10)
2078    ForAll([x, y], f(x, y) >= x)
2079    """
2080    return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2081
2082def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2083    """Create a Z3 exists formula.
2084
2085    The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2086
2087
2088    >>> f = Function('f', IntSort(), IntSort(), IntSort())
2089    >>> x = Int('x')
2090    >>> y = Int('y')
2091    >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2092    >>> q
2093    Exists([x, y], f(x, y) >= x)
2094    >>> is_quantifier(q)
2095    True
2096    >>> r = Tactic('nnf')(q).as_expr()
2097    >>> is_quantifier(r)
2098    False
2099    """
2100    return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2101
2102def Lambda(vs, body):
2103    """Create a Z3 lambda expression.
2104
2105    >>> f = Function('f', IntSort(), IntSort(), IntSort())
2106    >>> mem0 = Array('mem0', IntSort(), IntSort())
2107    >>> lo, hi, e, i = Ints('lo hi e i')
2108    >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2109    >>> mem1
2110    Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2111    """
2112    ctx = body.ctx
2113    if is_app(vs):
2114        vs = [vs]
2115    num_vars = len(vs)
2116    _vs = (Ast * num_vars)()
2117    for i in range(num_vars):
2118        ## TODO: Check if is constant
2119        _vs[i] = vs[i].as_ast()
2120    return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2121
2122#########################################
2123#
2124# Arithmetic
2125#
2126#########################################
2127
2128class ArithSortRef(SortRef):
2129    """Real and Integer sorts."""
2130
2131    def is_real(self):
2132        """Return `True` if `self` is of the sort Real.
2133
2134        >>> x = Real('x')
2135        >>> x.is_real()
2136        True
2137        >>> (x + 1).is_real()
2138        True
2139        >>> x = Int('x')
2140        >>> x.is_real()
2141        False
2142        """
2143        return self.kind() == Z3_REAL_SORT
2144
2145    def is_int(self):
2146        """Return `True` if `self` is of the sort Integer.
2147
2148        >>> x = Int('x')
2149        >>> x.is_int()
2150        True
2151        >>> (x + 1).is_int()
2152        True
2153        >>> x = Real('x')
2154        >>> x.is_int()
2155        False
2156        """
2157        return self.kind() == Z3_INT_SORT
2158
2159    def subsort(self, other):
2160        """Return `True` if `self` is a subsort of `other`."""
2161        return self.is_int() and is_arith_sort(other) and other.is_real()
2162
2163    def cast(self, val):
2164        """Try to cast `val` as an Integer or Real.
2165
2166        >>> IntSort().cast(10)
2167        10
2168        >>> is_int(IntSort().cast(10))
2169        True
2170        >>> is_int(10)
2171        False
2172        >>> RealSort().cast(10)
2173        10
2174        >>> is_real(RealSort().cast(10))
2175        True
2176        """
2177        if is_expr(val):
2178            if z3_debug():
2179                _z3_assert(self.ctx == val.ctx, "Context mismatch")
2180            val_s = val.sort()
2181            if self.eq(val_s):
2182                return val
2183            if val_s.is_int() and self.is_real():
2184                return ToReal(val)
2185            if val_s.is_bool() and self.is_int():
2186                return If(val, 1, 0)
2187            if val_s.is_bool() and self.is_real():
2188                return ToReal(If(val, 1, 0))
2189            if z3_debug():
2190                _z3_assert(False, "Z3 Integer/Real expression expected" )
2191        else:
2192            if self.is_int():
2193                return IntVal(val, self.ctx)
2194            if self.is_real():
2195                return RealVal(val, self.ctx)
2196            if z3_debug():
2197                _z3_assert(False, "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s" % self)
2198
2199def is_arith_sort(s):
2200    """Return `True` if s is an arithmetical sort (type).
2201
2202    >>> is_arith_sort(IntSort())
2203    True
2204    >>> is_arith_sort(RealSort())
2205    True
2206    >>> is_arith_sort(BoolSort())
2207    False
2208    >>> n = Int('x') + 1
2209    >>> is_arith_sort(n.sort())
2210    True
2211    """
2212    return isinstance(s, ArithSortRef)
2213
2214class ArithRef(ExprRef):
2215    """Integer and Real expressions."""
2216
2217    def sort(self):
2218        """Return the sort (type) of the arithmetical expression `self`.
2219
2220        >>> Int('x').sort()
2221        Int
2222        >>> (Real('x') + 1).sort()
2223        Real
2224        """
2225        return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
2226
2227    def is_int(self):
2228        """Return `True` if `self` is an integer expression.
2229
2230        >>> x = Int('x')
2231        >>> x.is_int()
2232        True
2233        >>> (x + 1).is_int()
2234        True
2235        >>> y = Real('y')
2236        >>> (x + y).is_int()
2237        False
2238        """
2239        return self.sort().is_int()
2240
2241    def is_real(self):
2242        """Return `True` if `self` is an real expression.
2243
2244        >>> x = Real('x')
2245        >>> x.is_real()
2246        True
2247        >>> (x + 1).is_real()
2248        True
2249        """
2250        return self.sort().is_real()
2251
2252    def __add__(self, other):
2253        """Create the Z3 expression `self + other`.
2254
2255        >>> x = Int('x')
2256        >>> y = Int('y')
2257        >>> x + y
2258        x + y
2259        >>> (x + y).sort()
2260        Int
2261        """
2262        a, b = _coerce_exprs(self, other)
2263        return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctx)
2264
2265    def __radd__(self, other):
2266        """Create the Z3 expression `other + self`.
2267
2268        >>> x = Int('x')
2269        >>> 10 + x
2270        10 + x
2271        """
2272        a, b = _coerce_exprs(self, other)
2273        return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctx)
2274
2275    def __mul__(self, other):
2276        """Create the Z3 expression `self * other`.
2277
2278        >>> x = Real('x')
2279        >>> y = Real('y')
2280        >>> x * y
2281        x*y
2282        >>> (x * y).sort()
2283        Real
2284        """
2285        if isinstance(other, BoolRef):
2286           return If(other, self, 0)
2287        a, b = _coerce_exprs(self, other)
2288        return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
2289
2290    def __rmul__(self, other):
2291        """Create the Z3 expression `other * self`.
2292
2293        >>> x = Real('x')
2294        >>> 10 * x
2295        10*x
2296        """
2297        a, b = _coerce_exprs(self, other)
2298        return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctx)
2299
2300    def __sub__(self, other):
2301        """Create the Z3 expression `self - other`.
2302
2303        >>> x = Int('x')
2304        >>> y = Int('y')
2305        >>> x - y
2306        x - y
2307        >>> (x - y).sort()
2308        Int
2309        """
2310        a, b = _coerce_exprs(self, other)
2311        return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctx)
2312
2313    def __rsub__(self, other):
2314        """Create the Z3 expression `other - self`.
2315
2316        >>> x = Int('x')
2317        >>> 10 - x
2318        10 - x
2319        """
2320        a, b = _coerce_exprs(self, other)
2321        return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctx)
2322
2323    def __pow__(self, other):
2324        """Create the Z3 expression `self**other` (** is the power operator).
2325
2326        >>> x = Real('x')
2327        >>> x**3
2328        x**3
2329        >>> (x**3).sort()
2330        Real
2331        >>> simplify(IntVal(2)**8)
2332        256
2333        """
2334        a, b = _coerce_exprs(self, other)
2335        return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2336
2337    def __rpow__(self, other):
2338        """Create the Z3 expression `other**self` (** is the power operator).
2339
2340        >>> x = Real('x')
2341        >>> 2**x
2342        2**x
2343        >>> (2**x).sort()
2344        Real
2345        >>> simplify(2**IntVal(8))
2346        256
2347        """
2348        a, b = _coerce_exprs(self, other)
2349        return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2350
2351    def __div__(self, other):
2352        """Create the Z3 expression `other/self`.
2353
2354        >>> x = Int('x')
2355        >>> y = Int('y')
2356        >>> x/y
2357        x/y
2358        >>> (x/y).sort()
2359        Int
2360        >>> (x/y).sexpr()
2361        '(div x y)'
2362        >>> x = Real('x')
2363        >>> y = Real('y')
2364        >>> x/y
2365        x/y
2366        >>> (x/y).sort()
2367        Real
2368        >>> (x/y).sexpr()
2369        '(/ x y)'
2370        """
2371        a, b = _coerce_exprs(self, other)
2372        return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2373
2374    def __truediv__(self, other):
2375        """Create the Z3 expression `other/self`."""
2376        return self.__div__(other)
2377
2378    def __rdiv__(self, other):
2379        """Create the Z3 expression `other/self`.
2380
2381        >>> x = Int('x')
2382        >>> 10/x
2383        10/x
2384        >>> (10/x).sexpr()
2385        '(div 10 x)'
2386        >>> x = Real('x')
2387        >>> 10/x
2388        10/x
2389        >>> (10/x).sexpr()
2390        '(/ 10.0 x)'
2391        """
2392        a, b = _coerce_exprs(self, other)
2393        return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2394
2395    def __rtruediv__(self, other):
2396        """Create the Z3 expression `other/self`."""
2397        return self.__rdiv__(other)
2398
2399    def __mod__(self, other):
2400        """Create the Z3 expression `other%self`.
2401
2402        >>> x = Int('x')
2403        >>> y = Int('y')
2404        >>> x % y
2405        x%y
2406        >>> simplify(IntVal(10) % IntVal(3))
2407        1
2408        """
2409        a, b = _coerce_exprs(self, other)
2410        if z3_debug():
2411            _z3_assert(a.is_int(), "Z3 integer expression expected")
2412        return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2413
2414    def __rmod__(self, other):
2415        """Create the Z3 expression `other%self`.
2416
2417        >>> x = Int('x')
2418        >>> 10 % x
2419        10%x
2420        """
2421        a, b = _coerce_exprs(self, other)
2422        if z3_debug():
2423            _z3_assert(a.is_int(), "Z3 integer expression expected")
2424        return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2425
2426    def __neg__(self):
2427        """Return an expression representing `-self`.
2428
2429        >>> x = Int('x')
2430        >>> -x
2431        -x
2432        >>> simplify(-(-x))
2433        x
2434        """
2435        return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
2436
2437    def __pos__(self):
2438        """Return `self`.
2439
2440        >>> x = Int('x')
2441        >>> +x
2442        x
2443        """
2444        return self
2445
2446    def __le__(self, other):
2447        """Create the Z3 expression `other <= self`.
2448
2449        >>> x, y = Ints('x y')
2450        >>> x <= y
2451        x <= y
2452        >>> y = Real('y')
2453        >>> x <= y
2454        ToReal(x) <= y
2455        """
2456        a, b = _coerce_exprs(self, other)
2457        return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2458
2459    def __lt__(self, other):
2460        """Create the Z3 expression `other < self`.
2461
2462        >>> x, y = Ints('x y')
2463        >>> x < y
2464        x < y
2465        >>> y = Real('y')
2466        >>> x < y
2467        ToReal(x) < y
2468        """
2469        a, b = _coerce_exprs(self, other)
2470        return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2471
2472    def __gt__(self, other):
2473        """Create the Z3 expression `other > self`.
2474
2475        >>> x, y = Ints('x y')
2476        >>> x > y
2477        x > y
2478        >>> y = Real('y')
2479        >>> x > y
2480        ToReal(x) > y
2481        """
2482        a, b = _coerce_exprs(self, other)
2483        return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2484
2485    def __ge__(self, other):
2486        """Create the Z3 expression `other >= self`.
2487
2488        >>> x, y = Ints('x y')
2489        >>> x >= y
2490        x >= y
2491        >>> y = Real('y')
2492        >>> x >= y
2493        ToReal(x) >= y
2494        """
2495        a, b = _coerce_exprs(self, other)
2496        return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2497
2498def is_arith(a):
2499    """Return `True` if `a` is an arithmetical expression.
2500
2501    >>> x = Int('x')
2502    >>> is_arith(x)
2503    True
2504    >>> is_arith(x + 1)
2505    True
2506    >>> is_arith(1)
2507    False
2508    >>> is_arith(IntVal(1))
2509    True
2510    >>> y = Real('y')
2511    >>> is_arith(y)
2512    True
2513    >>> is_arith(y + 1)
2514    True
2515    """
2516    return isinstance(a, ArithRef)
2517
2518def is_int(a):
2519    """Return `True` if `a` is an integer expression.
2520
2521    >>> x = Int('x')
2522    >>> is_int(x + 1)
2523    True
2524    >>> is_int(1)
2525    False
2526    >>> is_int(IntVal(1))
2527    True
2528    >>> y = Real('y')
2529    >>> is_int(y)
2530    False
2531    >>> is_int(y + 1)
2532    False
2533    """
2534    return is_arith(a) and a.is_int()
2535
2536def is_real(a):
2537    """Return `True` if `a` is a real expression.
2538
2539    >>> x = Int('x')
2540    >>> is_real(x + 1)
2541    False
2542    >>> y = Real('y')
2543    >>> is_real(y)
2544    True
2545    >>> is_real(y + 1)
2546    True
2547    >>> is_real(1)
2548    False
2549    >>> is_real(RealVal(1))
2550    True
2551    """
2552    return is_arith(a) and a.is_real()
2553
2554def _is_numeral(ctx, a):
2555    return Z3_is_numeral_ast(ctx.ref(), a)
2556
2557def _is_algebraic(ctx, a):
2558    return Z3_is_algebraic_number(ctx.ref(), a)
2559
2560def is_int_value(a):
2561    """Return `True` if `a` is an integer value of sort Int.
2562
2563    >>> is_int_value(IntVal(1))
2564    True
2565    >>> is_int_value(1)
2566    False
2567    >>> is_int_value(Int('x'))
2568    False
2569    >>> n = Int('x') + 1
2570    >>> n
2571    x + 1
2572    >>> n.arg(1)
2573    1
2574    >>> is_int_value(n.arg(1))
2575    True
2576    >>> is_int_value(RealVal("1/3"))
2577    False
2578    >>> is_int_value(RealVal(1))
2579    False
2580    """
2581    return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2582
2583def is_rational_value(a):
2584    """Return `True` if `a` is rational value of sort Real.
2585
2586    >>> is_rational_value(RealVal(1))
2587    True
2588    >>> is_rational_value(RealVal("3/5"))
2589    True
2590    >>> is_rational_value(IntVal(1))
2591    False
2592    >>> is_rational_value(1)
2593    False
2594    >>> n = Real('x') + 1
2595    >>> n.arg(1)
2596    1
2597    >>> is_rational_value(n.arg(1))
2598    True
2599    >>> is_rational_value(Real('x'))
2600    False
2601    """
2602    return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2603
2604def is_algebraic_value(a):
2605    """Return `True` if `a` is an algebraic value of sort Real.
2606
2607    >>> is_algebraic_value(RealVal("3/5"))
2608    False
2609    >>> n = simplify(Sqrt(2))
2610    >>> n
2611    1.4142135623?
2612    >>> is_algebraic_value(n)
2613    True
2614    """
2615    return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2616
2617def is_add(a):
2618    """Return `True` if `a` is an expression of the form b + c.
2619
2620    >>> x, y = Ints('x y')
2621    >>> is_add(x + y)
2622    True
2623    >>> is_add(x - y)
2624    False
2625    """
2626    return is_app_of(a, Z3_OP_ADD)
2627
2628def is_mul(a):
2629    """Return `True` if `a` is an expression of the form b * c.
2630
2631    >>> x, y = Ints('x y')
2632    >>> is_mul(x * y)
2633    True
2634    >>> is_mul(x - y)
2635    False
2636    """
2637    return is_app_of(a, Z3_OP_MUL)
2638
2639def is_sub(a):
2640    """Return `True` if `a` is an expression of the form b - c.
2641
2642    >>> x, y = Ints('x y')
2643    >>> is_sub(x - y)
2644    True
2645    >>> is_sub(x + y)
2646    False
2647    """
2648    return is_app_of(a, Z3_OP_SUB)
2649
2650def is_div(a):
2651    """Return `True` if `a` is an expression of the form b / c.
2652
2653    >>> x, y = Reals('x y')
2654    >>> is_div(x / y)
2655    True
2656    >>> is_div(x + y)
2657    False
2658    >>> x, y = Ints('x y')
2659    >>> is_div(x / y)
2660    False
2661    >>> is_idiv(x / y)
2662    True
2663    """
2664    return is_app_of(a, Z3_OP_DIV)
2665
2666def is_idiv(a):
2667    """Return `True` if `a` is an expression of the form b div c.
2668
2669    >>> x, y = Ints('x y')
2670    >>> is_idiv(x / y)
2671    True
2672    >>> is_idiv(x + y)
2673    False
2674    """
2675    return is_app_of(a, Z3_OP_IDIV)
2676
2677def is_mod(a):
2678    """Return `True` if `a` is an expression of the form b % c.
2679
2680    >>> x, y = Ints('x y')
2681    >>> is_mod(x % y)
2682    True
2683    >>> is_mod(x + y)
2684    False
2685    """
2686    return is_app_of(a, Z3_OP_MOD)
2687
2688def is_le(a):
2689    """Return `True` if `a` is an expression of the form b <= c.
2690
2691    >>> x, y = Ints('x y')
2692    >>> is_le(x <= y)
2693    True
2694    >>> is_le(x < y)
2695    False
2696    """
2697    return is_app_of(a, Z3_OP_LE)
2698
2699def is_lt(a):
2700    """Return `True` if `a` is an expression of the form b < c.
2701
2702    >>> x, y = Ints('x y')
2703    >>> is_lt(x < y)
2704    True
2705    >>> is_lt(x == y)
2706    False
2707    """
2708    return is_app_of(a, Z3_OP_LT)
2709
2710def is_ge(a):
2711    """Return `True` if `a` is an expression of the form b >= c.
2712
2713    >>> x, y = Ints('x y')
2714    >>> is_ge(x >= y)
2715    True
2716    >>> is_ge(x == y)
2717    False
2718    """
2719    return is_app_of(a, Z3_OP_GE)
2720
2721def is_gt(a):
2722    """Return `True` if `a` is an expression of the form b > c.
2723
2724    >>> x, y = Ints('x y')
2725    >>> is_gt(x > y)
2726    True
2727    >>> is_gt(x == y)
2728    False
2729    """
2730    return is_app_of(a, Z3_OP_GT)
2731
2732def is_is_int(a):
2733    """Return `True` if `a` is an expression of the form IsInt(b).
2734
2735    >>> x = Real('x')
2736    >>> is_is_int(IsInt(x))
2737    True
2738    >>> is_is_int(x)
2739    False
2740    """
2741    return is_app_of(a, Z3_OP_IS_INT)
2742
2743def is_to_real(a):
2744    """Return `True` if `a` is an expression of the form ToReal(b).
2745
2746    >>> x = Int('x')
2747    >>> n = ToReal(x)
2748    >>> n
2749    ToReal(x)
2750    >>> is_to_real(n)
2751    True
2752    >>> is_to_real(x)
2753    False
2754    """
2755    return is_app_of(a, Z3_OP_TO_REAL)
2756
2757def is_to_int(a):
2758    """Return `True` if `a` is an expression of the form ToInt(b).
2759
2760    >>> x = Real('x')
2761    >>> n = ToInt(x)
2762    >>> n
2763    ToInt(x)
2764    >>> is_to_int(n)
2765    True
2766    >>> is_to_int(x)
2767    False
2768    """
2769    return is_app_of(a, Z3_OP_TO_INT)
2770
2771class IntNumRef(ArithRef):
2772    """Integer values."""
2773
2774    def as_long(self):
2775        """Return a Z3 integer numeral as a Python long (bignum) numeral.
2776
2777        >>> v = IntVal(1)
2778        >>> v + 1
2779        1 + 1
2780        >>> v.as_long() + 1
2781        2
2782        """
2783        if z3_debug():
2784            _z3_assert(self.is_int(), "Integer value expected")
2785        return int(self.as_string())
2786
2787    def as_string(self):
2788        """Return a Z3 integer numeral as a Python string.
2789        >>> v = IntVal(100)
2790        >>> v.as_string()
2791        '100'
2792        """
2793        return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
2794
2795    def as_binary_string(self):
2796        """Return a Z3 integer numeral as a Python binary string.
2797        >>> v = IntVal(10)
2798        >>> v.as_binary_string()
2799        '1010'
2800        """
2801        return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
2802
2803class RatNumRef(ArithRef):
2804    """Rational values."""
2805
2806    def numerator(self):
2807        """ Return the numerator of a Z3 rational numeral.
2808
2809        >>> is_rational_value(RealVal("3/5"))
2810        True
2811        >>> n = RealVal("3/5")
2812        >>> n.numerator()
2813        3
2814        >>> is_rational_value(Q(3,5))
2815        True
2816        >>> Q(3,5).numerator()
2817        3
2818        """
2819        return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
2820
2821    def denominator(self):
2822        """ Return the denominator of a Z3 rational numeral.
2823
2824        >>> is_rational_value(Q(3,5))
2825        True
2826        >>> n = Q(3,5)
2827        >>> n.denominator()
2828        5
2829        """
2830        return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
2831
2832    def numerator_as_long(self):
2833        """ Return the numerator as a Python long.
2834
2835        >>> v = RealVal(10000000000)
2836        >>> v
2837        10000000000
2838        >>> v + 1
2839        10000000000 + 1
2840        >>> v.numerator_as_long() + 1 == 10000000001
2841        True
2842        """
2843        return self.numerator().as_long()
2844
2845    def denominator_as_long(self):
2846        """ Return the denominator as a Python long.
2847
2848        >>> v = RealVal("1/3")
2849        >>> v
2850        1/3
2851        >>> v.denominator_as_long()
2852        3
2853        """
2854        return self.denominator().as_long()
2855
2856    def is_int(self):
2857        return False
2858
2859    def is_real(self):
2860        return True
2861
2862    def is_int_value(self):
2863        return self.denominator().is_int() and self.denominator_as_long() == 1
2864
2865    def as_long(self):
2866        _z3_assert(self.is_int_value(), "Expected integer fraction")
2867        return self.numerator_as_long()
2868
2869    def as_decimal(self, prec):
2870        """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
2871
2872        >>> v = RealVal("1/5")
2873        >>> v.as_decimal(3)
2874        '0.2'
2875        >>> v = RealVal("1/3")
2876        >>> v.as_decimal(3)
2877        '0.333?'
2878        """
2879        return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
2880
2881    def as_string(self):
2882        """Return a Z3 rational numeral as a Python string.
2883
2884        >>> v = Q(3,6)
2885        >>> v.as_string()
2886        '1/2'
2887        """
2888        return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
2889
2890    def as_fraction(self):
2891        """Return a Z3 rational as a Python Fraction object.
2892
2893        >>> v = RealVal("1/5")
2894        >>> v.as_fraction()
2895        Fraction(1, 5)
2896        """
2897        return Fraction(self.numerator_as_long(), self.denominator_as_long())
2898
2899class AlgebraicNumRef(ArithRef):
2900    """Algebraic irrational values."""
2901
2902    def approx(self, precision=10):
2903        """Return a Z3 rational number that approximates the algebraic number `self`.
2904        The result `r` is such that |r - self| <= 1/10^precision
2905
2906        >>> x = simplify(Sqrt(2))
2907        >>> x.approx(20)
2908        6838717160008073720548335/4835703278458516698824704
2909        >>> x.approx(5)
2910        2965821/2097152
2911        """
2912        return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
2913    def as_decimal(self, prec):
2914        """Return a string representation of the algebraic number `self` in decimal notation using `prec` decimal places
2915
2916        >>> x = simplify(Sqrt(2))
2917        >>> x.as_decimal(10)
2918        '1.4142135623?'
2919        >>> x.as_decimal(20)
2920        '1.41421356237309504880?'
2921        """
2922        return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
2923
2924    def poly(self):
2925        return AstVector(Z3_algebraic_get_poly(self.ctx_ref(), self.as_ast()), self.ctx)
2926
2927    def index(self):
2928        return Z3_algebraic_get_i(self.ctx_ref(), self.as_ast())
2929
2930def _py2expr(a, ctx=None):
2931    if isinstance(a, bool):
2932        return BoolVal(a, ctx)
2933    if _is_int(a):
2934        return IntVal(a, ctx)
2935    if isinstance(a, float):
2936        return RealVal(a, ctx)
2937    if is_expr(a):
2938        return a
2939    if z3_debug():
2940        _z3_assert(False, "Python bool, int, long or float expected")
2941
2942def IntSort(ctx=None):
2943    """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
2944
2945    >>> IntSort()
2946    Int
2947    >>> x = Const('x', IntSort())
2948    >>> is_int(x)
2949    True
2950    >>> x.sort() == IntSort()
2951    True
2952    >>> x.sort() == BoolSort()
2953    False
2954    """
2955    ctx = _get_ctx(ctx)
2956    return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
2957
2958def RealSort(ctx=None):
2959    """Return the real sort in the given context. If `ctx=None`, then the global context is used.
2960
2961    >>> RealSort()
2962    Real
2963    >>> x = Const('x', RealSort())
2964    >>> is_real(x)
2965    True
2966    >>> is_int(x)
2967    False
2968    >>> x.sort() == RealSort()
2969    True
2970    """
2971    ctx = _get_ctx(ctx)
2972    return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
2973
2974def _to_int_str(val):
2975    if isinstance(val, float):
2976        return str(int(val))
2977    elif isinstance(val, bool):
2978        if val:
2979            return "1"
2980        else:
2981            return "0"
2982    elif _is_int(val):
2983        return str(val)
2984    elif isinstance(val, str):
2985        return val
2986    if z3_debug():
2987        _z3_assert(False, "Python value cannot be used as a Z3 integer")
2988
2989def IntVal(val, ctx=None):
2990    """Return a Z3 integer value. If `ctx=None`, then the global context is used.
2991
2992    >>> IntVal(1)
2993    1
2994    >>> IntVal("100")
2995    100
2996    """
2997    ctx = _get_ctx(ctx)
2998    return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
2999
3000def RealVal(val, ctx=None):
3001    """Return a Z3 real value.
3002
3003    `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3004    If `ctx=None`, then the global context is used.
3005
3006    >>> RealVal(1)
3007    1
3008    >>> RealVal(1).sort()
3009    Real
3010    >>> RealVal("3/5")
3011    3/5
3012    >>> RealVal("1.5")
3013    3/2
3014    """
3015    ctx = _get_ctx(ctx)
3016    return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3017
3018def RatVal(a, b, ctx=None):
3019    """Return a Z3 rational a/b.
3020
3021    If `ctx=None`, then the global context is used.
3022
3023    >>> RatVal(3,5)
3024    3/5
3025    >>> RatVal(3,5).sort()
3026    Real
3027    """
3028    if z3_debug():
3029        _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3030        _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3031    return simplify(RealVal(a, ctx)/RealVal(b, ctx))
3032
3033def Q(a, b, ctx=None):
3034    """Return a Z3 rational a/b.
3035
3036    If `ctx=None`, then the global context is used.
3037
3038    >>> Q(3,5)
3039    3/5
3040    >>> Q(3,5).sort()
3041    Real
3042    """
3043    return simplify(RatVal(a, b))
3044
3045def Int(name, ctx=None):
3046    """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3047
3048    >>> x = Int('x')
3049    >>> is_int(x)
3050    True
3051    >>> is_int(x + 1)
3052    True
3053    """
3054    ctx = _get_ctx(ctx)
3055    return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3056
3057def Ints(names, ctx=None):
3058    """Return a tuple of Integer constants.
3059
3060    >>> x, y, z = Ints('x y z')
3061    >>> Sum(x, y, z)
3062    x + y + z
3063    """
3064    ctx = _get_ctx(ctx)
3065    if isinstance(names, str):
3066        names = names.split(" ")
3067    return [Int(name, ctx) for name in names]
3068
3069def IntVector(prefix, sz, ctx=None):
3070    """Return a list of integer constants of size `sz`.
3071
3072    >>> X = IntVector('x', 3)
3073    >>> X
3074    [x__0, x__1, x__2]
3075    >>> Sum(X)
3076    x__0 + x__1 + x__2
3077    """
3078    ctx = _get_ctx(ctx)
3079    return [ Int('%s__%s' % (prefix, i), ctx) for i in range(sz) ]
3080
3081def FreshInt(prefix='x', ctx=None):
3082    """Return a fresh integer constant in the given context using the given prefix.
3083
3084    >>> x = FreshInt()
3085    >>> y = FreshInt()
3086    >>> eq(x, y)
3087    False
3088    >>> x.sort()
3089    Int
3090    """
3091    ctx = _get_ctx(ctx)
3092    return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3093
3094def Real(name, ctx=None):
3095    """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3096
3097    >>> x = Real('x')
3098    >>> is_real(x)
3099    True
3100    >>> is_real(x + 1)
3101    True
3102    """
3103    ctx = _get_ctx(ctx)
3104    return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3105
3106def Reals(names, ctx=None):
3107    """Return a tuple of real constants.
3108
3109    >>> x, y, z = Reals('x y z')
3110    >>> Sum(x, y, z)
3111    x + y + z
3112    >>> Sum(x, y, z).sort()
3113    Real
3114    """
3115    ctx = _get_ctx(ctx)
3116    if isinstance(names, str):
3117        names = names.split(" ")
3118    return [Real(name, ctx) for name in names]
3119
3120def RealVector(prefix, sz, ctx=None):
3121    """Return a list of real constants of size `sz`.
3122
3123    >>> X = RealVector('x', 3)
3124    >>> X
3125    [x__0, x__1, x__2]
3126    >>> Sum(X)
3127    x__0 + x__1 + x__2
3128    >>> Sum(X).sort()
3129    Real
3130    """
3131    ctx = _get_ctx(ctx)
3132    return [ Real('%s__%s' % (prefix, i), ctx) for i in range(sz) ]
3133
3134def FreshReal(prefix='b', ctx=None):
3135    """Return a fresh real constant in the given context using the given prefix.
3136
3137    >>> x = FreshReal()
3138    >>> y = FreshReal()
3139    >>> eq(x, y)
3140    False
3141    >>> x.sort()
3142    Real
3143    """
3144    ctx = _get_ctx(ctx)
3145    return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3146
3147def ToReal(a):
3148    """ Return the Z3 expression ToReal(a).
3149
3150    >>> x = Int('x')
3151    >>> x.sort()
3152    Int
3153    >>> n = ToReal(x)
3154    >>> n
3155    ToReal(x)
3156    >>> n.sort()
3157    Real
3158    """
3159    if z3_debug():
3160        _z3_assert(a.is_int(), "Z3 integer expression expected.")
3161    ctx = a.ctx
3162    return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3163
3164def ToInt(a):
3165    """ Return the Z3 expression ToInt(a).
3166
3167    >>> x = Real('x')
3168    >>> x.sort()
3169    Real
3170    >>> n = ToInt(x)
3171    >>> n
3172    ToInt(x)
3173    >>> n.sort()
3174    Int
3175    """
3176    if z3_debug():
3177        _z3_assert(a.is_real(), "Z3 real expression expected.")
3178    ctx = a.ctx
3179    return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3180
3181def IsInt(a):
3182    """ Return the Z3 predicate IsInt(a).
3183
3184    >>> x = Real('x')
3185    >>> IsInt(x + "1/2")
3186    IsInt(x + 1/2)
3187    >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3188    [x = 1/2]
3189    >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3190    no solution
3191    """
3192    if z3_debug():
3193        _z3_assert(a.is_real(), "Z3 real expression expected.")
3194    ctx = a.ctx
3195    return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3196
3197def Sqrt(a, ctx=None):
3198    """ Return a Z3 expression which represents the square root of a.
3199
3200    >>> x = Real('x')
3201    >>> Sqrt(x)
3202    x**(1/2)
3203    """
3204    if not is_expr(a):
3205        ctx = _get_ctx(ctx)
3206        a = RealVal(a, ctx)
3207    return a ** "1/2"
3208
3209def Cbrt(a, ctx=None):
3210    """ Return a Z3 expression which represents the cubic root of a.
3211
3212    >>> x = Real('x')
3213    >>> Cbrt(x)
3214    x**(1/3)
3215    """
3216    if not is_expr(a):
3217        ctx = _get_ctx(ctx)
3218        a = RealVal(a, ctx)
3219    return a ** "1/3"
3220
3221#########################################
3222#
3223# Bit-Vectors
3224#
3225#########################################
3226
3227class BitVecSortRef(SortRef):
3228    """Bit-vector sort."""
3229
3230    def size(self):
3231        """Return the size (number of bits) of the bit-vector sort `self`.
3232
3233        >>> b = BitVecSort(32)
3234        >>> b.size()
3235        32
3236        """
3237        return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
3238
3239    def subsort(self, other):
3240        return is_bv_sort(other) and self.size() < other.size()
3241
3242    def cast(self, val):
3243        """Try to cast `val` as a Bit-Vector.
3244
3245        >>> b = BitVecSort(32)
3246        >>> b.cast(10)
3247        10
3248        >>> b.cast(10).sexpr()
3249        '#x0000000a'
3250        """
3251        if is_expr(val):
3252            if z3_debug():
3253                _z3_assert(self.ctx == val.ctx, "Context mismatch")
3254            # Idea: use sign_extend if sort of val is a bitvector of smaller size
3255            return val
3256        else:
3257            return BitVecVal(val, self)
3258
3259def is_bv_sort(s):
3260    """Return True if `s` is a Z3 bit-vector sort.
3261
3262    >>> is_bv_sort(BitVecSort(32))
3263    True
3264    >>> is_bv_sort(IntSort())
3265    False
3266    """
3267    return isinstance(s, BitVecSortRef)
3268
3269class BitVecRef(ExprRef):
3270    """Bit-vector expressions."""
3271
3272    def sort(self):
3273        """Return the sort of the bit-vector expression `self`.
3274
3275        >>> x = BitVec('x', 32)
3276        >>> x.sort()
3277        BitVec(32)
3278        >>> x.sort() == BitVecSort(32)
3279        True
3280        """
3281        return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3282
3283    def size(self):
3284        """Return the number of bits of the bit-vector expression `self`.
3285
3286        >>> x = BitVec('x', 32)
3287        >>> (x + 1).size()
3288        32
3289        >>> Concat(x, x).size()
3290        64
3291        """
3292        return self.sort().size()
3293
3294    def __add__(self, other):
3295        """Create the Z3 expression `self + other`.
3296
3297        >>> x = BitVec('x', 32)
3298        >>> y = BitVec('y', 32)
3299        >>> x + y
3300        x + y
3301        >>> (x + y).sort()
3302        BitVec(32)
3303        """
3304        a, b = _coerce_exprs(self, other)
3305        return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3306
3307    def __radd__(self, other):
3308        """Create the Z3 expression `other + self`.
3309
3310        >>> x = BitVec('x', 32)
3311        >>> 10 + x
3312        10 + x
3313        """
3314        a, b = _coerce_exprs(self, other)
3315        return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3316
3317    def __mul__(self, other):
3318        """Create the Z3 expression `self * other`.
3319
3320        >>> x = BitVec('x', 32)
3321        >>> y = BitVec('y', 32)
3322        >>> x * y
3323        x*y
3324        >>> (x * y).sort()
3325        BitVec(32)
3326        """
3327        a, b = _coerce_exprs(self, other)
3328        return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3329
3330    def __rmul__(self, other):
3331        """Create the Z3 expression `other * self`.
3332
3333        >>> x = BitVec('x', 32)
3334        >>> 10 * x
3335        10*x
3336        """
3337        a, b = _coerce_exprs(self, other)
3338        return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3339
3340    def __sub__(self, other):
3341        """Create the Z3 expression `self - other`.
3342
3343        >>> x = BitVec('x', 32)
3344        >>> y = BitVec('y', 32)
3345        >>> x - y
3346        x - y
3347        >>> (x - y).sort()
3348        BitVec(32)
3349        """
3350        a, b = _coerce_exprs(self, other)
3351        return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3352
3353    def __rsub__(self, other):
3354        """Create the Z3 expression `other - self`.
3355
3356        >>> x = BitVec('x', 32)
3357        >>> 10 - x
3358        10 - x
3359        """
3360        a, b = _coerce_exprs(self, other)
3361        return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3362
3363    def __or__(self, other):
3364        """Create the Z3 expression bitwise-or `self | other`.
3365
3366        >>> x = BitVec('x', 32)
3367        >>> y = BitVec('y', 32)
3368        >>> x | y
3369        x | y
3370        >>> (x | y).sort()
3371        BitVec(32)
3372        """
3373        a, b = _coerce_exprs(self, other)
3374        return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3375
3376    def __ror__(self, other):
3377        """Create the Z3 expression bitwise-or `other | self`.
3378
3379        >>> x = BitVec('x', 32)
3380        >>> 10 | x
3381        10 | x
3382        """
3383        a, b = _coerce_exprs(self, other)
3384        return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3385
3386    def __and__(self, other):
3387        """Create the Z3 expression bitwise-and `self & other`.
3388
3389        >>> x = BitVec('x', 32)
3390        >>> y = BitVec('y', 32)
3391        >>> x & y
3392        x & y
3393        >>> (x & y).sort()
3394        BitVec(32)
3395        """
3396        a, b = _coerce_exprs(self, other)
3397        return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3398
3399    def __rand__(self, other):
3400        """Create the Z3 expression bitwise-or `other & self`.
3401
3402        >>> x = BitVec('x', 32)
3403        >>> 10 & x
3404        10 & x
3405        """
3406        a, b = _coerce_exprs(self, other)
3407        return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3408
3409    def __xor__(self, other):
3410        """Create the Z3 expression bitwise-xor `self ^ other`.
3411
3412        >>> x = BitVec('x', 32)
3413        >>> y = BitVec('y', 32)
3414        >>> x ^ y
3415        x ^ y
3416        >>> (x ^ y).sort()
3417        BitVec(32)
3418        """
3419        a, b = _coerce_exprs(self, other)
3420        return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3421
3422    def __rxor__(self, other):
3423        """Create the Z3 expression bitwise-xor `other ^ self`.
3424
3425        >>> x = BitVec('x', 32)
3426        >>> 10 ^ x
3427        10 ^ x
3428        """
3429        a, b = _coerce_exprs(self, other)
3430        return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3431
3432    def __pos__(self):
3433        """Return `self`.
3434
3435        >>> x = BitVec('x', 32)
3436        >>> +x
3437        x
3438        """
3439        return self
3440
3441    def __neg__(self):
3442        """Return an expression representing `-self`.
3443
3444        >>> x = BitVec('x', 32)
3445        >>> -x
3446        -x
3447        >>> simplify(-(-x))
3448        x
3449        """
3450        return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3451
3452    def __invert__(self):
3453        """Create the Z3 expression bitwise-not `~self`.
3454
3455        >>> x = BitVec('x', 32)
3456        >>> ~x
3457        ~x
3458        >>> simplify(~(~x))
3459        x
3460        """
3461        return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3462
3463    def __div__(self, other):
3464        """Create the Z3 expression (signed) division `self / other`.
3465
3466        Use the function UDiv() for unsigned division.
3467
3468        >>> x = BitVec('x', 32)
3469        >>> y = BitVec('y', 32)
3470        >>> x / y
3471        x/y
3472        >>> (x / y).sort()
3473        BitVec(32)
3474        >>> (x / y).sexpr()
3475        '(bvsdiv x y)'
3476        >>> UDiv(x, y).sexpr()
3477        '(bvudiv x y)'
3478        """
3479        a, b = _coerce_exprs(self, other)
3480        return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3481
3482    def __truediv__(self, other):
3483        """Create the Z3 expression (signed) division `self / other`."""
3484        return self.__div__(other)
3485
3486    def __rdiv__(self, other):
3487        """Create the Z3 expression (signed) division `other / self`.
3488
3489        Use the function UDiv() for unsigned division.
3490
3491        >>> x = BitVec('x', 32)
3492        >>> 10 / x
3493        10/x
3494        >>> (10 / x).sexpr()
3495        '(bvsdiv #x0000000a x)'
3496        >>> UDiv(10, x).sexpr()
3497        '(bvudiv #x0000000a x)'
3498        """
3499        a, b = _coerce_exprs(self, other)
3500        return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3501
3502    def __rtruediv__(self, other):
3503        """Create the Z3 expression (signed) division `other / self`."""
3504        return self.__rdiv__(other)
3505
3506    def __mod__(self, other):
3507        """Create the Z3 expression (signed) mod `self % other`.
3508
3509        Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3510
3511        >>> x = BitVec('x', 32)
3512        >>> y = BitVec('y', 32)
3513        >>> x % y
3514        x%y
3515        >>> (x % y).sort()
3516        BitVec(32)
3517        >>> (x % y).sexpr()
3518        '(bvsmod x y)'
3519        >>> URem(x, y).sexpr()
3520        '(bvurem x y)'
3521        >>> SRem(x, y).sexpr()
3522        '(bvsrem x y)'
3523        """
3524        a, b = _coerce_exprs(self, other)
3525        return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3526
3527    def __rmod__(self, other):
3528        """Create the Z3 expression (signed) mod `other % self`.
3529
3530        Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3531
3532        >>> x = BitVec('x', 32)
3533        >>> 10 % x
3534        10%x
3535        >>> (10 % x).sexpr()
3536        '(bvsmod #x0000000a x)'
3537        >>> URem(10, x).sexpr()
3538        '(bvurem #x0000000a x)'
3539        >>> SRem(10, x).sexpr()
3540        '(bvsrem #x0000000a x)'
3541        """
3542        a, b = _coerce_exprs(self, other)
3543        return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3544
3545    def __le__(self, other):
3546        """Create the Z3 expression (signed) `other <= self`.
3547
3548        Use the function ULE() for unsigned less than or equal to.
3549
3550        >>> x, y = BitVecs('x y', 32)
3551        >>> x <= y
3552        x <= y
3553        >>> (x <= y).sexpr()
3554        '(bvsle x y)'
3555        >>> ULE(x, y).sexpr()
3556        '(bvule x y)'
3557        """
3558        a, b = _coerce_exprs(self, other)
3559        return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3560
3561    def __lt__(self, other):
3562        """Create the Z3 expression (signed) `other < self`.
3563
3564        Use the function ULT() for unsigned less than.
3565
3566        >>> x, y = BitVecs('x y', 32)
3567        >>> x < y
3568        x < y
3569        >>> (x < y).sexpr()
3570        '(bvslt x y)'
3571        >>> ULT(x, y).sexpr()
3572        '(bvult x y)'
3573        """
3574        a, b = _coerce_exprs(self, other)
3575        return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3576
3577    def __gt__(self, other):
3578        """Create the Z3 expression (signed) `other > self`.
3579
3580        Use the function UGT() for unsigned greater than.
3581
3582        >>> x, y = BitVecs('x y', 32)
3583        >>> x > y
3584        x > y
3585        >>> (x > y).sexpr()
3586        '(bvsgt x y)'
3587        >>> UGT(x, y).sexpr()
3588        '(bvugt x y)'
3589        """
3590        a, b = _coerce_exprs(self, other)
3591        return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3592
3593    def __ge__(self, other):
3594        """Create the Z3 expression (signed) `other >= self`.
3595
3596        Use the function UGE() for unsigned greater than or equal to.
3597
3598        >>> x, y = BitVecs('x y', 32)
3599        >>> x >= y
3600        x >= y
3601        >>> (x >= y).sexpr()
3602        '(bvsge x y)'
3603        >>> UGE(x, y).sexpr()
3604        '(bvuge x y)'
3605        """
3606        a, b = _coerce_exprs(self, other)
3607        return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3608
3609    def __rshift__(self, other):
3610        """Create the Z3 expression (arithmetical) right shift `self >> other`
3611
3612        Use the function LShR() for the right logical shift
3613
3614        >>> x, y = BitVecs('x y', 32)
3615        >>> x >> y
3616        x >> y
3617        >>> (x >> y).sexpr()
3618        '(bvashr x y)'
3619        >>> LShR(x, y).sexpr()
3620        '(bvlshr x y)'
3621        >>> BitVecVal(4, 3)
3622        4
3623        >>> BitVecVal(4, 3).as_signed_long()
3624        -4
3625        >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3626        -2
3627        >>> simplify(BitVecVal(4, 3) >> 1)
3628        6
3629        >>> simplify(LShR(BitVecVal(4, 3), 1))
3630        2
3631        >>> simplify(BitVecVal(2, 3) >> 1)
3632        1
3633        >>> simplify(LShR(BitVecVal(2, 3), 1))
3634        1
3635        """
3636        a, b = _coerce_exprs(self, other)
3637        return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3638
3639    def __lshift__(self, other):
3640        """Create the Z3 expression left shift `self << other`
3641
3642        >>> x, y = BitVecs('x y', 32)
3643        >>> x << y
3644        x << y
3645        >>> (x << y).sexpr()
3646        '(bvshl x y)'
3647        >>> simplify(BitVecVal(2, 3) << 1)
3648        4
3649        """
3650        a, b = _coerce_exprs(self, other)
3651        return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3652
3653    def __rrshift__(self, other):
3654        """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
3655
3656        Use the function LShR() for the right logical shift
3657
3658        >>> x = BitVec('x', 32)
3659        >>> 10 >> x
3660        10 >> x
3661        >>> (10 >> x).sexpr()
3662        '(bvashr #x0000000a x)'
3663        """
3664        a, b = _coerce_exprs(self, other)
3665        return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3666
3667    def __rlshift__(self, other):
3668        """Create the Z3 expression left shift `other << self`.
3669
3670        Use the function LShR() for the right logical shift
3671
3672        >>> x = BitVec('x', 32)
3673        >>> 10 << x
3674        10 << x
3675        >>> (10 << x).sexpr()
3676        '(bvshl #x0000000a x)'
3677        """
3678        a, b = _coerce_exprs(self, other)
3679        return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3680
3681class BitVecNumRef(BitVecRef):
3682    """Bit-vector values."""
3683
3684    def as_long(self):
3685        """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3686
3687        >>> v = BitVecVal(0xbadc0de, 32)
3688        >>> v
3689        195936478
3690        >>> print("0x%.8x" % v.as_long())
3691        0x0badc0de
3692        """
3693        return int(self.as_string())
3694
3695    def as_signed_long(self):
3696        """Return a Z3 bit-vector numeral as a Python long (bignum) numeral. The most significant bit is assumed to be the sign.
3697
3698        >>> BitVecVal(4, 3).as_signed_long()
3699        -4
3700        >>> BitVecVal(7, 3).as_signed_long()
3701        -1
3702        >>> BitVecVal(3, 3).as_signed_long()
3703        3
3704        >>> BitVecVal(2**32 - 1, 32).as_signed_long()
3705        -1
3706        >>> BitVecVal(2**64 - 1, 64).as_signed_long()
3707        -1
3708        """
3709        sz = self.size()
3710        val = self.as_long()
3711        if val >= 2**(sz - 1):
3712            val = val - 2**sz
3713        if val < -2**(sz - 1):
3714            val = val + 2**sz
3715        return int(val)
3716
3717    def as_string(self):
3718        return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3719
3720    def as_binary_string(self):
3721        return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3722
3723
3724def is_bv(a):
3725    """Return `True` if `a` is a Z3 bit-vector expression.
3726
3727    >>> b = BitVec('b', 32)
3728    >>> is_bv(b)
3729    True
3730    >>> is_bv(b + 10)
3731    True
3732    >>> is_bv(Int('x'))
3733    False
3734    """
3735    return isinstance(a, BitVecRef)
3736
3737def is_bv_value(a):
3738    """Return `True` if `a` is a Z3 bit-vector numeral value.
3739
3740    >>> b = BitVec('b', 32)
3741    >>> is_bv_value(b)
3742    False
3743    >>> b = BitVecVal(10, 32)
3744    >>> b
3745    10
3746    >>> is_bv_value(b)
3747    True
3748    """
3749    return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
3750
3751def BV2Int(a, is_signed=False):
3752    """Return the Z3 expression BV2Int(a).
3753
3754    >>> b = BitVec('b', 3)
3755    >>> BV2Int(b).sort()
3756    Int
3757    >>> x = Int('x')
3758    >>> x > BV2Int(b)
3759    x > BV2Int(b)
3760    >>> x > BV2Int(b, is_signed=False)
3761    x > BV2Int(b)
3762    >>> x > BV2Int(b, is_signed=True)
3763    x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
3764    >>> solve(x > BV2Int(b), b == 1, x < 3)
3765    [x = 2, b = 1]
3766    """
3767    if z3_debug():
3768        _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
3769    ctx = a.ctx
3770    ## investigate problem with bv2int
3771    return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
3772
3773def Int2BV(a, num_bits):
3774    """Return the z3 expression Int2BV(a, num_bits).
3775    It is a bit-vector of width num_bits and represents the
3776    modulo of a by 2^num_bits
3777    """
3778    ctx = a.ctx
3779    return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
3780
3781def BitVecSort(sz, ctx=None):
3782    """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
3783
3784    >>> Byte = BitVecSort(8)
3785    >>> Word = BitVecSort(16)
3786    >>> Byte
3787    BitVec(8)
3788    >>> x = Const('x', Byte)
3789    >>> eq(x, BitVec('x', 8))
3790    True
3791    """
3792    ctx = _get_ctx(ctx)
3793    return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
3794
3795def BitVecVal(val, bv, ctx=None):
3796    """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
3797
3798    >>> v = BitVecVal(10, 32)
3799    >>> v
3800    10
3801    >>> print("0x%.8x" % v.as_long())
3802    0x0000000a
3803    """
3804    if is_bv_sort(bv):
3805        ctx = bv.ctx
3806        return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
3807    else:
3808        ctx = _get_ctx(ctx)
3809        return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
3810
3811def BitVec(name, bv, ctx=None):
3812    """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
3813    If `ctx=None`, then the global context is used.
3814
3815    >>> x  = BitVec('x', 16)
3816    >>> is_bv(x)
3817    True
3818    >>> x.size()
3819    16
3820    >>> x.sort()
3821    BitVec(16)
3822    >>> word = BitVecSort(16)
3823    >>> x2 = BitVec('x', word)
3824    >>> eq(x, x2)
3825    True
3826    """
3827    if isinstance(bv, BitVecSortRef):
3828        ctx = bv.ctx
3829    else:
3830        ctx = _get_ctx(ctx)
3831        bv = BitVecSort(bv, ctx)
3832    return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
3833
3834def BitVecs(names, bv, ctx=None):
3835    """Return a tuple of bit-vector constants of size bv.
3836
3837    >>> x, y, z = BitVecs('x y z', 16)
3838    >>> x.size()
3839    16
3840    >>> x.sort()
3841    BitVec(16)
3842    >>> Sum(x, y, z)
3843    0 + x + y + z
3844    >>> Product(x, y, z)
3845    1*x*y*z
3846    >>> simplify(Product(x, y, z))
3847    x*y*z
3848    """
3849    ctx = _get_ctx(ctx)
3850    if isinstance(names, str):
3851        names = names.split(" ")
3852    return [BitVec(name, bv, ctx) for name in names]
3853
3854def Concat(*args):
3855    """Create a Z3 bit-vector concatenation expression.
3856
3857    >>> v = BitVecVal(1, 4)
3858    >>> Concat(v, v+1, v)
3859    Concat(Concat(1, 1 + 1), 1)
3860    >>> simplify(Concat(v, v+1, v))
3861    289
3862    >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
3863    121
3864    """
3865    args = _get_args(args)
3866    sz = len(args)
3867    if z3_debug():
3868        _z3_assert(sz >= 2, "At least two arguments expected.")
3869
3870    ctx = None
3871    for a in args:
3872        if is_expr(a):
3873            ctx = a.ctx
3874            break
3875    if is_seq(args[0]) or isinstance(args[0], str):
3876        args = [_coerce_seq(s, ctx) for s in args]
3877        if z3_debug():
3878            _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
3879        v = (Ast * sz)()
3880        for i in range(sz):
3881            v[i] = args[i].as_ast()
3882        return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
3883
3884    if is_re(args[0]):
3885       if z3_debug():
3886           _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
3887       v = (Ast * sz)()
3888       for i in range(sz):
3889           v[i] = args[i].as_ast()
3890       return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
3891
3892    if z3_debug():
3893        _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
3894    r   = args[0]
3895    for i in range(sz - 1):
3896        r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i+1].as_ast()), ctx)
3897    return r
3898
3899def Extract(high, low, a):
3900    """Create a Z3 bit-vector extraction expression, or create a string extraction expression.
3901
3902    >>> x = BitVec('x', 8)
3903    >>> Extract(6, 2, x)
3904    Extract(6, 2, x)
3905    >>> Extract(6, 2, x).sort()
3906    BitVec(5)
3907    >>> simplify(Extract(StringVal("abcd"),2,1))
3908    "c"
3909    """
3910    if isinstance(high, str):
3911        high = StringVal(high)
3912    if is_seq(high):
3913        s = high
3914        offset, length = _coerce_exprs(low, a, s.ctx)
3915        return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
3916    if z3_debug():
3917        _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
3918        _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0, "First and second arguments must be non negative integers")
3919        _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
3920    return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
3921
3922def _check_bv_args(a, b):
3923    if z3_debug():
3924        _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
3925
3926def ULE(a, b):
3927    """Create the Z3 expression (unsigned) `other <= self`.
3928
3929    Use the operator <= for signed less than or equal to.
3930
3931    >>> x, y = BitVecs('x y', 32)
3932    >>> ULE(x, y)
3933    ULE(x, y)
3934    >>> (x <= y).sexpr()
3935    '(bvsle x y)'
3936    >>> ULE(x, y).sexpr()
3937    '(bvule x y)'
3938    """
3939    _check_bv_args(a, b)
3940    a, b = _coerce_exprs(a, b)
3941    return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3942
3943def ULT(a, b):
3944    """Create the Z3 expression (unsigned) `other < self`.
3945
3946    Use the operator < for signed less than.
3947
3948    >>> x, y = BitVecs('x y', 32)
3949    >>> ULT(x, y)
3950    ULT(x, y)
3951    >>> (x < y).sexpr()
3952    '(bvslt x y)'
3953    >>> ULT(x, y).sexpr()
3954    '(bvult x y)'
3955    """
3956    _check_bv_args(a, b)
3957    a, b = _coerce_exprs(a, b)
3958    return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3959
3960def UGE(a, b):
3961    """Create the Z3 expression (unsigned) `other >= self`.
3962
3963    Use the operator >= for signed greater than or equal to.
3964
3965    >>> x, y = BitVecs('x y', 32)
3966    >>> UGE(x, y)
3967    UGE(x, y)
3968    >>> (x >= y).sexpr()
3969    '(bvsge x y)'
3970    >>> UGE(x, y).sexpr()
3971    '(bvuge x y)'
3972    """
3973    _check_bv_args(a, b)
3974    a, b = _coerce_exprs(a, b)
3975    return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3976
3977def UGT(a, b):
3978    """Create the Z3 expression (unsigned) `other > self`.
3979
3980    Use the operator > for signed greater than.
3981
3982    >>> x, y = BitVecs('x y', 32)
3983    >>> UGT(x, y)
3984    UGT(x, y)
3985    >>> (x > y).sexpr()
3986    '(bvsgt x y)'
3987    >>> UGT(x, y).sexpr()
3988    '(bvugt x y)'
3989    """
3990    _check_bv_args(a, b)
3991    a, b = _coerce_exprs(a, b)
3992    return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3993
3994def UDiv(a, b):
3995    """Create the Z3 expression (unsigned) division `self / other`.
3996
3997    Use the operator / for signed division.
3998
3999    >>> x = BitVec('x', 32)
4000    >>> y = BitVec('y', 32)
4001    >>> UDiv(x, y)
4002    UDiv(x, y)
4003    >>> UDiv(x, y).sort()
4004    BitVec(32)
4005    >>> (x / y).sexpr()
4006    '(bvsdiv x y)'
4007    >>> UDiv(x, y).sexpr()
4008    '(bvudiv x y)'
4009    """
4010    _check_bv_args(a, b)
4011    a, b = _coerce_exprs(a, b)
4012    return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4013
4014def URem(a, b):
4015    """Create the Z3 expression (unsigned) remainder `self % other`.
4016
4017    Use the operator % for signed modulus, and SRem() for signed remainder.
4018
4019    >>> x = BitVec('x', 32)
4020    >>> y = BitVec('y', 32)
4021    >>> URem(x, y)
4022    URem(x, y)
4023    >>> URem(x, y).sort()
4024    BitVec(32)
4025    >>> (x % y).sexpr()
4026    '(bvsmod x y)'
4027    >>> URem(x, y).sexpr()
4028    '(bvurem x y)'
4029    """
4030    _check_bv_args(a, b)
4031    a, b = _coerce_exprs(a, b)
4032    return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4033
4034def SRem(a, b):
4035    """Create the Z3 expression signed remainder.
4036
4037    Use the operator % for signed modulus, and URem() for unsigned remainder.
4038
4039    >>> x = BitVec('x', 32)
4040    >>> y = BitVec('y', 32)
4041    >>> SRem(x, y)
4042    SRem(x, y)
4043    >>> SRem(x, y).sort()
4044    BitVec(32)
4045    >>> (x % y).sexpr()
4046    '(bvsmod x y)'
4047    >>> SRem(x, y).sexpr()
4048    '(bvsrem x y)'
4049    """
4050    _check_bv_args(a, b)
4051    a, b = _coerce_exprs(a, b)
4052    return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4053
4054def LShR(a, b):
4055    """Create the Z3 expression logical right shift.
4056
4057    Use the operator >> for the arithmetical right shift.
4058
4059    >>> x, y = BitVecs('x y', 32)
4060    >>> LShR(x, y)
4061    LShR(x, y)
4062    >>> (x >> y).sexpr()
4063    '(bvashr x y)'
4064    >>> LShR(x, y).sexpr()
4065    '(bvlshr x y)'
4066    >>> BitVecVal(4, 3)
4067    4
4068    >>> BitVecVal(4, 3).as_signed_long()
4069    -4
4070    >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4071    -2
4072    >>> simplify(BitVecVal(4, 3) >> 1)
4073    6
4074    >>> simplify(LShR(BitVecVal(4, 3), 1))
4075    2
4076    >>> simplify(BitVecVal(2, 3) >> 1)
4077    1
4078    >>> simplify(LShR(BitVecVal(2, 3), 1))
4079    1
4080    """
4081    _check_bv_args(a, b)
4082    a, b = _coerce_exprs(a, b)
4083    return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4084
4085def RotateLeft(a, b):
4086    """Return an expression representing `a` rotated to the left `b` times.
4087
4088    >>> a, b = BitVecs('a b', 16)
4089    >>> RotateLeft(a, b)
4090    RotateLeft(a, b)
4091    >>> simplify(RotateLeft(a, 0))
4092    a
4093    >>> simplify(RotateLeft(a, 16))
4094    a
4095    """
4096    _check_bv_args(a, b)
4097    a, b = _coerce_exprs(a, b)
4098    return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4099
4100def RotateRight(a, b):
4101    """Return an expression representing `a` rotated to the right `b` times.
4102
4103    >>> a, b = BitVecs('a b', 16)
4104    >>> RotateRight(a, b)
4105    RotateRight(a, b)
4106    >>> simplify(RotateRight(a, 0))
4107    a
4108    >>> simplify(RotateRight(a, 16))
4109    a
4110    """
4111    _check_bv_args(a, b)
4112    a, b = _coerce_exprs(a, b)
4113    return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4114
4115def SignExt(n, a):
4116    """Return a bit-vector expression with `n` extra sign-bits.
4117
4118    >>> x = BitVec('x', 16)
4119    >>> n = SignExt(8, x)
4120    >>> n.size()
4121    24
4122    >>> n
4123    SignExt(8, x)
4124    >>> n.sort()
4125    BitVec(24)
4126    >>> v0 = BitVecVal(2, 2)
4127    >>> v0
4128    2
4129    >>> v0.size()
4130    2
4131    >>> v  = simplify(SignExt(6, v0))
4132    >>> v
4133    254
4134    >>> v.size()
4135    8
4136    >>> print("%.x" % v.as_long())
4137    fe
4138    """
4139    if z3_debug():
4140        _z3_assert(_is_int(n), "First argument must be an integer")
4141        _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4142    return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4143
4144def ZeroExt(n, a):
4145    """Return a bit-vector expression with `n` extra zero-bits.
4146
4147    >>> x = BitVec('x', 16)
4148    >>> n = ZeroExt(8, x)
4149    >>> n.size()
4150    24
4151    >>> n
4152    ZeroExt(8, x)
4153    >>> n.sort()
4154    BitVec(24)
4155    >>> v0 = BitVecVal(2, 2)
4156    >>> v0
4157    2
4158    >>> v0.size()
4159    2
4160    >>> v  = simplify(ZeroExt(6, v0))
4161    >>> v
4162    2
4163    >>> v.size()
4164    8
4165    """
4166    if z3_debug():
4167        _z3_assert(_is_int(n), "First argument must be an integer")
4168        _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4169    return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4170
4171def RepeatBitVec(n, a):
4172    """Return an expression representing `n` copies of `a`.
4173
4174    >>> x = BitVec('x', 8)
4175    >>> n = RepeatBitVec(4, x)
4176    >>> n
4177    RepeatBitVec(4, x)
4178    >>> n.size()
4179    32
4180    >>> v0 = BitVecVal(10, 4)
4181    >>> print("%.x" % v0.as_long())
4182    a
4183    >>> v = simplify(RepeatBitVec(4, v0))
4184    >>> v.size()
4185    16
4186    >>> print("%.x" % v.as_long())
4187    aaaa
4188    """
4189    if z3_debug():
4190        _z3_assert(_is_int(n), "First argument must be an integer")
4191        _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4192    return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4193
4194def BVRedAnd(a):
4195    """Return the reduction-and expression of `a`."""
4196    if z3_debug():
4197        _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4198    return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4199
4200def BVRedOr(a):
4201    """Return the reduction-or expression of `a`."""
4202    if z3_debug():
4203        _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4204    return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4205
4206def BVAddNoOverflow(a, b, signed):
4207    """A predicate the determines that bit-vector addition does not overflow"""
4208    _check_bv_args(a, b)
4209    a, b = _coerce_exprs(a, b)
4210    return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4211
4212def BVAddNoUnderflow(a, b):
4213    """A predicate the determines that signed bit-vector addition does not underflow"""
4214    _check_bv_args(a, b)
4215    a, b = _coerce_exprs(a, b)
4216    return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4217
4218def BVSubNoOverflow(a, b):
4219    """A predicate the determines that bit-vector subtraction does not overflow"""
4220    _check_bv_args(a, b)
4221    a, b = _coerce_exprs(a, b)
4222    return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4223
4224
4225def BVSubNoUnderflow(a, b, signed):
4226    """A predicate the determines that bit-vector subtraction does not underflow"""
4227    _check_bv_args(a, b)
4228    a, b = _coerce_exprs(a, b)
4229    return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4230
4231def BVSDivNoOverflow(a, b):
4232    """A predicate the determines that bit-vector signed division does not overflow"""
4233    _check_bv_args(a, b)
4234    a, b = _coerce_exprs(a, b)
4235    return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4236
4237def BVSNegNoOverflow(a):
4238    """A predicate the determines that bit-vector unary negation does not overflow"""
4239    if z3_debug():
4240        _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4241    return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4242
4243def BVMulNoOverflow(a, b, signed):
4244    """A predicate the determines that bit-vector multiplication does not overflow"""
4245    _check_bv_args(a, b)
4246    a, b = _coerce_exprs(a, b)
4247    return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4248
4249
4250def BVMulNoUnderflow(a, b):
4251    """A predicate the determines that bit-vector signed multiplication does not underflow"""
4252    _check_bv_args(a, b)
4253    a, b = _coerce_exprs(a, b)
4254    return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4255
4256
4257
4258#########################################
4259#
4260# Arrays
4261#
4262#########################################
4263
4264class ArraySortRef(SortRef):
4265    """Array sorts."""
4266
4267    def domain(self):
4268        """Return the domain of the array sort `self`.
4269
4270        >>> A = ArraySort(IntSort(), BoolSort())
4271        >>> A.domain()
4272        Int
4273        """
4274        return _to_sort_ref(Z3_get_array_sort_domain(self.ctx_ref(), self.ast), self.ctx)
4275
4276    def range(self):
4277        """Return the range of the array sort `self`.
4278
4279        >>> A = ArraySort(IntSort(), BoolSort())
4280        >>> A.range()
4281        Bool
4282        """
4283        return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
4284
4285class ArrayRef(ExprRef):
4286    """Array expressions. """
4287
4288    def sort(self):
4289        """Return the array sort of the array expression `self`.
4290
4291        >>> a = Array('a', IntSort(), BoolSort())
4292        >>> a.sort()
4293        Array(Int, Bool)
4294        """
4295        return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4296
4297    def domain(self):
4298        """Shorthand for `self.sort().domain()`.
4299
4300        >>> a = Array('a', IntSort(), BoolSort())
4301        >>> a.domain()
4302        Int
4303        """
4304        return self.sort().domain()
4305
4306    def range(self):
4307        """Shorthand for `self.sort().range()`.
4308
4309        >>> a = Array('a', IntSort(), BoolSort())
4310        >>> a.range()
4311        Bool
4312        """
4313        return self.sort().range()
4314
4315    def __getitem__(self, arg):
4316        """Return the Z3 expression `self[arg]`.
4317
4318        >>> a = Array('a', IntSort(), BoolSort())
4319        >>> i = Int('i')
4320        >>> a[i]
4321        a[i]
4322        >>> a[i].sexpr()
4323        '(select a i)'
4324        """
4325        arg = self.domain().cast(arg)
4326        return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx)
4327
4328    def default(self):
4329        return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)
4330
4331def is_array_sort(a):
4332    return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4333
4334
4335def is_array(a):
4336    """Return `True` if `a` is a Z3 array expression.
4337
4338    >>> a = Array('a', IntSort(), IntSort())
4339    >>> is_array(a)
4340    True
4341    >>> is_array(Store(a, 0, 1))
4342    True
4343    >>> is_array(a[0])
4344    False
4345    """
4346    return isinstance(a, ArrayRef)
4347
4348def is_const_array(a):
4349    """Return `True` if `a` is a Z3 constant array.
4350
4351    >>> a = K(IntSort(), 10)
4352    >>> is_const_array(a)
4353    True
4354    >>> a = Array('a', IntSort(), IntSort())
4355    >>> is_const_array(a)
4356    False
4357    """
4358    return is_app_of(a, Z3_OP_CONST_ARRAY)
4359
4360def is_K(a):
4361    """Return `True` if `a` is a Z3 constant array.
4362
4363    >>> a = K(IntSort(), 10)
4364    >>> is_K(a)
4365    True
4366    >>> a = Array('a', IntSort(), IntSort())
4367    >>> is_K(a)
4368    False
4369    """
4370    return is_app_of(a, Z3_OP_CONST_ARRAY)
4371
4372def is_map(a):
4373    """Return `True` if `a` is a Z3 map array expression.
4374
4375    >>> f = Function('f', IntSort(), IntSort())
4376    >>> b = Array('b', IntSort(), IntSort())
4377    >>> a  = Map(f, b)
4378    >>> a
4379    Map(f, b)
4380    >>> is_map(a)
4381    True
4382    >>> is_map(b)
4383    False
4384    """
4385    return is_app_of(a, Z3_OP_ARRAY_MAP)
4386
4387def is_default(a):
4388    """Return `True` if `a` is a Z3 default array expression.
4389    >>> d = Default(K(IntSort(), 10))
4390    >>> is_default(d)
4391    True
4392    """
4393    return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4394
4395def get_map_func(a):
4396    """Return the function declaration associated with a Z3 map array expression.
4397
4398    >>> f = Function('f', IntSort(), IntSort())
4399    >>> b = Array('b', IntSort(), IntSort())
4400    >>> a  = Map(f, b)
4401    >>> eq(f, get_map_func(a))
4402    True
4403    >>> get_map_func(a)
4404    f
4405    >>> get_map_func(a)(0)
4406    f(0)
4407    """
4408    if z3_debug():
4409        _z3_assert(is_map(a), "Z3 array map expression expected.")
4410    return FuncDeclRef(Z3_to_func_decl(a.ctx_ref(), Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0)), a.ctx)
4411
4412def ArraySort(*sig):
4413    """Return the Z3 array sort with the given domain and range sorts.
4414
4415    >>> A = ArraySort(IntSort(), BoolSort())
4416    >>> A
4417    Array(Int, Bool)
4418    >>> A.domain()
4419    Int
4420    >>> A.range()
4421    Bool
4422    >>> AA = ArraySort(IntSort(), A)
4423    >>> AA
4424    Array(Int, Array(Int, Bool))
4425    """
4426    sig = _get_args(sig)
4427    if z3_debug():
4428        _z3_assert(len(sig) > 1, "At least two arguments expected")
4429    arity = len(sig) - 1
4430    r = sig[arity]
4431    d = sig[0]
4432    if z3_debug():
4433        for s in sig:
4434            _z3_assert(is_sort(s), "Z3 sort expected")
4435            _z3_assert(s.ctx == r.ctx, "Context mismatch")
4436    ctx = d.ctx
4437    if len(sig) == 2:
4438        return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4439    dom = (Sort * arity)()
4440    for i in range(arity):
4441        dom[i] = sig[i].ast
4442    return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4443
4444def Array(name, dom, rng):
4445    """Return an array constant named `name` with the given domain and range sorts.
4446
4447    >>> a = Array('a', IntSort(), IntSort())
4448    >>> a.sort()
4449    Array(Int, Int)
4450    >>> a[0]
4451    a[0]
4452    """
4453    s = ArraySort(dom, rng)
4454    ctx = s.ctx
4455    return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4456
4457def Update(a, i, v):
4458    """Return a Z3 store array expression.
4459
4460    >>> a    = Array('a', IntSort(), IntSort())
4461    >>> i, v = Ints('i v')
4462    >>> s    = Update(a, i, v)
4463    >>> s.sort()
4464    Array(Int, Int)
4465    >>> prove(s[i] == v)
4466    proved
4467    >>> j    = Int('j')
4468    >>> prove(Implies(i != j, s[j] == a[j]))
4469    proved
4470    """
4471    if z3_debug():
4472        _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4473    i = a.sort().domain().cast(i)
4474    v = a.sort().range().cast(v)
4475    ctx = a.ctx
4476    return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4477
4478def Default(a):
4479    """ Return a default value for array expression.
4480    >>> b = K(IntSort(), 1)
4481    >>> prove(Default(b) == 1)
4482    proved
4483    """
4484    if z3_debug():
4485        _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4486    return a.default()
4487
4488
4489def Store(a, i, v):
4490    """Return a Z3 store array expression.
4491
4492    >>> a    = Array('a', IntSort(), IntSort())
4493    >>> i, v = Ints('i v')
4494    >>> s    = Store(a, i, v)
4495    >>> s.sort()
4496    Array(Int, Int)
4497    >>> prove(s[i] == v)
4498    proved
4499    >>> j    = Int('j')
4500    >>> prove(Implies(i != j, s[j] == a[j]))
4501    proved
4502    """
4503    return Update(a, i, v)
4504
4505def Select(a, i):
4506    """Return a Z3 select array expression.
4507
4508    >>> a = Array('a', IntSort(), IntSort())
4509    >>> i = Int('i')
4510    >>> Select(a, i)
4511    a[i]
4512    >>> eq(Select(a, i), a[i])
4513    True
4514    """
4515    if z3_debug():
4516        _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4517    return a[i]
4518
4519
4520def Map(f, *args):
4521    """Return a Z3 map array expression.
4522
4523    >>> f = Function('f', IntSort(), IntSort(), IntSort())
4524    >>> a1 = Array('a1', IntSort(), IntSort())
4525    >>> a2 = Array('a2', IntSort(), IntSort())
4526    >>> b  = Map(f, a1, a2)
4527    >>> b
4528    Map(f, a1, a2)
4529    >>> prove(b[0] == f(a1[0], a2[0]))
4530    proved
4531    """
4532    args = _get_args(args)
4533    if z3_debug():
4534        _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
4535        _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
4536        _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
4537        _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
4538    _args, sz = _to_ast_array(args)
4539    ctx = f.ctx
4540    return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
4541
4542def K(dom, v):
4543    """Return a Z3 constant array expression.
4544
4545    >>> a = K(IntSort(), 10)
4546    >>> a
4547    K(Int, 10)
4548    >>> a.sort()
4549    Array(Int, Int)
4550    >>> i = Int('i')
4551    >>> a[i]
4552    K(Int, 10)[i]
4553    >>> simplify(a[i])
4554    10
4555    """
4556    if z3_debug():
4557        _z3_assert(is_sort(dom), "Z3 sort expected")
4558    ctx = dom.ctx
4559    if not is_expr(v):
4560        v = _py2expr(v, ctx)
4561    return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
4562
4563def Ext(a, b):
4564    """Return extensionality index for one-dimensional arrays.
4565    >> a, b = Consts('a b', SetSort(IntSort()))
4566    >> Ext(a, b)
4567    Ext(a, b)
4568    """
4569    ctx = a.ctx
4570    if z3_debug():
4571        _z3_assert(is_array_sort(a) and is_array(b), "arguments must be arrays")
4572    return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4573
4574def SetHasSize(a, k):
4575    ctx = a.ctx
4576    k = _py2expr(k, ctx)
4577    return _to_expr_ref(Z3_mk_set_has_size(ctx.ref(), a.as_ast(), k.as_ast()), ctx)
4578
4579def is_select(a):
4580    """Return `True` if `a` is a Z3 array select application.
4581
4582    >>> a = Array('a', IntSort(), IntSort())
4583    >>> is_select(a)
4584    False
4585    >>> i = Int('i')
4586    >>> is_select(a[i])
4587    True
4588    """
4589    return is_app_of(a, Z3_OP_SELECT)
4590
4591def is_store(a):
4592    """Return `True` if `a` is a Z3 array store application.
4593
4594    >>> a = Array('a', IntSort(), IntSort())
4595    >>> is_store(a)
4596    False
4597    >>> is_store(Store(a, 0, 1))
4598    True
4599    """
4600    return is_app_of(a, Z3_OP_STORE)
4601
4602#########################################
4603#
4604# Sets
4605#
4606#########################################
4607
4608
4609def SetSort(s):
4610    """ Create a set sort over element sort s"""
4611    return ArraySort(s, BoolSort())
4612
4613def EmptySet(s):
4614    """Create the empty set
4615    >>> EmptySet(IntSort())
4616    K(Int, False)
4617    """
4618    ctx = s.ctx
4619    return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
4620
4621def FullSet(s):
4622    """Create the full set
4623    >>> FullSet(IntSort())
4624    K(Int, True)
4625    """
4626    ctx = s.ctx
4627    return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
4628
4629def SetUnion(*args):
4630    """ Take the union of sets
4631    >>> a = Const('a', SetSort(IntSort()))
4632    >>> b = Const('b', SetSort(IntSort()))
4633    >>> SetUnion(a, b)
4634    union(a, b)
4635    """
4636    args = _get_args(args)
4637    ctx = _ctx_from_ast_arg_list(args)
4638    _args, sz = _to_ast_array(args)
4639    return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
4640
4641def SetIntersect(*args):
4642    """ Take the union of sets
4643    >>> a = Const('a', SetSort(IntSort()))
4644    >>> b = Const('b', SetSort(IntSort()))
4645    >>> SetIntersect(a, b)
4646    intersection(a, b)
4647    """
4648    args = _get_args(args)
4649    ctx = _ctx_from_ast_arg_list(args)
4650    _args, sz = _to_ast_array(args)
4651    return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
4652
4653def SetAdd(s, e):
4654    """ Add element e to set s
4655    >>> a = Const('a', SetSort(IntSort()))
4656    >>> SetAdd(a, 1)
4657    Store(a, 1, True)
4658    """
4659    ctx = _ctx_from_ast_arg_list([s,e])
4660    e = _py2expr(e, ctx)
4661    return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
4662
4663def SetDel(s, e):
4664    """ Remove element e to set s
4665    >>> a = Const('a', SetSort(IntSort()))
4666    >>> SetDel(a, 1)
4667    Store(a, 1, False)
4668    """
4669    ctx = _ctx_from_ast_arg_list([s,e])
4670    e = _py2expr(e, ctx)
4671    return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
4672
4673def SetComplement(s):
4674    """ The complement of set s
4675    >>> a = Const('a', SetSort(IntSort()))
4676    >>> SetComplement(a)
4677    complement(a)
4678    """
4679    ctx = s.ctx
4680    return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
4681
4682def SetDifference(a, b):
4683    """ The set difference of a and b
4684    >>> a = Const('a', SetSort(IntSort()))
4685    >>> b = Const('b', SetSort(IntSort()))
4686    >>> SetDifference(a, b)
4687    setminus(a, b)
4688    """
4689    ctx = _ctx_from_ast_arg_list([a, b])
4690    return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4691
4692def IsMember(e, s):
4693    """ Check if e is a member of set s
4694    >>> a = Const('a', SetSort(IntSort()))
4695    >>> IsMember(1, a)
4696    a[1]
4697    """
4698    ctx = _ctx_from_ast_arg_list([s,e])
4699    e = _py2expr(e, ctx)
4700    return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
4701
4702def IsSubset(a, b):
4703    """ Check if a is a subset of b
4704    >>> a = Const('a', SetSort(IntSort()))
4705    >>> b = Const('b', SetSort(IntSort()))
4706    >>> IsSubset(a, b)
4707    subset(a, b)
4708    """
4709    ctx = _ctx_from_ast_arg_list([a, b])
4710    return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4711
4712
4713#########################################
4714#
4715# Datatypes
4716#
4717#########################################
4718
4719def _valid_accessor(acc):
4720    """Return `True` if acc is pair of the form (String, Datatype or Sort). """
4721    return isinstance(acc, tuple) and len(acc) == 2 and isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
4722
4723class Datatype:
4724    """Helper class for declaring Z3 datatypes.
4725
4726    >>> List = Datatype('List')
4727    >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
4728    >>> List.declare('nil')
4729    >>> List = List.create()
4730    >>> # List is now a Z3 declaration
4731    >>> List.nil
4732    nil
4733    >>> List.cons(10, List.nil)
4734    cons(10, nil)
4735    >>> List.cons(10, List.nil).sort()
4736    List
4737    >>> cons = List.cons
4738    >>> nil  = List.nil
4739    >>> car  = List.car
4740    >>> cdr  = List.cdr
4741    >>> n = cons(1, cons(0, nil))
4742    >>> n
4743    cons(1, cons(0, nil))
4744    >>> simplify(cdr(n))
4745    cons(0, nil)
4746    >>> simplify(car(n))
4747    1
4748    """
4749    def __init__(self, name, ctx=None):
4750        self.ctx          = _get_ctx(ctx)
4751        self.name         = name
4752        self.constructors = []
4753
4754    def __deepcopy__(self, memo={}):
4755        r = Datatype(self.name, self.ctx)
4756        r.constructors = copy.deepcopy(self.constructors)
4757        return r
4758
4759    def declare_core(self, name, rec_name, *args):
4760        if z3_debug():
4761            _z3_assert(isinstance(name, str), "String expected")
4762            _z3_assert(isinstance(rec_name, str), "String expected")
4763            _z3_assert(all([_valid_accessor(a) for a in args]), "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)")
4764        self.constructors.append((name, rec_name, args))
4765
4766    def declare(self, name, *args):
4767        """Declare constructor named `name` with the given accessors `args`.
4768        Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort or a reference to the datatypes being declared.
4769
4770        In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
4771        declares the constructor named `cons` that builds a new List using an integer and a List.
4772        It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer of a `cons` cell,
4773        and `cdr` the list of a `cons` cell. After all constructors were declared, we use the method create() to create
4774        the actual datatype in Z3.
4775
4776        >>> List = Datatype('List')
4777        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
4778        >>> List.declare('nil')
4779        >>> List = List.create()
4780        """
4781        if z3_debug():
4782            _z3_assert(isinstance(name, str), "String expected")
4783            _z3_assert(name != "", "Constructor name cannot be empty")
4784        return self.declare_core(name, "is-" + name, *args)
4785
4786    def __repr__(self):
4787        return "Datatype(%s, %s)" % (self.name, self.constructors)
4788
4789    def create(self):
4790        """Create a Z3 datatype based on the constructors declared using the method `declare()`.
4791
4792        The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
4793
4794        >>> List = Datatype('List')
4795        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
4796        >>> List.declare('nil')
4797        >>> List = List.create()
4798        >>> List.nil
4799        nil
4800        >>> List.cons(10, List.nil)
4801        cons(10, nil)
4802        """
4803        return CreateDatatypes([self])[0]
4804
4805class ScopedConstructor:
4806    """Auxiliary object used to create Z3 datatypes."""
4807    def __init__(self, c, ctx):
4808        self.c   = c
4809        self.ctx = ctx
4810    def __del__(self):
4811        if self.ctx.ref() is not None:
4812           Z3_del_constructor(self.ctx.ref(), self.c)
4813
4814class ScopedConstructorList:
4815    """Auxiliary object used to create Z3 datatypes."""
4816    def __init__(self, c, ctx):
4817        self.c   = c
4818        self.ctx = ctx
4819    def __del__(self):
4820        if self.ctx.ref() is not None:
4821           Z3_del_constructor_list(self.ctx.ref(), self.c)
4822
4823def CreateDatatypes(*ds):
4824    """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
4825
4826    In the following example we define a Tree-List using two mutually recursive datatypes.
4827
4828    >>> TreeList = Datatype('TreeList')
4829    >>> Tree     = Datatype('Tree')
4830    >>> # Tree has two constructors: leaf and node
4831    >>> Tree.declare('leaf', ('val', IntSort()))
4832    >>> # a node contains a list of trees
4833    >>> Tree.declare('node', ('children', TreeList))
4834    >>> TreeList.declare('nil')
4835    >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
4836    >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
4837    >>> Tree.val(Tree.leaf(10))
4838    val(leaf(10))
4839    >>> simplify(Tree.val(Tree.leaf(10)))
4840    10
4841    >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
4842    >>> n1
4843    node(cons(leaf(10), cons(leaf(20), nil)))
4844    >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
4845    >>> simplify(n2 == n1)
4846    False
4847    >>> simplify(TreeList.car(Tree.children(n2)) == n1)
4848    True
4849    """
4850    ds = _get_args(ds)
4851    if z3_debug():
4852        _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
4853        _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
4854        _z3_assert(all([d.ctx == ds[0].ctx for d in  ds]), "Context mismatch")
4855        _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
4856    ctx = ds[0].ctx
4857    num    = len(ds)
4858    names  = (Symbol * num)()
4859    out    = (Sort * num)()
4860    clists = (ConstructorList * num)()
4861    to_delete = []
4862    for i in range(num):
4863        d        = ds[i]
4864        names[i] = to_symbol(d.name, ctx)
4865        num_cs   = len(d.constructors)
4866        cs       = (Constructor * num_cs)()
4867        for j in range(num_cs):
4868            c      = d.constructors[j]
4869            cname  = to_symbol(c[0], ctx)
4870            rname  = to_symbol(c[1], ctx)
4871            fs     = c[2]
4872            num_fs = len(fs)
4873            fnames = (Symbol * num_fs)()
4874            sorts  = (Sort   * num_fs)()
4875            refs   = (ctypes.c_uint * num_fs)()
4876            for k in range(num_fs):
4877                fname = fs[k][0]
4878                ftype = fs[k][1]
4879                fnames[k] = to_symbol(fname, ctx)
4880                if isinstance(ftype, Datatype):
4881                    if z3_debug():
4882                        _z3_assert(ds.count(ftype) == 1, "One and only one occurrence of each datatype is expected")
4883                    sorts[k] = None
4884                    refs[k]  = ds.index(ftype)
4885                else:
4886                    if z3_debug():
4887                        _z3_assert(is_sort(ftype), "Z3 sort expected")
4888                    sorts[k] = ftype.ast
4889                    refs[k]  = 0
4890            cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
4891            to_delete.append(ScopedConstructor(cs[j], ctx))
4892        clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
4893        to_delete.append(ScopedConstructorList(clists[i], ctx))
4894    Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
4895    result = []
4896    ## Create a field for every constructor, recognizer and accessor
4897    for i in range(num):
4898        dref = DatatypeSortRef(out[i], ctx)
4899        num_cs = dref.num_constructors()
4900        for j in range(num_cs):
4901            cref       = dref.constructor(j)
4902            cref_name  = cref.name()
4903            cref_arity = cref.arity()
4904            if cref.arity() == 0:
4905                cref = cref()
4906            setattr(dref, cref_name, cref)
4907            rref  = dref.recognizer(j)
4908            setattr(dref, "is_" + cref_name, rref)
4909            for k in range(cref_arity):
4910                aref = dref.accessor(j, k)
4911                setattr(dref, aref.name(), aref)
4912        result.append(dref)
4913    return tuple(result)
4914
4915class DatatypeSortRef(SortRef):
4916    """Datatype sorts."""
4917    def num_constructors(self):
4918        """Return the number of constructors in the given Z3 datatype.
4919
4920        >>> List = Datatype('List')
4921        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
4922        >>> List.declare('nil')
4923        >>> List = List.create()
4924        >>> # List is now a Z3 declaration
4925        >>> List.num_constructors()
4926        2
4927        """
4928        return int(Z3_get_datatype_sort_num_constructors(self.ctx_ref(), self.ast))
4929
4930    def constructor(self, idx):
4931        """Return a constructor of the datatype `self`.
4932
4933        >>> List = Datatype('List')
4934        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
4935        >>> List.declare('nil')
4936        >>> List = List.create()
4937        >>> # List is now a Z3 declaration
4938        >>> List.num_constructors()
4939        2
4940        >>> List.constructor(0)
4941        cons
4942        >>> List.constructor(1)
4943        nil
4944        """
4945        if z3_debug():
4946            _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
4947        return FuncDeclRef(Z3_get_datatype_sort_constructor(self.ctx_ref(), self.ast, idx), self.ctx)
4948
4949    def recognizer(self, idx):
4950        """In Z3, each constructor has an associated recognizer predicate.
4951
4952        If the constructor is named `name`, then the recognizer `is_name`.
4953
4954        >>> List = Datatype('List')
4955        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
4956        >>> List.declare('nil')
4957        >>> List = List.create()
4958        >>> # List is now a Z3 declaration
4959        >>> List.num_constructors()
4960        2
4961        >>> List.recognizer(0)
4962        is(cons)
4963        >>> List.recognizer(1)
4964        is(nil)
4965        >>> simplify(List.is_nil(List.cons(10, List.nil)))
4966        False
4967        >>> simplify(List.is_cons(List.cons(10, List.nil)))
4968        True
4969        >>> l = Const('l', List)
4970        >>> simplify(List.is_cons(l))
4971        is(cons, l)
4972        """
4973        if z3_debug():
4974            _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
4975        return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
4976
4977    def accessor(self, i, j):
4978        """In Z3, each constructor has 0 or more accessor. The number of accessors is equal to the arity of the constructor.
4979
4980        >>> List = Datatype('List')
4981        >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
4982        >>> List.declare('nil')
4983        >>> List = List.create()
4984        >>> List.num_constructors()
4985        2
4986        >>> List.constructor(0)
4987        cons
4988        >>> num_accs = List.constructor(0).arity()
4989        >>> num_accs
4990        2
4991        >>> List.accessor(0, 0)
4992        car
4993        >>> List.accessor(0, 1)
4994        cdr
4995        >>> List.constructor(1)
4996        nil
4997        >>> num_accs = List.constructor(1).arity()
4998        >>> num_accs
4999        0
5000        """
5001        if z3_debug():
5002            _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5003            _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5004        return FuncDeclRef(Z3_get_datatype_sort_constructor_accessor(self.ctx_ref(), self.ast, i, j), self.ctx)
5005
5006class DatatypeRef(ExprRef):
5007    """Datatype expressions."""
5008    def sort(self):
5009        """Return the datatype sort of the datatype expression `self`."""
5010        return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5011
5012def TupleSort(name, sorts, ctx = None):
5013    """Create a named tuple sort base on a set of underlying sorts
5014    Example:
5015        >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5016    """
5017    tuple = Datatype(name, ctx)
5018    projects = [ ('project%d' % i, sorts[i]) for i in range(len(sorts)) ]
5019    tuple.declare(name, *projects)
5020    tuple = tuple.create()
5021    return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5022
5023def DisjointSum(name, sorts, ctx=None):
5024    """Create a named tagged union sort base on a set of underlying sorts
5025    Example:
5026        >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5027    """
5028    sum = Datatype(name, ctx)
5029    for i in range(len(sorts)):
5030        sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5031    sum = sum.create()
5032    return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5033
5034
5035def EnumSort(name, values, ctx=None):
5036    """Return a new enumeration sort named `name` containing the given values.
5037
5038    The result is a pair (sort, list of constants).
5039    Example:
5040        >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5041    """
5042    if z3_debug():
5043        _z3_assert(isinstance(name, str), "Name must be a string")
5044        _z3_assert(all([isinstance(v, str) for v in values]), "Eumeration sort values must be strings")
5045        _z3_assert(len(values) > 0, "At least one value expected")
5046    ctx = _get_ctx(ctx)
5047    num = len(values)
5048    _val_names   = (Symbol * num)()
5049    for i in range(num):
5050        _val_names[i] = to_symbol(values[i])
5051    _values  = (FuncDecl * num)()
5052    _testers = (FuncDecl * num)()
5053    name = to_symbol(name)
5054    S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5055    V = []
5056    for i in range(num):
5057        V.append(FuncDeclRef(_values[i], ctx))
5058    V = [a() for a in V]
5059    return S, V
5060
5061#########################################
5062#
5063# Parameter Sets
5064#
5065#########################################
5066
5067class ParamsRef:
5068    """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5069
5070    Consider using the function `args2params` to create instances of this object.
5071    """
5072    def __init__(self, ctx=None, params=None):
5073        self.ctx    = _get_ctx(ctx)
5074        if params is None:
5075            self.params = Z3_mk_params(self.ctx.ref())
5076        else:
5077            self.params = params
5078        Z3_params_inc_ref(self.ctx.ref(), self.params)
5079
5080    def __deepcopy__(self, memo={}):
5081        return ParamsRef(self.ctx, self.params)
5082
5083    def __del__(self):
5084        if self.ctx.ref() is not None:
5085           Z3_params_dec_ref(self.ctx.ref(), self.params)
5086
5087    def set(self, name, val):
5088        """Set parameter name with value val."""
5089        if z3_debug():
5090            _z3_assert(isinstance(name, str), "parameter name must be a string")
5091        name_sym = to_symbol(name, self.ctx)
5092        if isinstance(val, bool):
5093            Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5094        elif _is_int(val):
5095            Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5096        elif isinstance(val, float):
5097            Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5098        elif isinstance(val, str):
5099            Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5100        else:
5101            if z3_debug():
5102                _z3_assert(False, "invalid parameter value")
5103
5104    def __repr__(self):
5105        return Z3_params_to_string(self.ctx.ref(), self.params)
5106
5107    def validate(self, ds):
5108        _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5109        Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5110
5111def args2params(arguments, keywords, ctx=None):
5112    """Convert python arguments into a Z3_params object.
5113    A ':' is added to the keywords, and '_' is replaced with '-'
5114
5115    >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5116    (params model true relevancy 2 elim_and true)
5117    """
5118    if z3_debug():
5119        _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5120    prev = None
5121    r    = ParamsRef(ctx)
5122    for a in arguments:
5123        if prev is None:
5124            prev = a
5125        else:
5126            r.set(prev, a)
5127            prev = None
5128    for k in keywords:
5129        v = keywords[k]
5130        r.set(k, v)
5131    return r
5132
5133class ParamDescrsRef:
5134    """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5135    """
5136    def __init__(self, descr, ctx=None):
5137        _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5138        self.ctx    = _get_ctx(ctx)
5139        self.descr  = descr
5140        Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5141
5142    def __deepcopy__(self, memo={}):
5143        return ParamsDescrsRef(self.descr, self.ctx)
5144
5145    def __del__(self):
5146        if self.ctx.ref() is not None:
5147           Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5148
5149    def size(self):
5150        """Return the size of in the parameter description `self`.
5151        """
5152        return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5153
5154    def __len__(self):
5155        """Return the size of in the parameter description `self`.
5156        """
5157        return self.size()
5158
5159    def get_name(self, i):
5160        """Return the i-th parameter name in the parameter description `self`.
5161        """
5162        return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5163
5164    def get_kind(self, n):
5165        """Return the kind of the parameter named `n`.
5166        """
5167        return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5168
5169    def get_documentation(self, n):
5170        """Return the documentation string of the parameter named `n`.
5171        """
5172        return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5173
5174    def __getitem__(self, arg):
5175        if _is_int(arg):
5176            return self.get_name(arg)
5177        else:
5178            return self.get_kind(arg)
5179
5180    def __repr__(self):
5181        return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5182
5183#########################################
5184#
5185# Goals
5186#
5187#########################################
5188
5189class Goal(Z3PPObject):
5190    """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5191
5192    Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5193    A goal has a solution if one of its subgoals has a solution.
5194    A goal is unsatisfiable if all subgoals are unsatisfiable.
5195    """
5196
5197    def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5198        if z3_debug():
5199            _z3_assert(goal is None or ctx is not None, "If goal is different from None, then ctx must be also different from None")
5200        self.ctx    = _get_ctx(ctx)
5201        self.goal   = goal
5202        if self.goal is None:
5203            self.goal   = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5204        Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5205
5206    def __deepcopy__(self, memo={}):
5207        return Goal(False, False, False, self.ctx, self.goal)
5208
5209    def __del__(self):
5210        if self.goal is not None and self.ctx.ref() is not None:
5211            Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5212
5213    def depth(self):
5214        """Return the depth of the goal `self`. The depth corresponds to the number of tactics applied to `self`.
5215
5216        >>> x, y = Ints('x y')
5217        >>> g = Goal()
5218        >>> g.add(x == 0, y >= x + 1)
5219        >>> g.depth()
5220        0
5221        >>> r = Then('simplify', 'solve-eqs')(g)
5222        >>> # r has 1 subgoal
5223        >>> len(r)
5224        1
5225        >>> r[0].depth()
5226        2
5227        """
5228        return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5229
5230    def inconsistent(self):
5231        """Return `True` if `self` contains the `False` constraints.
5232
5233        >>> x, y = Ints('x y')
5234        >>> g = Goal()
5235        >>> g.inconsistent()
5236        False
5237        >>> g.add(x == 0, x == 1)
5238        >>> g
5239        [x == 0, x == 1]
5240        >>> g.inconsistent()
5241        False
5242        >>> g2 = Tactic('propagate-values')(g)[0]
5243        >>> g2.inconsistent()
5244        True
5245        """
5246        return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5247
5248    def prec(self):
5249        """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5250
5251        >>> g = Goal()
5252        >>> g.prec() == Z3_GOAL_PRECISE
5253        True
5254        >>> x, y = Ints('x y')
5255        >>> g.add(x == y + 1)
5256        >>> g.prec() == Z3_GOAL_PRECISE
5257        True
5258        >>> t  = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5259        >>> g2 = t(g)[0]
5260        >>> g2
5261        [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5262        >>> g2.prec() == Z3_GOAL_PRECISE
5263        False
5264        >>> g2.prec() == Z3_GOAL_UNDER
5265        True
5266        """
5267        return Z3_goal_precision(self.ctx.ref(), self.goal)
5268
5269    def precision(self):
5270        """Alias for `prec()`.
5271
5272        >>> g = Goal()
5273        >>> g.precision() == Z3_GOAL_PRECISE
5274        True
5275        """
5276        return self.prec()
5277
5278    def size(self):
5279        """Return the number of constraints in the goal `self`.
5280
5281        >>> g = Goal()
5282        >>> g.size()
5283        0
5284        >>> x, y = Ints('x y')
5285        >>> g.add(x == 0, y > x)
5286        >>> g.size()
5287        2
5288        """
5289        return int(Z3_goal_size(self.ctx.ref(), self.goal))
5290
5291    def __len__(self):
5292        """Return the number of constraints in the goal `self`.
5293
5294        >>> g = Goal()
5295        >>> len(g)
5296        0
5297        >>> x, y = Ints('x y')
5298        >>> g.add(x == 0, y > x)
5299        >>> len(g)
5300        2
5301        """
5302        return self.size()
5303
5304    def get(self, i):
5305        """Return a constraint in the goal `self`.
5306
5307        >>> g = Goal()
5308        >>> x, y = Ints('x y')
5309        >>> g.add(x == 0, y > x)
5310        >>> g.get(0)
5311        x == 0
5312        >>> g.get(1)
5313        y > x
5314        """
5315        return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5316
5317    def __getitem__(self, arg):
5318        """Return a constraint in the goal `self`.
5319
5320        >>> g = Goal()
5321        >>> x, y = Ints('x y')
5322        >>> g.add(x == 0, y > x)
5323        >>> g[0]
5324        x == 0
5325        >>> g[1]
5326        y > x
5327        """
5328        if arg >= len(self):
5329            raise IndexError
5330        return self.get(arg)
5331
5332    def assert_exprs(self, *args):
5333        """Assert constraints into the goal.
5334
5335        >>> x = Int('x')
5336        >>> g = Goal()
5337        >>> g.assert_exprs(x > 0, x < 2)
5338        >>> g
5339        [x > 0, x < 2]
5340        """
5341        args = _get_args(args)
5342        s    = BoolSort(self.ctx)
5343        for arg in args:
5344            arg = s.cast(arg)
5345            Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5346
5347    def append(self, *args):
5348        """Add constraints.
5349
5350        >>> x = Int('x')
5351        >>> g = Goal()
5352        >>> g.append(x > 0, x < 2)
5353        >>> g
5354        [x > 0, x < 2]
5355        """
5356        self.assert_exprs(*args)
5357
5358    def insert(self, *args):
5359        """Add constraints.
5360
5361        >>> x = Int('x')
5362        >>> g = Goal()
5363        >>> g.insert(x > 0, x < 2)
5364        >>> g
5365        [x > 0, x < 2]
5366        """
5367        self.assert_exprs(*args)
5368
5369    def add(self, *args):
5370        """Add constraints.
5371
5372        >>> x = Int('x')
5373        >>> g = Goal()
5374        >>> g.add(x > 0, x < 2)
5375        >>> g
5376        [x > 0, x < 2]
5377        """
5378        self.assert_exprs(*args)
5379
5380    def convert_model(self, model):
5381        """Retrieve model from a satisfiable goal
5382        >>> a, b = Ints('a b')
5383        >>> g = Goal()
5384        >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5385        >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5386        >>> r = t(g)
5387        >>> r[0]
5388        [Or(b == 0, b == 1), Not(0 <= b)]
5389        >>> r[1]
5390        [Or(b == 0, b == 1), Not(1 <= b)]
5391        >>> # Remark: the subgoal r[0] is unsatisfiable
5392        >>> # Creating a solver for solving the second subgoal
5393        >>> s = Solver()
5394        >>> s.add(r[1])
5395        >>> s.check()
5396        sat
5397        >>> s.model()
5398        [b = 0]
5399        >>> # Model s.model() does not assign a value to `a`
5400        >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5401        >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5402        >>> r[1].convert_model(s.model())
5403        [b = 0, a = 1]
5404        """
5405        if z3_debug():
5406            _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5407        return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5408
5409    def __repr__(self):
5410        return obj_to_string(self)
5411
5412    def sexpr(self):
5413        """Return a textual representation of the s-expression representing the goal."""
5414        return Z3_goal_to_string(self.ctx.ref(), self.goal)
5415
5416    def dimacs(self, include_names = True):
5417        """Return a textual representation of the goal in DIMACS format."""
5418        return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5419
5420    def translate(self, target):
5421        """Copy goal `self` to context `target`.
5422
5423        >>> x = Int('x')
5424        >>> g = Goal()
5425        >>> g.add(x > 10)
5426        >>> g
5427        [x > 10]
5428        >>> c2 = Context()
5429        >>> g2 = g.translate(c2)
5430        >>> g2
5431        [x > 10]
5432        >>> g.ctx == main_ctx()
5433        True
5434        >>> g2.ctx == c2
5435        True
5436        >>> g2.ctx == main_ctx()
5437        False
5438        """
5439        if z3_debug():
5440            _z3_assert(isinstance(target, Context), "target must be a context")
5441        return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5442
5443    def __copy__(self):
5444        return self.translate(self.ctx)
5445
5446    def __deepcopy__(self, memo={}):
5447        return self.translate(self.ctx)
5448
5449    def simplify(self, *arguments, **keywords):
5450        """Return a new simplified goal.
5451
5452        This method is essentially invoking the simplify tactic.
5453
5454        >>> g = Goal()
5455        >>> x = Int('x')
5456        >>> g.add(x + 1 >= 2)
5457        >>> g
5458        [x + 1 >= 2]
5459        >>> g2 = g.simplify()
5460        >>> g2
5461        [x >= 1]
5462        >>> # g was not modified
5463        >>> g
5464        [x + 1 >= 2]
5465        """
5466        t = Tactic('simplify')
5467        return t.apply(self, *arguments, **keywords)[0]
5468
5469    def as_expr(self):
5470        """Return goal `self` as a single Z3 expression.
5471
5472        >>> x = Int('x')
5473        >>> g = Goal()
5474        >>> g.as_expr()
5475        True
5476        >>> g.add(x > 1)
5477        >>> g.as_expr()
5478        x > 1
5479        >>> g.add(x < 10)
5480        >>> g.as_expr()
5481        And(x > 1, x < 10)
5482        """
5483        sz = len(self)
5484        if sz == 0:
5485            return BoolVal(True, self.ctx)
5486        elif sz == 1:
5487            return self.get(0)
5488        else:
5489            return And([ self.get(i) for i in range(len(self)) ], self.ctx)
5490
5491#########################################
5492#
5493# AST Vector
5494#
5495#########################################
5496class AstVector(Z3PPObject):
5497    """A collection (vector) of ASTs."""
5498
5499    def __init__(self, v=None, ctx=None):
5500        self.vector = None
5501        if v is None:
5502            self.ctx = _get_ctx(ctx)
5503            self.vector = Z3_mk_ast_vector(self.ctx.ref())
5504        else:
5505            self.vector = v
5506            assert ctx is not None
5507            self.ctx    = ctx
5508        Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
5509
5510    def __deepcopy__(self, memo={}):
5511        return AstVector(self.vector, self.ctx)
5512
5513    def __del__(self):
5514        if self.vector is not None and self.ctx.ref() is not None:
5515            Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
5516
5517    def __len__(self):
5518        """Return the size of the vector `self`.
5519
5520        >>> A = AstVector()
5521        >>> len(A)
5522        0
5523        >>> A.push(Int('x'))
5524        >>> A.push(Int('x'))
5525        >>> len(A)
5526        2
5527        """
5528        return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
5529
5530    def __getitem__(self, i):
5531        """Return the AST at position `i`.
5532
5533        >>> A = AstVector()
5534        >>> A.push(Int('x') + 1)
5535        >>> A.push(Int('y'))
5536        >>> A[0]
5537        x + 1
5538        >>> A[1]
5539        y
5540        """
5541
5542        if isinstance(i, int):
5543            if i < 0:
5544                i += self.__len__()
5545
5546            if i >= self.__len__():
5547                raise IndexError
5548            return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
5549
5550        elif isinstance(i, slice):
5551            return [_to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, ii), self.ctx) for ii in range(*i.indices(self.__len__()))]
5552
5553
5554    def __setitem__(self, i, v):
5555        """Update AST at position `i`.
5556
5557        >>> A = AstVector()
5558        >>> A.push(Int('x') + 1)
5559        >>> A.push(Int('y'))
5560        >>> A[0]
5561        x + 1
5562        >>> A[0] = Int('x')
5563        >>> A[0]
5564        x
5565        """
5566        if i >= self.__len__():
5567            raise IndexError
5568        Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
5569
5570    def push(self, v):
5571        """Add `v` in the end of the vector.
5572
5573        >>> A = AstVector()
5574        >>> len(A)
5575        0
5576        >>> A.push(Int('x'))
5577        >>> len(A)
5578        1
5579        """
5580        Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
5581
5582    def resize(self, sz):
5583        """Resize the vector to `sz` elements.
5584
5585        >>> A = AstVector()
5586        >>> A.resize(10)
5587        >>> len(A)
5588        10
5589        >>> for i in range(10): A[i] = Int('x')
5590        >>> A[5]
5591        x
5592        """
5593        Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
5594
5595    def __contains__(self, item):
5596        """Return `True` if the vector contains `item`.
5597
5598        >>> x = Int('x')
5599        >>> A = AstVector()
5600        >>> x in A
5601        False
5602        >>> A.push(x)
5603        >>> x in A
5604        True
5605        >>> (x+1) in A
5606        False
5607        >>> A.push(x+1)
5608        >>> (x+1) in A
5609        True
5610        >>> A
5611        [x, x + 1]
5612        """
5613        for elem in self:
5614            if elem.eq(item):
5615                return True
5616        return False
5617
5618    def translate(self, other_ctx):
5619        """Copy vector `self` to context `other_ctx`.
5620
5621        >>> x = Int('x')
5622        >>> A = AstVector()
5623        >>> A.push(x)
5624        >>> c2 = Context()
5625        >>> B = A.translate(c2)
5626        >>> B
5627        [x]
5628        """
5629        return AstVector(Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()), other_ctx)
5630
5631    def __copy__(self):
5632        return self.translate(self.ctx)
5633
5634    def __deepcopy__(self, memo={}):
5635        return self.translate(self.ctx)
5636
5637    def __repr__(self):
5638        return obj_to_string(self)
5639
5640    def sexpr(self):
5641        """Return a textual representation of the s-expression representing the vector."""
5642        return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
5643
5644#########################################
5645#
5646# AST Map
5647#
5648#########################################
5649class AstMap:
5650    """A mapping from ASTs to ASTs."""
5651
5652    def __init__(self, m=None, ctx=None):
5653        self.map = None
5654        if m is None:
5655            self.ctx = _get_ctx(ctx)
5656            self.map = Z3_mk_ast_map(self.ctx.ref())
5657        else:
5658            self.map = m
5659            assert ctx is not None
5660            self.ctx    = ctx
5661        Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
5662
5663    def __deepcopy__(self, memo={}):
5664        return AstMap(self.map, self.ctx)
5665
5666    def __del__(self):
5667        if self.map is not None and self.ctx.ref() is not None:
5668            Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
5669
5670    def __len__(self):
5671        """Return the size of the map.
5672
5673        >>> M = AstMap()
5674        >>> len(M)
5675        0
5676        >>> x = Int('x')
5677        >>> M[x] = IntVal(1)
5678        >>> len(M)
5679        1
5680        """
5681        return int(Z3_ast_map_size(self.ctx.ref(), self.map))
5682
5683    def __contains__(self, key):
5684        """Return `True` if the map contains key `key`.
5685
5686        >>> M = AstMap()
5687        >>> x = Int('x')
5688        >>> M[x] = x + 1
5689        >>> x in M
5690        True
5691        >>> x+1 in M
5692        False
5693        """
5694        return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
5695
5696    def __getitem__(self, key):
5697        """Retrieve the value associated with key `key`.
5698
5699        >>> M = AstMap()
5700        >>> x = Int('x')
5701        >>> M[x] = x + 1
5702        >>> M[x]
5703        x + 1
5704        """
5705        return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
5706
5707    def __setitem__(self, k, v):
5708        """Add/Update key `k` with value `v`.
5709
5710        >>> M = AstMap()
5711        >>> x = Int('x')
5712        >>> M[x] = x + 1
5713        >>> len(M)
5714        1
5715        >>> M[x]
5716        x + 1
5717        >>> M[x] = IntVal(1)
5718        >>> M[x]
5719        1
5720        """
5721        Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
5722
5723    def __repr__(self):
5724        return Z3_ast_map_to_string(self.ctx.ref(), self.map)
5725
5726    def erase(self, k):
5727        """Remove the entry associated with key `k`.
5728
5729        >>> M = AstMap()
5730        >>> x = Int('x')
5731        >>> M[x] = x + 1
5732        >>> len(M)
5733        1
5734        >>> M.erase(x)
5735        >>> len(M)
5736        0
5737        """
5738        Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
5739
5740    def reset(self):
5741        """Remove all entries from the map.
5742
5743        >>> M = AstMap()
5744        >>> x = Int('x')
5745        >>> M[x]   = x + 1
5746        >>> M[x+x] = IntVal(1)
5747        >>> len(M)
5748        2
5749        >>> M.reset()
5750        >>> len(M)
5751        0
5752        """
5753        Z3_ast_map_reset(self.ctx.ref(), self.map)
5754
5755    def keys(self):
5756        """Return an AstVector containing all keys in the map.
5757
5758        >>> M = AstMap()
5759        >>> x = Int('x')
5760        >>> M[x]   = x + 1
5761        >>> M[x+x] = IntVal(1)
5762        >>> M.keys()
5763        [x, x + x]
5764        """
5765        return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
5766
5767#########################################
5768#
5769# Model
5770#
5771#########################################
5772
5773class FuncEntry:
5774    """Store the value of the interpretation of a function in a particular point."""
5775
5776    def __init__(self, entry, ctx):
5777        self.entry = entry
5778        self.ctx   = ctx
5779        Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
5780
5781    def __deepcopy__(self, memo={}):
5782        return FuncEntry(self.entry, self.ctx)
5783
5784    def __del__(self):
5785        if self.ctx.ref() is not None:
5786           Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
5787
5788    def num_args(self):
5789        """Return the number of arguments in the given entry.
5790
5791        >>> f = Function('f', IntSort(), IntSort(), IntSort())
5792        >>> s = Solver()
5793        >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
5794        >>> s.check()
5795        sat
5796        >>> m = s.model()
5797        >>> f_i = m[f]
5798        >>> f_i.num_entries()
5799        1
5800        >>> e = f_i.entry(0)
5801        >>> e.num_args()
5802        2
5803        """
5804        return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
5805
5806    def arg_value(self, idx):
5807        """Return the value of argument `idx`.
5808
5809        >>> f = Function('f', IntSort(), IntSort(), IntSort())
5810        >>> s = Solver()
5811        >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
5812        >>> s.check()
5813        sat
5814        >>> m = s.model()
5815        >>> f_i = m[f]
5816        >>> f_i.num_entries()
5817        1
5818        >>> e = f_i.entry(0)
5819        >>> e
5820        [1, 2, 20]
5821        >>> e.num_args()
5822        2
5823        >>> e.arg_value(0)
5824        1
5825        >>> e.arg_value(1)
5826        2
5827        >>> try:
5828        ...   e.arg_value(2)
5829        ... except IndexError:
5830        ...   print("index error")
5831        index error
5832        """
5833        if idx >= self.num_args():
5834            raise IndexError
5835        return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
5836
5837    def value(self):
5838        """Return the value of the function at point `self`.
5839
5840        >>> f = Function('f', IntSort(), IntSort(), IntSort())
5841        >>> s = Solver()
5842        >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
5843        >>> s.check()
5844        sat
5845        >>> m = s.model()
5846        >>> f_i = m[f]
5847        >>> f_i.num_entries()
5848        1
5849        >>> e = f_i.entry(0)
5850        >>> e
5851        [1, 2, 20]
5852        >>> e.num_args()
5853        2
5854        >>> e.value()
5855        20
5856        """
5857        return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
5858
5859    def as_list(self):
5860        """Return entry `self` as a Python list.
5861        >>> f = Function('f', IntSort(), IntSort(), IntSort())
5862        >>> s = Solver()
5863        >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
5864        >>> s.check()
5865        sat
5866        >>> m = s.model()
5867        >>> f_i = m[f]
5868        >>> f_i.num_entries()
5869        1
5870        >>> e = f_i.entry(0)
5871        >>> e.as_list()
5872        [1, 2, 20]
5873        """
5874        args = [ self.arg_value(i) for i in range(self.num_args())]
5875        args.append(self.value())
5876        return args
5877
5878    def __repr__(self):
5879        return repr(self.as_list())
5880
5881class FuncInterp(Z3PPObject):
5882    """Stores the interpretation of a function in a Z3 model."""
5883
5884    def __init__(self, f, ctx):
5885        self.f   = f
5886        self.ctx = ctx
5887        if self.f is not None:
5888            Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
5889
5890    def __deepcopy__(self, memo={}):
5891        return FuncInterp(self.f, self.ctx)
5892
5893    def __del__(self):
5894        if self.f is not None and self.ctx.ref() is not None:
5895            Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
5896
5897    def else_value(self):
5898        """
5899        Return the `else` value for a function interpretation.
5900        Return None if Z3 did not specify the `else` value for
5901        this object.
5902
5903        >>> f = Function('f', IntSort(), IntSort())
5904        >>> s = Solver()
5905        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
5906        >>> s.check()
5907        sat
5908        >>> m = s.model()
5909        >>> m[f]
5910        [2 -> 0, else -> 1]
5911        >>> m[f].else_value()
5912        1
5913        """
5914        r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
5915        if r:
5916            return _to_expr_ref(r, self.ctx)
5917        else:
5918            return None
5919
5920    def num_entries(self):
5921        """Return the number of entries/points in the function interpretation `self`.
5922
5923        >>> f = Function('f', IntSort(), IntSort())
5924        >>> s = Solver()
5925        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
5926        >>> s.check()
5927        sat
5928        >>> m = s.model()
5929        >>> m[f]
5930        [2 -> 0, else -> 1]
5931        >>> m[f].num_entries()
5932        1
5933        """
5934        return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
5935
5936    def arity(self):
5937        """Return the number of arguments for each entry in the function interpretation `self`.
5938
5939        >>> f = Function('f', IntSort(), IntSort())
5940        >>> s = Solver()
5941        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
5942        >>> s.check()
5943        sat
5944        >>> m = s.model()
5945        >>> m[f].arity()
5946        1
5947        """
5948        return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
5949
5950    def entry(self, idx):
5951        """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
5952
5953        >>> f = Function('f', IntSort(), IntSort())
5954        >>> s = Solver()
5955        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
5956        >>> s.check()
5957        sat
5958        >>> m = s.model()
5959        >>> m[f]
5960        [2 -> 0, else -> 1]
5961        >>> m[f].num_entries()
5962        1
5963        >>> m[f].entry(0)
5964        [2, 0]
5965        """
5966        if idx >= self.num_entries():
5967            raise IndexError
5968        return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
5969
5970    def translate(self, other_ctx):
5971        """Copy model 'self' to context 'other_ctx'.
5972        """
5973        return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
5974
5975    def __copy__(self):
5976        return self.translate(self.ctx)
5977
5978    def __deepcopy__(self, memo={}):
5979        return self.translate(self.ctx)
5980
5981    def as_list(self):
5982        """Return the function interpretation as a Python list.
5983        >>> f = Function('f', IntSort(), IntSort())
5984        >>> s = Solver()
5985        >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
5986        >>> s.check()
5987        sat
5988        >>> m = s.model()
5989        >>> m[f]
5990        [2 -> 0, else -> 1]
5991        >>> m[f].as_list()
5992        [[2, 0], 1]
5993        """
5994        r = [ self.entry(i).as_list() for i in range(self.num_entries())]
5995        r.append(self.else_value())
5996        return r
5997
5998    def __repr__(self):
5999        return obj_to_string(self)
6000
6001class ModelRef(Z3PPObject):
6002    """Model/Solution of a satisfiability problem (aka system of constraints)."""
6003
6004    def __init__(self, m, ctx):
6005        assert ctx is not None
6006        self.model = m
6007        self.ctx   = ctx
6008        Z3_model_inc_ref(self.ctx.ref(), self.model)
6009
6010    def __del__(self):
6011        if self.ctx.ref() is not None:
6012           Z3_model_dec_ref(self.ctx.ref(), self.model)
6013
6014    def __repr__(self):
6015        return obj_to_string(self)
6016
6017    def sexpr(self):
6018        """Return a textual representation of the s-expression representing the model."""
6019        return Z3_model_to_string(self.ctx.ref(), self.model)
6020
6021    def eval(self, t, model_completion=False):
6022        """Evaluate the expression `t` in the model `self`. If `model_completion` is enabled, then a default interpretation is automatically added for symbols that do not have an interpretation in the model `self`.
6023
6024        >>> x = Int('x')
6025        >>> s = Solver()
6026        >>> s.add(x > 0, x < 2)
6027        >>> s.check()
6028        sat
6029        >>> m = s.model()
6030        >>> m.eval(x + 1)
6031        2
6032        >>> m.eval(x == 1)
6033        True
6034        >>> y = Int('y')
6035        >>> m.eval(y + x)
6036        1 + y
6037        >>> m.eval(y)
6038        y
6039        >>> m.eval(y, model_completion=True)
6040        0
6041        >>> # Now, m contains an interpretation for y
6042        >>> m.eval(y + x)
6043        1
6044        """
6045        r = (Ast * 1)()
6046        if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6047            return _to_expr_ref(r[0], self.ctx)
6048        raise Z3Exception("failed to evaluate expression in the model")
6049
6050    def evaluate(self, t, model_completion=False):
6051        """Alias for `eval`.
6052
6053        >>> x = Int('x')
6054        >>> s = Solver()
6055        >>> s.add(x > 0, x < 2)
6056        >>> s.check()
6057        sat
6058        >>> m = s.model()
6059        >>> m.evaluate(x + 1)
6060        2
6061        >>> m.evaluate(x == 1)
6062        True
6063        >>> y = Int('y')
6064        >>> m.evaluate(y + x)
6065        1 + y
6066        >>> m.evaluate(y)
6067        y
6068        >>> m.evaluate(y, model_completion=True)
6069        0
6070        >>> # Now, m contains an interpretation for y
6071        >>> m.evaluate(y + x)
6072        1
6073        """
6074        return self.eval(t, model_completion)
6075
6076    def __len__(self):
6077        """Return the number of constant and function declarations in the model `self`.
6078
6079        >>> f = Function('f', IntSort(), IntSort())
6080        >>> x = Int('x')
6081        >>> s = Solver()
6082        >>> s.add(x > 0, f(x) != x)
6083        >>> s.check()
6084        sat
6085        >>> m = s.model()
6086        >>> len(m)
6087        2
6088        """
6089        return int(Z3_model_get_num_consts(self.ctx.ref(), self.model)) + int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6090
6091    def get_interp(self, decl):
6092        """Return the interpretation for a given declaration or constant.
6093
6094        >>> f = Function('f', IntSort(), IntSort())
6095        >>> x = Int('x')
6096        >>> s = Solver()
6097        >>> s.add(x > 0, x < 2, f(x) == 0)
6098        >>> s.check()
6099        sat
6100        >>> m = s.model()
6101        >>> m[x]
6102        1
6103        >>> m[f]
6104        [else -> 0]
6105        """
6106        if z3_debug():
6107            _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6108        if is_const(decl):
6109            decl = decl.decl()
6110        try:
6111            if decl.arity() == 0:
6112                _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6113                if _r.value is None:
6114                    return None
6115                r = _to_expr_ref(_r, self.ctx)
6116                if is_as_array(r):
6117                    return self.get_interp(get_as_array_func(r))
6118                else:
6119                    return r
6120            else:
6121                return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6122        except Z3Exception:
6123            return None
6124
6125    def num_sorts(self):
6126        """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6127
6128        >>> A = DeclareSort('A')
6129        >>> a, b = Consts('a b', A)
6130        >>> s = Solver()
6131        >>> s.add(a != b)
6132        >>> s.check()
6133        sat
6134        >>> m = s.model()
6135        >>> m.num_sorts()
6136        1
6137        """
6138        return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6139
6140    def get_sort(self, idx):
6141        """Return the uninterpreted sort at position `idx` < self.num_sorts().
6142
6143        >>> A = DeclareSort('A')
6144        >>> B = DeclareSort('B')
6145        >>> a1, a2 = Consts('a1 a2', A)
6146        >>> b1, b2 = Consts('b1 b2', B)
6147        >>> s = Solver()
6148        >>> s.add(a1 != a2, b1 != b2)
6149        >>> s.check()
6150        sat
6151        >>> m = s.model()
6152        >>> m.num_sorts()
6153        2
6154        >>> m.get_sort(0)
6155        A
6156        >>> m.get_sort(1)
6157        B
6158        """
6159        if idx >= self.num_sorts():
6160            raise IndexError
6161        return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6162
6163    def sorts(self):
6164        """Return all uninterpreted sorts that have an interpretation in the model `self`.
6165
6166        >>> A = DeclareSort('A')
6167        >>> B = DeclareSort('B')
6168        >>> a1, a2 = Consts('a1 a2', A)
6169        >>> b1, b2 = Consts('b1 b2', B)
6170        >>> s = Solver()
6171        >>> s.add(a1 != a2, b1 != b2)
6172        >>> s.check()
6173        sat
6174        >>> m = s.model()
6175        >>> m.sorts()
6176        [A, B]
6177        """
6178        return [ self.get_sort(i) for i in range(self.num_sorts()) ]
6179
6180    def get_universe(self, s):
6181        """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6182
6183        >>> A = DeclareSort('A')
6184        >>> a, b = Consts('a b', A)
6185        >>> s = Solver()
6186        >>> s.add(a != b)
6187        >>> s.check()
6188        sat
6189        >>> m = s.model()
6190        >>> m.get_universe(A)
6191        [A!val!0, A!val!1]
6192        """
6193        if z3_debug():
6194            _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6195        try:
6196            return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6197        except Z3Exception:
6198            return None
6199
6200    def __getitem__(self, idx):
6201        """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned. If `idx` is a declaration, then the actual interpretation is returned.
6202
6203        The elements can be retrieved using position or the actual declaration.
6204
6205        >>> f = Function('f', IntSort(), IntSort())
6206        >>> x = Int('x')
6207        >>> s = Solver()
6208        >>> s.add(x > 0, x < 2, f(x) == 0)
6209        >>> s.check()
6210        sat
6211        >>> m = s.model()
6212        >>> len(m)
6213        2
6214        >>> m[0]
6215        x
6216        >>> m[1]
6217        f
6218        >>> m[x]
6219        1
6220        >>> m[f]
6221        [else -> 0]
6222        >>> for d in m: print("%s -> %s" % (d, m[d]))
6223        x -> 1
6224        f -> [else -> 0]
6225        """
6226        if _is_int(idx):
6227            if idx >= len(self):
6228                raise IndexError
6229            num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6230            if (idx < num_consts):
6231                return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6232            else:
6233                return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6234        if isinstance(idx, FuncDeclRef):
6235            return self.get_interp(idx)
6236        if is_const(idx):
6237            return self.get_interp(idx.decl())
6238        if isinstance(idx, SortRef):
6239            return self.get_universe(idx)
6240        if z3_debug():
6241            _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6242        return None
6243
6244    def decls(self):
6245        """Return a list with all symbols that have an interpretation in the model `self`.
6246        >>> f = Function('f', IntSort(), IntSort())
6247        >>> x = Int('x')
6248        >>> s = Solver()
6249        >>> s.add(x > 0, x < 2, f(x) == 0)
6250        >>> s.check()
6251        sat
6252        >>> m = s.model()
6253        >>> m.decls()
6254        [x, f]
6255        """
6256        r = []
6257        for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6258            r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6259        for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6260            r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6261        return r
6262
6263    def translate(self, target):
6264        """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6265        """
6266        if z3_debug():
6267            _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6268        model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6269        return ModelRef(model, target)
6270
6271    def __copy__(self):
6272        return self.translate(self.ctx)
6273
6274    def __deepcopy__(self, memo={}):
6275        return self.translate(self.ctx)
6276
6277def Model(ctx = None):
6278    ctx = _get_ctx(ctx)
6279    return ModelRef(Z3_mk_model(ctx.ref()), ctx)
6280
6281def is_as_array(n):
6282    """Return true if n is a Z3 expression of the form (_ as-array f)."""
6283    return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6284
6285def get_as_array_func(n):
6286    """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6287    if z3_debug():
6288        _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6289    return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6290
6291#########################################
6292#
6293# Statistics
6294#
6295#########################################
6296class Statistics:
6297    """Statistics for `Solver.check()`."""
6298
6299    def __init__(self, stats, ctx):
6300        self.stats = stats
6301        self.ctx   = ctx
6302        Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6303
6304    def __deepcopy__(self, memo={}):
6305        return Statistics(self.stats, self.ctx)
6306
6307    def __del__(self):
6308        if self.ctx.ref() is not None:
6309           Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6310
6311    def __repr__(self):
6312        if in_html_mode():
6313            out = io.StringIO()
6314            even = True
6315            out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6316            for k, v in self:
6317                if even:
6318                    out.write(u('<tr style="background-color:#CFCFCF">'))
6319                    even = False
6320                else:
6321                    out.write(u('<tr>'))
6322                    even = True
6323                out.write(u('<td>%s</td><td>%s</td></tr>' % (k, v)))
6324            out.write(u('</table>'))
6325            return out.getvalue()
6326        else:
6327            return Z3_stats_to_string(self.ctx.ref(), self.stats)
6328
6329    def __len__(self):
6330        """Return the number of statistical counters.
6331
6332        >>> x = Int('x')
6333        >>> s = Then('simplify', 'nlsat').solver()
6334        >>> s.add(x > 0)
6335        >>> s.check()
6336        sat
6337        >>> st = s.statistics()
6338        >>> len(st)
6339        6
6340        """
6341        return int(Z3_stats_size(self.ctx.ref(), self.stats))
6342
6343    def __getitem__(self, idx):
6344        """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6345
6346        >>> x = Int('x')
6347        >>> s = Then('simplify', 'nlsat').solver()
6348        >>> s.add(x > 0)
6349        >>> s.check()
6350        sat
6351        >>> st = s.statistics()
6352        >>> len(st)
6353        6
6354        >>> st[0]
6355        ('nlsat propagations', 2)
6356        >>> st[1]
6357        ('nlsat stages', 2)
6358        """
6359        if idx >= len(self):
6360            raise IndexError
6361        if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6362            val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6363        else:
6364            val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6365        return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
6366
6367    def keys(self):
6368        """Return the list of statistical counters.
6369
6370        >>> x = Int('x')
6371        >>> s = Then('simplify', 'nlsat').solver()
6372        >>> s.add(x > 0)
6373        >>> s.check()
6374        sat
6375        >>> st = s.statistics()
6376        """
6377        return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
6378
6379    def get_key_value(self, key):
6380        """Return the value of a particular statistical counter.
6381
6382        >>> x = Int('x')
6383        >>> s = Then('simplify', 'nlsat').solver()
6384        >>> s.add(x > 0)
6385        >>> s.check()
6386        sat
6387        >>> st = s.statistics()
6388        >>> st.get_key_value('nlsat propagations')
6389        2
6390        """
6391        for idx in range(len(self)):
6392            if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
6393                if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6394                    return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6395                else:
6396                    return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6397        raise Z3Exception("unknown key")
6398
6399    def __getattr__(self, name):
6400        """Access the value of statistical using attributes.
6401
6402        Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
6403        we should use '_' (e.g., 'nlsat_propagations').
6404
6405        >>> x = Int('x')
6406        >>> s = Then('simplify', 'nlsat').solver()
6407        >>> s.add(x > 0)
6408        >>> s.check()
6409        sat
6410        >>> st = s.statistics()
6411        >>> st.nlsat_propagations
6412        2
6413        >>> st.nlsat_stages
6414        2
6415        """
6416        key = name.replace('_', ' ')
6417        try:
6418            return self.get_key_value(key)
6419        except Z3Exception:
6420            raise AttributeError
6421
6422#########################################
6423#
6424# Solver
6425#
6426#########################################
6427class CheckSatResult:
6428    """Represents the result of a satisfiability check: sat, unsat, unknown.
6429
6430    >>> s = Solver()
6431    >>> s.check()
6432    sat
6433    >>> r = s.check()
6434    >>> isinstance(r, CheckSatResult)
6435    True
6436    """
6437
6438    def __init__(self, r):
6439        self.r = r
6440
6441    def __deepcopy__(self, memo={}):
6442        return CheckSatResult(self.r)
6443
6444    def __eq__(self, other):
6445        return isinstance(other, CheckSatResult) and self.r == other.r
6446
6447    def __ne__(self, other):
6448        return not self.__eq__(other)
6449
6450    def __repr__(self):
6451        if in_html_mode():
6452            if self.r == Z3_L_TRUE:
6453                return "<b>sat</b>"
6454            elif self.r == Z3_L_FALSE:
6455                return "<b>unsat</b>"
6456            else:
6457                return "<b>unknown</b>"
6458        else:
6459            if self.r == Z3_L_TRUE:
6460                return "sat"
6461            elif self.r == Z3_L_FALSE:
6462                return "unsat"
6463            else:
6464                return "unknown"
6465
6466    def _repr_html_(self):
6467        in_html = in_html_mode()
6468        set_html_mode(True)
6469        res = repr(self)
6470        set_html_mode(in_html)
6471        return res
6472
6473sat     = CheckSatResult(Z3_L_TRUE)
6474unsat   = CheckSatResult(Z3_L_FALSE)
6475unknown = CheckSatResult(Z3_L_UNDEF)
6476
6477class Solver(Z3PPObject):
6478    """Solver API provides methods for implementing the main SMT 2.0 commands: push, pop, check, get-model, etc."""
6479
6480    def __init__(self, solver=None, ctx=None, logFile=None):
6481        assert solver is None or ctx is not None
6482        self.ctx    = _get_ctx(ctx)
6483        self.backtrack_level = 4000000000
6484        self.solver = None
6485        if solver is None:
6486            self.solver = Z3_mk_solver(self.ctx.ref())
6487        else:
6488            self.solver = solver
6489        Z3_solver_inc_ref(self.ctx.ref(), self.solver)
6490        if logFile is not None:
6491            self.set("smtlib2_log", logFile)
6492
6493    def __del__(self):
6494        if self.solver is not None and self.ctx.ref() is not None:
6495            Z3_solver_dec_ref(self.ctx.ref(), self.solver)
6496
6497    def set(self, *args, **keys):
6498        """Set a configuration option. The method `help()` return a string containing all available options.
6499
6500        >>> s = Solver()
6501        >>> # The option MBQI can be set using three different approaches.
6502        >>> s.set(mbqi=True)
6503        >>> s.set('MBQI', True)
6504        >>> s.set(':mbqi', True)
6505        """
6506        p = args2params(args, keys, self.ctx)
6507        Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
6508
6509    def push(self):
6510        """Create a backtracking point.
6511
6512        >>> x = Int('x')
6513        >>> s = Solver()
6514        >>> s.add(x > 0)
6515        >>> s
6516        [x > 0]
6517        >>> s.push()
6518        >>> s.add(x < 1)
6519        >>> s
6520        [x > 0, x < 1]
6521        >>> s.check()
6522        unsat
6523        >>> s.pop()
6524        >>> s.check()
6525        sat
6526        >>> s
6527        [x > 0]
6528        """
6529        Z3_solver_push(self.ctx.ref(), self.solver)
6530
6531    def pop(self, num=1):
6532        """Backtrack \c num backtracking points.
6533
6534        >>> x = Int('x')
6535        >>> s = Solver()
6536        >>> s.add(x > 0)
6537        >>> s
6538        [x > 0]
6539        >>> s.push()
6540        >>> s.add(x < 1)
6541        >>> s
6542        [x > 0, x < 1]
6543        >>> s.check()
6544        unsat
6545        >>> s.pop()
6546        >>> s.check()
6547        sat
6548        >>> s
6549        [x > 0]
6550        """
6551        Z3_solver_pop(self.ctx.ref(), self.solver, num)
6552
6553    def num_scopes(self):
6554        """Return the current number of backtracking points.
6555
6556        >>> s = Solver()
6557        >>> s.num_scopes()
6558        0L
6559        >>> s.push()
6560        >>> s.num_scopes()
6561        1L
6562        >>> s.push()
6563        >>> s.num_scopes()
6564        2L
6565        >>> s.pop()
6566        >>> s.num_scopes()
6567        1L
6568        """
6569        return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
6570
6571    def reset(self):
6572        """Remove all asserted constraints and backtracking points created using `push()`.
6573
6574        >>> x = Int('x')
6575        >>> s = Solver()
6576        >>> s.add(x > 0)
6577        >>> s
6578        [x > 0]
6579        >>> s.reset()
6580        >>> s
6581        []
6582        """
6583        Z3_solver_reset(self.ctx.ref(), self.solver)
6584
6585    def assert_exprs(self, *args):
6586        """Assert constraints into the solver.
6587
6588        >>> x = Int('x')
6589        >>> s = Solver()
6590        >>> s.assert_exprs(x > 0, x < 2)
6591        >>> s
6592        [x > 0, x < 2]
6593        """
6594        args = _get_args(args)
6595        s    = BoolSort(self.ctx)
6596        for arg in args:
6597            if isinstance(arg, Goal) or isinstance(arg, AstVector):
6598                for f in arg:
6599                    Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
6600            else:
6601                arg = s.cast(arg)
6602                Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
6603
6604    def add(self, *args):
6605        """Assert constraints into the solver.
6606
6607        >>> x = Int('x')
6608        >>> s = Solver()
6609        >>> s.add(x > 0, x < 2)
6610        >>> s
6611        [x > 0, x < 2]
6612        """
6613        self.assert_exprs(*args)
6614
6615    def __iadd__(self, fml):
6616        self.add(fml)
6617        return self
6618
6619    def append(self, *args):
6620        """Assert constraints into the solver.
6621
6622        >>> x = Int('x')
6623        >>> s = Solver()
6624        >>> s.append(x > 0, x < 2)
6625        >>> s
6626        [x > 0, x < 2]
6627        """
6628        self.assert_exprs(*args)
6629
6630    def insert(self, *args):
6631        """Assert constraints into the solver.
6632
6633        >>> x = Int('x')
6634        >>> s = Solver()
6635        >>> s.insert(x > 0, x < 2)
6636        >>> s
6637        [x > 0, x < 2]
6638        """
6639        self.assert_exprs(*args)
6640
6641    def assert_and_track(self, a, p):
6642        """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
6643
6644        If `p` is a string, it will be automatically converted into a Boolean constant.
6645
6646        >>> x = Int('x')
6647        >>> p3 = Bool('p3')
6648        >>> s = Solver()
6649        >>> s.set(unsat_core=True)
6650        >>> s.assert_and_track(x > 0,  'p1')
6651        >>> s.assert_and_track(x != 1, 'p2')
6652        >>> s.assert_and_track(x < 0,  p3)
6653        >>> print(s.check())
6654        unsat
6655        >>> c = s.unsat_core()
6656        >>> len(c)
6657        2
6658        >>> Bool('p1') in c
6659        True
6660        >>> Bool('p2') in c
6661        False
6662        >>> p3 in c
6663        True
6664        """
6665        if isinstance(p, str):
6666            p = Bool(p, self.ctx)
6667        _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
6668        _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
6669        Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
6670
6671    def check(self, *assumptions):
6672        """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
6673
6674        >>> x = Int('x')
6675        >>> s = Solver()
6676        >>> s.check()
6677        sat
6678        >>> s.add(x > 0, x < 2)
6679        >>> s.check()
6680        sat
6681        >>> s.model().eval(x)
6682        1
6683        >>> s.add(x < 1)
6684        >>> s.check()
6685        unsat
6686        >>> s.reset()
6687        >>> s.add(2**x == 4)
6688        >>> s.check()
6689        unknown
6690        """
6691        s = BoolSort(self.ctx)
6692        assumptions = _get_args(assumptions)
6693        num = len(assumptions)
6694        _assumptions = (Ast * num)()
6695        for i in range(num):
6696            _assumptions[i] = s.cast(assumptions[i]).as_ast()
6697        r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
6698        return CheckSatResult(r)
6699
6700    def model(self):
6701        """Return a model for the last `check()`.
6702
6703        This function raises an exception if
6704        a model is not available (e.g., last `check()` returned unsat).
6705
6706        >>> s = Solver()
6707        >>> a = Int('a')
6708        >>> s.add(a + 2 == 0)
6709        >>> s.check()
6710        sat
6711        >>> s.model()
6712        [a = -2]
6713        """
6714        try:
6715            return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
6716        except Z3Exception:
6717            raise Z3Exception("model is not available")
6718
6719    def import_model_converter(self, other):
6720        """Import model converter from other into the current solver"""
6721        Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
6722
6723    def unsat_core(self):
6724        """Return a subset (as an AST vector) of the assumptions provided to the last check().
6725
6726        These are the assumptions Z3 used in the unsatisfiability proof.
6727        Assumptions are available in Z3. They are used to extract unsatisfiable cores.
6728        They may be also used to "retract" assumptions. Note that, assumptions are not really
6729        "soft constraints", but they can be used to implement them.
6730
6731        >>> p1, p2, p3 = Bools('p1 p2 p3')
6732        >>> x, y       = Ints('x y')
6733        >>> s          = Solver()
6734        >>> s.add(Implies(p1, x > 0))
6735        >>> s.add(Implies(p2, y > x))
6736        >>> s.add(Implies(p2, y < 1))
6737        >>> s.add(Implies(p3, y > -3))
6738        >>> s.check(p1, p2, p3)
6739        unsat
6740        >>> core = s.unsat_core()
6741        >>> len(core)
6742        2
6743        >>> p1 in core
6744        True
6745        >>> p2 in core
6746        True
6747        >>> p3 in core
6748        False
6749        >>> # "Retracting" p2
6750        >>> s.check(p1, p3)
6751        sat
6752        """
6753        return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
6754
6755    def consequences(self, assumptions, variables):
6756        """Determine fixed values for the variables based on the solver state and assumptions.
6757        >>> s = Solver()
6758        >>> a, b, c, d = Bools('a b c d')
6759        >>> s.add(Implies(a,b), Implies(b, c))
6760        >>> s.consequences([a],[b,c,d])
6761        (sat, [Implies(a, b), Implies(a, c)])
6762        >>> s.consequences([Not(c),d],[a,b,c,d])
6763        (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
6764        """
6765        if isinstance(assumptions, list):
6766            _asms = AstVector(None, self.ctx)
6767            for a in assumptions:
6768                _asms.push(a)
6769            assumptions = _asms
6770        if isinstance(variables, list):
6771            _vars = AstVector(None, self.ctx)
6772            for a in variables:
6773                _vars.push(a)
6774            variables = _vars
6775        _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
6776        _z3_assert(isinstance(variables, AstVector), "ast vector expected")
6777        consequences = AstVector(None, self.ctx)
6778        r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector, variables.vector, consequences.vector)
6779        sz = len(consequences)
6780        consequences = [ consequences[i] for i in range(sz) ]
6781        return CheckSatResult(r), consequences
6782
6783    def from_file(self, filename):
6784        """Parse assertions from a file"""
6785        Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
6786
6787    def from_string(self, s):
6788        """Parse assertions from a string"""
6789        Z3_solver_from_string(self.ctx.ref(), self.solver, s)
6790
6791    def cube(self, vars = None):
6792        """Get set of cubes
6793        The method takes an optional set of variables that restrict which
6794        variables may be used as a starting point for cubing.
6795        If vars is not None, then the first case split is based on a variable in
6796        this set.
6797        """
6798        self.cube_vs = AstVector(None, self.ctx)
6799        if vars is not None:
6800           for v in vars:
6801               self.cube_vs.push(v)
6802        while True:
6803            lvl = self.backtrack_level
6804            self.backtrack_level = 4000000000
6805            r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
6806            if (len(r) == 1 and is_false(r[0])):
6807                return
6808            yield r
6809            if (len(r) == 0):
6810                return
6811
6812    def cube_vars(self):
6813        """Access the set of variables that were touched by the most recently generated cube.
6814        This set of variables can be used as a starting point for additional cubes.
6815        The idea is that variables that appear in clauses that are reduced by the most recent
6816        cube are likely more useful to cube on."""
6817        return self.cube_vs
6818
6819    def proof(self):
6820        """Return a proof for the last `check()`. Proof construction must be enabled."""
6821        return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
6822
6823    def assertions(self):
6824        """Return an AST vector containing all added constraints.
6825
6826        >>> s = Solver()
6827        >>> s.assertions()
6828        []
6829        >>> a = Int('a')
6830        >>> s.add(a > 0)
6831        >>> s.add(a < 10)
6832        >>> s.assertions()
6833        [a > 0, a < 10]
6834        """
6835        return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
6836
6837    def units(self):
6838        """Return an AST vector containing all currently inferred units.
6839        """
6840        return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
6841
6842    def non_units(self):
6843        """Return an AST vector containing all atomic formulas in solver state that are not units.
6844        """
6845        return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
6846
6847    def trail_levels(self):
6848        """Return trail and decision levels of the solver state after a check() call.
6849        """
6850        trail = self.trail()
6851        levels = (ctypes.c_uint * len(trail))()
6852        Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
6853        return trail, levels
6854
6855    def trail(self):
6856        """Return trail of the solver state after a check() call.
6857        """
6858        return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
6859
6860    def statistics(self):
6861        """Return statistics for the last `check()`.
6862
6863        >>> s = SimpleSolver()
6864        >>> x = Int('x')
6865        >>> s.add(x > 0)
6866        >>> s.check()
6867        sat
6868        >>> st = s.statistics()
6869        >>> st.get_key_value('final checks')
6870        1
6871        >>> len(st) > 0
6872        True
6873        >>> st[0] != 0
6874        True
6875        """
6876        return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
6877
6878    def reason_unknown(self):
6879        """Return a string describing why the last `check()` returned `unknown`.
6880
6881        >>> x = Int('x')
6882        >>> s = SimpleSolver()
6883        >>> s.add(2**x == 4)
6884        >>> s.check()
6885        unknown
6886        >>> s.reason_unknown()
6887        '(incomplete (theory arithmetic))'
6888        """
6889        return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
6890
6891    def help(self):
6892        """Display a string describing all available options."""
6893        print(Z3_solver_get_help(self.ctx.ref(), self.solver))
6894
6895    def param_descrs(self):
6896        """Return the parameter description set."""
6897        return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
6898
6899    def __repr__(self):
6900        """Return a formatted string with all added constraints."""
6901        return obj_to_string(self)
6902
6903    def translate(self, target):
6904        """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6905
6906        >>> c1 = Context()
6907        >>> c2 = Context()
6908        >>> s1 = Solver(ctx=c1)
6909        >>> s2 = s1.translate(c2)
6910        """
6911        if z3_debug():
6912            _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6913        solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
6914        return Solver(solver, target)
6915
6916    def __copy__(self):
6917        return self.translate(self.ctx)
6918
6919    def __deepcopy__(self, memo={}):
6920        return self.translate(self.ctx)
6921
6922    def sexpr(self):
6923        """Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
6924
6925        >>> x = Int('x')
6926        >>> s = Solver()
6927        >>> s.add(x > 0)
6928        >>> s.add(x < 2)
6929        >>> r = s.sexpr()
6930        """
6931        return Z3_solver_to_string(self.ctx.ref(), self.solver)
6932
6933    def dimacs(self, include_names=True):
6934        """Return a textual representation of the solver in DIMACS format."""
6935        return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
6936
6937    def to_smt2(self):
6938        """return SMTLIB2 formatted benchmark for solver's assertions"""
6939        es = self.assertions()
6940        sz = len(es)
6941        sz1 = sz
6942        if sz1 > 0:
6943            sz1 -= 1
6944        v = (Ast * sz1)()
6945        for i in range(sz1):
6946            v[i] = es[i].as_ast()
6947        if sz > 0:
6948            e = es[sz1].as_ast()
6949        else:
6950            e = BoolVal(True, self.ctx).as_ast()
6951        return Z3_benchmark_to_smtlib_string(self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e)
6952
6953def SolverFor(logic, ctx=None, logFile=None):
6954    """Create a solver customized for the given logic.
6955
6956    The parameter `logic` is a string. It should be contains
6957    the name of a SMT-LIB logic.
6958    See http://www.smtlib.org/ for the name of all available logics.
6959
6960    >>> s = SolverFor("QF_LIA")
6961    >>> x = Int('x')
6962    >>> s.add(x > 0)
6963    >>> s.add(x < 2)
6964    >>> s.check()
6965    sat
6966    >>> s.model()
6967    [x = 1]
6968    """
6969    ctx = _get_ctx(ctx)
6970    logic = to_symbol(logic)
6971    return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
6972
6973def SimpleSolver(ctx=None, logFile=None):
6974    """Return a simple general purpose solver with limited amount of preprocessing.
6975
6976    >>> s = SimpleSolver()
6977    >>> x = Int('x')
6978    >>> s.add(x > 0)
6979    >>> s.check()
6980    sat
6981    """
6982    ctx = _get_ctx(ctx)
6983    return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
6984
6985#########################################
6986#
6987# Fixedpoint
6988#
6989#########################################
6990
6991class Fixedpoint(Z3PPObject):
6992    """Fixedpoint API provides methods for solving with recursive predicates"""
6993
6994    def __init__(self, fixedpoint=None, ctx=None):
6995        assert fixedpoint is None or ctx is not None
6996        self.ctx    = _get_ctx(ctx)
6997        self.fixedpoint = None
6998        if fixedpoint is None:
6999            self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7000        else:
7001            self.fixedpoint = fixedpoint
7002        Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7003        self.vars = []
7004
7005    def __deepcopy__(self, memo={}):
7006        return FixedPoint(self.fixedpoint, self.ctx)
7007
7008    def __del__(self):
7009        if self.fixedpoint is not None and self.ctx.ref() is not None:
7010            Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7011
7012    def set(self, *args, **keys):
7013        """Set a configuration option. The method `help()` return a string containing all available options.
7014        """
7015        p = args2params(args, keys, self.ctx)
7016        Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7017
7018    def help(self):
7019        """Display a string describing all available options."""
7020        print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7021
7022    def param_descrs(self):
7023        """Return the parameter description set."""
7024        return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7025
7026    def assert_exprs(self, *args):
7027        """Assert constraints as background axioms for the fixedpoint solver."""
7028        args = _get_args(args)
7029        s    = BoolSort(self.ctx)
7030        for arg in args:
7031            if isinstance(arg, Goal) or isinstance(arg, AstVector):
7032                for f in arg:
7033                    f = self.abstract(f)
7034                    Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7035            else:
7036                arg = s.cast(arg)
7037                arg = self.abstract(arg)
7038                Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7039
7040    def add(self, *args):
7041        """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7042        self.assert_exprs(*args)
7043
7044    def __iadd__(self, fml):
7045        self.add(fml)
7046        return self
7047
7048    def append(self, *args):
7049        """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7050        self.assert_exprs(*args)
7051
7052    def insert(self, *args):
7053        """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7054        self.assert_exprs(*args)
7055
7056    def add_rule(self, head, body = None, name = None):
7057        """Assert rules defining recursive predicates to the fixedpoint solver.
7058        >>> a = Bool('a')
7059        >>> b = Bool('b')
7060        >>> s = Fixedpoint()
7061        >>> s.register_relation(a.decl())
7062        >>> s.register_relation(b.decl())
7063        >>> s.fact(a)
7064        >>> s.rule(b, a)
7065        >>> s.query(b)
7066        sat
7067        """
7068        if name is None:
7069            name = ""
7070        name = to_symbol(name, self.ctx)
7071        if body is None:
7072            head = self.abstract(head)
7073            Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7074        else:
7075            body = _get_args(body)
7076            f    = self.abstract(Implies(And(body, self.ctx),head))
7077            Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7078
7079    def rule(self, head, body = None, name = None):
7080        """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7081        self.add_rule(head, body, name)
7082
7083    def fact(self, head, name = None):
7084        """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7085        self.add_rule(head, None, name)
7086
7087    def query(self, *query):
7088        """Query the fixedpoint engine whether formula is derivable.
7089           You can also pass an tuple or list of recursive predicates.
7090        """
7091        query = _get_args(query)
7092        sz = len(query)
7093        if sz >= 1 and isinstance(query[0], FuncDeclRef):
7094            _decls = (FuncDecl * sz)()
7095            i = 0
7096            for q in query:
7097                _decls[i] = q.ast
7098                i = i + 1
7099            r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7100        else:
7101            if sz == 1:
7102                query = query[0]
7103            else:
7104                query = And(query, self.ctx)
7105            query = self.abstract(query, False)
7106            r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7107        return CheckSatResult(r)
7108
7109    def query_from_lvl (self, lvl, *query):
7110        """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7111        """
7112        query = _get_args(query)
7113        sz = len(query)
7114        if sz >= 1 and isinstance(query[0], FuncDecl):
7115            _z3_assert (False, "unsupported")
7116        else:
7117            if sz == 1:
7118                query = query[0]
7119            else:
7120                query = And(query)
7121            query = self.abstract(query, False)
7122            r = Z3_fixedpoint_query_from_lvl (self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7123        return CheckSatResult(r)
7124
7125    def update_rule(self, head, body, name):
7126        """update rule"""
7127        if name is None:
7128            name = ""
7129        name = to_symbol(name, self.ctx)
7130        body = _get_args(body)
7131        f    = self.abstract(Implies(And(body, self.ctx),head))
7132        Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7133
7134    def get_answer(self):
7135        """Retrieve answer from last query call."""
7136        r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7137        return _to_expr_ref(r, self.ctx)
7138
7139    def get_ground_sat_answer(self):
7140        """Retrieve a ground cex from last query call."""
7141        r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7142        return _to_expr_ref(r, self.ctx)
7143
7144    def get_rules_along_trace(self):
7145        """retrieve rules along the counterexample trace"""
7146        return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7147
7148    def get_rule_names_along_trace(self):
7149        """retrieve rule names along the counterexample trace"""
7150        # this is a hack as I don't know how to return a list of symbols from C++;
7151        # obtain names as a single string separated by semicolons
7152        names = _symbol2py (self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7153        # split into individual names
7154        return names.split (';')
7155
7156    def get_num_levels(self, predicate):
7157        """Retrieve number of levels used for predicate in PDR engine"""
7158        return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7159
7160    def get_cover_delta(self, level, predicate):
7161        """Retrieve properties known about predicate for the level'th unfolding. -1 is treated as the limit (infinity)"""
7162        r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7163        return _to_expr_ref(r, self.ctx)
7164
7165    def add_cover(self, level, predicate, property):
7166        """Add property to predicate for the level'th unfolding. -1 is treated as infinity (infinity)"""
7167        Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7168
7169    def register_relation(self, *relations):
7170        """Register relation as recursive"""
7171        relations = _get_args(relations)
7172        for f in relations:
7173            Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7174
7175    def set_predicate_representation(self, f, *representations):
7176        """Control how relation is represented"""
7177        representations = _get_args(representations)
7178        representations = [to_symbol(s) for s in representations]
7179        sz = len(representations)
7180        args = (Symbol * sz)()
7181        for i in range(sz):
7182            args[i] = representations[i]
7183        Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7184
7185    def parse_string(self, s):
7186        """Parse rules and queries from a string"""
7187        return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7188
7189    def parse_file(self, f):
7190        """Parse rules and queries from a file"""
7191        return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7192
7193    def get_rules(self):
7194        """retrieve rules that have been added to fixedpoint context"""
7195        return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7196
7197    def get_assertions(self):
7198        """retrieve assertions that have been added to fixedpoint context"""
7199        return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7200
7201    def __repr__(self):
7202        """Return a formatted string with all added rules and constraints."""
7203        return self.sexpr()
7204
7205    def sexpr(self):
7206        """Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
7207        """
7208        return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7209
7210    def to_string(self, queries):
7211        """Return a formatted string (in Lisp-like format) with all added constraints.
7212           We say the string is in s-expression format.
7213           Include also queries.
7214        """
7215        args, len = _to_ast_array(queries)
7216        return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7217
7218    def statistics(self):
7219        """Return statistics for the last `query()`.
7220        """
7221        return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7222
7223    def reason_unknown(self):
7224        """Return a string describing why the last `query()` returned `unknown`.
7225        """
7226        return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7227
7228    def declare_var(self, *vars):
7229        """Add variable or several variables.
7230        The added variable or variables will be bound in the rules
7231        and queries
7232        """
7233        vars = _get_args(vars)
7234        for v in vars:
7235            self.vars += [v]
7236
7237    def abstract(self, fml, is_forall=True):
7238        if self.vars == []:
7239            return fml
7240        if is_forall:
7241            return ForAll(self.vars, fml)
7242        else:
7243            return Exists(self.vars, fml)
7244
7245
7246#########################################
7247#
7248# Finite domains
7249#
7250#########################################
7251
7252class FiniteDomainSortRef(SortRef):
7253    """Finite domain sort."""
7254
7255    def size(self):
7256        """Return the size of the finite domain sort"""
7257        r = (ctypes.c_ulonglong * 1)()
7258        if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7259            return r[0]
7260        else:
7261            raise Z3Exception("Failed to retrieve finite domain sort size")
7262
7263def FiniteDomainSort(name, sz, ctx=None):
7264    """Create a named finite domain sort of a given size sz"""
7265    if not isinstance(name, Symbol):
7266        name = to_symbol(name)
7267    ctx = _get_ctx(ctx)
7268    return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7269
7270def is_finite_domain_sort(s):
7271    """Return True if `s` is a Z3 finite-domain sort.
7272
7273    >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7274    True
7275    >>> is_finite_domain_sort(IntSort())
7276    False
7277    """
7278    return isinstance(s, FiniteDomainSortRef)
7279
7280
7281class FiniteDomainRef(ExprRef):
7282    """Finite-domain expressions."""
7283
7284    def sort(self):
7285        """Return the sort of the finite-domain expression `self`."""
7286        return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7287
7288    def as_string(self):
7289        """Return a Z3 floating point expression as a Python string."""
7290        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7291
7292def is_finite_domain(a):
7293    """Return `True` if `a` is a Z3 finite-domain expression.
7294
7295    >>> s = FiniteDomainSort('S', 100)
7296    >>> b = Const('b', s)
7297    >>> is_finite_domain(b)
7298    True
7299    >>> is_finite_domain(Int('x'))
7300    False
7301    """
7302    return isinstance(a, FiniteDomainRef)
7303
7304
7305class FiniteDomainNumRef(FiniteDomainRef):
7306    """Integer values."""
7307
7308    def as_long(self):
7309        """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7310
7311        >>> s = FiniteDomainSort('S', 100)
7312        >>> v = FiniteDomainVal(3, s)
7313        >>> v
7314        3
7315        >>> v.as_long() + 1
7316        4
7317        """
7318        return int(self.as_string())
7319
7320    def as_string(self):
7321        """Return a Z3 finite-domain numeral as a Python string.
7322
7323        >>> s = FiniteDomainSort('S', 100)
7324        >>> v = FiniteDomainVal(42, s)
7325        >>> v.as_string()
7326        '42'
7327        """
7328        return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
7329
7330
7331def FiniteDomainVal(val, sort, ctx=None):
7332    """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
7333
7334    >>> s = FiniteDomainSort('S', 256)
7335    >>> FiniteDomainVal(255, s)
7336    255
7337    >>> FiniteDomainVal('100', s)
7338    100
7339    """
7340    if z3_debug():
7341        _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort" )
7342    ctx = sort.ctx
7343    return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
7344
7345def is_finite_domain_value(a):
7346    """Return `True` if `a` is a Z3 finite-domain value.
7347
7348    >>> s = FiniteDomainSort('S', 100)
7349    >>> b = Const('b', s)
7350    >>> is_finite_domain_value(b)
7351    False
7352    >>> b = FiniteDomainVal(10, s)
7353    >>> b
7354    10
7355    >>> is_finite_domain_value(b)
7356    True
7357    """
7358    return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
7359
7360
7361#########################################
7362#
7363# Optimize
7364#
7365#########################################
7366
7367class OptimizeObjective:
7368    def __init__(self, opt, value, is_max):
7369        self._opt = opt
7370        self._value = value
7371        self._is_max = is_max
7372
7373    def lower(self):
7374        opt = self._opt
7375        return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7376
7377    def upper(self):
7378        opt = self._opt
7379        return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7380
7381    def lower_values(self):
7382        opt = self._opt
7383        return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7384
7385    def upper_values(self):
7386        opt = self._opt
7387        return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7388
7389    def value(self):
7390        if self._is_max:
7391            return self.upper()
7392        else:
7393            return self.lower()
7394
7395    def __str__(self):
7396        return "%s:%s" % (self._value, self._is_max)
7397
7398
7399class Optimize(Z3PPObject):
7400    """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
7401
7402    def __init__(self, ctx=None):
7403        self.ctx    = _get_ctx(ctx)
7404        self.optimize = Z3_mk_optimize(self.ctx.ref())
7405        Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
7406
7407    def __deepcopy__(self, memo={}):
7408        return Optimize(self.optimize, self.ctx)
7409
7410    def __del__(self):
7411        if self.optimize is not None and self.ctx.ref() is not None:
7412            Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
7413
7414    def set(self, *args, **keys):
7415        """Set a configuration option. The method `help()` return a string containing all available options.
7416        """
7417        p = args2params(args, keys, self.ctx)
7418        Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
7419
7420    def help(self):
7421        """Display a string describing all available options."""
7422        print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
7423
7424    def param_descrs(self):
7425        """Return the parameter description set."""
7426        return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
7427
7428    def assert_exprs(self, *args):
7429        """Assert constraints as background axioms for the optimize solver."""
7430        args = _get_args(args)
7431        s    = BoolSort(self.ctx)
7432        for arg in args:
7433            if isinstance(arg, Goal) or isinstance(arg, AstVector):
7434                for f in arg:
7435                    Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
7436            else:
7437                arg = s.cast(arg)
7438                Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
7439
7440    def add(self, *args):
7441        """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
7442        self.assert_exprs(*args)
7443
7444    def __iadd__(self, fml):
7445        self.add(fml)
7446        return self
7447
7448    def assert_and_track(self, a, p):
7449        """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7450
7451        If `p` is a string, it will be automatically converted into a Boolean constant.
7452
7453        >>> x = Int('x')
7454        >>> p3 = Bool('p3')
7455        >>> s = Optimize()
7456        >>> s.assert_and_track(x > 0,  'p1')
7457        >>> s.assert_and_track(x != 1, 'p2')
7458        >>> s.assert_and_track(x < 0,  p3)
7459        >>> print(s.check())
7460        unsat
7461        >>> c = s.unsat_core()
7462        >>> len(c)
7463        2
7464        >>> Bool('p1') in c
7465        True
7466        >>> Bool('p2') in c
7467        False
7468        >>> p3 in c
7469        True
7470        """
7471        if isinstance(p, str):
7472            p = Bool(p, self.ctx)
7473        _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7474        _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7475        Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
7476
7477    def add_soft(self, arg, weight = "1", id = None):
7478        """Add soft constraint with optional weight and optional identifier.
7479           If no weight is supplied, then the penalty for violating the soft constraint
7480           is 1.
7481           Soft constraints are grouped by identifiers. Soft constraints that are
7482           added without identifiers are grouped by default.
7483        """
7484        if _is_int(weight):
7485            weight = "%d" % weight
7486        elif isinstance(weight, float):
7487            weight = "%f" % weight
7488        if not isinstance(weight, str):
7489            raise Z3Exception("weight should be a string or an integer")
7490        if id is None:
7491            id = ""
7492        id = to_symbol(id, self.ctx)
7493        v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, arg.as_ast(), weight, id)
7494        return OptimizeObjective(self, v, False)
7495
7496    def maximize(self, arg):
7497        """Add objective function to maximize."""
7498        return OptimizeObjective(self, Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()), True)
7499
7500    def minimize(self, arg):
7501        """Add objective function to minimize."""
7502        return OptimizeObjective(self, Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()), False)
7503
7504    def push(self):
7505        """create a backtracking point for added rules, facts and assertions"""
7506        Z3_optimize_push(self.ctx.ref(), self.optimize)
7507
7508    def pop(self):
7509        """restore to previously created backtracking point"""
7510        Z3_optimize_pop(self.ctx.ref(), self.optimize)
7511
7512    def check(self, *assumptions):
7513        """Check satisfiability while optimizing objective functions."""
7514        assumptions = _get_args(assumptions)
7515        num = len(assumptions)
7516        _assumptions = (Ast * num)()
7517        for i in range(num):
7518            _assumptions[i] = assumptions[i].as_ast()
7519        return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
7520
7521    def reason_unknown(self):
7522        """Return a string that describes why the last `check()` returned `unknown`."""
7523        return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
7524
7525    def model(self):
7526        """Return a model for the last check()."""
7527        try:
7528            return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
7529        except Z3Exception:
7530            raise Z3Exception("model is not available")
7531
7532    def unsat_core(self):
7533        return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
7534
7535    def lower(self, obj):
7536        if not isinstance(obj, OptimizeObjective):
7537            raise Z3Exception("Expecting objective handle returned by maximize/minimize")
7538        return obj.lower()
7539
7540    def upper(self, obj):
7541        if not isinstance(obj, OptimizeObjective):
7542            raise Z3Exception("Expecting objective handle returned by maximize/minimize")
7543        return obj.upper()
7544
7545    def lower_values(self, obj):
7546        if not isinstance(obj, OptimizeObjective):
7547            raise Z3Exception("Expecting objective handle returned by maximize/minimize")
7548        return obj.lower_values()
7549
7550    def upper_values(self, obj):
7551        if not isinstance(obj, OptimizeObjective):
7552            raise Z3Exception("Expecting objective handle returned by maximize/minimize")
7553        return obj.upper_values()
7554
7555    def from_file(self, filename):
7556        """Parse assertions and objectives from a file"""
7557        Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
7558
7559    def from_string(self, s):
7560        """Parse assertions and objectives from a string"""
7561        Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
7562
7563    def assertions(self):
7564        """Return an AST vector containing all added constraints."""
7565        return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
7566
7567    def objectives(self):
7568        """returns set of objective functions"""
7569        return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
7570
7571    def __repr__(self):
7572        """Return a formatted string with all added rules and constraints."""
7573        return self.sexpr()
7574
7575    def sexpr(self):
7576        """Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
7577        """
7578        return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
7579
7580    def statistics(self):
7581        """Return statistics for the last check`.
7582        """
7583        return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
7584
7585
7586
7587
7588#########################################
7589#
7590# ApplyResult
7591#
7592#########################################
7593class ApplyResult(Z3PPObject):
7594    """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal. It also contains model and proof converters."""
7595
7596    def __init__(self, result, ctx):
7597        self.result = result
7598        self.ctx    = ctx
7599        Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
7600
7601    def __deepcopy__(self, memo={}):
7602        return ApplyResult(self.result, self.ctx)
7603
7604    def __del__(self):
7605        if self.ctx.ref() is not None:
7606            Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
7607
7608    def __len__(self):
7609        """Return the number of subgoals in `self`.
7610
7611        >>> a, b = Ints('a b')
7612        >>> g = Goal()
7613        >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
7614        >>> t = Tactic('split-clause')
7615        >>> r = t(g)
7616        >>> len(r)
7617        2
7618        >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
7619        >>> len(t(g))
7620        4
7621        >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
7622        >>> len(t(g))
7623        1
7624        """
7625        return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
7626
7627    def __getitem__(self, idx):
7628        """Return one of the subgoals stored in ApplyResult object `self`.
7629
7630        >>> a, b = Ints('a b')
7631        >>> g = Goal()
7632        >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
7633        >>> t = Tactic('split-clause')
7634        >>> r = t(g)
7635        >>> r[0]
7636        [a == 0, Or(b == 0, b == 1), a > b]
7637        >>> r[1]
7638        [a == 1, Or(b == 0, b == 1), a > b]
7639        """
7640        if idx >= len(self):
7641            raise IndexError
7642        return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
7643
7644    def __repr__(self):
7645        return obj_to_string(self)
7646
7647    def sexpr(self):
7648        """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
7649        return Z3_apply_result_to_string(self.ctx.ref(), self.result)
7650
7651
7652    def as_expr(self):
7653        """Return a Z3 expression consisting of all subgoals.
7654
7655        >>> x = Int('x')
7656        >>> g = Goal()
7657        >>> g.add(x > 1)
7658        >>> g.add(Or(x == 2, x == 3))
7659        >>> r = Tactic('simplify')(g)
7660        >>> r
7661        [[Not(x <= 1), Or(x == 2, x == 3)]]
7662        >>> r.as_expr()
7663        And(Not(x <= 1), Or(x == 2, x == 3))
7664        >>> r = Tactic('split-clause')(g)
7665        >>> r
7666        [[x > 1, x == 2], [x > 1, x == 3]]
7667        >>> r.as_expr()
7668        Or(And(x > 1, x == 2), And(x > 1, x == 3))
7669        """
7670        sz = len(self)
7671        if sz == 0:
7672            return BoolVal(False, self.ctx)
7673        elif sz == 1:
7674            return self[0].as_expr()
7675        else:
7676            return Or([ self[i].as_expr() for i in range(len(self)) ])
7677
7678#########################################
7679#
7680# Tactics
7681#
7682#########################################
7683class Tactic:
7684    """Tactics transform, solver and/or simplify sets of constraints (Goal). A Tactic can be converted into a Solver using the method solver().
7685
7686    Several combinators are available for creating new tactics using the built-in ones: Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
7687    """
7688    def __init__(self, tactic, ctx=None):
7689        self.ctx    = _get_ctx(ctx)
7690        self.tactic = None
7691        if isinstance(tactic, TacticObj):
7692            self.tactic = tactic
7693        else:
7694            if z3_debug():
7695                _z3_assert(isinstance(tactic, str), "tactic name expected")
7696            try:
7697                self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
7698            except Z3Exception:
7699                raise Z3Exception("unknown tactic '%s'" % tactic)
7700        Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
7701
7702    def __deepcopy__(self, memo={}):
7703        return Tactic(self.tactic, self.ctx)
7704
7705    def __del__(self):
7706        if self.tactic is not None and self.ctx.ref() is not None:
7707            Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
7708
7709    def solver(self, logFile=None):
7710        """Create a solver using the tactic `self`.
7711
7712        The solver supports the methods `push()` and `pop()`, but it
7713        will always solve each `check()` from scratch.
7714
7715        >>> t = Then('simplify', 'nlsat')
7716        >>> s = t.solver()
7717        >>> x = Real('x')
7718        >>> s.add(x**2 == 2, x > 0)
7719        >>> s.check()
7720        sat
7721        >>> s.model()
7722        [x = 1.4142135623?]
7723        """
7724        return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
7725
7726    def apply(self, goal, *arguments, **keywords):
7727        """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
7728
7729        >>> x, y = Ints('x y')
7730        >>> t = Tactic('solve-eqs')
7731        >>> t.apply(And(x == 0, y >= x + 1))
7732        [[y >= 1]]
7733        """
7734        if z3_debug():
7735            _z3_assert(isinstance(goal, Goal) or isinstance(goal, BoolRef), "Z3 Goal or Boolean expressions expected")
7736        goal = _to_goal(goal)
7737        if len(arguments) > 0 or len(keywords) > 0:
7738            p = args2params(arguments, keywords, self.ctx)
7739            return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
7740        else:
7741            return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
7742
7743    def __call__(self, goal, *arguments, **keywords):
7744        """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
7745
7746        >>> x, y = Ints('x y')
7747        >>> t = Tactic('solve-eqs')
7748        >>> t(And(x == 0, y >= x + 1))
7749        [[y >= 1]]
7750        """
7751        return self.apply(goal, *arguments, **keywords)
7752
7753    def help(self):
7754        """Display a string containing a description of the available options for the `self` tactic."""
7755        print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
7756
7757    def param_descrs(self):
7758        """Return the parameter description set."""
7759        return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
7760
7761def _to_goal(a):
7762    if isinstance(a, BoolRef):
7763        goal = Goal(ctx = a.ctx)
7764        goal.add(a)
7765        return goal
7766    else:
7767        return a
7768
7769def _to_tactic(t, ctx=None):
7770    if isinstance(t, Tactic):
7771        return t
7772    else:
7773        return Tactic(t, ctx)
7774
7775def _and_then(t1, t2, ctx=None):
7776    t1 = _to_tactic(t1, ctx)
7777    t2 = _to_tactic(t2, ctx)
7778    if z3_debug():
7779        _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
7780    return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
7781
7782def _or_else(t1, t2, ctx=None):
7783    t1 = _to_tactic(t1, ctx)
7784    t2 = _to_tactic(t2, ctx)
7785    if z3_debug():
7786        _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
7787    return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
7788
7789def AndThen(*ts, **ks):
7790    """Return a tactic that applies the tactics in `*ts` in sequence.
7791
7792    >>> x, y = Ints('x y')
7793    >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
7794    >>> t(And(x == 0, y > x + 1))
7795    [[Not(y <= 1)]]
7796    >>> t(And(x == 0, y > x + 1)).as_expr()
7797    Not(y <= 1)
7798    """
7799    if z3_debug():
7800        _z3_assert(len(ts) >= 2, "At least two arguments expected")
7801    ctx = ks.get('ctx', None)
7802    num = len(ts)
7803    r = ts[0]
7804    for i in range(num - 1):
7805        r = _and_then(r, ts[i+1], ctx)
7806    return r
7807
7808def Then(*ts, **ks):
7809    """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
7810
7811    >>> x, y = Ints('x y')
7812    >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
7813    >>> t(And(x == 0, y > x + 1))
7814    [[Not(y <= 1)]]
7815    >>> t(And(x == 0, y > x + 1)).as_expr()
7816    Not(y <= 1)
7817    """
7818    return AndThen(*ts, **ks)
7819
7820def OrElse(*ts, **ks):
7821    """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
7822
7823    >>> x = Int('x')
7824    >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
7825    >>> # Tactic split-clause fails if there is no clause in the given goal.
7826    >>> t(x == 0)
7827    [[x == 0]]
7828    >>> t(Or(x == 0, x == 1))
7829    [[x == 0], [x == 1]]
7830    """
7831    if z3_debug():
7832        _z3_assert(len(ts) >= 2, "At least two arguments expected")
7833    ctx = ks.get('ctx', None)
7834    num = len(ts)
7835    r = ts[0]
7836    for i in range(num - 1):
7837        r = _or_else(r, ts[i+1], ctx)
7838    return r
7839
7840def ParOr(*ts, **ks):
7841    """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
7842
7843    >>> x = Int('x')
7844    >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
7845    >>> t(x + 1 == 2)
7846    [[x == 1]]
7847    """
7848    if z3_debug():
7849        _z3_assert(len(ts) >= 2, "At least two arguments expected")
7850    ctx = _get_ctx(ks.get('ctx', None))
7851    ts  = [ _to_tactic(t, ctx) for t in ts ]
7852    sz  = len(ts)
7853    _args = (TacticObj * sz)()
7854    for i in range(sz):
7855        _args[i] = ts[i].tactic
7856    return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
7857
7858def ParThen(t1, t2, ctx=None):
7859    """Return a tactic that applies t1 and then t2 to every subgoal produced by t1. The subgoals are processed in parallel.
7860
7861    >>> x, y = Ints('x y')
7862    >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
7863    >>> t(And(Or(x == 1, x == 2), y == x + 1))
7864    [[x == 1, y == 2], [x == 2, y == 3]]
7865    """
7866    t1 = _to_tactic(t1, ctx)
7867    t2 = _to_tactic(t2, ctx)
7868    if z3_debug():
7869        _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
7870    return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
7871
7872def ParAndThen(t1, t2, ctx=None):
7873    """Alias for ParThen(t1, t2, ctx)."""
7874    return ParThen(t1, t2, ctx)
7875
7876def With(t, *args, **keys):
7877    """Return a tactic that applies tactic `t` using the given configuration options.
7878
7879    >>> x, y = Ints('x y')
7880    >>> t = With(Tactic('simplify'), som=True)
7881    >>> t((x + 1)*(y + 2) == 0)
7882    [[2*x + y + x*y == -2]]
7883    """
7884    ctx = keys.pop('ctx', None)
7885    t = _to_tactic(t, ctx)
7886    p = args2params(args, keys, t.ctx)
7887    return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
7888
7889def WithParams(t, p):
7890    """Return a tactic that applies tactic `t` using the given configuration options.
7891
7892    >>> x, y = Ints('x y')
7893    >>> p = ParamsRef()
7894    >>> p.set("som", True)
7895    >>> t = WithParams(Tactic('simplify'), p)
7896    >>> t((x + 1)*(y + 2) == 0)
7897    [[2*x + y + x*y == -2]]
7898    """
7899    t = _to_tactic(t, None)
7900    return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
7901
7902def Repeat(t, max=4294967295, ctx=None):
7903    """Return a tactic that keeps applying `t` until the goal is not modified anymore or the maximum number of iterations `max` is reached.
7904
7905    >>> x, y = Ints('x y')
7906    >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
7907    >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
7908    >>> r = t(c)
7909    >>> for subgoal in r: print(subgoal)
7910    [x == 0, y == 0, x > y]
7911    [x == 0, y == 1, x > y]
7912    [x == 1, y == 0, x > y]
7913    [x == 1, y == 1, x > y]
7914    >>> t = Then(t, Tactic('propagate-values'))
7915    >>> t(c)
7916    [[x == 1, y == 0]]
7917    """
7918    t = _to_tactic(t, ctx)
7919    return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
7920
7921def TryFor(t, ms, ctx=None):
7922    """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
7923
7924    If `t` does not terminate in `ms` milliseconds, then it fails.
7925    """
7926    t = _to_tactic(t, ctx)
7927    return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
7928
7929def tactics(ctx=None):
7930    """Return a list of all available tactics in Z3.
7931
7932    >>> l = tactics()
7933    >>> l.count('simplify') == 1
7934    True
7935    """
7936    ctx = _get_ctx(ctx)
7937    return [ Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref())) ]
7938
7939def tactic_description(name, ctx=None):
7940    """Return a short description for the tactic named `name`.
7941
7942    >>> d = tactic_description('simplify')
7943    """
7944    ctx = _get_ctx(ctx)
7945    return Z3_tactic_get_descr(ctx.ref(), name)
7946
7947def describe_tactics():
7948    """Display a (tabular) description of all available tactics in Z3."""
7949    if in_html_mode():
7950        even = True
7951        print('<table border="1" cellpadding="2" cellspacing="0">')
7952        for t in tactics():
7953            if even:
7954                print('<tr style="background-color:#CFCFCF">')
7955                even = False
7956            else:
7957                print('<tr>')
7958                even = True
7959            print('<td>%s</td><td>%s</td></tr>' % (t, insert_line_breaks(tactic_description(t), 40)))
7960        print('</table>')
7961    else:
7962        for t in tactics():
7963            print('%s : %s' % (t, tactic_description(t)))
7964
7965class Probe:
7966    """Probes are used to inspect a goal (aka problem) and collect information that may be used to decide which solver and/or preprocessing step will be used."""
7967    def __init__(self, probe, ctx=None):
7968        self.ctx    = _get_ctx(ctx)
7969        self.probe  = None
7970        if isinstance(probe, ProbeObj):
7971            self.probe = probe
7972        elif isinstance(probe, float):
7973            self.probe = Z3_probe_const(self.ctx.ref(), probe)
7974        elif _is_int(probe):
7975            self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
7976        elif isinstance(probe, bool):
7977            if probe:
7978                self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
7979            else:
7980                self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
7981        else:
7982            if z3_debug():
7983                _z3_assert(isinstance(probe, str), "probe name expected")
7984            try:
7985                self.probe = Z3_mk_probe(self.ctx.ref(), probe)
7986            except Z3Exception:
7987                raise Z3Exception("unknown probe '%s'" % probe)
7988        Z3_probe_inc_ref(self.ctx.ref(), self.probe)
7989
7990    def __deepcopy__(self, memo={}):
7991        return Probe(self.probe, self.ctx)
7992
7993    def __del__(self):
7994        if self.probe is not None and self.ctx.ref() is not None:
7995            Z3_probe_dec_ref(self.ctx.ref(), self.probe)
7996
7997    def __lt__(self, other):
7998        """Return a probe that evaluates to "true" when the value returned by `self` is less than the value returned by `other`.
7999
8000        >>> p = Probe('size') < 10
8001        >>> x = Int('x')
8002        >>> g = Goal()
8003        >>> g.add(x > 0)
8004        >>> g.add(x < 10)
8005        >>> p(g)
8006        1.0
8007        """
8008        return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8009
8010    def __gt__(self, other):
8011        """Return a probe that evaluates to "true" when the value returned by `self` is greater than the value returned by `other`.
8012
8013        >>> p = Probe('size') > 10
8014        >>> x = Int('x')
8015        >>> g = Goal()
8016        >>> g.add(x > 0)
8017        >>> g.add(x < 10)
8018        >>> p(g)
8019        0.0
8020        """
8021        return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8022
8023    def __le__(self, other):
8024        """Return a probe that evaluates to "true" when the value returned by `self` is less than or equal to the value returned by `other`.
8025
8026        >>> p = Probe('size') <= 2
8027        >>> x = Int('x')
8028        >>> g = Goal()
8029        >>> g.add(x > 0)
8030        >>> g.add(x < 10)
8031        >>> p(g)
8032        1.0
8033        """
8034        return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8035
8036    def __ge__(self, other):
8037        """Return a probe that evaluates to "true" when the value returned by `self` is greater than or equal to the value returned by `other`.
8038
8039        >>> p = Probe('size') >= 2
8040        >>> x = Int('x')
8041        >>> g = Goal()
8042        >>> g.add(x > 0)
8043        >>> g.add(x < 10)
8044        >>> p(g)
8045        1.0
8046        """
8047        return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8048
8049    def __eq__(self, other):
8050        """Return a probe that evaluates to "true" when the value returned by `self` is equal to the value returned by `other`.
8051
8052        >>> p = Probe('size') == 2
8053        >>> x = Int('x')
8054        >>> g = Goal()
8055        >>> g.add(x > 0)
8056        >>> g.add(x < 10)
8057        >>> p(g)
8058        1.0
8059        """
8060        return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8061
8062    def __ne__(self, other):
8063        """Return a probe that evaluates to "true" when the value returned by `self` is not equal to the value returned by `other`.
8064
8065        >>> p = Probe('size') != 2
8066        >>> x = Int('x')
8067        >>> g = Goal()
8068        >>> g.add(x > 0)
8069        >>> g.add(x < 10)
8070        >>> p(g)
8071        0.0
8072        """
8073        p = self.__eq__(other)
8074        return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8075
8076    def __call__(self, goal):
8077        """Evaluate the probe `self` in the given goal.
8078
8079        >>> p = Probe('size')
8080        >>> x = Int('x')
8081        >>> g = Goal()
8082        >>> g.add(x > 0)
8083        >>> g.add(x < 10)
8084        >>> p(g)
8085        2.0
8086        >>> g.add(x < 20)
8087        >>> p(g)
8088        3.0
8089        >>> p = Probe('num-consts')
8090        >>> p(g)
8091        1.0
8092        >>> p = Probe('is-propositional')
8093        >>> p(g)
8094        0.0
8095        >>> p = Probe('is-qflia')
8096        >>> p(g)
8097        1.0
8098        """
8099        if z3_debug():
8100            _z3_assert(isinstance(goal, Goal) or isinstance(goal, BoolRef), "Z3 Goal or Boolean expression expected")
8101        goal = _to_goal(goal)
8102        return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8103
8104def is_probe(p):
8105    """Return `True` if `p` is a Z3 probe.
8106
8107    >>> is_probe(Int('x'))
8108    False
8109    >>> is_probe(Probe('memory'))
8110    True
8111    """
8112    return isinstance(p, Probe)
8113
8114def _to_probe(p, ctx=None):
8115    if is_probe(p):
8116        return p
8117    else:
8118        return Probe(p, ctx)
8119
8120def probes(ctx=None):
8121    """Return a list of all available probes in Z3.
8122
8123    >>> l = probes()
8124    >>> l.count('memory') == 1
8125    True
8126    """
8127    ctx = _get_ctx(ctx)
8128    return [ Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref())) ]
8129
8130def probe_description(name, ctx=None):
8131    """Return a short description for the probe named `name`.
8132
8133    >>> d = probe_description('memory')
8134    """
8135    ctx = _get_ctx(ctx)
8136    return Z3_probe_get_descr(ctx.ref(), name)
8137
8138def describe_probes():
8139    """Display a (tabular) description of all available probes in Z3."""
8140    if in_html_mode():
8141        even = True
8142        print('<table border="1" cellpadding="2" cellspacing="0">')
8143        for p in probes():
8144            if even:
8145                print('<tr style="background-color:#CFCFCF">')
8146                even = False
8147            else:
8148                print('<tr>')
8149                even = True
8150            print('<td>%s</td><td>%s</td></tr>' % (p, insert_line_breaks(probe_description(p), 40)))
8151        print('</table>')
8152    else:
8153        for p in probes():
8154            print('%s : %s' % (p, probe_description(p)))
8155
8156def _probe_nary(f, args, ctx):
8157    if z3_debug():
8158        _z3_assert(len(args) > 0, "At least one argument expected")
8159    num = len(args)
8160    r = _to_probe(args[0], ctx)
8161    for i in range(num - 1):
8162        r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i+1], ctx).probe), ctx)
8163    return r
8164
8165def _probe_and(args, ctx):
8166    return _probe_nary(Z3_probe_and, args, ctx)
8167
8168def _probe_or(args, ctx):
8169    return _probe_nary(Z3_probe_or, args, ctx)
8170
8171def FailIf(p, ctx=None):
8172    """Return a tactic that fails if the probe `p` evaluates to true. Otherwise, it returns the input goal unmodified.
8173
8174    In the following example, the tactic applies 'simplify' if and only if there are more than 2 constraints in the goal.
8175
8176    >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
8177    >>> x, y = Ints('x y')
8178    >>> g = Goal()
8179    >>> g.add(x > 0)
8180    >>> g.add(y > 0)
8181    >>> t(g)
8182    [[x > 0, y > 0]]
8183    >>> g.add(x == y + 1)
8184    >>> t(g)
8185    [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8186    """
8187    p = _to_probe(p, ctx)
8188    return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
8189
8190def When(p, t, ctx=None):
8191    """Return a tactic that applies tactic `t` only if probe `p` evaluates to true. Otherwise, it returns the input goal unmodified.
8192
8193    >>> t = When(Probe('size') > 2, Tactic('simplify'))
8194    >>> x, y = Ints('x y')
8195    >>> g = Goal()
8196    >>> g.add(x > 0)
8197    >>> g.add(y > 0)
8198    >>> t(g)
8199    [[x > 0, y > 0]]
8200    >>> g.add(x == y + 1)
8201    >>> t(g)
8202    [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8203    """
8204    p = _to_probe(p, ctx)
8205    t = _to_tactic(t, ctx)
8206    return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
8207
8208def Cond(p, t1, t2, ctx=None):
8209    """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
8210
8211    >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
8212    """
8213    p = _to_probe(p, ctx)
8214    t1 = _to_tactic(t1, ctx)
8215    t2 = _to_tactic(t2, ctx)
8216    return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
8217
8218#########################################
8219#
8220# Utils
8221#
8222#########################################
8223
8224def simplify(a, *arguments, **keywords):
8225    """Simplify the expression `a` using the given options.
8226
8227    This function has many options. Use `help_simplify` to obtain the complete list.
8228
8229    >>> x = Int('x')
8230    >>> y = Int('y')
8231    >>> simplify(x + 1 + y + x + 1)
8232    2 + 2*x + y
8233    >>> simplify((x + 1)*(y + 1), som=True)
8234    1 + x + y + x*y
8235    >>> simplify(Distinct(x, y, 1), blast_distinct=True)
8236    And(Not(x == y), Not(x == 1), Not(y == 1))
8237    >>> simplify(And(x == 0, y == 1), elim_and=True)
8238    Not(Or(Not(x == 0), Not(y == 1)))
8239    """
8240    if z3_debug():
8241        _z3_assert(is_expr(a), "Z3 expression expected")
8242    if len(arguments) > 0 or len(keywords) > 0:
8243        p = args2params(arguments, keywords, a.ctx)
8244        return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
8245    else:
8246        return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
8247
8248def help_simplify():
8249    """Return a string describing all options available for Z3 `simplify` procedure."""
8250    print(Z3_simplify_get_help(main_ctx().ref()))
8251
8252def simplify_param_descrs():
8253    """Return the set of parameter descriptions for Z3 `simplify` procedure."""
8254    return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
8255
8256def substitute(t, *m):
8257    """Apply substitution m on t, m is a list of pairs of the form (from, to). Every occurrence in t of from is replaced with to.
8258
8259    >>> x = Int('x')
8260    >>> y = Int('y')
8261    >>> substitute(x + 1, (x, y + 1))
8262    y + 1 + 1
8263    >>> f = Function('f', IntSort(), IntSort())
8264    >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
8265    1 + 1
8266    """
8267    if isinstance(m, tuple):
8268        m1 = _get_args(m)
8269        if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
8270            m = m1
8271    if z3_debug():
8272        _z3_assert(is_expr(t), "Z3 expression expected")
8273        _z3_assert(all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) and p[0].sort().eq(p[1].sort()) for p in m]), "Z3 invalid substitution, expression pairs expected.")
8274    num = len(m)
8275    _from = (Ast * num)()
8276    _to   = (Ast * num)()
8277    for i in range(num):
8278        _from[i] = m[i][0].as_ast()
8279        _to[i]   = m[i][1].as_ast()
8280    return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
8281
8282def substitute_vars(t, *m):
8283    """Substitute the free variables in t with the expression in m.
8284
8285    >>> v0 = Var(0, IntSort())
8286    >>> v1 = Var(1, IntSort())
8287    >>> x  = Int('x')
8288    >>> f  = Function('f', IntSort(), IntSort(), IntSort())
8289    >>> # replace v0 with x+1 and v1 with x
8290    >>> substitute_vars(f(v0, v1), x + 1, x)
8291    f(x + 1, x)
8292    """
8293    if z3_debug():
8294        _z3_assert(is_expr(t), "Z3 expression expected")
8295        _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
8296    num = len(m)
8297    _to   = (Ast * num)()
8298    for i in range(num):
8299        _to[i] = m[i].as_ast()
8300    return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
8301
8302def Sum(*args):
8303    """Create the sum of the Z3 expressions.
8304
8305    >>> a, b, c = Ints('a b c')
8306    >>> Sum(a, b, c)
8307    a + b + c
8308    >>> Sum([a, b, c])
8309    a + b + c
8310    >>> A = IntVector('a', 5)
8311    >>> Sum(A)
8312    a__0 + a__1 + a__2 + a__3 + a__4
8313    """
8314    args  = _get_args(args)
8315    if len(args) == 0:
8316        return 0
8317    ctx   = _ctx_from_ast_arg_list(args)
8318    if ctx is None:
8319        return _reduce(lambda a, b: a + b, args, 0)
8320    args  = _coerce_expr_list(args, ctx)
8321    if is_bv(args[0]):
8322        return _reduce(lambda a, b: a + b, args, 0)
8323    else:
8324        _args, sz = _to_ast_array(args)
8325        return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
8326
8327
8328def Product(*args):
8329    """Create the product of the Z3 expressions.
8330
8331    >>> a, b, c = Ints('a b c')
8332    >>> Product(a, b, c)
8333    a*b*c
8334    >>> Product([a, b, c])
8335    a*b*c
8336    >>> A = IntVector('a', 5)
8337    >>> Product(A)
8338    a__0*a__1*a__2*a__3*a__4
8339    """
8340    args  = _get_args(args)
8341    if len(args) == 0:
8342        return 1
8343    ctx   = _ctx_from_ast_arg_list(args)
8344    if ctx is None:
8345        return _reduce(lambda a, b: a * b, args, 1)
8346    args  = _coerce_expr_list(args, ctx)
8347    if is_bv(args[0]):
8348        return _reduce(lambda a, b: a * b, args, 1)
8349    else:
8350        _args, sz = _to_ast_array(args)
8351        return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
8352
8353def AtMost(*args):
8354    """Create an at-most Pseudo-Boolean k constraint.
8355
8356    >>> a, b, c = Bools('a b c')
8357    >>> f = AtMost(a, b, c, 2)
8358    """
8359    args  = _get_args(args)
8360    if z3_debug():
8361        _z3_assert(len(args) > 1, "Non empty list of arguments expected")
8362    ctx   = _ctx_from_ast_arg_list(args)
8363    if z3_debug():
8364        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
8365    args1 = _coerce_expr_list(args[:-1], ctx)
8366    k = args[-1]
8367    _args, sz = _to_ast_array(args1)
8368    return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
8369
8370def AtLeast(*args):
8371    """Create an at-most Pseudo-Boolean k constraint.
8372
8373    >>> a, b, c = Bools('a b c')
8374    >>> f = AtLeast(a, b, c, 2)
8375    """
8376    args  = _get_args(args)
8377    if z3_debug():
8378        _z3_assert(len(args) > 1, "Non empty list of arguments expected")
8379    ctx   = _ctx_from_ast_arg_list(args)
8380    if z3_debug():
8381        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
8382    args1 = _coerce_expr_list(args[:-1], ctx)
8383    k = args[-1]
8384    _args, sz = _to_ast_array(args1)
8385    return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
8386
8387def _reorder_pb_arg(arg):
8388    a, b = arg
8389    if not _is_int(b) and _is_int(a):
8390        return b, a
8391    return arg
8392
8393def _pb_args_coeffs(args, default_ctx = None):
8394    args  = _get_args_ast_list(args)
8395    if len(args) == 0:
8396       return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
8397    args = [_reorder_pb_arg(arg) for arg in args]
8398    args, coeffs = zip(*args)
8399    if z3_debug():
8400        _z3_assert(len(args) > 0, "Non empty list of arguments expected")
8401    ctx   = _ctx_from_ast_arg_list(args)
8402    if z3_debug():
8403        _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
8404    args = _coerce_expr_list(args, ctx)
8405    _args, sz = _to_ast_array(args)
8406    _coeffs = (ctypes.c_int * len(coeffs))()
8407    for i in range(len(coeffs)):
8408        _z3_check_cint_overflow(coeffs[i], "coefficient")
8409        _coeffs[i] = coeffs[i]
8410    return ctx, sz, _args, _coeffs
8411
8412def PbLe(args, k):
8413    """Create a Pseudo-Boolean inequality k constraint.
8414
8415    >>> a, b, c = Bools('a b c')
8416    >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
8417    """
8418    _z3_check_cint_overflow(k, "k")
8419    ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
8420    return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
8421
8422def PbGe(args, k):
8423    """Create a Pseudo-Boolean inequality k constraint.
8424
8425    >>> a, b, c = Bools('a b c')
8426    >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
8427    """
8428    _z3_check_cint_overflow(k, "k")
8429    ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
8430    return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
8431
8432def PbEq(args, k, ctx = None):
8433    """Create a Pseudo-Boolean inequality k constraint.
8434
8435    >>> a, b, c = Bools('a b c')
8436    >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
8437    """
8438    _z3_check_cint_overflow(k, "k")
8439    ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
8440    return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
8441
8442
8443def solve(*args, **keywords):
8444    """Solve the constraints `*args`.
8445
8446    This is a simple function for creating demonstrations. It creates a solver,
8447    configure it using the options in `keywords`, adds the constraints
8448    in `args`, and invokes check.
8449
8450    >>> a = Int('a')
8451    >>> solve(a > 0, a < 2)
8452    [a = 1]
8453    """
8454    s = Solver()
8455    s.set(**keywords)
8456    s.add(*args)
8457    if keywords.get('show', False):
8458        print(s)
8459    r = s.check()
8460    if r == unsat:
8461        print("no solution")
8462    elif r == unknown:
8463        print("failed to solve")
8464        try:
8465            print(s.model())
8466        except Z3Exception:
8467            return
8468    else:
8469        print(s.model())
8470
8471def solve_using(s, *args, **keywords):
8472    """Solve the constraints `*args` using solver `s`.
8473
8474    This is a simple function for creating demonstrations. It is similar to `solve`,
8475    but it uses the given solver `s`.
8476    It configures solver `s` using the options in `keywords`, adds the constraints
8477    in `args`, and invokes check.
8478    """
8479    if z3_debug():
8480        _z3_assert(isinstance(s, Solver), "Solver object expected")
8481    s.set(**keywords)
8482    s.add(*args)
8483    if keywords.get('show', False):
8484        print("Problem:")
8485        print(s)
8486    r = s.check()
8487    if r == unsat:
8488        print("no solution")
8489    elif r == unknown:
8490        print("failed to solve")
8491        try:
8492            print(s.model())
8493        except Z3Exception:
8494            return
8495    else:
8496        if keywords.get('show', False):
8497            print("Solution:")
8498        print(s.model())
8499
8500def prove(claim, **keywords):
8501    """Try to prove the given claim.
8502
8503    This is a simple function for creating demonstrations.  It tries to prove
8504    `claim` by showing the negation is unsatisfiable.
8505
8506    >>> p, q = Bools('p q')
8507    >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
8508    proved
8509    """
8510    if z3_debug():
8511        _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
8512    s = Solver()
8513    s.set(**keywords)
8514    s.add(Not(claim))
8515    if keywords.get('show', False):
8516        print(s)
8517    r = s.check()
8518    if r == unsat:
8519        print("proved")
8520    elif r == unknown:
8521        print("failed to prove")
8522        print(s.model())
8523    else:
8524        print("counterexample")
8525        print(s.model())
8526
8527def _solve_html(*args, **keywords):
8528    """Version of function `solve` used in RiSE4Fun."""
8529    s = Solver()
8530    s.set(**keywords)
8531    s.add(*args)
8532    if keywords.get('show', False):
8533        print("<b>Problem:</b>")
8534        print(s)
8535    r = s.check()
8536    if r == unsat:
8537        print("<b>no solution</b>")
8538    elif r == unknown:
8539        print("<b>failed to solve</b>")
8540        try:
8541            print(s.model())
8542        except Z3Exception:
8543            return
8544    else:
8545        if keywords.get('show', False):
8546            print("<b>Solution:</b>")
8547        print(s.model())
8548
8549def _solve_using_html(s, *args, **keywords):
8550    """Version of function `solve_using` used in RiSE4Fun."""
8551    if z3_debug():
8552        _z3_assert(isinstance(s, Solver), "Solver object expected")
8553    s.set(**keywords)
8554    s.add(*args)
8555    if keywords.get('show', False):
8556        print("<b>Problem:</b>")
8557        print(s)
8558    r = s.check()
8559    if r == unsat:
8560        print("<b>no solution</b>")
8561    elif r == unknown:
8562        print("<b>failed to solve</b>")
8563        try:
8564            print(s.model())
8565        except Z3Exception:
8566            return
8567    else:
8568        if keywords.get('show', False):
8569            print("<b>Solution:</b>")
8570        print(s.model())
8571
8572def _prove_html(claim, **keywords):
8573    """Version of function `prove` used in RiSE4Fun."""
8574    if z3_debug():
8575        _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
8576    s = Solver()
8577    s.set(**keywords)
8578    s.add(Not(claim))
8579    if keywords.get('show', False):
8580        print(s)
8581    r = s.check()
8582    if r == unsat:
8583        print("<b>proved</b>")
8584    elif r == unknown:
8585        print("<b>failed to prove</b>")
8586        print(s.model())
8587    else:
8588        print("<b>counterexample</b>")
8589        print(s.model())
8590
8591def _dict2sarray(sorts, ctx):
8592    sz = len(sorts)
8593    _names = (Symbol * sz)()
8594    _sorts = (Sort * sz) ()
8595    i = 0
8596    for k in sorts:
8597        v = sorts[k]
8598        if z3_debug():
8599            _z3_assert(isinstance(k, str), "String expected")
8600            _z3_assert(is_sort(v), "Z3 sort expected")
8601        _names[i] = to_symbol(k, ctx)
8602        _sorts[i] = v.ast
8603        i = i + 1
8604    return sz, _names, _sorts
8605
8606def _dict2darray(decls, ctx):
8607    sz = len(decls)
8608    _names = (Symbol * sz)()
8609    _decls = (FuncDecl * sz) ()
8610    i = 0
8611    for k in decls:
8612        v = decls[k]
8613        if z3_debug():
8614            _z3_assert(isinstance(k, str), "String expected")
8615            _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
8616        _names[i] = to_symbol(k, ctx)
8617        if is_const(v):
8618            _decls[i] = v.decl().ast
8619        else:
8620            _decls[i] = v.ast
8621        i = i + 1
8622    return sz, _names, _decls
8623
8624
8625def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
8626    """Parse a string in SMT 2.0 format using the given sorts and decls.
8627
8628    The arguments sorts and decls are Python dictionaries used to initialize
8629    the symbol table used for the SMT 2.0 parser.
8630
8631    >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
8632    [x > 0, x < 10]
8633    >>> x, y = Ints('x y')
8634    >>> f = Function('f', IntSort(), IntSort())
8635    >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
8636    [x + f(y) > 0]
8637    >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
8638    [a > 0]
8639    """
8640    ctx = _get_ctx(ctx)
8641    ssz, snames, ssorts = _dict2sarray(sorts, ctx)
8642    dsz, dnames, ddecls = _dict2darray(decls, ctx)
8643    return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
8644
8645def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
8646    """Parse a file in SMT 2.0 format using the given sorts and decls.
8647
8648    This function is similar to parse_smt2_string().
8649    """
8650    ctx = _get_ctx(ctx)
8651    ssz, snames, ssorts = _dict2sarray(sorts, ctx)
8652    dsz, dnames, ddecls = _dict2darray(decls, ctx)
8653    return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
8654
8655
8656#########################################
8657#
8658# Floating-Point Arithmetic
8659#
8660#########################################
8661
8662
8663# Global default rounding mode
8664_dflt_rounding_mode = Z3_OP_FPA_RM_TOWARD_ZERO
8665_dflt_fpsort_ebits = 11
8666_dflt_fpsort_sbits = 53
8667
8668def get_default_rounding_mode(ctx=None):
8669    """Retrieves the global default rounding mode."""
8670    global _dflt_rounding_mode
8671    if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
8672        return RTZ(ctx)
8673    elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
8674        return RTN(ctx)
8675    elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
8676        return RTP(ctx)
8677    elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
8678        return RNE(ctx)
8679    elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
8680        return RNA(ctx)
8681
8682def set_default_rounding_mode(rm, ctx=None):
8683    global _dflt_rounding_mode
8684    if is_fprm_value(rm):
8685        _dflt_rounding_mode = rm.decl().kind()
8686    else:
8687        _z3_assert(_dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO or
8688                   _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE or
8689                   _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE or
8690                   _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN or
8691                   _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY,
8692                   "illegal rounding mode")
8693        _dflt_rounding_mode = rm
8694
8695def get_default_fp_sort(ctx=None):
8696    return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
8697
8698def set_default_fp_sort(ebits, sbits, ctx=None):
8699    global _dflt_fpsort_ebits
8700    global _dflt_fpsort_sbits
8701    _dflt_fpsort_ebits = ebits
8702    _dflt_fpsort_sbits = sbits
8703
8704def _dflt_rm(ctx=None):
8705    return get_default_rounding_mode(ctx)
8706
8707def _dflt_fps(ctx=None):
8708    return get_default_fp_sort(ctx)
8709
8710def _coerce_fp_expr_list(alist, ctx):
8711    first_fp_sort = None
8712    for a in alist:
8713        if is_fp(a):
8714            if first_fp_sort is None:
8715                first_fp_sort = a.sort()
8716            elif first_fp_sort == a.sort():
8717                pass # OK, same as before
8718            else:
8719                # we saw at least 2 different float sorts; something will
8720                # throw a sort mismatch later, for now assume None.
8721                first_fp_sort = None
8722                break
8723
8724    r = []
8725    for i in range(len(alist)):
8726        a = alist[i]
8727        if (isinstance(a, str) and a.contains('2**(') and a.endswith(')')) or _is_int(a) or isinstance(a, float) or isinstance(a, bool):
8728            r.append(FPVal(a, None, first_fp_sort, ctx))
8729        else:
8730            r.append(a)
8731    return _coerce_expr_list(r, ctx)
8732
8733
8734### FP Sorts
8735
8736class FPSortRef(SortRef):
8737    """Floating-point sort."""
8738
8739    def ebits(self):
8740       """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
8741       >>> b = FPSort(8, 24)
8742       >>> b.ebits()
8743       8
8744       """
8745       return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
8746
8747    def sbits(self):
8748       """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
8749       >>> b = FPSort(8, 24)
8750       >>> b.sbits()
8751       24
8752       """
8753       return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
8754
8755    def cast(self, val):
8756        """Try to cast `val` as a floating-point expression.
8757        >>> b = FPSort(8, 24)
8758        >>> b.cast(1.0)
8759        1
8760        >>> b.cast(1.0).sexpr()
8761        '(fp #b0 #x7f #b00000000000000000000000)'
8762        """
8763        if is_expr(val):
8764            if z3_debug():
8765                _z3_assert(self.ctx == val.ctx, "Context mismatch")
8766            return val
8767        else:
8768            return FPVal(val, None, self, self.ctx)
8769
8770
8771def Float16(ctx=None):
8772    """Floating-point 16-bit (half) sort."""
8773    ctx = _get_ctx(ctx)
8774    return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
8775
8776def FloatHalf(ctx=None):
8777    """Floating-point 16-bit (half) sort."""
8778    ctx = _get_ctx(ctx)
8779    return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
8780
8781def Float32(ctx=None):
8782    """Floating-point 32-bit (single) sort."""
8783    ctx = _get_ctx(ctx)
8784    return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
8785
8786def FloatSingle(ctx=None):
8787    """Floating-point 32-bit (single) sort."""
8788    ctx = _get_ctx(ctx)
8789    return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
8790
8791def Float64(ctx=None):
8792    """Floating-point 64-bit (double) sort."""
8793    ctx = _get_ctx(ctx)
8794    return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
8795
8796def FloatDouble(ctx=None):
8797    """Floating-point 64-bit (double) sort."""
8798    ctx = _get_ctx(ctx)
8799    return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
8800
8801def Float128(ctx=None):
8802    """Floating-point 128-bit (quadruple) sort."""
8803    ctx = _get_ctx(ctx)
8804    return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
8805
8806def FloatQuadruple(ctx=None):
8807    """Floating-point 128-bit (quadruple) sort."""
8808    ctx = _get_ctx(ctx)
8809    return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
8810
8811class FPRMSortRef(SortRef):
8812    """"Floating-point rounding mode sort."""
8813
8814
8815def is_fp_sort(s):
8816    """Return True if `s` is a Z3 floating-point sort.
8817
8818    >>> is_fp_sort(FPSort(8, 24))
8819    True
8820    >>> is_fp_sort(IntSort())
8821    False
8822    """
8823    return isinstance(s, FPSortRef)
8824
8825def is_fprm_sort(s):
8826    """Return True if `s` is a Z3 floating-point rounding mode sort.
8827
8828    >>> is_fprm_sort(FPSort(8, 24))
8829    False
8830    >>> is_fprm_sort(RNE().sort())
8831    True
8832    """
8833    return isinstance(s, FPRMSortRef)
8834
8835### FP Expressions
8836
8837class FPRef(ExprRef):
8838    """Floating-point expressions."""
8839
8840    def sort(self):
8841        """Return the sort of the floating-point expression `self`.
8842
8843        >>> x = FP('1.0', FPSort(8, 24))
8844        >>> x.sort()
8845        FPSort(8, 24)
8846        >>> x.sort() == FPSort(8, 24)
8847        True
8848        """
8849        return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
8850
8851    def ebits(self):
8852       """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
8853       >>> b = FPSort(8, 24)
8854       >>> b.ebits()
8855       8
8856       """
8857       return self.sort().ebits();
8858
8859    def sbits(self):
8860       """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
8861       >>> b = FPSort(8, 24)
8862       >>> b.sbits()
8863       24
8864       """
8865       return self.sort().sbits();
8866
8867    def as_string(self):
8868        """Return a Z3 floating point expression as a Python string."""
8869        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
8870
8871    def __le__(self, other):
8872        return fpLEQ(self, other, self.ctx)
8873
8874    def __lt__(self, other):
8875        return fpLT(self, other, self.ctx)
8876
8877    def __ge__(self, other):
8878        return fpGEQ(self, other, self.ctx)
8879
8880    def __gt__(self, other):
8881        return fpGT(self, other, self.ctx)
8882
8883    def __add__(self, other):
8884        """Create the Z3 expression `self + other`.
8885
8886        >>> x = FP('x', FPSort(8, 24))
8887        >>> y = FP('y', FPSort(8, 24))
8888        >>> x + y
8889        x + y
8890        >>> (x + y).sort()
8891        FPSort(8, 24)
8892        """
8893        [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
8894        return fpAdd(_dflt_rm(), a, b, self.ctx)
8895
8896    def __radd__(self, other):
8897        """Create the Z3 expression `other + self`.
8898
8899        >>> x = FP('x', FPSort(8, 24))
8900        >>> 10 + x
8901        1.25*(2**3) + x
8902        """
8903        [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
8904        return fpAdd(_dflt_rm(), a, b, self.ctx)
8905
8906    def __sub__(self, other):
8907        """Create the Z3 expression `self - other`.
8908
8909        >>> x = FP('x', FPSort(8, 24))
8910        >>> y = FP('y', FPSort(8, 24))
8911        >>> x - y
8912        x - y
8913        >>> (x - y).sort()
8914        FPSort(8, 24)
8915        """
8916        [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
8917        return fpSub(_dflt_rm(), a, b, self.ctx)
8918
8919    def __rsub__(self, other):
8920        """Create the Z3 expression `other - self`.
8921
8922        >>> x = FP('x', FPSort(8, 24))
8923        >>> 10 - x
8924        1.25*(2**3) - x
8925        """
8926        [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
8927        return fpSub(_dflt_rm(), a, b, self.ctx)
8928
8929    def __mul__(self, other):
8930        """Create the Z3 expression `self * other`.
8931
8932        >>> x = FP('x', FPSort(8, 24))
8933        >>> y = FP('y', FPSort(8, 24))
8934        >>> x * y
8935        x * y
8936        >>> (x * y).sort()
8937        FPSort(8, 24)
8938        >>> 10 * y
8939        1.25*(2**3) * y
8940        """
8941        [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
8942        return fpMul(_dflt_rm(), a, b, self.ctx)
8943
8944    def __rmul__(self, other):
8945        """Create the Z3 expression `other * self`.
8946
8947        >>> x = FP('x', FPSort(8, 24))
8948        >>> y = FP('y', FPSort(8, 24))
8949        >>> x * y
8950        x * y
8951        >>> x * 10
8952        x * 1.25*(2**3)
8953        """
8954        [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
8955        return fpMul(_dflt_rm(), a, b, self.ctx)
8956
8957    def __pos__(self):
8958        """Create the Z3 expression `+self`."""
8959        return self
8960
8961    def __neg__(self):
8962        """Create the Z3 expression `-self`.
8963
8964        >>> x = FP('x', Float32())
8965        >>> -x
8966        -x
8967        """
8968        return fpNeg(self)
8969
8970    def __div__(self, other):
8971        """Create the Z3 expression `self / other`.
8972
8973        >>> x = FP('x', FPSort(8, 24))
8974        >>> y = FP('y', FPSort(8, 24))
8975        >>> x / y
8976        x / y
8977        >>> (x / y).sort()
8978        FPSort(8, 24)
8979        >>> 10 / y
8980        1.25*(2**3) / y
8981        """
8982        [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
8983        return fpDiv(_dflt_rm(), a, b, self.ctx)
8984
8985    def __rdiv__(self, other):
8986        """Create the Z3 expression `other / self`.
8987
8988        >>> x = FP('x', FPSort(8, 24))
8989        >>> y = FP('y', FPSort(8, 24))
8990        >>> x / y
8991        x / y
8992        >>> x / 10
8993        x / 1.25*(2**3)
8994        """
8995        [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
8996        return fpDiv(_dflt_rm(), a, b, self.ctx)
8997
8998    def __truediv__(self, other):
8999        """Create the Z3 expression division `self / other`."""
9000        return self.__div__(other)
9001
9002    def __rtruediv__(self, other):
9003        """Create the Z3 expression division `other / self`."""
9004        return self.__rdiv__(other)
9005
9006    def __mod__(self, other):
9007        """Create the Z3 expression mod `self % other`."""
9008        return fpRem(self, other)
9009
9010    def __rmod__(self, other):
9011        """Create the Z3 expression mod `other % self`."""
9012        return fpRem(other, self)
9013
9014class FPRMRef(ExprRef):
9015    """Floating-point rounding mode expressions"""
9016
9017    def as_string(self):
9018        """Return a Z3 floating point expression as a Python string."""
9019        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9020
9021
9022def RoundNearestTiesToEven(ctx=None):
9023    ctx = _get_ctx(ctx)
9024    return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9025
9026def RNE (ctx=None):
9027    ctx = _get_ctx(ctx)
9028    return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9029
9030def RoundNearestTiesToAway(ctx=None):
9031    ctx = _get_ctx(ctx)
9032    return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9033
9034def RNA (ctx=None):
9035    ctx = _get_ctx(ctx)
9036    return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9037
9038def RoundTowardPositive(ctx=None):
9039    ctx = _get_ctx(ctx)
9040    return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9041
9042def RTP(ctx=None):
9043    ctx = _get_ctx(ctx)
9044    return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9045
9046def RoundTowardNegative(ctx=None):
9047    ctx = _get_ctx(ctx)
9048    return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9049
9050def RTN(ctx=None):
9051    ctx = _get_ctx(ctx)
9052    return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9053
9054def RoundTowardZero(ctx=None):
9055    ctx = _get_ctx(ctx)
9056    return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9057
9058def RTZ(ctx=None):
9059    ctx = _get_ctx(ctx)
9060    return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9061
9062def is_fprm(a):
9063    """Return `True` if `a` is a Z3 floating-point rounding mode expression.
9064
9065    >>> rm = RNE()
9066    >>> is_fprm(rm)
9067    True
9068    >>> rm = 1.0
9069    >>> is_fprm(rm)
9070    False
9071    """
9072    return isinstance(a, FPRMRef)
9073
9074def is_fprm_value(a):
9075    """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
9076    return is_fprm(a) and _is_numeral(a.ctx, a.ast)
9077
9078### FP Numerals
9079
9080class FPNumRef(FPRef):
9081    """The sign of the numeral.
9082
9083    >>> x = FPVal(+1.0, FPSort(8, 24))
9084    >>> x.sign()
9085    False
9086    >>> x = FPVal(-1.0, FPSort(8, 24))
9087    >>> x.sign()
9088    True
9089    """
9090    def sign(self):
9091        l = (ctypes.c_int)()
9092        if Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(l)) == False:
9093            raise Z3Exception("error retrieving the sign of a numeral.")
9094        return l.value != 0
9095
9096    """The sign of a floating-point numeral as a bit-vector expression.
9097
9098    Remark: NaN's are invalid arguments.
9099    """
9100    def sign_as_bv(self):
9101        return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9102
9103    """The significand of the numeral.
9104
9105    >>> x = FPVal(2.5, FPSort(8, 24))
9106    >>> x.significand()
9107    1.25
9108    """
9109    def significand(self):
9110        return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
9111
9112    """The significand of the numeral as a long.
9113
9114    >>> x = FPVal(2.5, FPSort(8, 24))
9115    >>> x.significand_as_long()
9116    1.25
9117    """
9118    def significand_as_long(self):
9119        ptr = (ctypes.c_ulonglong * 1)()
9120        if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
9121            raise Z3Exception("error retrieving the significand of a numeral.")
9122        return ptr[0]
9123
9124    """The significand of the numeral as a bit-vector expression.
9125
9126    Remark: NaN are invalid arguments.
9127    """
9128    def significand_as_bv(self):
9129        return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9130
9131    """The exponent of the numeral.
9132
9133    >>> x = FPVal(2.5, FPSort(8, 24))
9134    >>> x.exponent()
9135    1
9136    """
9137    def exponent(self, biased=True):
9138        return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
9139
9140    """The exponent of the numeral as a long.
9141
9142    >>> x = FPVal(2.5, FPSort(8, 24))
9143    >>> x.exponent_as_long()
9144    1
9145    """
9146    def exponent_as_long(self, biased=True):
9147        ptr = (ctypes.c_longlong * 1)()
9148        if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
9149            raise Z3Exception("error retrieving the exponent of a numeral.")
9150        return ptr[0]
9151
9152    """The exponent of the numeral as a bit-vector expression.
9153
9154    Remark: NaNs are invalid arguments.
9155    """
9156    def exponent_as_bv(self, biased=True):
9157        return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
9158
9159    """Indicates whether the numeral is a NaN."""
9160    def isNaN(self):
9161        return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
9162
9163    """Indicates whether the numeral is +oo or -oo."""
9164    def isInf(self):
9165        return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
9166
9167    """Indicates whether the numeral is +zero or -zero."""
9168    def isZero(self):
9169        return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
9170
9171    """Indicates whether the numeral is normal."""
9172    def isNormal(self):
9173        return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
9174
9175    """Indicates whether the numeral is subnormal."""
9176    def isSubnormal(self):
9177        return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
9178
9179    """Indicates whether the numeral is positive."""
9180    def isPositive(self):
9181        return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
9182
9183    """Indicates whether the numeral is negative."""
9184    def isNegative(self):
9185        return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
9186
9187    """
9188    The string representation of the numeral.
9189
9190    >>> x = FPVal(20, FPSort(8, 24))
9191    >>> x.as_string()
9192    1.25*(2**4)
9193    """
9194    def as_string(self):
9195        s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
9196        return ("FPVal(%s, %s)" % (s, self.sort()))
9197
9198def is_fp(a):
9199    """Return `True` if `a` is a Z3 floating-point expression.
9200
9201    >>> b = FP('b', FPSort(8, 24))
9202    >>> is_fp(b)
9203    True
9204    >>> is_fp(b + 1.0)
9205    True
9206    >>> is_fp(Int('x'))
9207    False
9208    """
9209    return isinstance(a, FPRef)
9210
9211def is_fp_value(a):
9212    """Return `True` if `a` is a Z3 floating-point numeral value.
9213
9214    >>> b = FP('b', FPSort(8, 24))
9215    >>> is_fp_value(b)
9216    False
9217    >>> b = FPVal(1.0, FPSort(8, 24))
9218    >>> b
9219    1
9220    >>> is_fp_value(b)
9221    True
9222    """
9223    return is_fp(a) and _is_numeral(a.ctx, a.ast)
9224
9225def FPSort(ebits, sbits, ctx=None):
9226    """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
9227
9228    >>> Single = FPSort(8, 24)
9229    >>> Double = FPSort(11, 53)
9230    >>> Single
9231    FPSort(8, 24)
9232    >>> x = Const('x', Single)
9233    >>> eq(x, FP('x', FPSort(8, 24)))
9234    True
9235    """
9236    ctx = _get_ctx(ctx)
9237    return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
9238
9239def _to_float_str(val, exp=0):
9240    if isinstance(val, float):
9241        if math.isnan(val):
9242            res = "NaN"
9243        elif val == 0.0:
9244            sone = math.copysign(1.0, val)
9245            if sone < 0.0:
9246                return "-0.0"
9247            else:
9248                return "+0.0"
9249        elif val == float("+inf"):
9250            res = "+oo"
9251        elif val == float("-inf"):
9252            res = "-oo"
9253        else:
9254            v = val.as_integer_ratio()
9255            num = v[0]
9256            den = v[1]
9257            rvs = str(num) + '/' + str(den)
9258            res = rvs + 'p' + _to_int_str(exp)
9259    elif isinstance(val, bool):
9260        if val:
9261            res = "1.0"
9262        else:
9263            res = "0.0"
9264    elif _is_int(val):
9265        res = str(val)
9266    elif isinstance(val, str):
9267        inx = val.find('*(2**')
9268        if inx == -1:
9269            res = val
9270        elif val[-1] == ')':
9271            res = val[0:inx]
9272            exp = str(int(val[inx+5:-1]) + int(exp))
9273        else:
9274            _z3_assert(False, "String does not have floating-point numeral form.")
9275    elif z3_debug():
9276        _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
9277    if exp == 0:
9278        return res
9279    else:
9280        return res + 'p' + exp
9281
9282
9283def fpNaN(s):
9284    """Create a Z3 floating-point NaN term.
9285
9286    >>> s = FPSort(8, 24)
9287    >>> set_fpa_pretty(True)
9288    >>> fpNaN(s)
9289    NaN
9290    >>> pb = get_fpa_pretty()
9291    >>> set_fpa_pretty(False)
9292    >>> fpNaN(s)
9293    fpNaN(FPSort(8, 24))
9294    >>> set_fpa_pretty(pb)
9295    """
9296    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9297    return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
9298
9299def fpPlusInfinity(s):
9300    """Create a Z3 floating-point +oo term.
9301
9302    >>> s = FPSort(8, 24)
9303    >>> pb = get_fpa_pretty()
9304    >>> set_fpa_pretty(True)
9305    >>> fpPlusInfinity(s)
9306    +oo
9307    >>> set_fpa_pretty(False)
9308    >>> fpPlusInfinity(s)
9309    fpPlusInfinity(FPSort(8, 24))
9310    >>> set_fpa_pretty(pb)
9311    """
9312    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9313    return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
9314
9315def fpMinusInfinity(s):
9316    """Create a Z3 floating-point -oo term."""
9317    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9318    return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
9319
9320def fpInfinity(s, negative):
9321    """Create a Z3 floating-point +oo or -oo term."""
9322    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9323    _z3_assert(isinstance(negative, bool), "expected Boolean flag")
9324    return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
9325
9326def fpPlusZero(s):
9327    """Create a Z3 floating-point +0.0 term."""
9328    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9329    return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
9330
9331def fpMinusZero(s):
9332    """Create a Z3 floating-point -0.0 term."""
9333    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9334    return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
9335
9336def fpZero(s, negative):
9337    """Create a Z3 floating-point +0.0 or -0.0 term."""
9338    _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
9339    _z3_assert(isinstance(negative, bool), "expected Boolean flag")
9340    return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
9341
9342def FPVal(sig, exp=None, fps=None, ctx=None):
9343    """Return a floating-point value of value `val` and sort `fps`. If `ctx=None`, then the global context is used.
9344
9345    >>> v = FPVal(20.0, FPSort(8, 24))
9346    >>> v
9347    1.25*(2**4)
9348    >>> print("0x%.8x" % v.exponent_as_long(False))
9349    0x00000004
9350    >>> v = FPVal(2.25, FPSort(8, 24))
9351    >>> v
9352    1.125*(2**1)
9353    >>> v = FPVal(-2.25, FPSort(8, 24))
9354    >>> v
9355    -1.125*(2**1)
9356    >>> FPVal(-0.0, FPSort(8, 24))
9357    -0.0
9358    >>> FPVal(0.0, FPSort(8, 24))
9359    +0.0
9360    >>> FPVal(+0.0, FPSort(8, 24))
9361    +0.0
9362    """
9363    ctx = _get_ctx(ctx)
9364    if is_fp_sort(exp):
9365        fps = exp
9366        exp = None
9367    elif fps is None:
9368        fps = _dflt_fps(ctx)
9369    _z3_assert(is_fp_sort(fps), "sort mismatch")
9370    if exp is None:
9371        exp = 0
9372    val = _to_float_str(sig)
9373    if val == "NaN" or val == "nan":
9374        return fpNaN(fps)
9375    elif val == "-0.0":
9376        return fpMinusZero(fps)
9377    elif val == "0.0" or val == "+0.0":
9378        return fpPlusZero(fps)
9379    elif val == "+oo" or val == "+inf" or val == "+Inf":
9380        return fpPlusInfinity(fps)
9381    elif val == "-oo" or val == "-inf" or val == "-Inf":
9382        return fpMinusInfinity(fps)
9383    else:
9384        return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
9385
9386def FP(name, fpsort, ctx=None):
9387    """Return a floating-point constant named `name`.
9388    `fpsort` is the floating-point sort.
9389    If `ctx=None`, then the global context is used.
9390
9391    >>> x  = FP('x', FPSort(8, 24))
9392    >>> is_fp(x)
9393    True
9394    >>> x.ebits()
9395    8
9396    >>> x.sort()
9397    FPSort(8, 24)
9398    >>> word = FPSort(8, 24)
9399    >>> x2 = FP('x', word)
9400    >>> eq(x, x2)
9401    True
9402    """
9403    if isinstance(fpsort, FPSortRef) and ctx is None:
9404        ctx = fpsort.ctx
9405    else:
9406        ctx = _get_ctx(ctx)
9407    return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
9408
9409def FPs(names, fpsort, ctx=None):
9410    """Return an array of floating-point constants.
9411
9412    >>> x, y, z = FPs('x y z', FPSort(8, 24))
9413    >>> x.sort()
9414    FPSort(8, 24)
9415    >>> x.sbits()
9416    24
9417    >>> x.ebits()
9418    8
9419    >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
9420    fpMul(RNE(), fpAdd(RNE(), x, y), z)
9421    """
9422    ctx = _get_ctx(ctx)
9423    if isinstance(names, str):
9424        names = names.split(" ")
9425    return [FP(name, fpsort, ctx) for name in names]
9426
9427def fpAbs(a, ctx=None):
9428    """Create a Z3 floating-point absolute value expression.
9429
9430    >>> s = FPSort(8, 24)
9431    >>> rm = RNE()
9432    >>> x = FPVal(1.0, s)
9433    >>> fpAbs(x)
9434    fpAbs(1)
9435    >>> y = FPVal(-20.0, s)
9436    >>> y
9437    -1.25*(2**4)
9438    >>> fpAbs(y)
9439    fpAbs(-1.25*(2**4))
9440    >>> fpAbs(-1.25*(2**4))
9441    fpAbs(-1.25*(2**4))
9442    >>> fpAbs(x).sort()
9443    FPSort(8, 24)
9444    """
9445    ctx = _get_ctx(ctx)
9446    [a] = _coerce_fp_expr_list([a], ctx)
9447    return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
9448
9449def fpNeg(a, ctx=None):
9450    """Create a Z3 floating-point addition expression.
9451
9452    >>> s = FPSort(8, 24)
9453    >>> rm = RNE()
9454    >>> x = FP('x', s)
9455    >>> fpNeg(x)
9456    -x
9457    >>> fpNeg(x).sort()
9458    FPSort(8, 24)
9459    """
9460    ctx = _get_ctx(ctx)
9461    [a] = _coerce_fp_expr_list([a], ctx)
9462    return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
9463
9464def _mk_fp_unary(f, rm, a, ctx):
9465    ctx = _get_ctx(ctx)
9466    [a] = _coerce_fp_expr_list([a], ctx)
9467    if z3_debug():
9468        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
9469        _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
9470    return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
9471
9472def _mk_fp_unary_pred(f, a, ctx):
9473    ctx = _get_ctx(ctx)
9474    [a] = _coerce_fp_expr_list([a], ctx)
9475    if z3_debug():
9476        _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
9477    return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
9478
9479def _mk_fp_bin(f, rm, a, b, ctx):
9480    ctx = _get_ctx(ctx)
9481    [a, b] = _coerce_fp_expr_list([a, b], ctx)
9482    if z3_debug():
9483        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
9484        _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
9485    return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
9486
9487def _mk_fp_bin_norm(f, a, b, ctx):
9488    ctx = _get_ctx(ctx)
9489    [a, b] = _coerce_fp_expr_list([a, b], ctx)
9490    if z3_debug():
9491        _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
9492    return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
9493
9494def _mk_fp_bin_pred(f, a, b, ctx):
9495    ctx = _get_ctx(ctx)
9496    [a, b] = _coerce_fp_expr_list([a, b], ctx)
9497    if z3_debug():
9498        _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
9499    return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
9500
9501def _mk_fp_tern(f, rm, a, b, c, ctx):
9502    ctx = _get_ctx(ctx)
9503    [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
9504    if z3_debug():
9505        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
9506        _z3_assert(is_fp(a) or is_fp(b) or is_fp(c), "Second, third or fourth argument must be a Z3 floating-point expression")
9507    return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
9508
9509def fpAdd(rm, a, b, ctx=None):
9510    """Create a Z3 floating-point addition expression.
9511
9512    >>> s = FPSort(8, 24)
9513    >>> rm = RNE()
9514    >>> x = FP('x', s)
9515    >>> y = FP('y', s)
9516    >>> fpAdd(rm, x, y)
9517    fpAdd(RNE(), x, y)
9518    >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
9519    x + y
9520    >>> fpAdd(rm, x, y).sort()
9521    FPSort(8, 24)
9522    """
9523    return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
9524
9525def fpSub(rm, a, b, ctx=None):
9526    """Create a Z3 floating-point subtraction expression.
9527
9528    >>> s = FPSort(8, 24)
9529    >>> rm = RNE()
9530    >>> x = FP('x', s)
9531    >>> y = FP('y', s)
9532    >>> fpSub(rm, x, y)
9533    fpSub(RNE(), x, y)
9534    >>> fpSub(rm, x, y).sort()
9535    FPSort(8, 24)
9536    """
9537    return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
9538
9539def fpMul(rm, a, b, ctx=None):
9540    """Create a Z3 floating-point multiplication expression.
9541
9542    >>> s = FPSort(8, 24)
9543    >>> rm = RNE()
9544    >>> x = FP('x', s)
9545    >>> y = FP('y', s)
9546    >>> fpMul(rm, x, y)
9547    fpMul(RNE(), x, y)
9548    >>> fpMul(rm, x, y).sort()
9549    FPSort(8, 24)
9550    """
9551    return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
9552
9553def fpDiv(rm, a, b, ctx=None):
9554    """Create a Z3 floating-point division expression.
9555
9556    >>> s = FPSort(8, 24)
9557    >>> rm = RNE()
9558    >>> x = FP('x', s)
9559    >>> y = FP('y', s)
9560    >>> fpDiv(rm, x, y)
9561    fpDiv(RNE(), x, y)
9562    >>> fpDiv(rm, x, y).sort()
9563    FPSort(8, 24)
9564    """
9565    return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
9566
9567def fpRem(a, b, ctx=None):
9568    """Create a Z3 floating-point remainder expression.
9569
9570    >>> s = FPSort(8, 24)
9571    >>> x = FP('x', s)
9572    >>> y = FP('y', s)
9573    >>> fpRem(x, y)
9574    fpRem(x, y)
9575    >>> fpRem(x, y).sort()
9576    FPSort(8, 24)
9577    """
9578    return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
9579
9580def fpMin(a, b, ctx=None):
9581    """Create a Z3 floating-point minimum expression.
9582
9583    >>> s = FPSort(8, 24)
9584    >>> rm = RNE()
9585    >>> x = FP('x', s)
9586    >>> y = FP('y', s)
9587    >>> fpMin(x, y)
9588    fpMin(x, y)
9589    >>> fpMin(x, y).sort()
9590    FPSort(8, 24)
9591    """
9592    return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
9593
9594def fpMax(a, b, ctx=None):
9595    """Create a Z3 floating-point maximum expression.
9596
9597    >>> s = FPSort(8, 24)
9598    >>> rm = RNE()
9599    >>> x = FP('x', s)
9600    >>> y = FP('y', s)
9601    >>> fpMax(x, y)
9602    fpMax(x, y)
9603    >>> fpMax(x, y).sort()
9604    FPSort(8, 24)
9605    """
9606    return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
9607
9608def fpFMA(rm, a, b, c, ctx=None):
9609    """Create a Z3 floating-point fused multiply-add expression.
9610    """
9611    return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
9612
9613def fpSqrt(rm, a, ctx=None):
9614    """Create a Z3 floating-point square root expression.
9615    """
9616    return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
9617
9618def fpRoundToIntegral(rm, a, ctx=None):
9619    """Create a Z3 floating-point roundToIntegral expression.
9620    """
9621    return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
9622
9623def fpIsNaN(a, ctx=None):
9624    """Create a Z3 floating-point isNaN expression.
9625
9626    >>> s = FPSort(8, 24)
9627    >>> x = FP('x', s)
9628    >>> y = FP('y', s)
9629    >>> fpIsNaN(x)
9630    fpIsNaN(x)
9631    """
9632    return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
9633
9634def fpIsInf(a, ctx=None):
9635    """Create a Z3 floating-point isInfinite expression.
9636
9637    >>> s = FPSort(8, 24)
9638    >>> x = FP('x', s)
9639    >>> fpIsInf(x)
9640    fpIsInf(x)
9641    """
9642    return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
9643
9644def fpIsZero(a, ctx=None):
9645    """Create a Z3 floating-point isZero expression.
9646    """
9647    return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
9648
9649def fpIsNormal(a, ctx=None):
9650    """Create a Z3 floating-point isNormal expression.
9651    """
9652    return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
9653
9654def fpIsSubnormal(a, ctx=None):
9655    """Create a Z3 floating-point isSubnormal expression.
9656    """
9657    return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
9658
9659def fpIsNegative(a, ctx=None):
9660    """Create a Z3 floating-point isNegative expression.
9661    """
9662    return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
9663
9664def fpIsPositive(a, ctx=None):
9665    """Create a Z3 floating-point isPositive expression.
9666    """
9667    return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
9668
9669def _check_fp_args(a, b):
9670    if z3_debug():
9671        _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
9672
9673def fpLT(a, b, ctx=None):
9674    """Create the Z3 floating-point expression `other < self`.
9675
9676    >>> x, y = FPs('x y', FPSort(8, 24))
9677    >>> fpLT(x, y)
9678    x < y
9679    >>> (x < y).sexpr()
9680    '(fp.lt x y)'
9681    """
9682    return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
9683
9684def fpLEQ(a, b, ctx=None):
9685    """Create the Z3 floating-point expression `other <= self`.
9686
9687    >>> x, y = FPs('x y', FPSort(8, 24))
9688    >>> fpLEQ(x, y)
9689    x <= y
9690    >>> (x <= y).sexpr()
9691    '(fp.leq x y)'
9692    """
9693    return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
9694
9695def fpGT(a, b, ctx=None):
9696    """Create the Z3 floating-point expression `other > self`.
9697
9698    >>> x, y = FPs('x y', FPSort(8, 24))
9699    >>> fpGT(x, y)
9700    x > y
9701    >>> (x > y).sexpr()
9702    '(fp.gt x y)'
9703    """
9704    return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
9705
9706def fpGEQ(a, b, ctx=None):
9707    """Create the Z3 floating-point expression `other >= self`.
9708
9709    >>> x, y = FPs('x y', FPSort(8, 24))
9710    >>> fpGEQ(x, y)
9711    x >= y
9712    >>> (x >= y).sexpr()
9713    '(fp.geq x y)'
9714    """
9715    return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
9716
9717def fpEQ(a, b, ctx=None):
9718    """Create the Z3 floating-point expression `fpEQ(other, self)`.
9719
9720    >>> x, y = FPs('x y', FPSort(8, 24))
9721    >>> fpEQ(x, y)
9722    fpEQ(x, y)
9723    >>> fpEQ(x, y).sexpr()
9724    '(fp.eq x y)'
9725    """
9726    return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
9727
9728def fpNEQ(a, b, ctx=None):
9729    """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
9730
9731    >>> x, y = FPs('x y', FPSort(8, 24))
9732    >>> fpNEQ(x, y)
9733    Not(fpEQ(x, y))
9734    >>> (x != y).sexpr()
9735    '(distinct x y)'
9736    """
9737    return Not(fpEQ(a, b, ctx))
9738
9739def fpFP(sgn, exp, sig, ctx=None):
9740    """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
9741
9742    >>> s = FPSort(8, 24)
9743    >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
9744    >>> print(x)
9745    fpFP(1, 127, 4194304)
9746    >>> xv = FPVal(-1.5, s)
9747    >>> print(xv)
9748    -1.5
9749    >>> slvr = Solver()
9750    >>> slvr.add(fpEQ(x, xv))
9751    >>> slvr.check()
9752    sat
9753    >>> xv = FPVal(+1.5, s)
9754    >>> print(xv)
9755    1.5
9756    >>> slvr = Solver()
9757    >>> slvr.add(fpEQ(x, xv))
9758    >>> slvr.check()
9759    unsat
9760    """
9761    _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
9762    _z3_assert(sgn.sort().size() == 1, "sort mismatch")
9763    ctx = _get_ctx(ctx)
9764    _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
9765    return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
9766
9767def fpToFP(a1, a2=None, a3=None, ctx=None):
9768    """Create a Z3 floating-point conversion expression from other term sorts
9769    to floating-point.
9770
9771    From a bit-vector term in IEEE 754-2008 format:
9772    >>> x = FPVal(1.0, Float32())
9773    >>> x_bv = fpToIEEEBV(x)
9774    >>> simplify(fpToFP(x_bv, Float32()))
9775    1
9776
9777    From a floating-point term with different precision:
9778    >>> x = FPVal(1.0, Float32())
9779    >>> x_db = fpToFP(RNE(), x, Float64())
9780    >>> x_db.sort()
9781    FPSort(11, 53)
9782
9783    From a real term:
9784    >>> x_r = RealVal(1.5)
9785    >>> simplify(fpToFP(RNE(), x_r, Float32()))
9786    1.5
9787
9788    From a signed bit-vector term:
9789    >>> x_signed = BitVecVal(-5, BitVecSort(32))
9790    >>> simplify(fpToFP(RNE(), x_signed, Float32()))
9791    -1.25*(2**2)
9792    """
9793    ctx = _get_ctx(ctx)
9794    if is_bv(a1) and is_fp_sort(a2):
9795        return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
9796    elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
9797        return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
9798    elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
9799        return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
9800    elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
9801        return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
9802    else:
9803        raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
9804
9805def fpBVToFP(v, sort, ctx=None):
9806    """Create a Z3 floating-point conversion expression that represents the
9807    conversion from a bit-vector term to a floating-point term.
9808
9809    >>> x_bv = BitVecVal(0x3F800000, 32)
9810    >>> x_fp = fpBVToFP(x_bv, Float32())
9811    >>> x_fp
9812    fpToFP(1065353216)
9813    >>> simplify(x_fp)
9814    1
9815    """
9816    _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
9817    _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
9818    ctx = _get_ctx(ctx)
9819    return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
9820
9821def fpFPToFP(rm, v, sort, ctx=None):
9822    """Create a Z3 floating-point conversion expression that represents the
9823    conversion from a floating-point term to a floating-point term of different precision.
9824
9825    >>> x_sgl = FPVal(1.0, Float32())
9826    >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
9827    >>> x_dbl
9828    fpToFP(RNE(), 1)
9829    >>> simplify(x_dbl)
9830    1
9831    >>> x_dbl.sort()
9832    FPSort(11, 53)
9833    """
9834    _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
9835    _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
9836    _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
9837    ctx = _get_ctx(ctx)
9838    return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
9839
9840def fpRealToFP(rm, v, sort, ctx=None):
9841    """Create a Z3 floating-point conversion expression that represents the
9842    conversion from a real term to a floating-point term.
9843
9844    >>> x_r = RealVal(1.5)
9845    >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
9846    >>> x_fp
9847    fpToFP(RNE(), 3/2)
9848    >>> simplify(x_fp)
9849    1.5
9850    """
9851    _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
9852    _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
9853    _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
9854    ctx = _get_ctx(ctx)
9855    return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
9856
9857def fpSignedToFP(rm, v, sort, ctx=None):
9858    """Create a Z3 floating-point conversion expression that represents the
9859    conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
9860
9861    >>> x_signed = BitVecVal(-5, BitVecSort(32))
9862    >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
9863    >>> x_fp
9864    fpToFP(RNE(), 4294967291)
9865    >>> simplify(x_fp)
9866    -1.25*(2**2)
9867    """
9868    _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
9869    _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
9870    _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
9871    ctx = _get_ctx(ctx)
9872    return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
9873
9874def fpUnsignedToFP(rm, v, sort, ctx=None):
9875    """Create a Z3 floating-point conversion expression that represents the
9876    conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
9877
9878    >>> x_signed = BitVecVal(-5, BitVecSort(32))
9879    >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
9880    >>> x_fp
9881    fpToFPUnsigned(RNE(), 4294967291)
9882    >>> simplify(x_fp)
9883    1*(2**32)
9884    """
9885    _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
9886    _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
9887    _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
9888    ctx = _get_ctx(ctx)
9889    return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
9890
9891def fpToFPUnsigned(rm, x, s, ctx=None):
9892    """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
9893    if z3_debug():
9894        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
9895        _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
9896        _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
9897    ctx = _get_ctx(ctx)
9898    return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
9899
9900def fpToSBV(rm, x, s, ctx=None):
9901    """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
9902
9903    >>> x = FP('x', FPSort(8, 24))
9904    >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
9905    >>> print(is_fp(x))
9906    True
9907    >>> print(is_bv(y))
9908    True
9909    >>> print(is_fp(y))
9910    False
9911    >>> print(is_bv(x))
9912    False
9913    """
9914    if z3_debug():
9915        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
9916        _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
9917        _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
9918    ctx = _get_ctx(ctx)
9919    return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
9920
9921def fpToUBV(rm, x, s, ctx=None):
9922    """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
9923
9924    >>> x = FP('x', FPSort(8, 24))
9925    >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
9926    >>> print(is_fp(x))
9927    True
9928    >>> print(is_bv(y))
9929    True
9930    >>> print(is_fp(y))
9931    False
9932    >>> print(is_bv(x))
9933    False
9934    """
9935    if z3_debug():
9936        _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
9937        _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
9938        _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
9939    ctx = _get_ctx(ctx)
9940    return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
9941
9942def fpToReal(x, ctx=None):
9943    """Create a Z3 floating-point conversion expression, from floating-point expression to real.
9944
9945    >>> x = FP('x', FPSort(8, 24))
9946    >>> y = fpToReal(x)
9947    >>> print(is_fp(x))
9948    True
9949    >>> print(is_real(y))
9950    True
9951    >>> print(is_fp(y))
9952    False
9953    >>> print(is_real(x))
9954    False
9955    """
9956    if z3_debug():
9957        _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
9958    ctx = _get_ctx(ctx)
9959    return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
9960
9961def fpToIEEEBV(x, ctx=None):
9962    """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
9963
9964    The size of the resulting bit-vector is automatically determined.
9965
9966    Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
9967    knows only one NaN and it will always produce the same bit-vector representation of
9968    that NaN.
9969
9970    >>> x = FP('x', FPSort(8, 24))
9971    >>> y = fpToIEEEBV(x)
9972    >>> print(is_fp(x))
9973    True
9974    >>> print(is_bv(y))
9975    True
9976    >>> print(is_fp(y))
9977    False
9978    >>> print(is_bv(x))
9979    False
9980    """
9981    if z3_debug():
9982        _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
9983    ctx = _get_ctx(ctx)
9984    return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
9985
9986
9987
9988#########################################
9989#
9990# Strings, Sequences and Regular expressions
9991#
9992#########################################
9993
9994class SeqSortRef(SortRef):
9995    """Sequence sort."""
9996
9997    def is_string(self):
9998        """Determine if sort is a string
9999        >>> s = StringSort()
10000        >>> s.is_string()
10001        True
10002        >>> s = SeqSort(IntSort())
10003        >>> s.is_string()
10004        False
10005        """
10006        return Z3_is_string_sort(self.ctx_ref(), self.ast)
10007
10008    def basis(self):
10009        return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10010
10011
10012def StringSort(ctx=None):
10013    """Create a string sort
10014    >>> s = StringSort()
10015    >>> print(s)
10016    String
10017    """
10018    ctx = _get_ctx(ctx)
10019    return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
10020
10021
10022def SeqSort(s):
10023    """Create a sequence sort over elements provided in the argument
10024    >>> s = SeqSort(IntSort())
10025    >>> s == Unit(IntVal(1)).sort()
10026    True
10027    """
10028    return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
10029
10030class SeqRef(ExprRef):
10031    """Sequence expression."""
10032
10033    def sort(self):
10034        return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
10035
10036    def __add__(self, other):
10037        return Concat(self, other)
10038
10039    def __radd__(self, other):
10040        return Concat(other, self)
10041
10042    def __getitem__(self, i):
10043        if _is_int(i):
10044            i = IntVal(i, self.ctx)
10045        return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
10046
10047    def at(self, i):
10048        if _is_int(i):
10049            i = IntVal(i, self.ctx)
10050        return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
10051
10052    def is_string(self):
10053        return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
10054
10055    def is_string_value(self):
10056        return Z3_is_string(self.ctx_ref(), self.as_ast())
10057
10058
10059    def as_string(self):
10060        """Return a string representation of sequence expression."""
10061        if self.is_string_value():
10062            string_length = ctypes.c_uint()
10063            chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
10064            return string_at(chars, size=string_length.value).decode('latin-1')
10065        return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10066
10067    def __le__(self, other):
10068        return SeqRef(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10069
10070    def __lt__(self, other):
10071        return SeqRef(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10072
10073    def __ge__(self, other):
10074        return SeqRef(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
10075
10076    def __gt__(self, other):
10077        return SeqRef(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
10078
10079
10080def _coerce_seq(s, ctx=None):
10081    if isinstance(s, str):
10082        ctx = _get_ctx(ctx)
10083        s = StringVal(s, ctx)
10084    if not is_expr(s):
10085        raise Z3Exception("Non-expression passed as a sequence")
10086    if not is_seq(s):
10087        raise Z3Exception("Non-sequence passed as a sequence")
10088    return s
10089
10090def _get_ctx2(a, b, ctx=None):
10091    if is_expr(a):
10092        return a.ctx
10093    if is_expr(b):
10094        return b.ctx
10095    if ctx is None:
10096        ctx = main_ctx()
10097    return ctx
10098
10099def is_seq(a):
10100    """Return `True` if `a` is a Z3 sequence expression.
10101    >>> print (is_seq(Unit(IntVal(0))))
10102    True
10103    >>> print (is_seq(StringVal("abc")))
10104    True
10105    """
10106    return isinstance(a, SeqRef)
10107
10108def is_string(a):
10109    """Return `True` if `a` is a Z3 string expression.
10110    >>> print (is_string(StringVal("ab")))
10111    True
10112    """
10113    return isinstance(a, SeqRef) and a.is_string()
10114
10115def is_string_value(a):
10116    """return 'True' if 'a' is a Z3 string constant expression.
10117    >>> print (is_string_value(StringVal("a")))
10118    True
10119    >>> print (is_string_value(StringVal("a") + StringVal("b")))
10120    False
10121    """
10122    return isinstance(a, SeqRef) and a.is_string_value()
10123
10124
10125def StringVal(s, ctx=None):
10126    """create a string expression"""
10127    ctx = _get_ctx(ctx)
10128    return SeqRef(Z3_mk_lstring(ctx.ref(), len(s), s), ctx)
10129
10130def String(name, ctx=None):
10131    """Return a string constant named `name`. If `ctx=None`, then the global context is used.
10132
10133    >>> x = String('x')
10134    """
10135    ctx = _get_ctx(ctx)
10136    return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
10137
10138def Strings(names, ctx=None):
10139    """Return string constants"""
10140    ctx = _get_ctx(ctx)
10141    if isinstance(names, str):
10142        names = names.split(" ")
10143    return [String(name, ctx) for name in names]
10144
10145def SubString(s, offset, length):
10146    """Extract substring or subsequence starting at offset"""
10147    return Extract(s, offset, length)
10148
10149def SubSeq(s, offset, length):
10150    """Extract substring or subsequence starting at offset"""
10151    return Extract(s, offset, length)
10152
10153def Strings(names, ctx=None):
10154    """Return a tuple of String constants. """
10155    ctx = _get_ctx(ctx)
10156    if isinstance(names, str):
10157        names = names.split(" ")
10158    return [String(name, ctx) for name in names]
10159
10160def Empty(s):
10161    """Create the empty sequence of the given sort
10162    >>> e = Empty(StringSort())
10163    >>> e2 = StringVal("")
10164    >>> print(e.eq(e2))
10165    True
10166    >>> e3 = Empty(SeqSort(IntSort()))
10167    >>> print(e3)
10168    Empty(Seq(Int))
10169    >>> e4 = Empty(ReSort(SeqSort(IntSort())))
10170    >>> print(e4)
10171    Empty(ReSort(Seq(Int)))
10172    """
10173    if isinstance(s, SeqSortRef):
10174       return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
10175    if isinstance(s, ReSortRef):
10176       return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
10177    raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
10178
10179def Full(s):
10180    """Create the regular expression that accepts the universal language
10181    >>> e = Full(ReSort(SeqSort(IntSort())))
10182    >>> print(e)
10183    Full(ReSort(Seq(Int)))
10184    >>> e1 = Full(ReSort(StringSort()))
10185    >>> print(e1)
10186    Full(ReSort(String))
10187    """
10188    if isinstance(s, ReSortRef):
10189       return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
10190    raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
10191
10192
10193def Unit(a):
10194    """Create a singleton sequence"""
10195    return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
10196
10197def PrefixOf(a, b):
10198    """Check if 'a' is a prefix of 'b'
10199    >>> s1 = PrefixOf("ab", "abc")
10200    >>> simplify(s1)
10201    True
10202    >>> s2 = PrefixOf("bc", "abc")
10203    >>> simplify(s2)
10204    False
10205    """
10206    ctx = _get_ctx2(a, b)
10207    a = _coerce_seq(a, ctx)
10208    b = _coerce_seq(b, ctx)
10209    return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
10210
10211def SuffixOf(a, b):
10212    """Check if 'a' is a suffix of 'b'
10213    >>> s1 = SuffixOf("ab", "abc")
10214    >>> simplify(s1)
10215    False
10216    >>> s2 = SuffixOf("bc", "abc")
10217    >>> simplify(s2)
10218    True
10219    """
10220    ctx = _get_ctx2(a, b)
10221    a = _coerce_seq(a, ctx)
10222    b = _coerce_seq(b, ctx)
10223    return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
10224
10225def Contains(a, b):
10226    """Check if 'a' contains 'b'
10227    >>> s1 = Contains("abc", "ab")
10228    >>> simplify(s1)
10229    True
10230    >>> s2 = Contains("abc", "bc")
10231    >>> simplify(s2)
10232    True
10233    >>> x, y, z = Strings('x y z')
10234    >>> s3 = Contains(Concat(x,y,z), y)
10235    >>> simplify(s3)
10236    True
10237    """
10238    ctx = _get_ctx2(a, b)
10239    a = _coerce_seq(a, ctx)
10240    b = _coerce_seq(b, ctx)
10241    return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
10242
10243
10244def Replace(s, src, dst):
10245    """Replace the first occurrence of 'src' by 'dst' in 's'
10246    >>> r = Replace("aaa", "a", "b")
10247    >>> simplify(r)
10248    "baa"
10249    """
10250    ctx = _get_ctx2(dst, s)
10251    if ctx is None and is_expr(src):
10252        ctx = src.ctx
10253    src = _coerce_seq(src, ctx)
10254    dst = _coerce_seq(dst, ctx)
10255    s   = _coerce_seq(s, ctx)
10256    return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
10257
10258def IndexOf(s, substr):
10259    return IndexOf(s, substr, IntVal(0))
10260
10261def IndexOf(s, substr, offset):
10262    """Retrieve the index of substring within a string starting at a specified offset.
10263    >>> simplify(IndexOf("abcabc", "bc", 0))
10264    1
10265    >>> simplify(IndexOf("abcabc", "bc", 2))
10266    4
10267    """
10268    ctx = None
10269    if is_expr(offset):
10270        ctx = offset.ctx
10271    ctx = _get_ctx2(s, substr, ctx)
10272    s = _coerce_seq(s, ctx)
10273    substr = _coerce_seq(substr, ctx)
10274    if _is_int(offset):
10275        offset = IntVal(offset, ctx)
10276    return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
10277
10278def LastIndexOf(s, substr):
10279    """Retrieve the last index of substring within a string"""
10280    ctx = None
10281    ctx = _get_ctx2(s, substr, ctx)
10282    s = _coerce_seq(s, ctx)
10283    substr = _coerce_seq(substr, ctx)
10284    return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
10285
10286
10287def Length(s):
10288    """Obtain the length of a sequence 's'
10289    >>> l = Length(StringVal("abc"))
10290    >>> simplify(l)
10291    3
10292    """
10293    s = _coerce_seq(s)
10294    return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
10295
10296def StrToInt(s):
10297    """Convert string expression to integer
10298    >>> a = StrToInt("1")
10299    >>> simplify(1 == a)
10300    True
10301    >>> b = StrToInt("2")
10302    >>> simplify(1 == b)
10303    False
10304    >>> c = StrToInt(IntToStr(2))
10305    >>> simplify(1 == c)
10306    False
10307    """
10308    s = _coerce_seq(s)
10309    return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
10310
10311
10312def IntToStr(s):
10313    """Convert integer expression to string"""
10314    if not is_expr(s):
10315        s = _py2expr(s)
10316    return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
10317
10318
10319def Re(s, ctx=None):
10320    """The regular expression that accepts sequence 's'
10321    >>> s1 = Re("ab")
10322    >>> s2 = Re(StringVal("ab"))
10323    >>> s3 = Re(Unit(BoolVal(True)))
10324    """
10325    s = _coerce_seq(s, ctx)
10326    return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
10327
10328
10329
10330
10331## Regular expressions
10332
10333class ReSortRef(SortRef):
10334    """Regular expression sort."""
10335
10336    def basis(self):
10337        return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10338
10339def ReSort(s):
10340    if is_ast(s):
10341        return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
10342    if s is None or isinstance(s, Context):
10343        ctx = _get_ctx(s)
10344        return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
10345    raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
10346
10347
10348class ReRef(ExprRef):
10349    """Regular expressions."""
10350
10351    def __add__(self, other):
10352        return Union(self, other)
10353
10354def is_re(s):
10355    return isinstance(s, ReRef)
10356
10357
10358def InRe(s, re):
10359    """Create regular expression membership test
10360    >>> re = Union(Re("a"),Re("b"))
10361    >>> print (simplify(InRe("a", re)))
10362    True
10363    >>> print (simplify(InRe("b", re)))
10364    True
10365    >>> print (simplify(InRe("c", re)))
10366    False
10367    """
10368    s = _coerce_seq(s, re.ctx)
10369    return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
10370
10371def Union(*args):
10372    """Create union of regular expressions.
10373    >>> re = Union(Re("a"), Re("b"), Re("c"))
10374    >>> print (simplify(InRe("d", re)))
10375    False
10376    """
10377    args = _get_args(args)
10378    sz = len(args)
10379    if z3_debug():
10380        _z3_assert(sz > 0, "At least one argument expected.")
10381        _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
10382    if sz == 1:
10383        return args[0]
10384    ctx = args[0].ctx
10385    v = (Ast * sz)()
10386    for i in range(sz):
10387        v[i] = args[i].as_ast()
10388    return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
10389
10390def Intersect(*args):
10391    """Create intersection of regular expressions.
10392    >>> re = Intersect(Re("a"), Re("b"), Re("c"))
10393    """
10394    args = _get_args(args)
10395    sz = len(args)
10396    if z3_debug():
10397        _z3_assert(sz > 0, "At least one argument expected.")
10398        _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
10399    if sz == 1:
10400        return args[0]
10401    ctx = args[0].ctx
10402    v = (Ast * sz)()
10403    for i in range(sz):
10404        v[i] = args[i].as_ast()
10405    return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
10406
10407def Plus(re):
10408    """Create the regular expression accepting one or more repetitions of argument.
10409    >>> re = Plus(Re("a"))
10410    >>> print(simplify(InRe("aa", re)))
10411    True
10412    >>> print(simplify(InRe("ab", re)))
10413    False
10414    >>> print(simplify(InRe("", re)))
10415    False
10416    """
10417    return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
10418
10419def Option(re):
10420    """Create the regular expression that optionally accepts the argument.
10421    >>> re = Option(Re("a"))
10422    >>> print(simplify(InRe("a", re)))
10423    True
10424    >>> print(simplify(InRe("", re)))
10425    True
10426    >>> print(simplify(InRe("aa", re)))
10427    False
10428    """
10429    return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
10430
10431def Complement(re):
10432    """Create the complement regular expression."""
10433    return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
10434
10435def Star(re):
10436    """Create the regular expression accepting zero or more repetitions of argument.
10437    >>> re = Star(Re("a"))
10438    >>> print(simplify(InRe("aa", re)))
10439    True
10440    >>> print(simplify(InRe("ab", re)))
10441    False
10442    >>> print(simplify(InRe("", re)))
10443    True
10444    """
10445    return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
10446
10447def Loop(re, lo, hi=0):
10448    """Create the regular expression accepting between a lower and upper bound repetitions
10449    >>> re = Loop(Re("a"), 1, 3)
10450    >>> print(simplify(InRe("aa", re)))
10451    True
10452    >>> print(simplify(InRe("aaaa", re)))
10453    False
10454    >>> print(simplify(InRe("", re)))
10455    False
10456    """
10457    return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
10458
10459def Range(lo, hi, ctx = None):
10460    """Create the range regular expression over two sequences of length 1
10461    >>> range = Range("a","z")
10462    >>> print(simplify(InRe("b", range)))
10463    True
10464    >>> print(simplify(InRe("bb", range)))
10465    False
10466    """
10467    lo = _coerce_seq(lo, ctx)
10468    hi = _coerce_seq(hi, ctx)
10469    return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
10470
10471# Special Relations
10472
10473def PartialOrder(a, index):
10474    return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx);
10475
10476def LinearOrder(a, index):
10477    return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx);
10478
10479def TreeOrder(a, index):
10480    return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx);
10481
10482def PiecewiseLinearOrder(a, index):
10483    return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx);
10484
10485def TransitiveClosure(f):
10486    """Given a binary relation R, such that the two arguments have the same sort
10487    create the transitive closure relation R+.
10488    The transitive closure R+ is a new relation.
10489    """
10490    return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
10491
10492
10493class PropClosures:
10494    def __init__(self):
10495        self.bases = {}
10496        self.lock = None
10497
10498    def set_threaded():
10499        if self.lock is None:
10500            import threading
10501            self.lock = threading.thread.Lock()
10502
10503    def get(self, ctx):
10504        if self.lock: self.lock.acquire()
10505        r = self.bases[ctx]
10506        if self.lock: self.lock.release()
10507        return r
10508
10509    def set(self, ctx, r):
10510        if self.lock: self.lock.acquire()
10511        self.bases[ctx] = r
10512        if self.lock: self.lock.release()
10513
10514    def insert(self, r):
10515        if self.lock: self.lock.acquire()
10516        id = len(self.bases) + 3
10517        self.bases[id] = r
10518        if self.lock: self.lock.release()
10519        return id
10520
10521_prop_closures = None
10522
10523def ensure_prop_closures():
10524    global _prop_closures
10525    if _prop_closures is None:
10526        _prop_closures = PropClosures()
10527
10528def user_prop_push(ctx):
10529    _prop_closures.get(ctx).push();
10530
10531def user_prop_pop(ctx, num_scopes):
10532    _prop_closures.get(ctx).pop(num_scopes)
10533
10534def user_prop_fresh(id, ctx):
10535    prop = _prop_closures.get(id)
10536    _prop_closures.set_threaded()
10537    new_prop = UsePropagateBase(None, ctx)
10538    _prop_closures.set(new_prop.id, new_prop.fresh())
10539    return ctypes.c_void_p(new_prop.id)
10540
10541def user_prop_fixed(ctx, cb, id, value):
10542    prop = _prop_closures.get(ctx)
10543    prop.cb = cb
10544    prop.fixed(id, _to_expr_ref(ctypes.c_void_p(value), prop.ctx()))
10545    prop.cb = None
10546
10547def user_prop_final(ctx, cb):
10548    prop = _prop_closures.get(ctx)
10549    prop.cb = cb
10550    prop.final()
10551    prop.cb = None
10552
10553def user_prop_eq(ctx, cb, x, y):
10554    prop = _prop_closures.get(ctx)
10555    prop.cb = cb
10556    prop.eq(x, y)
10557    prop.cb = None
10558
10559def user_prop_diseq(ctx, cb, x, y):
10560    prop = _prop_closures.get(ctx)
10561    prop.cb = cb
10562    prop.diseq(x, y)
10563    prop.cb = None
10564
10565_user_prop_push  = push_eh_type(user_prop_push)
10566_user_prop_pop   = pop_eh_type(user_prop_pop)
10567_user_prop_fresh = fresh_eh_type(user_prop_fresh)
10568_user_prop_fixed = fixed_eh_type(user_prop_fixed)
10569_user_prop_final = final_eh_type(user_prop_final)
10570_user_prop_eq    = eq_eh_type(user_prop_eq)
10571_user_prop_diseq = eq_eh_type(user_prop_diseq)
10572
10573class UserPropagateBase:
10574
10575    #
10576    # Either solver is set or ctx is set.
10577    # Propagators that are created throuh callbacks
10578    # to "fresh" inherit the context of that is supplied
10579    # as argument to the callback.
10580    # This context should not be deleted. It is owned by the solver.
10581    #
10582    def __init__(self, s, ctx = None):
10583        assert s is None or ctx is None
10584        ensure_prop_closures()
10585        self.solver = s
10586        self._ctx = None
10587        self.cb = None
10588        self.id = _prop_closures.insert(self)
10589        self.fixed = None
10590        self.final = None
10591        self.eq    = None
10592        self.diseq = None
10593        if ctx:
10594            self._ctx = Context()
10595            Z3_del_context(self._ctx.ctx)
10596            self._ctx.ctx = ctx
10597            self._ctx.eh = Z3_set_error_handler(ctx, z3_error_handler)
10598            Z3_set_ast_print_mode(ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
10599        if s:
10600            Z3_solver_propagate_init(self.ctx_ref(),
10601                                     s.solver,
10602                                     ctypes.c_void_p(self.id),
10603                                     _user_prop_push,
10604                                     _user_prop_pop,
10605                                     _user_prop_fresh)
10606
10607    def __del__(self):
10608        if self._ctx:
10609            self._ctx.ctx = None
10610
10611    def ctx(self):
10612        if self._ctx:
10613            return self._ctx
10614        else:
10615            return self.solver.ctx
10616
10617    def ctx_ref(self):
10618        return self.ctx().ref()
10619
10620    def add_fixed(self, fixed):
10621        assert not self.fixed
10622        assert not self._ctx
10623        Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
10624        self.fixed = fixed
10625
10626    def add_final(self, final):
10627        assert not self.final
10628        assert not self._ctx
10629        Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
10630        self.final = final
10631
10632    def add_eq(self, eq):
10633        assert not self.eq
10634        assert not self._ctx
10635        Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
10636        self.eq = eq
10637
10638    def add_diseq(self, diseq):
10639        assert not self.diseq
10640        assert not self._ctx
10641        Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
10642        self.diseq = diseq
10643
10644    def push(self):
10645        raise Z3Exception("push needs to be overwritten")
10646
10647    def pop(self, num_scopes):
10648        raise Z3Exception("pop needs to be overwritten")
10649
10650    def fresh(self):
10651        raise Z3Exception("fresh needs to be overwritten")
10652
10653    def add(self, e):
10654        assert self.solver
10655        assert not self._ctx
10656        return Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
10657
10658    #
10659    # Propagation can only be invoked as during a fixed or final callback.
10660    #
10661    def propagate(self, e, ids, eqs = []):
10662        num_fixed = len(ids)
10663        _ids = (ctypes.c_uint * num_fixed)()
10664        for i in range(num_fixed):
10665            _ids[i] = ids[i]
10666        num_eqs = len(eqs)
10667        _lhs = (ctypes.c_uint * num_eqs)()
10668        _rhs = (ctypes.c_uint * num_eqs)()
10669        for i in range(num_eqs):
10670            _lhs[i] = eqs[i][0]
10671            _rhs[i] = eqs[i][1]
10672        Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
10673
10674    def conflict(self, ids):
10675        self.propagate(BoolVal(False, self.ctx()), ids, eqs=[])
10676