Z3
doc/tmp/z3py.py
Go to the documentation of this file.
00001 ############################################
00002 # Copyright (c) 2012 Microsoft Corporation
00003 # 
00004 # Z3 Python interface
00005 #
00006 # Author: Leonardo de Moura (leonardo)
00007 ############################################
00008 
00009 """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.
00010 
00011 Several online tutorials for Z3Py are available at:
00012 http://rise4fun.com/Z3Py/tutorial/guide
00013 
00014 Please send feedback, comments and/or corrections to leonardo@microsoft.com. Your comments are very valuable.
00015 
00016 Small example:
00017 
00018 >>> x = Int('x')
00019 >>> y = Int('y')
00020 >>> s = Solver()
00021 >>> s.add(x > 0)
00022 >>> s.add(x < 2)
00023 >>> s.add(y == x + 1)
00024 >>> s.check()
00025 sat
00026 >>> m = s.model()
00027 >>> m[x]
00028 1
00029 >>> m[y]
00030 2
00031 
00032 Z3 exceptions:
00033 
00034 >>> try:
00035 ...   x = BitVec('x', 32)
00036 ...   y = Bool('y')
00037 ...   # the expression x + y is type incorrect
00038 ...   n = x + y
00039 ... except Z3Exception as ex:
00040 ...   print("failed: %s" % ex)
00041 failed: sort mismatch
00042 """
00043 from z3core import *
00044 from z3types import *
00045 from z3consts import *
00046 from z3printer import *
00047 from fractions import Fraction
00048 import sys
00049 import io
00050 
00051 if sys.version < '3':
00052     def _is_int(v):
00053         return isinstance(v, int) or isinstance(v, long)
00054 else:
00055     def _is_int(v):
00056         return isinstance(v, int)
00057 
00058 def enable_trace(msg):
00059     Z3_enable_trace(msg)
00060 
00061 def disable_trace(msg):
00062     Z3_disable_trace(msg)
00063 
00064 def get_version_string():
00065   major = ctypes.c_uint(0)
00066   minor = ctypes.c_uint(0)
00067   build = ctypes.c_uint(0)
00068   rev = ctypes.c_uint(0)
00069   Z3_get_version(major, minor, build, rev)
00070   return "%s.%s.%s" % (major.value, minor.value, build.value)
00071 
00072 def get_version():
00073   major = ctypes.c_uint(0)
00074   minor = ctypes.c_uint(0)
00075   build = ctypes.c_uint(0)
00076   rev = ctypes.c_uint(0)
00077   Z3_get_version(major, minor, build, rev)
00078   return (major.value, minor.value, build.value, rev.value)
00079 
00080 # We use _z3_assert instead of the assert command because we want to
00081 # produce nice error messages in Z3Py at rise4fun.com
00082 def _z3_assert(cond, msg):
00083     if not cond:
00084         raise Z3Exception(msg)
00085 
00086 def open_log(fname):
00087     """Log interaction to a file. This function must be invoked immediately after init(). """
00088     Z3_open_log(fname)
00089 
00090 def append_log(s):
00091     """Append user-defined string to interaction log. """
00092     Z3_append_log(s)
00093 
00094 def to_symbol(s, ctx=None):
00095     """Convert an integer or string into a Z3 symbol."""
00096     if isinstance(s, int):
00097         return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
00098     else:
00099         return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
00100 
00101 def _symbol2py(ctx, s):
00102     """Convert a Z3 symbol back into a Python object. """
00103     if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
00104         return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
00105     else:
00106         return Z3_get_symbol_string(ctx.ref(), s)
00107 
00108 _error_handler_fptr = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_uint)
00109 
00110 # Hack for having nary functions that can receive one argument that is the
00111 # list of arguments.
00112 def _get_args(args):
00113     try:
00114         if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
00115             return args[0]
00116         else:
00117             return args
00118     except:  # len is not necessarily defined when args is not a sequence (use reflection?)
00119         return args
00120 
00121 def _Z3python_error_handler_core(c, e):
00122     # Do nothing error handler, just avoid exit(0)
00123     # The wrappers in z3core.py will raise a Z3Exception if an error is detected
00124     return
00125     
00126 _Z3Python_error_handler = _error_handler_fptr(_Z3python_error_handler_core)
00127 
00128 def _to_param_value(val):
00129     if isinstance(val, bool):
00130         if val == True:
00131             return "true"
00132         else:
00133             return "false"
00134     else:
00135         return str(val)
00136 
00137 class Context:
00138     """A Context manages all other Z3 objects, global configuration options, etc.
00139     
00140     Z3Py uses a default global context. For most applications this is sufficient.
00141     An application may use multiple Z3 contexts. Objects created in one context
00142     cannot be used in another one. However, several objects may be "translated" from
00143     one context to another. It is not safe to access Z3 objects from multiple threads.
00144     The only exception is the method `interrupt()` that can be used to interrupt() a long 
00145     computation.
00146     The initialization method receives global configuration options for the new context.
00147     """
00148     def __init__(self, *args, **kws):
00149         if __debug__:
00150             _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
00151         conf = Z3_mk_config()
00152         for key in kws:
00153             value = kws[key]
00154             Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
00155         prev = None
00156         for a in args:
00157             if prev == None:
00158                 prev = a
00159             else:
00160                 Z3_set_param_value(conf, str(prev), _to_param_value(a))
00161                 prev = None
00162         self.lib = lib()
00163         self.ctx = Z3_mk_context_rc(conf)
00164         Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
00165         lib().Z3_set_error_handler.restype  = None
00166         lib().Z3_set_error_handler.argtypes = [ContextObj, _error_handler_fptr]
00167         lib().Z3_set_error_handler(self.ctx, _Z3Python_error_handler)
00168         Z3_del_config(conf)
00169 
00170     def __del__(self):
00171         self.lib.Z3_del_context(self.ctx)
00172 
00173     def ref(self):
00174         """Return a reference to the actual C pointer to the Z3 context."""
00175         return self.ctx
00176 
00177     def interrupt(self):
00178         """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.  
00179 
00180         This method can be invoked from a thread different from the one executing the
00181         interruptable procedure.
00182         """
00183         Z3_interrupt(self.ref())
00184         
00185 
00186 # Global Z3 context
00187 _main_ctx = None
00188 def main_ctx():
00189     """Return a reference to the global Z3 context. 
00190     
00191     >>> x = Real('x')
00192     >>> x.ctx == main_ctx()
00193     True
00194     >>> c = Context()
00195     >>> c == main_ctx()
00196     False
00197     >>> x2 = Real('x', c)
00198     >>> x2.ctx == c
00199     True
00200     >>> eq(x, x2)
00201     False
00202     """
00203     global _main_ctx
00204     if _main_ctx == None:
00205         _main_ctx = Context()
00206     return _main_ctx    
00207 
00208 def _get_ctx(ctx):
00209     if ctx == None:
00210         return main_ctx()
00211     else:
00212         return ctx
00213 
00214 def set_param(*args, **kws):
00215     """Set Z3 global (or module) parameters.
00216 
00217     >>> set_param(precision=10)
00218     """
00219     if __debug__:
00220         _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
00221     new_kws = {}
00222     for k in kws:
00223         v = kws[k]
00224         if not set_pp_option(k, v):
00225             new_kws[k] = v
00226     for key in new_kws:
00227         value = new_kws[key]
00228         Z3_global_param_set(str(key).upper(), _to_param_value(value))
00229     prev = None
00230     for a in args:
00231         if prev == None:
00232             prev = a
00233         else:
00234             Z3_global_param_set(str(prev), _to_param_value(a))
00235             prev = None
00236 
00237 def reset_params():
00238     """Reset all global (or module) parameters.
00239     """
00240     Z3_global_param_reset_all()
00241 
00242 def set_option(*args, **kws):
00243     """Alias for 'set_param' for backward compatibility.
00244     """
00245     return set_param(*args, **kws)
00246 
00247 def get_param(name):
00248     """Return the value of a Z3 global (or module) parameter
00249 
00250     >>> get_param('nlsat.reorder')
00251     'true'
00252     """
00253     ptr = (ctypes.c_char_p * 1)()
00254     if Z3_global_param_get(str(name), ptr):
00255         r = z3core._to_pystr(ptr[0])
00256         return r
00257     raise Z3Exception("failed to retrieve value for '%s'" % name)
00258 
00259 #########################################
00260 #
00261 # ASTs base class
00262 #
00263 #########################################
00264 
00265 # Mark objects that use pretty printer
00266 class Z3PPObject:
00267     """Superclass for all Z3 objects that have support for pretty printing."""
00268     def use_pp(self):
00269         return True
00270 
00271 class AstRef(Z3PPObject):
00272     """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
00273     def __init__(self, ast, ctx=None):
00274         self.ast  = ast
00275         self.ctx  = _get_ctx(ctx)
00276         Z3_inc_ref(self.ctx.ref(), self.as_ast())
00277 
00278     def __del__(self):
00279         Z3_dec_ref(self.ctx.ref(), self.as_ast())
00280 
00281     def __str__(self):
00282         return obj_to_string(self)
00283 
00284     def __repr__(self):
00285         return obj_to_string(self)
00286 
00287     def sexpr(self):
00288         """Return an string representing the AST node in s-expression notation.
00289         
00290         >>> x = Int('x')
00291         >>> ((x + 1)*x).sexpr()
00292         '(* (+ x 1) x)'
00293         """
00294         return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
00295 
00296     def as_ast(self):
00297         """Return a pointer to the corresponding C Z3_ast object."""
00298         return self.ast
00299 
00300     def get_id(self):
00301         """Return unique identifier for object. It can be used for hash-tables and maps."""
00302         return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
00303 
00304     def ctx_ref(self):
00305         """Return a reference to the C context where this AST node is stored."""
00306         return self.ctx.ref()
00307         
00308     def eq(self, other):
00309         """Return `True` if `self` and `other` are structurally identical.
00310         
00311         >>> x = Int('x')
00312         >>> n1 = x + 1
00313         >>> n2 = 1 + x
00314         >>> n1.eq(n2)
00315         False
00316         >>> n1 = simplify(n1)
00317         >>> n2 = simplify(n2)
00318         >>> n1.eq(n2)
00319         True
00320         """
00321         if __debug__:
00322             _z3_assert(is_ast(other), "Z3 AST expected")
00323         return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
00324     
00325     def translate(self, target):
00326         """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`. 
00327         
00328         >>> c1 = Context()
00329         >>> c2 = Context()
00330         >>> x  = Int('x', c1)
00331         >>> y  = Int('y', c2)
00332         >>> # Nodes in different contexts can't be mixed.
00333         >>> # However, we can translate nodes from one context to another.
00334         >>> x.translate(c2) + y
00335         x + y
00336         """
00337         if __debug__:
00338             _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
00339         return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
00340 
00341     def hash(self):
00342         """Return a hashcode for the `self`.
00343         
00344         >>> n1 = simplify(Int('x') + 1)
00345         >>> n2 = simplify(2 + Int('x') - 1)
00346         >>> n1.hash() == n2.hash()
00347         True
00348         """
00349         return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
00350 
00351 def is_ast(a):
00352     """Return `True` if `a` is an AST node.
00353     
00354     >>> is_ast(10)
00355     False
00356     >>> is_ast(IntVal(10))
00357     True
00358     >>> is_ast(Int('x'))
00359     True
00360     >>> is_ast(BoolSort())
00361     True
00362     >>> is_ast(Function('f', IntSort(), IntSort()))
00363     True
00364     >>> is_ast("x")
00365     False
00366     >>> is_ast(Solver())
00367     False
00368     """
00369     return isinstance(a, AstRef)
00370 
00371 def eq(a, b):
00372     """Return `True` if `a` and `b` are structurally identical AST nodes.
00373     
00374     >>> x = Int('x')
00375     >>> y = Int('y')
00376     >>> eq(x, y)
00377     False
00378     >>> eq(x + 1, x + 1)
00379     True
00380     >>> eq(x + 1, 1 + x)
00381     False
00382     >>> eq(simplify(x + 1), simplify(1 + x))
00383     True
00384     """
00385     if __debug__:
00386         _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
00387     return a.eq(b)
00388 
00389 def _ast_kind(ctx, a):
00390     if is_ast(a):
00391         a = a.as_ast()
00392     return Z3_get_ast_kind(ctx.ref(), a)
00393 
00394 def _ctx_from_ast_arg_list(args, default_ctx=None):
00395     ctx = None
00396     for a in args:
00397         if is_ast(a) or is_probe(a):
00398             if ctx == None:
00399                 ctx = a.ctx
00400             else:
00401                 if __debug__:
00402                     _z3_assert(ctx == a.ctx, "Context mismatch")
00403     if ctx == None:
00404         ctx = default_ctx
00405     return ctx
00406 
00407 def _ctx_from_ast_args(*args):
00408     return _ctx_from_ast_arg_list(args)
00409 
00410 def _to_func_decl_array(args):
00411     sz = len(args)
00412     _args = (FuncDecl * sz)()
00413     for i in range(sz):
00414         _args[i] = args[i].as_func_decl()
00415     return _args, sz
00416 
00417 def _to_ast_array(args):
00418     sz = len(args)
00419     _args = (Ast * sz)()
00420     for i in range(sz):
00421         _args[i] = args[i].as_ast()
00422     return _args, sz
00423 
00424 def _to_ref_array(ref, args):
00425     sz = len(args)
00426     _args = (ref * sz)()
00427     for i in range(sz):
00428         _args[i] = args[i].as_ast()
00429     return _args, sz
00430 
00431 def _to_ast_ref(a, ctx):
00432     k = _ast_kind(ctx, a)
00433     if k == Z3_SORT_AST:
00434         return _to_sort_ref(a, ctx)
00435     elif k == Z3_FUNC_DECL_AST:
00436         return _to_func_decl_ref(a, ctx)
00437     else:
00438         return _to_expr_ref(a, ctx)
00439 
00440 #########################################
00441 #
00442 # Sorts
00443 #
00444 #########################################
00445 
00446 def _sort_kind(ctx, s):
00447     return Z3_get_sort_kind(ctx.ref(), s)
00448 
00449 class SortRef(AstRef):
00450     """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
00451     def as_ast(self):
00452         return Z3_sort_to_ast(self.ctx_ref(), self.ast)
00453 
00454     def get_id(self):
00455         return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
00456 
00457     def kind(self):
00458         """Return the Z3 internal kind of a sort. This method can be used to test if `self` is one of the Z3 builtin sorts.
00459         
00460         >>> b = BoolSort()
00461         >>> b.kind() == Z3_BOOL_SORT
00462         True
00463         >>> b.kind() == Z3_INT_SORT
00464         False
00465         >>> A = ArraySort(IntSort(), IntSort())
00466         >>> A.kind() == Z3_ARRAY_SORT
00467         True
00468         >>> A.kind() == Z3_INT_SORT
00469         False
00470         """
00471         return _sort_kind(self.ctx, self.ast)
00472 
00473     def subsort(self, other):
00474         """Return `True` if `self` is a subsort of `other`. 
00475         
00476         >>> IntSort().subsort(RealSort())
00477         True
00478         """
00479         return False
00480 
00481     def cast(self, val):
00482         """Try to cast `val` as an element of sort `self`. 
00483 
00484         This method is used in Z3Py to convert Python objects such as integers,
00485         floats, longs and strings into Z3 expressions.
00486 
00487         >>> x = Int('x')
00488         >>> RealSort().cast(x)
00489         ToReal(x)
00490         """ 
00491         if __debug__:
00492             _z3_assert(is_expr(val), "Z3 expression expected")
00493             _z3_assert(self.eq(val.sort()), "Sort mismatch")
00494         return val
00495 
00496     def name(self):
00497         """Return the name (string) of sort `self`.
00498         
00499         >>> BoolSort().name()
00500         'Bool'
00501         >>> ArraySort(IntSort(), IntSort()).name()
00502         'Array'
00503         """
00504         return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
00505 
00506     def __eq__(self, other):
00507         """Return `True` if `self` and `other` are the same Z3 sort.
00508         
00509         >>> p = Bool('p')
00510         >>> p.sort() == BoolSort()
00511         True
00512         >>> p.sort() == IntSort()
00513         False
00514         """
00515         if other == None:
00516             return False
00517         return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
00518 
00519     def __ne__(self, other):
00520         """Return `True` if `self` and `other` are not the same Z3 sort.
00521         
00522         >>> p = Bool('p')
00523         >>> p.sort() != BoolSort()
00524         False
00525         >>> p.sort() != IntSort()
00526         True
00527         """
00528         return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
00529 
00530 def is_sort(s):
00531     """Return `True` if `s` is a Z3 sort.
00532     
00533     >>> is_sort(IntSort())
00534     True
00535     >>> is_sort(Int('x'))
00536     False
00537     >>> is_expr(Int('x'))
00538     True
00539     """
00540     return isinstance(s, SortRef)
00541 
00542 def _to_sort_ref(s, ctx):
00543     if __debug__:
00544         _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
00545     k = _sort_kind(ctx, s)
00546     if k == Z3_BOOL_SORT:
00547         return BoolSortRef(s, ctx)
00548     elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
00549         return ArithSortRef(s, ctx)
00550     elif k == Z3_BV_SORT:
00551         return BitVecSortRef(s, ctx)
00552     elif k == Z3_ARRAY_SORT:
00553         return ArraySortRef(s, ctx)
00554     elif k == Z3_DATATYPE_SORT:
00555         return DatatypeSortRef(s, ctx)
00556     elif k == Z3_FINITE_DOMAIN_SORT:
00557         return FiniteDomainSortRef(s, ctx)
00558     elif k == Z3_FLOATING_POINT_SORT:
00559         return FPSortRef(s, ctx)
00560     elif k == Z3_ROUNDING_MODE_SORT:
00561         return FPRMSortRef(s, ctx)
00562     return SortRef(s, ctx)
00563 
00564 def _sort(ctx, a):
00565     return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
00566 
00567 def DeclareSort(name, ctx=None):
00568     """Create a new uninterpred sort named `name`.
00569 
00570     If `ctx=None`, then the new sort is declared in the global Z3Py context.
00571 
00572     >>> A = DeclareSort('A')
00573     >>> a = Const('a', A)
00574     >>> b = Const('b', A)
00575     >>> a.sort() == A
00576     True
00577     >>> b.sort() == A
00578     True
00579     >>> a == b
00580     a == b
00581     """
00582     ctx = _get_ctx(ctx)
00583     return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
00584 
00585 #########################################
00586 #
00587 # Function Declarations
00588 #
00589 #########################################
00590 
00591 class FuncDeclRef(AstRef):
00592     """Function declaration. Every constant and function have an associated declaration.
00593     
00594     The declaration assigns a name, a sort (i.e., type), and for function
00595     the sort (i.e., type) of each of its arguments. Note that, in Z3, 
00596     a constant is a function with 0 arguments.
00597     """
00598     def as_ast(self):
00599         return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
00600 
00601     def get_id(self):
00602         return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
00603 
00604     def as_func_decl(self):
00605         return self.ast
00606 
00607     def name(self):
00608         """Return the name of the function declaration `self`.
00609         
00610         >>> f = Function('f', IntSort(), IntSort())
00611         >>> f.name()
00612         'f'
00613         >>> isinstance(f.name(), str)
00614         True
00615         """
00616         return _symbol2py(self.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
00617 
00618     def arity(self):
00619         """Return the number of arguments of a function declaration. If `self` is a constant, then `self.arity()` is 0.
00620         
00621         >>> f = Function('f', IntSort(), RealSort(), BoolSort())
00622         >>> f.arity()
00623         2
00624         """
00625         return int(Z3_get_arity(self.ctx_ref(), self.ast))
00626 
00627     def domain(self, i):
00628         """Return the sort of the argument `i` of a function declaration. This method assumes that `0 <= i < self.arity()`.
00629         
00630         >>> f = Function('f', IntSort(), RealSort(), BoolSort())
00631         >>> f.domain(0)
00632         Int
00633         >>> f.domain(1)
00634         Real
00635         """
00636         if __debug__:
00637             _z3_assert(i < self.arity(), "Index out of bounds")
00638         return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
00639 
00640     def range(self):
00641         """Return the sort of the range of a function declaration. For constants, this is the sort of the constant.
00642         
00643         >>> f = Function('f', IntSort(), RealSort(), BoolSort())
00644         >>> f.range()
00645         Bool
00646         """
00647         return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.ast), self.ctx)
00648 
00649     def kind(self):
00650         """Return the internal kind of a function declaration. It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
00651         
00652         >>> x = Int('x')
00653         >>> d = (x + 1).decl()
00654         >>> d.kind() == Z3_OP_ADD
00655         True
00656         >>> d.kind() == Z3_OP_MUL
00657         False
00658         """
00659         return Z3_get_decl_kind(self.ctx_ref(), self.ast)
00660 
00661     def __call__(self, *args):
00662         """Create a Z3 application expression using the function `self`, and the given arguments. 
00663 
00664         The arguments must be Z3 expressions. This method assumes that
00665         the sorts of the elements in `args` match the sorts of the
00666         domain. Limited coersion is supported.  For example, if
00667         args[0] is a Python integer, and the function expects a Z3
00668         integer, then the argument is automatically converted into a
00669         Z3 integer.
00670 
00671         >>> f = Function('f', IntSort(), RealSort(), BoolSort())
00672         >>> x = Int('x')
00673         >>> y = Real('y')
00674         >>> f(x, y)
00675         f(x, y)
00676         >>> f(x, x)
00677         f(x, ToReal(x))
00678         """
00679         args = _get_args(args)
00680         num = len(args)
00681         if __debug__:
00682             _z3_assert(num == self.arity(), "Incorrect number of arguments to %s" % self)
00683         _args = (Ast * num)()
00684         saved = []
00685         for i in range(num):
00686             # self.domain(i).cast(args[i]) may create a new Z3 expression,
00687             # then we must save in 'saved' to prevent it from being garbage collected.
00688             tmp      = self.domain(i).cast(args[i])
00689             saved.append(tmp)
00690             _args[i] = tmp.as_ast()
00691         return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
00692 
00693 def is_func_decl(a):
00694     """Return `True` if `a` is a Z3 function declaration.
00695     
00696     >>> f = Function('f', IntSort(), IntSort())
00697     >>> is_func_decl(f)
00698     True
00699     >>> x = Real('x')
00700     >>> is_func_decl(x)
00701     False
00702     """
00703     return isinstance(a, FuncDeclRef)
00704 
00705 def Function(name, *sig):
00706     """Create a new Z3 uninterpreted function with the given sorts. 
00707     
00708     >>> f = Function('f', IntSort(), IntSort())
00709     >>> f(f(0))
00710     f(f(0))
00711     """
00712     sig = _get_args(sig)
00713     if __debug__:
00714         _z3_assert(len(sig) > 0, "At least two arguments expected")
00715     arity = len(sig) - 1
00716     rng   = sig[arity]
00717     if __debug__:
00718         _z3_assert(is_sort(rng), "Z3 sort expected")
00719     dom   = (Sort * arity)()
00720     for i in range(arity):
00721         if __debug__:
00722             _z3_assert(is_sort(sig[i]), "Z3 sort expected")
00723         dom[i] = sig[i].ast
00724     ctx = rng.ctx
00725     return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
00726 
00727 def _to_func_decl_ref(a, ctx):
00728     return FuncDeclRef(a, ctx)
00729 
00730 #########################################
00731 #
00732 # Expressions
00733 #
00734 #########################################
00735 
00736 class ExprRef(AstRef):
00737     """Constraints, formulas and terms are expressions in Z3.
00738 
00739     Expressions are ASTs. Every expression has a sort.
00740     There are three main kinds of expressions: 
00741     function applications, quantifiers and bounded variables.
00742     A constant is a function application with 0 arguments.
00743     For quantifier free problems, all expressions are 
00744     function applications.
00745     """
00746     def as_ast(self):
00747         return self.ast
00748 
00749     def get_id(self):
00750         return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
00751 
00752     def sort(self):
00753         """Return the sort of expression `self`.
00754         
00755         >>> x = Int('x')
00756         >>> (x + 1).sort()
00757         Int
00758         >>> y = Real('y')
00759         >>> (x + y).sort()
00760         Real
00761         """
00762         return _sort(self.ctx, self.as_ast())
00763 
00764     def sort_kind(self):
00765         """Shorthand for `self.sort().kind()`.
00766         
00767         >>> a = Array('a', IntSort(), IntSort())
00768         >>> a.sort_kind() == Z3_ARRAY_SORT
00769         True
00770         >>> a.sort_kind() == Z3_INT_SORT
00771         False
00772         """
00773         return self.sort().kind()
00774 
00775     def __eq__(self, other):
00776         """Return a Z3 expression that represents the constraint `self == other`.
00777 
00778         If `other` is `None`, then this method simply returns `False`. 
00779 
00780         >>> a = Int('a')
00781         >>> b = Int('b')
00782         >>> a == b
00783         a == b
00784         >>> a == None
00785         False
00786         """
00787         if other == None:
00788             return False
00789         a, b = _coerce_exprs(self, other)
00790         return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
00791 
00792     def __ne__(self, other):
00793         """Return a Z3 expression that represents the constraint `self != other`.
00794         
00795         If `other` is `None`, then this method simply returns `True`. 
00796 
00797         >>> a = Int('a')
00798         >>> b = Int('b')
00799         >>> a != b
00800         a != b
00801         >>> a != None
00802         True
00803         """
00804         if other == None:
00805             return True
00806         a, b = _coerce_exprs(self, other)
00807         _args, sz = _to_ast_array((a, b))
00808         return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
00809 
00810     def decl(self):
00811         """Return the Z3 function declaration associated with a Z3 application.
00812         
00813         >>> f = Function('f', IntSort(), IntSort())
00814         >>> a = Int('a')
00815         >>> t = f(a)
00816         >>> eq(t.decl(), f)
00817         True
00818         >>> (a + 1).decl()
00819         +
00820         """
00821         if __debug__:
00822             _z3_assert(is_app(self), "Z3 application expected")
00823         return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_ast()), self.ctx)
00824     
00825     def num_args(self):
00826         """Return the number of arguments of a Z3 application.
00827 
00828         >>> a = Int('a')
00829         >>> b = Int('b')
00830         >>> (a + b).num_args()
00831         2
00832         >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
00833         >>> t = f(a, b, 0)
00834         >>> t.num_args()
00835         3
00836         """
00837         if __debug__:
00838             _z3_assert(is_app(self), "Z3 application expected")
00839         return int(Z3_get_app_num_args(self.ctx_ref(), self.as_ast()))
00840 
00841     def arg(self, idx):
00842         """Return argument `idx` of the application `self`. 
00843 
00844         This method assumes that `self` is a function application with at least `idx+1` arguments.
00845 
00846         >>> a = Int('a')
00847         >>> b = Int('b')
00848         >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
00849         >>> t = f(a, b, 0)
00850         >>> t.arg(0)
00851         a
00852         >>> t.arg(1)
00853         b
00854         >>> t.arg(2)
00855         0
00856         """
00857         if __debug__:
00858             _z3_assert(is_app(self), "Z3 application expected")
00859             _z3_assert(idx < self.num_args(), "Invalid argument index")
00860         return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_ast(), idx), self.ctx)
00861 
00862     def children(self):
00863         """Return a list containing the children of the given expression
00864 
00865         >>> a = Int('a')
00866         >>> b = Int('b')
00867         >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
00868         >>> t = f(a, b, 0)
00869         >>> t.children()
00870         [a, b, 0]
00871         """
00872         if is_app(self):
00873             return [self.arg(i) for i in range(self.num_args())]
00874         else:
00875             return []
00876 
00877 def _to_expr_ref(a, ctx):
00878     if isinstance(a, Pattern):
00879         return PatternRef(a, ctx)
00880     ctx_ref = ctx.ref()
00881     k = Z3_get_ast_kind(ctx_ref, a) 
00882     if k == Z3_QUANTIFIER_AST:
00883         return QuantifierRef(a, ctx)
00884     sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
00885     if sk == Z3_BOOL_SORT:
00886         return BoolRef(a, ctx)
00887     if sk == Z3_INT_SORT:
00888         if k == Z3_NUMERAL_AST:
00889             return IntNumRef(a, ctx)
00890         return ArithRef(a, ctx)
00891     if sk == Z3_REAL_SORT:
00892         if k == Z3_NUMERAL_AST:
00893             return RatNumRef(a, ctx)
00894         if _is_algebraic(ctx, a):
00895             return AlgebraicNumRef(a, ctx)
00896         return ArithRef(a, ctx)
00897     if sk == Z3_BV_SORT:
00898         if k == Z3_NUMERAL_AST:
00899             return BitVecNumRef(a, ctx)
00900         else:
00901             return BitVecRef(a, ctx)
00902     if sk == Z3_ARRAY_SORT:
00903         return ArrayRef(a, ctx)
00904     if sk == Z3_DATATYPE_SORT:
00905         return DatatypeRef(a, ctx)
00906     if sk == Z3_FLOATING_POINT_SORT:  
00907         if k == Z3_APP_AST and _is_numeral(ctx, a):
00908             return FPNumRef(a, ctx)
00909         else:
00910             return FPRef(a, ctx)
00911     if sk == Z3_ROUNDING_MODE_SORT:
00912         return FPRMRef(a, ctx)
00913     return ExprRef(a, ctx)
00914 
00915 def _coerce_expr_merge(s, a):
00916     if is_expr(a):
00917         s1 = a.sort()
00918         if s == None:
00919             return s1
00920         if s1.eq(s):
00921             return s
00922         elif s.subsort(s1):
00923             return s1
00924         elif s1.subsort(s):
00925             return s
00926         else:
00927             if __debug__:
00928                 _z3_assert(s1.ctx == s.ctx, "context mismatch")
00929                 _z3_assert(False, "sort mismatch")
00930     else:
00931         return s
00932 
00933 def _coerce_exprs(a, b, ctx=None):
00934     if not is_expr(a) and not is_expr(b):
00935         a = _py2expr(a, ctx)
00936         b = _py2expr(b, ctx)
00937     s = None
00938     s = _coerce_expr_merge(s, a)
00939     s = _coerce_expr_merge(s, b)
00940     a = s.cast(a)
00941     b = s.cast(b)
00942     return (a, b)
00943     
00944 def _reduce(f, l, a):
00945     r = a
00946     for e in l:
00947         r = f(r, e)
00948     return r
00949 
00950 def _coerce_expr_list(alist, ctx=None):
00951     has_expr = False
00952     for a in alist:
00953         if is_expr(a):
00954             has_expr = True
00955             break
00956     if not has_expr:
00957         alist = [ _py2expr(a, ctx) for a in alist ]
00958     s = _reduce(_coerce_expr_merge, alist, None)
00959     return [ s.cast(a) for a in alist ]
00960 
00961 def is_expr(a):
00962     """Return `True` if `a` is a Z3 expression.
00963     
00964     >>> a = Int('a')
00965     >>> is_expr(a)
00966     True
00967     >>> is_expr(a + 1)
00968     True
00969     >>> is_expr(IntSort())
00970     False
00971     >>> is_expr(1)
00972     False
00973     >>> is_expr(IntVal(1))
00974     True
00975     >>> x = Int('x')
00976     >>> is_expr(ForAll(x, x >= 0))
00977     True
00978     """
00979     return isinstance(a, ExprRef)
00980 
00981 def is_app(a):
00982     """Return `True` if `a` is a Z3 function application. 
00983     
00984     Note that, constants are function applications with 0 arguments. 
00985 
00986     >>> a = Int('a')
00987     >>> is_app(a)
00988     True
00989     >>> is_app(a + 1)
00990     True
00991     >>> is_app(IntSort())
00992     False
00993     >>> is_app(1)
00994     False
00995     >>> is_app(IntVal(1))
00996     True
00997     >>> x = Int('x')
00998     >>> is_app(ForAll(x, x >= 0))
00999     False
01000     """
01001     if not isinstance(a, ExprRef):
01002         return False
01003     k = _ast_kind(a.ctx, a)
01004     return k == Z3_NUMERAL_AST or k == Z3_APP_AST
01005 
01006 def is_const(a):
01007     """Return `True` if `a` is Z3 constant/variable expression. 
01008     
01009     >>> a = Int('a')
01010     >>> is_const(a)
01011     True
01012     >>> is_const(a + 1)
01013     False
01014     >>> is_const(1)
01015     False
01016     >>> is_const(IntVal(1))
01017     True
01018     >>> x = Int('x')
01019     >>> is_const(ForAll(x, x >= 0))
01020     False
01021     """
01022     return is_app(a) and a.num_args() == 0
01023 
01024 def is_var(a):
01025     """Return `True` if `a` is variable. 
01026     
01027     Z3 uses de-Bruijn indices for representing bound variables in
01028     quantifiers.
01029 
01030     >>> x = Int('x')
01031     >>> is_var(x)
01032     False
01033     >>> is_const(x)
01034     True
01035     >>> f = Function('f', IntSort(), IntSort())
01036     >>> # Z3 replaces x with bound variables when ForAll is executed.
01037     >>> q = ForAll(x, f(x) == x)
01038     >>> b = q.body()
01039     >>> b
01040     f(Var(0)) == Var(0)
01041     >>> b.arg(1)
01042     Var(0)
01043     >>> is_var(b.arg(1))
01044     True
01045     """
01046     return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
01047 
01048 def get_var_index(a):
01049     """Return the de-Bruijn index of the Z3 bounded variable `a`.
01050     
01051     >>> x = Int('x')
01052     >>> y = Int('y')
01053     >>> is_var(x)
01054     False
01055     >>> is_const(x)
01056     True
01057     >>> f = Function('f', IntSort(), IntSort(), IntSort())
01058     >>> # Z3 replaces x and y with bound variables when ForAll is executed.
01059     >>> q = ForAll([x, y], f(x, y) == x + y)
01060     >>> q.body()
01061     f(Var(1), Var(0)) == Var(1) + Var(0)
01062     >>> b = q.body()
01063     >>> b.arg(0)
01064     f(Var(1), Var(0))
01065     >>> v1 = b.arg(0).arg(0)
01066     >>> v2 = b.arg(0).arg(1)
01067     >>> v1
01068     Var(1)
01069     >>> v2
01070     Var(0)
01071     >>> get_var_index(v1)
01072     1
01073     >>> get_var_index(v2)
01074     0
01075     """
01076     if __debug__:
01077         _z3_assert(is_var(a), "Z3 bound variable expected")
01078     return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
01079 
01080 def is_app_of(a, k):
01081     """Return `True` if `a` is an application of the given kind `k`. 
01082     
01083     >>> x = Int('x')
01084     >>> n = x + 1
01085     >>> is_app_of(n, Z3_OP_ADD)
01086     True
01087     >>> is_app_of(n, Z3_OP_MUL)
01088     False
01089     """
01090     return is_app(a) and a.decl().kind() == k
01091 
01092 def If(a, b, c, ctx=None):
01093     """Create a Z3 if-then-else expression. 
01094     
01095     >>> x = Int('x')
01096     >>> y = Int('y')
01097     >>> max = If(x > y, x, y)
01098     >>> max
01099     If(x > y, x, y)
01100     >>> simplify(max)
01101     If(x <= y, y, x)
01102     """
01103     if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
01104         return Cond(a, b, c, ctx)
01105     else:
01106         ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
01107         s = BoolSort(ctx)
01108         a = s.cast(a)
01109         b, c = _coerce_exprs(b, c, ctx)
01110         if __debug__:
01111             _z3_assert(a.ctx == b.ctx, "Context mismatch")
01112         return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
01113 
01114 def Distinct(*args):
01115     """Create a Z3 distinct expression. 
01116     
01117     >>> x = Int('x')
01118     >>> y = Int('y')
01119     >>> Distinct(x, y)
01120     x != y
01121     >>> z = Int('z')
01122     >>> Distinct(x, y, z)
01123     Distinct(x, y, z)
01124     >>> simplify(Distinct(x, y, z))
01125     Distinct(x, y, z)
01126     >>> simplify(Distinct(x, y, z), blast_distinct=True)
01127     And(Not(x == y), Not(x == z), Not(y == z))
01128     """
01129     args  = _get_args(args)
01130     ctx   = _ctx_from_ast_arg_list(args)
01131     if __debug__:
01132         _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression")
01133     args  = _coerce_expr_list(args, ctx)
01134     _args, sz = _to_ast_array(args)
01135     return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
01136 
01137 def _mk_bin(f, a, b):
01138     args = (Ast * 2)()
01139     if __debug__:
01140         _z3_assert(a.ctx == b.ctx, "Context mismatch")
01141     args[0] = a.as_ast()
01142     args[1] = b.as_ast()
01143     return f(a.ctx.ref(), 2, args)
01144 
01145 def Const(name, sort):
01146     """Create a constant of the given sort.
01147 
01148     >>> Const('x', IntSort())
01149     x
01150     """
01151     if __debug__:
01152         _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
01153     ctx = sort.ctx
01154     return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
01155 
01156 def Consts(names, sort):
01157     """Create a several constants of the given sort. 
01158     
01159     `names` is a string containing the names of all constants to be created. 
01160     Blank spaces separate the names of different constants.
01161     
01162     >>> x, y, z = Consts('x y z', IntSort())
01163     >>> x + y + z
01164     x + y + z
01165     """
01166     if isinstance(names, str):
01167         names = names.split(" ")
01168     return [Const(name, sort) for name in names]
01169 
01170 def Var(idx, s):
01171     """Create a Z3 free variable. Free variables are used to create quantified formulas.
01172     
01173     >>> Var(0, IntSort())
01174     Var(0)
01175     >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
01176     False
01177     """
01178     if __debug__:
01179         _z3_assert(is_sort(s), "Z3 sort expected")
01180     return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
01181 
01182 def RealVar(idx, ctx=None):
01183     """
01184     Create a real free variable. Free variables are used to create quantified formulas.
01185     They are also used to create polynomials.
01186     
01187     >>> RealVar(0)
01188     Var(0)
01189     """
01190     return Var(idx, RealSort(ctx))
01191 
01192 def RealVarVector(n, ctx=None):
01193     """
01194     Create a list of Real free variables.
01195     The variables have ids: 0, 1, ..., n-1
01196     
01197     >>> x0, x1, x2, x3 = RealVarVector(4)
01198     >>> x2
01199     Var(2)
01200     """
01201     return [ RealVar(i, ctx) for i in range(n) ]
01202 
01203 #########################################
01204 #
01205 # Booleans
01206 #
01207 #########################################
01208 
01209 class BoolSortRef(SortRef):
01210     """Boolean sort."""
01211     def cast(self, val):
01212         """Try to cast `val` as a Boolean.
01213         
01214         >>> x = BoolSort().cast(True)
01215         >>> x
01216         True
01217         >>> is_expr(x)
01218         True
01219         >>> is_expr(True)
01220         False
01221         >>> x.sort()
01222         Bool
01223         """
01224         if isinstance(val, bool):
01225             return BoolVal(val, self.ctx)
01226         if __debug__:
01227             _z3_assert(is_expr(val), "True, False or Z3 Boolean expression expected")
01228             _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
01229         return val
01230 
01231     def subsort(self, other):
01232         return isinstance(other, ArithSortRef)
01233 
01234     def is_int(self):
01235         return True
01236 
01237     def is_bool(self):
01238         return True
01239 
01240 
01241 class BoolRef(ExprRef):
01242     """All Boolean expressions are instances of this class."""
01243     def sort(self):
01244         return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
01245 
01246 def is_bool(a):
01247     """Return `True` if `a` is a Z3 Boolean expression.
01248 
01249     >>> p = Bool('p')
01250     >>> is_bool(p)
01251     True
01252     >>> q = Bool('q')
01253     >>> is_bool(And(p, q))
01254     True
01255     >>> x = Real('x')
01256     >>> is_bool(x)
01257     False
01258     >>> is_bool(x == 0)
01259     True
01260     """
01261     return isinstance(a, BoolRef)
01262 
01263 def is_true(a):
01264     """Return `True` if `a` is the Z3 true expression.
01265     
01266     >>> p = Bool('p')
01267     >>> is_true(p)
01268     False
01269     >>> is_true(simplify(p == p))
01270     True
01271     >>> x = Real('x')
01272     >>> is_true(x == 0)
01273     False
01274     >>> # True is a Python Boolean expression
01275     >>> is_true(True)
01276     False
01277     """
01278     return is_app_of(a, Z3_OP_TRUE)
01279 
01280 def is_false(a):
01281     """Return `True` if `a` is the Z3 false expression.
01282 
01283     >>> p = Bool('p')
01284     >>> is_false(p)
01285     False
01286     >>> is_false(False)
01287     False
01288     >>> is_false(BoolVal(False))
01289     True
01290     """
01291     return is_app_of(a, Z3_OP_FALSE)
01292 
01293 def is_and(a):
01294     """Return `True` if `a` is a Z3 and expression.
01295     
01296     >>> p, q = Bools('p q')
01297     >>> is_and(And(p, q))
01298     True
01299     >>> is_and(Or(p, q))
01300     False
01301     """
01302     return is_app_of(a, Z3_OP_AND)
01303 
01304 def is_or(a):
01305     """Return `True` if `a` is a Z3 or expression.
01306 
01307     >>> p, q = Bools('p q')
01308     >>> is_or(Or(p, q))
01309     True
01310     >>> is_or(And(p, q))
01311     False
01312     """
01313     return is_app_of(a, Z3_OP_OR)
01314 
01315 def is_not(a):
01316     """Return `True` if `a` is a Z3 not expression.
01317     
01318     >>> p = Bool('p')
01319     >>> is_not(p)
01320     False
01321     >>> is_not(Not(p))
01322     True
01323     """
01324     return is_app_of(a, Z3_OP_NOT)
01325 
01326 def is_eq(a):
01327     """Return `True` if `a` is a Z3 equality expression.
01328     
01329     >>> x, y = Ints('x y')
01330     >>> is_eq(x == y)
01331     True
01332     """
01333     return is_app_of(a, Z3_OP_EQ)
01334 
01335 def is_distinct(a):
01336     """Return `True` if `a` is a Z3 distinct expression.
01337     
01338     >>> x, y, z = Ints('x y z')
01339     >>> is_distinct(x == y)
01340     False
01341     >>> is_distinct(Distinct(x, y, z))
01342     True
01343     """
01344     return is_app_of(a, Z3_OP_DISTINCT)
01345 
01346 def BoolSort(ctx=None):
01347     """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
01348     
01349     >>> BoolSort()
01350     Bool
01351     >>> p = Const('p', BoolSort())
01352     >>> is_bool(p)
01353     True
01354     >>> r = Function('r', IntSort(), IntSort(), BoolSort())
01355     >>> r(0, 1)
01356     r(0, 1)
01357     >>> is_bool(r(0, 1))
01358     True
01359     """
01360     ctx = _get_ctx(ctx)
01361     return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
01362 
01363 def BoolVal(val, ctx=None):
01364     """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
01365     
01366     >>> BoolVal(True)
01367     True
01368     >>> is_true(BoolVal(True))
01369     True
01370     >>> is_true(True)
01371     False
01372     >>> is_false(BoolVal(False))
01373     True
01374     """
01375     ctx = _get_ctx(ctx)
01376     if val == False:
01377         return BoolRef(Z3_mk_false(ctx.ref()), ctx)
01378     else:
01379         return BoolRef(Z3_mk_true(ctx.ref()), ctx)
01380 
01381 def Bool(name, ctx=None):
01382     """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
01383     
01384     >>> p = Bool('p')
01385     >>> q = Bool('q')
01386     >>> And(p, q)
01387     And(p, q)
01388     """
01389     ctx = _get_ctx(ctx)
01390     return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
01391 
01392 def Bools(names, ctx=None):
01393     """Return a tuple of Boolean constants. 
01394     
01395     `names` is a single string containing all names separated by blank spaces. 
01396     If `ctx=None`, then the global context is used.
01397 
01398     >>> p, q, r = Bools('p q r')
01399     >>> And(p, Or(q, r))
01400     And(p, Or(q, r))
01401     """
01402     ctx = _get_ctx(ctx)
01403     if isinstance(names, str):
01404         names = names.split(" ")
01405     return [Bool(name, ctx) for name in names]
01406 
01407 def BoolVector(prefix, sz, ctx=None):
01408     """Return a list of Boolean constants of size `sz`.
01409 
01410     The constants are named using the given prefix.
01411     If `ctx=None`, then the global context is used.
01412     
01413     >>> P = BoolVector('p', 3)
01414     >>> P
01415     [p__0, p__1, p__2]
01416     >>> And(P)
01417     And(p__0, p__1, p__2)
01418     """
01419     return [ Bool('%s__%s' % (prefix, i)) for i in range(sz) ]
01420 
01421 def FreshBool(prefix='b', ctx=None):
01422     """Return a fresh Boolean constant in the given context using the given prefix.
01423     
01424     If `ctx=None`, then the global context is used.    
01425 
01426     >>> b1 = FreshBool()
01427     >>> b2 = FreshBool()
01428     >>> eq(b1, b2)
01429     False
01430     """
01431     ctx = _get_ctx(ctx)
01432     return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
01433 
01434 def Implies(a, b, ctx=None):
01435     """Create a Z3 implies expression. 
01436     
01437     >>> p, q = Bools('p q')
01438     >>> Implies(p, q)
01439     Implies(p, q)
01440     >>> simplify(Implies(p, q))
01441     Or(Not(p), q)
01442     """
01443     ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
01444     s = BoolSort(ctx)
01445     a = s.cast(a)
01446     b = s.cast(b)
01447     return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
01448 
01449 def Xor(a, b, ctx=None):
01450     """Create a Z3 Xor expression.
01451 
01452     >>> p, q = Bools('p q')
01453     >>> Xor(p, q)
01454     Xor(p, q)
01455     >>> simplify(Xor(p, q))
01456     Not(p) == q
01457     """
01458     ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
01459     s = BoolSort(ctx)
01460     a = s.cast(a)
01461     b = s.cast(b)
01462     return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
01463 
01464 def Not(a, ctx=None):
01465     """Create a Z3 not expression or probe. 
01466     
01467     >>> p = Bool('p')
01468     >>> Not(Not(p))
01469     Not(Not(p))
01470     >>> simplify(Not(Not(p)))
01471     p
01472     """
01473     ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
01474     if is_probe(a):
01475         # Not is also used to build probes
01476         return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
01477     else:
01478         s = BoolSort(ctx)
01479         a = s.cast(a)
01480         return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
01481 
01482 def _has_probe(args):
01483     """Return `True` if one of the elements of the given collection is a Z3 probe."""
01484     for arg in args:
01485         if is_probe(arg):
01486             return True
01487     return False
01488 
01489 def And(*args):
01490     """Create a Z3 and-expression or and-probe. 
01491     
01492     >>> p, q, r = Bools('p q r')
01493     >>> And(p, q, r)
01494     And(p, q, r)
01495     >>> P = BoolVector('p', 5)
01496     >>> And(P)
01497     And(p__0, p__1, p__2, p__3, p__4)
01498     """
01499     last_arg = None
01500     if len(args) > 0:
01501         last_arg = args[len(args)-1]
01502     if isinstance(last_arg, Context):
01503         ctx = args[len(args)-1]
01504         args = args[:len(args)-1]
01505     else:
01506         ctx = main_ctx()
01507     args = _get_args(args)
01508     ctx_args  = _ctx_from_ast_arg_list(args, ctx)
01509     if __debug__:
01510         _z3_assert(ctx_args == None or ctx_args == ctx, "context mismatch")
01511         _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
01512     if _has_probe(args):
01513         return _probe_and(args, ctx)
01514     else:
01515         args  = _coerce_expr_list(args, ctx)
01516         _args, sz = _to_ast_array(args)
01517         return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
01518 
01519 def Or(*args):
01520     """Create a Z3 or-expression or or-probe. 
01521     
01522     >>> p, q, r = Bools('p q r')
01523     >>> Or(p, q, r)
01524     Or(p, q, r)
01525     >>> P = BoolVector('p', 5)
01526     >>> Or(P)
01527     Or(p__0, p__1, p__2, p__3, p__4)
01528     """
01529     last_arg = None
01530     if len(args) > 0:
01531         last_arg = args[len(args)-1]
01532     if isinstance(last_arg, Context):
01533         ctx = args[len(args)-1]
01534         args = args[:len(args)-1]
01535     else:
01536         ctx = main_ctx()
01537     args = _get_args(args)
01538     ctx_args  = _ctx_from_ast_arg_list(args, ctx)
01539     if __debug__:
01540         _z3_assert(ctx_args == None or ctx_args == ctx, "context mismatch")
01541         _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
01542     if _has_probe(args):
01543         return _probe_or(args, ctx)
01544     else:
01545         args  = _coerce_expr_list(args, ctx)
01546         _args, sz = _to_ast_array(args)
01547         return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
01548 
01549 #########################################
01550 #
01551 # Patterns
01552 #
01553 #########################################
01554 
01555 class PatternRef(ExprRef):
01556     """Patterns are hints for quantifier instantiation. 
01557     
01558     See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
01559     """
01560     def as_ast(self):
01561         return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
01562 
01563     def get_id(self):
01564         return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
01565 
01566 def is_pattern(a):
01567     """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
01568 
01569     See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
01570     
01571     >>> f = Function('f', IntSort(), IntSort())
01572     >>> x = Int('x')
01573     >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
01574     >>> q
01575     ForAll(x, f(x) == 0)
01576     >>> q.num_patterns()
01577     1
01578     >>> is_pattern(q.pattern(0))
01579     True
01580     >>> q.pattern(0)
01581     f(Var(0))
01582     """
01583     return isinstance(a, PatternRef)
01584 
01585 def MultiPattern(*args):
01586     """Create a Z3 multi-pattern using the given expressions `*args`
01587 
01588     See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
01589     
01590     >>> f = Function('f', IntSort(), IntSort())
01591     >>> g = Function('g', IntSort(), IntSort())
01592     >>> x = Int('x')
01593     >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
01594     >>> q
01595     ForAll(x, f(x) != g(x))
01596     >>> q.num_patterns()
01597     1
01598     >>> is_pattern(q.pattern(0))
01599     True
01600     >>> q.pattern(0)
01601     MultiPattern(f(Var(0)), g(Var(0)))
01602     """
01603     if __debug__:
01604         _z3_assert(len(args) > 0, "At least one argument expected")
01605         _z3_assert(all([ is_expr(a) for a in args ]), "Z3 expressions expected")
01606     ctx = args[0].ctx
01607     args, sz = _to_ast_array(args)
01608     return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
01609 
01610 def _to_pattern(arg):
01611     if is_pattern(arg):
01612         return arg
01613     else:
01614         return MultiPattern(arg)
01615 
01616 #########################################
01617 #
01618 # Quantifiers
01619 #
01620 #########################################
01621 
01622 class QuantifierRef(BoolRef):
01623     """Universally and Existentially quantified formulas."""
01624 
01625     def as_ast(self):
01626         return self.ast
01627 
01628     def get_id(self):
01629         return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
01630 
01631     def sort(self):
01632         """Return the Boolean sort."""
01633         return BoolSort(self.ctx)
01634 
01635     def is_forall(self):
01636         """Return `True` if `self` is a universal quantifier.
01637         
01638         >>> f = Function('f', IntSort(), IntSort())
01639         >>> x = Int('x')
01640         >>> q = ForAll(x, f(x) == 0)
01641         >>> q.is_forall()
01642         True
01643         >>> q = Exists(x, f(x) != 0)
01644         >>> q.is_forall()
01645         False
01646         """
01647         return Z3_is_quantifier_forall(self.ctx_ref(), self.ast)
01648 
01649     def weight(self):
01650         """Return the weight annotation of `self`.
01651 
01652         >>> f = Function('f', IntSort(), IntSort())
01653         >>> x = Int('x')
01654         >>> q = ForAll(x, f(x) == 0)
01655         >>> q.weight()
01656         1
01657         >>> q = ForAll(x, f(x) == 0, weight=10)
01658         >>> q.weight()
01659         10
01660         """
01661         return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
01662 
01663     def num_patterns(self):
01664         """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
01665 
01666         >>> f = Function('f', IntSort(), IntSort())
01667         >>> g = Function('g', IntSort(), IntSort())
01668         >>> x = Int('x')
01669         >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
01670         >>> q.num_patterns()
01671         2
01672         """
01673         return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
01674 
01675     def pattern(self, idx):
01676         """Return a pattern (i.e., quantifier instantiation hints) in `self`.
01677 
01678         >>> f = Function('f', IntSort(), IntSort())
01679         >>> g = Function('g', IntSort(), IntSort())
01680         >>> x = Int('x')
01681         >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
01682         >>> q.num_patterns()
01683         2
01684         >>> q.pattern(0)
01685         f(Var(0))
01686         >>> q.pattern(1)
01687         g(Var(0))
01688         """
01689         if __debug__:
01690             _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
01691         return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
01692 
01693     def num_no_patterns(self):
01694         """Return the number of no-patterns."""
01695         return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
01696 
01697     def no_pattern(self, idx):
01698         """Return a no-pattern."""
01699         if __debug__:
01700             _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
01701         return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
01702 
01703     def body(self):
01704         """Return the expression being quantified.
01705 
01706         >>> f = Function('f', IntSort(), IntSort())
01707         >>> x = Int('x')
01708         >>> q = ForAll(x, f(x) == 0)
01709         >>> q.body()
01710         f(Var(0)) == 0
01711         """
01712         return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
01713     
01714     def num_vars(self):
01715         """Return the number of variables bounded by this quantifier. 
01716         
01717         >>> f = Function('f', IntSort(), IntSort(), IntSort())
01718         >>> x = Int('x')
01719         >>> y = Int('y')
01720         >>> q = ForAll([x, y], f(x, y) >= x)
01721         >>> q.num_vars() 
01722         2
01723         """
01724         return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
01725 
01726     def var_name(self, idx):
01727         """Return a string representing a name used when displaying the quantifier. 
01728         
01729         >>> f = Function('f', IntSort(), IntSort(), IntSort())
01730         >>> x = Int('x')
01731         >>> y = Int('y')
01732         >>> q = ForAll([x, y], f(x, y) >= x)
01733         >>> q.var_name(0)
01734         'x'
01735         >>> q.var_name(1)
01736         'y'
01737         """
01738         if __debug__:
01739             _z3_assert(idx < self.num_vars(), "Invalid variable idx")
01740         return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
01741 
01742     def var_sort(self, idx):
01743         """Return the sort of a bound variable.
01744 
01745         >>> f = Function('f', IntSort(), RealSort(), IntSort())
01746         >>> x = Int('x')
01747         >>> y = Real('y')
01748         >>> q = ForAll([x, y], f(x, y) >= x)
01749         >>> q.var_sort(0)
01750         Int
01751         >>> q.var_sort(1)
01752         Real
01753         """
01754         if __debug__:
01755             _z3_assert(idx < self.num_vars(), "Invalid variable idx")
01756         return SortRef(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
01757 
01758     def children(self):
01759         """Return a list containing a single element self.body()
01760 
01761         >>> f = Function('f', IntSort(), IntSort())
01762         >>> x = Int('x')
01763         >>> q = ForAll(x, f(x) == 0)
01764         >>> q.children()
01765         [f(Var(0)) == 0]
01766         """
01767         return [ self.body() ]
01768 
01769 def is_quantifier(a):
01770     """Return `True` if `a` is a Z3 quantifier.
01771     
01772     >>> f = Function('f', IntSort(), IntSort())
01773     >>> x = Int('x')
01774     >>> q = ForAll(x, f(x) == 0)
01775     >>> is_quantifier(q)
01776     True
01777     >>> is_quantifier(f(x))
01778     False
01779     """
01780     return isinstance(a, QuantifierRef)
01781 
01782 def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
01783     if __debug__:
01784         _z3_assert(is_bool(body), "Z3 expression expected")
01785         _z3_assert(is_const(vs) or (len(vs) > 0 and all([ is_const(v) for v in vs])), "Invalid bounded variable(s)")
01786         _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
01787         _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
01788     ctx = body.ctx
01789     if is_app(vs):
01790         vs = [vs]
01791     num_vars = len(vs)
01792     _vs = (Ast * num_vars)()
01793     for i in range(num_vars):
01794         ## TODO: Check if is constant
01795         _vs[i] = vs[i].as_ast()
01796     patterns = [ _to_pattern(p) for p in patterns ]
01797     num_pats = len(patterns)
01798     _pats = (Pattern * num_pats)()
01799     for i in range(num_pats):
01800         _pats[i] = patterns[i].ast
01801     _no_pats, num_no_pats = _to_ast_array(no_patterns)
01802     qid  = to_symbol(qid, ctx)
01803     skid = to_symbol(skid, ctx)
01804     return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid, 
01805                                                    num_vars, _vs, 
01806                                                    num_pats, _pats, 
01807                                                    num_no_pats, _no_pats, 
01808                                                    body.as_ast()), ctx)
01809 
01810 def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
01811     """Create a Z3 forall formula.
01812     
01813     The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
01814 
01815     See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
01816 
01817     >>> f = Function('f', IntSort(), IntSort(), IntSort())
01818     >>> x = Int('x')
01819     >>> y = Int('y')
01820     >>> ForAll([x, y], f(x, y) >= x)
01821     ForAll([x, y], f(x, y) >= x)
01822     >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
01823     ForAll([x, y], f(x, y) >= x)
01824     >>> ForAll([x, y], f(x, y) >= x, weight=10)
01825     ForAll([x, y], f(x, y) >= x)
01826     """
01827     return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
01828 
01829 def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
01830     """Create a Z3 exists formula.
01831     
01832     The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
01833 
01834     See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
01835 
01836     >>> f = Function('f', IntSort(), IntSort(), IntSort())
01837     >>> x = Int('x')
01838     >>> y = Int('y')
01839     >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
01840     >>> q
01841     Exists([x, y], f(x, y) >= x)
01842     >>> is_quantifier(q)
01843     True
01844     >>> r = Tactic('nnf')(q).as_expr()
01845     >>> is_quantifier(r)
01846     False
01847     """
01848     return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
01849 
01850 #########################################
01851 #
01852 # Arithmetic
01853 #
01854 #########################################
01855 
01856 class ArithSortRef(SortRef):
01857     """Real and Integer sorts."""
01858 
01859     def is_real(self):
01860         """Return `True` if `self` is of the sort Real.
01861         
01862         >>> x = Real('x')
01863         >>> x.is_real()
01864         True
01865         >>> (x + 1).is_real()
01866         True
01867         >>> x = Int('x')
01868         >>> x.is_real()
01869         False
01870         """
01871         return self.kind() == Z3_REAL_SORT
01872 
01873     def is_int(self):
01874         """Return `True` if `self` is of the sort Integer.
01875         
01876         >>> x = Int('x')
01877         >>> x.is_int()
01878         True
01879         >>> (x + 1).is_int()
01880         True
01881         >>> x = Real('x')
01882         >>> x.is_int()
01883         False
01884         """
01885         return self.kind() == Z3_INT_SORT
01886 
01887     def subsort(self, other):
01888         """Return `True` if `self` is a subsort of `other`."""
01889         return self.is_int() and is_arith_sort(other) and other.is_real()
01890 
01891     def cast(self, val):
01892         """Try to cast `val` as an Integer or Real.
01893         
01894         >>> IntSort().cast(10)
01895         10
01896         >>> is_int(IntSort().cast(10))
01897         True
01898         >>> is_int(10)
01899         False
01900         >>> RealSort().cast(10)
01901         10
01902         >>> is_real(RealSort().cast(10))
01903         True
01904         """
01905         if is_expr(val):
01906             if __debug__:
01907                 _z3_assert(self.ctx == val.ctx, "Context mismatch")
01908             val_s = val.sort()
01909             if self.eq(val_s):
01910                 return val
01911             if val_s.is_int() and self.is_real():
01912                 return ToReal(val)
01913             if val_s.is_bool() and self.is_int():
01914                 return If(val, 1, 0)
01915             if val_s.is_bool() and self.is_real():
01916                 return ToReal(If(val, 1, 0))
01917             if __debug__:
01918                 _z3_assert(False, "Z3 Integer/Real expression expected" )
01919         else:
01920             if self.is_int():
01921                 return IntVal(val, self.ctx)
01922             if self.is_real():
01923                 return RealVal(val, self.ctx)
01924             if __debug__:
01925                 _z3_assert(False, "int, long, float, string (numeral), or Z3 Integer/Real expression expected")
01926 
01927 def is_arith_sort(s):
01928     """Return `True` if s is an arithmetical sort (type).
01929     
01930     >>> is_arith_sort(IntSort())
01931     True
01932     >>> is_arith_sort(RealSort())
01933     True
01934     >>> is_arith_sort(BoolSort())
01935     False
01936     >>> n = Int('x') + 1
01937     >>> is_arith_sort(n.sort())
01938     True
01939     """
01940     return isinstance(s, ArithSortRef)
01941     
01942 class ArithRef(ExprRef):
01943     """Integer and Real expressions."""
01944 
01945     def sort(self):
01946         """Return the sort (type) of the arithmetical expression `self`.
01947         
01948         >>> Int('x').sort()
01949         Int
01950         >>> (Real('x') + 1).sort()
01951         Real
01952         """
01953         return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
01954 
01955     def is_int(self):
01956         """Return `True` if `self` is an integer expression.
01957         
01958         >>> x = Int('x')
01959         >>> x.is_int()
01960         True
01961         >>> (x + 1).is_int()
01962         True
01963         >>> y = Real('y')
01964         >>> (x + y).is_int()
01965         False
01966         """
01967         return self.sort().is_int()
01968 
01969     def is_real(self):
01970         """Return `True` if `self` is an real expression.
01971         
01972         >>> x = Real('x')
01973         >>> x.is_real()
01974         True
01975         >>> (x + 1).is_real()
01976         True
01977         """
01978         return self.sort().is_real()
01979 
01980     def __add__(self, other):
01981         """Create the Z3 expression `self + other`.
01982         
01983         >>> x = Int('x')
01984         >>> y = Int('y')
01985         >>> x + y
01986         x + y
01987         >>> (x + y).sort()
01988         Int
01989         """
01990         a, b = _coerce_exprs(self, other)
01991         return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctx)
01992 
01993     def __radd__(self, other):
01994         """Create the Z3 expression `other + self`.
01995         
01996         >>> x = Int('x')
01997         >>> 10 + x
01998         10 + x
01999         """
02000         a, b = _coerce_exprs(self, other)
02001         return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctx)
02002 
02003     def __mul__(self, other):
02004         """Create the Z3 expression `self * other`.
02005         
02006         >>> x = Real('x')
02007         >>> y = Real('y')
02008         >>> x * y
02009         x*y
02010         >>> (x * y).sort()
02011         Real
02012         """
02013         a, b = _coerce_exprs(self, other)
02014         return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
02015 
02016     def __rmul__(self, other):
02017         """Create the Z3 expression `other * self`.
02018         
02019         >>> x = Real('x')
02020         >>> 10 * x
02021         10*x
02022         """
02023         a, b = _coerce_exprs(self, other)
02024         return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctx)
02025 
02026     def __sub__(self, other):
02027         """Create the Z3 expression `self - other`.
02028 
02029         >>> x = Int('x')
02030         >>> y = Int('y')
02031         >>> x - y
02032         x - y
02033         >>> (x - y).sort()
02034         Int
02035         """
02036         a, b = _coerce_exprs(self, other)
02037         return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctx)
02038 
02039     def __rsub__(self, other):
02040         """Create the Z3 expression `other - self`.
02041         
02042         >>> x = Int('x')
02043         >>> 10 - x
02044         10 - x
02045         """
02046         a, b = _coerce_exprs(self, other)
02047         return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctx)
02048 
02049     def __pow__(self, other):
02050         """Create the Z3 expression `self**other` (** is the power operator).
02051         
02052         >>> x = Real('x')
02053         >>> x**3
02054         x**3
02055         >>> (x**3).sort()
02056         Real
02057         >>> simplify(IntVal(2)**8)
02058         256
02059         """
02060         a, b = _coerce_exprs(self, other)
02061         return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
02062 
02063     def __rpow__(self, other):
02064         """Create the Z3 expression `other**self` (** is the power operator).
02065         
02066         >>> x = Real('x')
02067         >>> 2**x
02068         2**x
02069         >>> (2**x).sort()
02070         Real
02071         >>> simplify(2**IntVal(8))
02072         256
02073         """
02074         a, b = _coerce_exprs(self, other)
02075         return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
02076 
02077     def __div__(self, other):
02078         """Create the Z3 expression `other/self`.
02079         
02080         >>> x = Int('x')
02081         >>> y = Int('y')
02082         >>> x/y
02083         x/y
02084         >>> (x/y).sort()
02085         Int
02086         >>> (x/y).sexpr()
02087         '(div x y)'
02088         >>> x = Real('x')
02089         >>> y = Real('y')
02090         >>> x/y
02091         x/y
02092         >>> (x/y).sort()
02093         Real
02094         >>> (x/y).sexpr()
02095         '(/ x y)'
02096         """
02097         a, b = _coerce_exprs(self, other)
02098         return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
02099 
02100     def __truediv__(self, other):
02101         """Create the Z3 expression `other/self`."""
02102         return self.__div__(other)
02103 
02104     def __rdiv__(self, other):
02105         """Create the Z3 expression `other/self`.
02106         
02107         >>> x = Int('x')
02108         >>> 10/x
02109         10/x
02110         >>> (10/x).sexpr()
02111         '(div 10 x)'
02112         >>> x = Real('x')
02113         >>> 10/x
02114         10/x
02115         >>> (10/x).sexpr()
02116         '(/ 10.0 x)'
02117         """
02118         a, b = _coerce_exprs(self, other)
02119         return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
02120 
02121     def __rtruediv__(self, other):
02122         """Create the Z3 expression `other/self`."""
02123         return self.__rdiv__(other)
02124 
02125     def __mod__(self, other):
02126         """Create the Z3 expression `other%self`.
02127         
02128         >>> x = Int('x')
02129         >>> y = Int('y')
02130         >>> x % y
02131         x%y
02132         >>> simplify(IntVal(10) % IntVal(3))
02133         1
02134         """
02135         a, b = _coerce_exprs(self, other)
02136         if __debug__:
02137             _z3_assert(a.is_int(), "Z3 integer expression expected")
02138         return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
02139 
02140     def __rmod__(self, other):
02141         """Create the Z3 expression `other%self`.
02142         
02143         >>> x = Int('x')
02144         >>> 10 % x
02145         10%x
02146         """
02147         a, b = _coerce_exprs(self, other)
02148         if __debug__:
02149             _z3_assert(a.is_int(), "Z3 integer expression expected")
02150         return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
02151 
02152     def __neg__(self):
02153         """Return an expression representing `-self`.
02154 
02155         >>> x = Int('x')
02156         >>> -x
02157         -x
02158         >>> simplify(-(-x))
02159         x
02160         """
02161         return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
02162     
02163     def __pos__(self):
02164         """Return `self`.
02165         
02166         >>> x = Int('x')
02167         >>> +x
02168         x
02169         """
02170         return self
02171 
02172     def __le__(self, other):
02173         """Create the Z3 expression `other <= self`.
02174         
02175         >>> x, y = Ints('x y')
02176         >>> x <= y
02177         x <= y
02178         >>> y = Real('y')
02179         >>> x <= y
02180         ToReal(x) <= y
02181         """
02182         a, b = _coerce_exprs(self, other)
02183         return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
02184 
02185     def __lt__(self, other):
02186         """Create the Z3 expression `other < self`.
02187         
02188         >>> x, y = Ints('x y')
02189         >>> x < y
02190         x < y
02191         >>> y = Real('y')
02192         >>> x < y
02193         ToReal(x) < y
02194         """
02195         a, b = _coerce_exprs(self, other)
02196         return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
02197 
02198     def __gt__(self, other):
02199         """Create the Z3 expression `other > self`.
02200         
02201         >>> x, y = Ints('x y')
02202         >>> x > y
02203         x > y
02204         >>> y = Real('y')
02205         >>> x > y
02206         ToReal(x) > y
02207         """
02208         a, b = _coerce_exprs(self, other)
02209         return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
02210         
02211     def __ge__(self, other):
02212         """Create the Z3 expression `other >= self`.
02213         
02214         >>> x, y = Ints('x y')
02215         >>> x >= y
02216         x >= y
02217         >>> y = Real('y')
02218         >>> x >= y
02219         ToReal(x) >= y
02220         """
02221         a, b = _coerce_exprs(self, other)
02222         return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
02223 
02224 def is_arith(a):
02225     """Return `True` if `a` is an arithmetical expression.
02226     
02227     >>> x = Int('x')
02228     >>> is_arith(x)
02229     True
02230     >>> is_arith(x + 1)
02231     True
02232     >>> is_arith(1)
02233     False
02234     >>> is_arith(IntVal(1))
02235     True
02236     >>> y = Real('y')
02237     >>> is_arith(y)
02238     True
02239     >>> is_arith(y + 1)
02240     True
02241     """
02242     return isinstance(a, ArithRef)
02243 
02244 def is_int(a):
02245     """Return `True` if `a` is an integer expression.
02246     
02247     >>> x = Int('x')
02248     >>> is_int(x + 1)
02249     True
02250     >>> is_int(1)
02251     False
02252     >>> is_int(IntVal(1))
02253     True
02254     >>> y = Real('y')
02255     >>> is_int(y)
02256     False
02257     >>> is_int(y + 1)
02258     False
02259     """
02260     return is_arith(a) and a.is_int()
02261 
02262 def is_real(a):
02263     """Return `True` if `a` is a real expression.
02264     
02265     >>> x = Int('x')
02266     >>> is_real(x + 1)
02267     False
02268     >>> y = Real('y')
02269     >>> is_real(y)
02270     True
02271     >>> is_real(y + 1)
02272     True
02273     >>> is_real(1)
02274     False
02275     >>> is_real(RealVal(1))
02276     True
02277     """
02278     return is_arith(a) and a.is_real()
02279 
02280 def _is_numeral(ctx, a):
02281     return Z3_is_numeral_ast(ctx.ref(), a)
02282 
02283 def _is_algebraic(ctx, a):
02284     return Z3_is_algebraic_number(ctx.ref(), a)
02285 
02286 def is_int_value(a):
02287     """Return `True` if `a` is an integer value of sort Int.
02288     
02289     >>> is_int_value(IntVal(1))
02290     True
02291     >>> is_int_value(1)
02292     False
02293     >>> is_int_value(Int('x'))
02294     False
02295     >>> n = Int('x') + 1
02296     >>> n
02297     x + 1
02298     >>> n.arg(1)
02299     1
02300     >>> is_int_value(n.arg(1))
02301     True
02302     >>> is_int_value(RealVal("1/3"))
02303     False
02304     >>> is_int_value(RealVal(1))
02305     False
02306     """
02307     return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
02308 
02309 def is_rational_value(a):
02310     """Return `True` if `a` is rational value of sort Real.
02311     
02312     >>> is_rational_value(RealVal(1))
02313     True
02314     >>> is_rational_value(RealVal("3/5"))
02315     True
02316     >>> is_rational_value(IntVal(1))
02317     False
02318     >>> is_rational_value(1)
02319     False
02320     >>> n = Real('x') + 1
02321     >>> n.arg(1)
02322     1
02323     >>> is_rational_value(n.arg(1))
02324     True
02325     >>> is_rational_value(Real('x'))
02326     False
02327     """
02328     return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
02329 
02330 def is_algebraic_value(a):
02331     """Return `True` if `a` is an algerbraic value of sort Real.
02332     
02333     >>> is_algebraic_value(RealVal("3/5"))
02334     False
02335     >>> n = simplify(Sqrt(2))
02336     >>> n
02337     1.4142135623?
02338     >>> is_algebraic_value(n)
02339     True
02340     """
02341     return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
02342 
02343 def is_add(a):
02344     """Return `True` if `a` is an expression of the form b + c.
02345     
02346     >>> x, y = Ints('x y')
02347     >>> is_add(x + y)
02348     True
02349     >>> is_add(x - y)
02350     False
02351     """
02352     return is_app_of(a, Z3_OP_ADD)
02353 
02354 def is_mul(a):
02355     """Return `True` if `a` is an expression of the form b * c.
02356     
02357     >>> x, y = Ints('x y')
02358     >>> is_mul(x * y)
02359     True
02360     >>> is_mul(x - y)
02361     False
02362     """
02363     return is_app_of(a, Z3_OP_MUL)
02364 
02365 def is_sub(a):
02366     """Return `True` if `a` is an expression of the form b - c.
02367     
02368     >>> x, y = Ints('x y')
02369     >>> is_sub(x - y)
02370     True
02371     >>> is_sub(x + y)
02372     False
02373     """
02374     return is_app_of(a, Z3_OP_SUB)
02375 
02376 def is_div(a):
02377     """Return `True` if `a` is an expression of the form b / c.
02378     
02379     >>> x, y = Reals('x y')
02380     >>> is_div(x / y)
02381     True
02382     >>> is_div(x + y)
02383     False
02384     >>> x, y = Ints('x y')
02385     >>> is_div(x / y)
02386     False
02387     >>> is_idiv(x / y)
02388     True
02389     """
02390     return is_app_of(a, Z3_OP_DIV)
02391 
02392 def is_idiv(a):
02393     """Return `True` if `a` is an expression of the form b div c.
02394     
02395     >>> x, y = Ints('x y')
02396     >>> is_idiv(x / y)
02397     True
02398     >>> is_idiv(x + y)
02399     False
02400     """
02401     return is_app_of(a, Z3_OP_IDIV)
02402 
02403 def is_mod(a):
02404     """Return `True` if `a` is an expression of the form b % c.
02405 
02406     >>> x, y = Ints('x y')
02407     >>> is_mod(x % y)
02408     True
02409     >>> is_mod(x + y)
02410     False
02411     """
02412     return is_app_of(a, Z3_OP_MOD)
02413 
02414 def is_le(a):
02415     """Return `True` if `a` is an expression of the form b <= c.
02416     
02417     >>> x, y = Ints('x y')
02418     >>> is_le(x <= y)
02419     True
02420     >>> is_le(x < y)
02421     False
02422     """
02423     return is_app_of(a, Z3_OP_LE)
02424 
02425 def is_lt(a):
02426     """Return `True` if `a` is an expression of the form b < c.
02427     
02428     >>> x, y = Ints('x y')
02429     >>> is_lt(x < y)
02430     True
02431     >>> is_lt(x == y)
02432     False
02433     """
02434     return is_app_of(a, Z3_OP_LT)
02435 
02436 def is_ge(a):
02437     """Return `True` if `a` is an expression of the form b >= c.
02438     
02439     >>> x, y = Ints('x y')
02440     >>> is_ge(x >= y)
02441     True
02442     >>> is_ge(x == y)
02443     False
02444     """
02445     return is_app_of(a, Z3_OP_GE)
02446 
02447 def is_gt(a):
02448     """Return `True` if `a` is an expression of the form b > c.
02449     
02450     >>> x, y = Ints('x y')
02451     >>> is_gt(x > y)
02452     True
02453     >>> is_gt(x == y)
02454     False
02455     """
02456     return is_app_of(a, Z3_OP_GT)
02457 
02458 def is_is_int(a):
02459     """Return `True` if `a` is an expression of the form IsInt(b).
02460     
02461     >>> x = Real('x')
02462     >>> is_is_int(IsInt(x))
02463     True
02464     >>> is_is_int(x)
02465     False
02466     """
02467     return is_app_of(a, Z3_OP_IS_INT)
02468 
02469 def is_to_real(a):
02470     """Return `True` if `a` is an expression of the form ToReal(b).
02471     
02472     >>> x = Int('x')
02473     >>> n = ToReal(x)
02474     >>> n
02475     ToReal(x)
02476     >>> is_to_real(n)
02477     True
02478     >>> is_to_real(x)
02479     False
02480     """
02481     return is_app_of(a, Z3_OP_TO_REAL)
02482 
02483 def is_to_int(a):
02484     """Return `True` if `a` is an expression of the form ToInt(b).
02485     
02486     >>> x = Real('x')
02487     >>> n = ToInt(x)
02488     >>> n
02489     ToInt(x)
02490     >>> is_to_int(n)
02491     True
02492     >>> is_to_int(x)
02493     False
02494     """
02495     return is_app_of(a, Z3_OP_TO_INT)
02496 
02497 class IntNumRef(ArithRef):
02498     """Integer values."""
02499 
02500     def as_long(self):
02501         """Return a Z3 integer numeral as a Python long (bignum) numeral. 
02502         
02503         >>> v = IntVal(1)
02504         >>> v + 1
02505         1 + 1
02506         >>> v.as_long() + 1
02507         2
02508         """
02509         if __debug__:
02510             _z3_assert(self.is_int(), "Integer value expected")
02511         return int(self.as_string())
02512 
02513     def as_string(self):
02514         """Return a Z3 integer numeral as a Python string.
02515         >>> v = IntVal(100)
02516         >>> v.as_string()
02517         '100'
02518         """
02519         return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
02520 
02521 class RatNumRef(ArithRef):
02522     """Rational values."""
02523 
02524     def numerator(self):
02525         """ Return the numerator of a Z3 rational numeral. 
02526 
02527         >>> is_rational_value(RealVal("3/5"))
02528         True
02529         >>> n = RealVal("3/5")
02530         >>> n.numerator()
02531         3
02532         >>> is_rational_value(Q(3,5))
02533         True
02534         >>> Q(3,5).numerator()
02535         3
02536         """
02537         return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
02538 
02539     def denominator(self):
02540         """ Return the denominator of a Z3 rational numeral. 
02541         
02542         >>> is_rational_value(Q(3,5))
02543         True
02544         >>> n = Q(3,5)
02545         >>> n.denominator()
02546         5
02547         """
02548         return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
02549 
02550     def numerator_as_long(self):
02551         """ Return the numerator as a Python long.
02552         
02553         >>> v = RealVal(10000000000)
02554         >>> v
02555         10000000000
02556         >>> v + 1
02557         10000000000 + 1
02558         >>> v.numerator_as_long() + 1 == 10000000001
02559         True
02560         """
02561         return self.numerator().as_long()
02562         
02563     def denominator_as_long(self):
02564         """ Return the denominator as a Python long.
02565 
02566         >>> v = RealVal("1/3")
02567         >>> v
02568         1/3
02569         >>> v.denominator_as_long()
02570         3
02571         """
02572         return self.denominator().as_long()
02573 
02574     def as_decimal(self, prec):
02575         """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
02576         
02577         >>> v = RealVal("1/5")
02578         >>> v.as_decimal(3)
02579         '0.2'
02580         >>> v = RealVal("1/3")
02581         >>> v.as_decimal(3)
02582         '0.333?'
02583         """
02584         return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
02585 
02586     def as_string(self):
02587         """Return a Z3 rational numeral as a Python string.
02588 
02589         >>> v = Q(3,6)
02590         >>> v.as_string()
02591         '1/2'
02592         """
02593         return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
02594 
02595     def as_fraction(self):
02596         """Return a Z3 rational as a Python Fraction object.
02597         
02598         >>> v = RealVal("1/5")
02599         >>> v.as_fraction()
02600         Fraction(1, 5)
02601         """
02602         return Fraction(self.numerator_as_long(), self.denominator_as_long())
02603 
02604 class AlgebraicNumRef(ArithRef):
02605     """Algebraic irrational values."""
02606 
02607     def approx(self, precision=10):
02608         """Return a Z3 rational number that approximates the algebraic number `self`. 
02609         The result `r` is such that |r - self| <= 1/10^precision 
02610         
02611         >>> x = simplify(Sqrt(2))
02612         >>> x.approx(20)
02613         6838717160008073720548335/4835703278458516698824704
02614         >>> x.approx(5)
02615         2965821/2097152
02616         """
02617         return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
02618     def as_decimal(self, prec):
02619         """Return a string representation of the algebraic number `self` in decimal notation using `prec` decimal places
02620 
02621         >>> x = simplify(Sqrt(2))
02622         >>> x.as_decimal(10)
02623         '1.4142135623?'
02624         >>> x.as_decimal(20)
02625         '1.41421356237309504880?'
02626         """
02627         return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
02628 
02629 def _py2expr(a, ctx=None):
02630     if isinstance(a, bool):
02631         return BoolVal(a, ctx)
02632     if _is_int(a):
02633         return IntVal(a, ctx)
02634     if isinstance(a, float):
02635         return RealVal(a, ctx)
02636     if __debug__:
02637         _z3_assert(False, "Python bool, int, long or float expected")
02638 
02639 def IntSort(ctx=None):
02640     """Return the interger sort in the given context. If `ctx=None`, then the global context is used.
02641     
02642     >>> IntSort()
02643     Int
02644     >>> x = Const('x', IntSort())
02645     >>> is_int(x)
02646     True
02647     >>> x.sort() == IntSort()
02648     True
02649     >>> x.sort() == BoolSort()
02650     False
02651     """
02652     ctx = _get_ctx(ctx)
02653     return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
02654 
02655 def RealSort(ctx=None):
02656     """Return the real sort in the given context. If `ctx=None`, then the global context is used.
02657     
02658     >>> RealSort()
02659     Real
02660     >>> x = Const('x', RealSort())
02661     >>> is_real(x)
02662     True
02663     >>> is_int(x)
02664     False
02665     >>> x.sort() == RealSort()
02666     True
02667     """
02668     ctx = _get_ctx(ctx)
02669     return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
02670 
02671 def _to_int_str(val):
02672     if isinstance(val, float):
02673         return str(int(val))
02674     elif isinstance(val, bool):
02675         if val:
02676             return "1"
02677         else:
02678             return "0"
02679     elif _is_int(val):
02680         return str(val)
02681     elif isinstance(val, str):
02682         return val
02683     if __debug__:
02684         _z3_assert(False, "Python value cannot be used as a Z3 integer")
02685 
02686 def IntVal(val, ctx=None):
02687     """Return a Z3 integer value. If `ctx=None`, then the global context is used.
02688     
02689     >>> IntVal(1)
02690     1
02691     >>> IntVal("100")
02692     100
02693     """
02694     ctx = _get_ctx(ctx)
02695     return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
02696 
02697 def RealVal(val, ctx=None):
02698     """Return a Z3 real value. 
02699     
02700     `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
02701     If `ctx=None`, then the global context is used.
02702     
02703     >>> RealVal(1)
02704     1
02705     >>> RealVal(1).sort()
02706     Real
02707     >>> RealVal("3/5")
02708     3/5
02709     >>> RealVal("1.5")
02710     3/2
02711     """
02712     ctx = _get_ctx(ctx)
02713     return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
02714 
02715 def RatVal(a, b, ctx=None):
02716     """Return a Z3 rational a/b.
02717 
02718     If `ctx=None`, then the global context is used.
02719     
02720     >>> RatVal(3,5)
02721     3/5
02722     >>> RatVal(3,5).sort()
02723     Real
02724     """
02725     if __debug__:
02726         _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
02727         _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
02728     return simplify(RealVal(a, ctx)/RealVal(b, ctx))
02729 
02730 def Q(a, b, ctx=None):
02731     """Return a Z3 rational a/b.
02732     
02733     If `ctx=None`, then the global context is used.
02734 
02735     >>> Q(3,5)
02736     3/5
02737     >>> Q(3,5).sort()
02738     Real
02739     """
02740     return simplify(RatVal(a, b))
02741 
02742 def Int(name, ctx=None):
02743     """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
02744 
02745     >>> x = Int('x')
02746     >>> is_int(x)
02747     True
02748     >>> is_int(x + 1)
02749     True
02750     """
02751     ctx = _get_ctx(ctx)
02752     return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
02753 
02754 def Ints(names, ctx=None):
02755     """Return a tuple of Integer constants. 
02756     
02757     >>> x, y, z = Ints('x y z')
02758     >>> Sum(x, y, z)
02759     x + y + z
02760     """
02761     ctx = _get_ctx(ctx)
02762     if isinstance(names, str):
02763         names = names.split(" ")
02764     return [Int(name, ctx) for name in names]
02765 
02766 def IntVector(prefix, sz, ctx=None):
02767     """Return a list of integer constants of size `sz`.
02768     
02769     >>> X = IntVector('x', 3)
02770     >>> X
02771     [x__0, x__1, x__2]
02772     >>> Sum(X)
02773     x__0 + x__1 + x__2
02774     """
02775     return [ Int('%s__%s' % (prefix, i)) for i in range(sz) ]
02776 
02777 def FreshInt(prefix='x', ctx=None):
02778     """Return a fresh integer constant in the given context using the given prefix.
02779 
02780     >>> x = FreshInt()
02781     >>> y = FreshInt()
02782     >>> eq(x, y)
02783     False
02784     >>> x.sort()
02785     Int
02786     """
02787     ctx = _get_ctx(ctx)
02788     return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
02789 
02790 def Real(name, ctx=None):
02791     """Return a real constant named `name`. If `ctx=None`, then the global context is used.
02792 
02793     >>> x = Real('x')
02794     >>> is_real(x)
02795     True
02796     >>> is_real(x + 1)
02797     True
02798     """
02799     ctx = _get_ctx(ctx)
02800     return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
02801 
02802 def Reals(names, ctx=None):
02803     """Return a tuple of real constants. 
02804     
02805     >>> x, y, z = Reals('x y z')
02806     >>> Sum(x, y, z)
02807     x + y + z
02808     >>> Sum(x, y, z).sort()
02809     Real
02810     """
02811     ctx = _get_ctx(ctx)
02812     if isinstance(names, str):
02813         names = names.split(" ")
02814     return [Real(name, ctx) for name in names]
02815 
02816 def RealVector(prefix, sz, ctx=None):
02817     """Return a list of real constants of size `sz`.
02818     
02819     >>> X = RealVector('x', 3)
02820     >>> X
02821     [x__0, x__1, x__2]
02822     >>> Sum(X)
02823     x__0 + x__1 + x__2
02824     >>> Sum(X).sort()
02825     Real
02826     """
02827     return [ Real('%s__%s' % (prefix, i)) for i in range(sz) ]
02828 
02829 def FreshReal(prefix='b', ctx=None):
02830     """Return a fresh real constant in the given context using the given prefix.
02831 
02832     >>> x = FreshReal()
02833     >>> y = FreshReal()
02834     >>> eq(x, y)
02835     False
02836     >>> x.sort()
02837     Real
02838     """
02839     ctx = _get_ctx(ctx)
02840     return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
02841 
02842 def ToReal(a):
02843     """ Return the Z3 expression ToReal(a). 
02844     
02845     >>> x = Int('x')
02846     >>> x.sort()
02847     Int
02848     >>> n = ToReal(x)
02849     >>> n
02850     ToReal(x)
02851     >>> n.sort()
02852     Real
02853     """
02854     if __debug__:
02855         _z3_assert(a.is_int(), "Z3 integer expression expected.")
02856     ctx = a.ctx
02857     return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
02858 
02859 def ToInt(a):
02860     """ Return the Z3 expression ToInt(a). 
02861     
02862     >>> x = Real('x')
02863     >>> x.sort()
02864     Real
02865     >>> n = ToInt(x)
02866     >>> n
02867     ToInt(x)
02868     >>> n.sort()
02869     Int
02870     """
02871     if __debug__:
02872         _z3_assert(a.is_real(), "Z3 real expression expected.")
02873     ctx = a.ctx
02874     return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
02875 
02876 def IsInt(a):
02877     """ Return the Z3 predicate IsInt(a). 
02878     
02879     >>> x = Real('x')
02880     >>> IsInt(x + "1/2")
02881     IsInt(x + 1/2)
02882     >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
02883     [x = 1/2]
02884     >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
02885     no solution
02886     """
02887     if __debug__:
02888         _z3_assert(a.is_real(), "Z3 real expression expected.")
02889     ctx = a.ctx
02890     return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
02891     
02892 def Sqrt(a, ctx=None):
02893     """ Return a Z3 expression which represents the square root of a. 
02894     
02895     >>> x = Real('x')
02896     >>> Sqrt(x)
02897     x**(1/2)
02898     """
02899     if not is_expr(a):
02900         ctx = _get_ctx(ctx)
02901         a = RealVal(a, ctx)
02902     return a ** "1/2"
02903 
02904 def Cbrt(a, ctx=None):
02905     """ Return a Z3 expression which represents the cubic root of a. 
02906     
02907     >>> x = Real('x')
02908     >>> Cbrt(x)
02909     x**(1/3)
02910     """
02911     if not is_expr(a):
02912         ctx = _get_ctx(ctx)
02913         a = RealVal(a, ctx)
02914     return a ** "1/3"
02915 
02916 #########################################
02917 #
02918 # Bit-Vectors
02919 #
02920 #########################################
02921 
02922 class BitVecSortRef(SortRef):
02923     """Bit-vector sort."""
02924 
02925     def size(self):
02926         """Return the size (number of bits) of the bit-vector sort `self`.
02927         
02928         >>> b = BitVecSort(32)
02929         >>> b.size()
02930         32
02931         """
02932         return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
02933 
02934     def subsort(self, other):
02935         return is_bv_sort(other) and self.size() < other.size()
02936 
02937     def cast(self, val):
02938         """Try to cast `val` as a Bit-Vector.
02939 
02940         >>> b = BitVecSort(32)
02941         >>> b.cast(10)
02942         10
02943         >>> b.cast(10).sexpr()
02944         '#x0000000a'
02945         """
02946         if is_expr(val):
02947             if __debug__:
02948                 _z3_assert(self.ctx == val.ctx, "Context mismatch")
02949             # Idea: use sign_extend if sort of val is a bitvector of smaller size
02950             return val
02951         else:
02952             return BitVecVal(val, self)
02953 
02954 def is_bv_sort(s):
02955     """Return True if `s` is a Z3 bit-vector sort.
02956 
02957     >>> is_bv_sort(BitVecSort(32))
02958     True
02959     >>> is_bv_sort(IntSort())
02960     False
02961     """
02962     return isinstance(s, BitVecSortRef)
02963 
02964 class BitVecRef(ExprRef):
02965     """Bit-vector expressions."""
02966 
02967     def sort(self):
02968         """Return the sort of the bit-vector expression `self`.
02969 
02970         >>> x = BitVec('x', 32)
02971         >>> x.sort()
02972         BitVec(32)
02973         >>> x.sort() == BitVecSort(32)
02974         True
02975         """
02976         return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
02977 
02978     def size(self):
02979         """Return the number of bits of the bit-vector expression `self`.
02980         
02981         >>> x = BitVec('x', 32)
02982         >>> (x + 1).size()
02983         32
02984         >>> Concat(x, x).size()
02985         64
02986         """
02987         return self.sort().size()
02988     
02989     def __add__(self, other):
02990         """Create the Z3 expression `self + other`.
02991         
02992         >>> x = BitVec('x', 32)
02993         >>> y = BitVec('y', 32)
02994         >>> x + y
02995         x + y
02996         >>> (x + y).sort()
02997         BitVec(32)
02998         """
02999         a, b = _coerce_exprs(self, other)
03000         return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03001 
03002     def __radd__(self, other):
03003         """Create the Z3 expression `other + self`.
03004         
03005         >>> x = BitVec('x', 32)
03006         >>> 10 + x
03007         10 + x
03008         """
03009         a, b = _coerce_exprs(self, other)
03010         return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03011 
03012     def __mul__(self, other):
03013         """Create the Z3 expression `self * other`.
03014         
03015         >>> x = BitVec('x', 32)
03016         >>> y = BitVec('y', 32)
03017         >>> x * y
03018         x*y
03019         >>> (x * y).sort()
03020         BitVec(32)
03021         """
03022         a, b = _coerce_exprs(self, other)
03023         return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03024 
03025     def __rmul__(self, other):
03026         """Create the Z3 expression `other * self`.
03027         
03028         >>> x = BitVec('x', 32)
03029         >>> 10 * x
03030         10*x
03031         """
03032         a, b = _coerce_exprs(self, other)
03033         return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03034 
03035     def __sub__(self, other):
03036         """Create the Z3 expression `self - other`.
03037         
03038         >>> x = BitVec('x', 32)
03039         >>> y = BitVec('y', 32)
03040         >>> x - y
03041         x - y
03042         >>> (x - y).sort()
03043         BitVec(32)
03044         """
03045         a, b = _coerce_exprs(self, other)
03046         return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03047 
03048     def __rsub__(self, other):
03049         """Create the Z3 expression `other - self`.
03050         
03051         >>> x = BitVec('x', 32)
03052         >>> 10 - x
03053         10 - x
03054         """
03055         a, b = _coerce_exprs(self, other)
03056         return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03057 
03058     def __or__(self, other):
03059         """Create the Z3 expression bitwise-or `self | other`.
03060         
03061         >>> x = BitVec('x', 32)
03062         >>> y = BitVec('y', 32)
03063         >>> x | y
03064         x | y
03065         >>> (x | y).sort()
03066         BitVec(32)
03067         """
03068         a, b = _coerce_exprs(self, other)
03069         return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03070 
03071     def __ror__(self, other):
03072         """Create the Z3 expression bitwise-or `other | self`.
03073         
03074         >>> x = BitVec('x', 32)
03075         >>> 10 | x
03076         10 | x
03077         """
03078         a, b = _coerce_exprs(self, other)
03079         return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03080 
03081     def __and__(self, other):
03082         """Create the Z3 expression bitwise-and `self & other`.
03083         
03084         >>> x = BitVec('x', 32)
03085         >>> y = BitVec('y', 32)
03086         >>> x & y
03087         x & y
03088         >>> (x & y).sort()
03089         BitVec(32)
03090         """
03091         a, b = _coerce_exprs(self, other)
03092         return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03093 
03094     def __rand__(self, other):
03095         """Create the Z3 expression bitwise-or `other & self`.
03096         
03097         >>> x = BitVec('x', 32)
03098         >>> 10 & x
03099         10 & x
03100         """
03101         a, b = _coerce_exprs(self, other)
03102         return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03103 
03104     def __xor__(self, other):
03105         """Create the Z3 expression bitwise-xor `self ^ other`.
03106         
03107         >>> x = BitVec('x', 32)
03108         >>> y = BitVec('y', 32)
03109         >>> x ^ y
03110         x ^ y
03111         >>> (x ^ y).sort()
03112         BitVec(32)
03113         """
03114         a, b = _coerce_exprs(self, other)
03115         return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03116 
03117     def __rxor__(self, other):
03118         """Create the Z3 expression bitwise-xor `other ^ self`.
03119         
03120         >>> x = BitVec('x', 32)
03121         >>> 10 ^ x
03122         10 ^ x
03123         """
03124         a, b = _coerce_exprs(self, other)
03125         return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03126 
03127     def __pos__(self):
03128         """Return `self`.
03129 
03130         >>> x = BitVec('x', 32)
03131         >>> +x
03132         x
03133         """
03134         return self
03135 
03136     def __neg__(self):
03137         """Return an expression representing `-self`.
03138 
03139         >>> x = BitVec('x', 32)
03140         >>> -x
03141         -x
03142         >>> simplify(-(-x))
03143         x
03144         """
03145         return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
03146 
03147     def __invert__(self):
03148         """Create the Z3 expression bitwise-not `~self`.
03149 
03150         >>> x = BitVec('x', 32)
03151         >>> ~x
03152         ~x
03153         >>> simplify(~(~x))
03154         x
03155         """
03156         return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
03157 
03158     def __div__(self, other):
03159         """Create the Z3 expression (signed) division `self / other`.
03160 
03161         Use the function UDiv() for unsigned division.
03162 
03163         >>> x = BitVec('x', 32)
03164         >>> y = BitVec('y', 32)
03165         >>> x / y
03166         x/y
03167         >>> (x / y).sort()
03168         BitVec(32)
03169         >>> (x / y).sexpr()
03170         '(bvsdiv x y)'
03171         >>> UDiv(x, y).sexpr()
03172         '(bvudiv x y)'
03173         """
03174         a, b = _coerce_exprs(self, other)
03175         return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03176 
03177     def __truediv__(self, other):
03178         """Create the Z3 expression (signed) division `self / other`."""
03179         return self.__div__(other)
03180 
03181     def __rdiv__(self, other):
03182         """Create the Z3 expression (signed) division `other / self`.
03183 
03184         Use the function UDiv() for unsigned division.
03185 
03186         >>> x = BitVec('x', 32)
03187         >>> 10 / x
03188         10/x
03189         >>> (10 / x).sexpr()
03190         '(bvsdiv #x0000000a x)'
03191         >>> UDiv(10, x).sexpr()
03192         '(bvudiv #x0000000a x)'
03193         """
03194         a, b = _coerce_exprs(self, other)
03195         return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03196 
03197     def __rtruediv__(self, other):
03198         """Create the Z3 expression (signed) division `other / self`."""
03199         return self.__rdiv__(other)
03200 
03201     def __mod__(self, other):
03202         """Create the Z3 expression (signed) mod `self % other`.
03203 
03204         Use the function URem() for unsigned remainder, and SRem() for signed remainder.
03205 
03206         >>> x = BitVec('x', 32)
03207         >>> y = BitVec('y', 32)
03208         >>> x % y
03209         x%y
03210         >>> (x % y).sort()
03211         BitVec(32)
03212         >>> (x % y).sexpr()
03213         '(bvsmod x y)'
03214         >>> URem(x, y).sexpr()
03215         '(bvurem x y)'
03216         >>> SRem(x, y).sexpr()
03217         '(bvsrem x y)'
03218         """
03219         a, b = _coerce_exprs(self, other)
03220         return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03221 
03222     def __rmod__(self, other):
03223         """Create the Z3 expression (signed) mod `other % self`.
03224 
03225         Use the function URem() for unsigned remainder, and SRem() for signed remainder.
03226 
03227         >>> x = BitVec('x', 32)
03228         >>> 10 % x
03229         10%x
03230         >>> (10 % x).sexpr()
03231         '(bvsmod #x0000000a x)'
03232         >>> URem(10, x).sexpr()
03233         '(bvurem #x0000000a x)'
03234         >>> SRem(10, x).sexpr()
03235         '(bvsrem #x0000000a x)'
03236         """
03237         a, b = _coerce_exprs(self, other)
03238         return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03239 
03240     def __le__(self, other):
03241         """Create the Z3 expression (signed) `other <= self`.
03242         
03243         Use the function ULE() for unsigned less than or equal to.
03244 
03245         >>> x, y = BitVecs('x y', 32)
03246         >>> x <= y
03247         x <= y
03248         >>> (x <= y).sexpr()
03249         '(bvsle x y)'
03250         >>> ULE(x, y).sexpr()
03251         '(bvule x y)'
03252         """
03253         a, b = _coerce_exprs(self, other)
03254         return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03255 
03256     def __lt__(self, other):
03257         """Create the Z3 expression (signed) `other < self`.
03258         
03259         Use the function ULT() for unsigned less than.
03260 
03261         >>> x, y = BitVecs('x y', 32)
03262         >>> x < y
03263         x < y
03264         >>> (x < y).sexpr()
03265         '(bvslt x y)'
03266         >>> ULT(x, y).sexpr()
03267         '(bvult x y)'
03268         """
03269         a, b = _coerce_exprs(self, other)
03270         return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03271 
03272     def __gt__(self, other):
03273         """Create the Z3 expression (signed) `other > self`.
03274         
03275         Use the function UGT() for unsigned greater than.
03276 
03277         >>> x, y = BitVecs('x y', 32)
03278         >>> x > y
03279         x > y
03280         >>> (x > y).sexpr()
03281         '(bvsgt x y)'
03282         >>> UGT(x, y).sexpr()
03283         '(bvugt x y)'
03284         """
03285         a, b = _coerce_exprs(self, other)
03286         return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03287         
03288     def __ge__(self, other):
03289         """Create the Z3 expression (signed) `other >= self`.
03290         
03291         Use the function UGE() for unsigned greater than or equal to.
03292 
03293         >>> x, y = BitVecs('x y', 32)
03294         >>> x >= y
03295         x >= y
03296         >>> (x >= y).sexpr()
03297         '(bvsge x y)'
03298         >>> UGE(x, y).sexpr()
03299         '(bvuge x y)'
03300         """
03301         a, b = _coerce_exprs(self, other)
03302         return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03303 
03304     def __rshift__(self, other):
03305         """Create the Z3 expression (arithmetical) right shift `self >> other`
03306 
03307         Use the function LShR() for the right logical shift
03308 
03309         >>> x, y = BitVecs('x y', 32)
03310         >>> x >> y
03311         x >> y
03312         >>> (x >> y).sexpr()
03313         '(bvashr x y)'
03314         >>> LShR(x, y).sexpr()
03315         '(bvlshr x y)'
03316         >>> BitVecVal(4, 3)
03317         4
03318         >>> BitVecVal(4, 3).as_signed_long()
03319         -4
03320         >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
03321         -2
03322         >>> simplify(BitVecVal(4, 3) >> 1)
03323         6
03324         >>> simplify(LShR(BitVecVal(4, 3), 1))
03325         2
03326         >>> simplify(BitVecVal(2, 3) >> 1)
03327         1
03328         >>> simplify(LShR(BitVecVal(2, 3), 1))
03329         1
03330         """
03331         a, b = _coerce_exprs(self, other)
03332         return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03333 
03334     def __lshift__(self, other):
03335         """Create the Z3 expression left shift `self << other`
03336 
03337         >>> x, y = BitVecs('x y', 32)
03338         >>> x << y
03339         x << y
03340         >>> (x << y).sexpr()
03341         '(bvshl x y)'
03342         >>> simplify(BitVecVal(2, 3) << 1)
03343         4
03344         """
03345         a, b = _coerce_exprs(self, other)
03346         return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
03347 
03348     def __rrshift__(self, other):
03349         """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
03350 
03351         Use the function LShR() for the right logical shift
03352 
03353         >>> x = BitVec('x', 32)
03354         >>> 10 >> x
03355         10 >> x
03356         >>> (10 >> x).sexpr()
03357         '(bvashr #x0000000a x)'
03358         """
03359         a, b = _coerce_exprs(self, other)
03360         return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03361 
03362     def __rlshift__(self, other):
03363         """Create the Z3 expression left shift `other << self`.
03364 
03365         Use the function LShR() for the right logical shift
03366 
03367         >>> x = BitVec('x', 32)
03368         >>> 10 << x
03369         10 << x
03370         >>> (10 << x).sexpr()
03371         '(bvshl #x0000000a x)'
03372         """
03373         a, b = _coerce_exprs(self, other)
03374         return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
03375 
03376 class BitVecNumRef(BitVecRef):
03377     """Bit-vector values."""
03378 
03379     def as_long(self):
03380         """Return a Z3 bit-vector numeral as a Python long (bignum) numeral. 
03381         
03382         >>> v = BitVecVal(0xbadc0de, 32)
03383         >>> v
03384         195936478
03385         >>> print("0x%.8x" % v.as_long())
03386         0x0badc0de
03387         """
03388         return int(self.as_string())
03389 
03390     def as_signed_long(self):
03391         """Return a Z3 bit-vector numeral as a Python long (bignum) numeral. The most significant bit is assumed to be the sign.
03392         
03393         >>> BitVecVal(4, 3).as_signed_long()
03394         -4
03395         >>> BitVecVal(7, 3).as_signed_long()
03396         -1
03397         >>> BitVecVal(3, 3).as_signed_long()
03398         3
03399         >>> BitVecVal(2**32 - 1, 32).as_signed_long()
03400         -1
03401         >>> BitVecVal(2**64 - 1, 64).as_signed_long()
03402         -1
03403         """
03404         sz = self.size()
03405         val = self.as_long()
03406         if val >= 2**(sz - 1):
03407             val = val - 2**sz
03408         if val < -2**(sz - 1):
03409             val = val + 2**sz
03410         return int(val)
03411 
03412     def as_string(self):
03413         return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
03414 
03415 def is_bv(a):
03416     """Return `True` if `a` is a Z3 bit-vector expression.
03417     
03418     >>> b = BitVec('b', 32)
03419     >>> is_bv(b)
03420     True
03421     >>> is_bv(b + 10)
03422     True
03423     >>> is_bv(Int('x'))
03424     False
03425     """
03426     return isinstance(a, BitVecRef)
03427 
03428 def is_bv_value(a):
03429     """Return `True` if `a` is a Z3 bit-vector numeral value.
03430 
03431     >>> b = BitVec('b', 32)
03432     >>> is_bv_value(b)
03433     False
03434     >>> b = BitVecVal(10, 32)
03435     >>> b
03436     10
03437     >>> is_bv_value(b)
03438     True
03439     """
03440     return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
03441 
03442 def BV2Int(a):
03443     """Return the Z3 expression BV2Int(a). 
03444     
03445     >>> b = BitVec('b', 3)
03446     >>> BV2Int(b).sort()
03447     Int
03448     >>> x = Int('x')
03449     >>> x > BV2Int(b)
03450     x > BV2Int(b)
03451     >>> solve(x > BV2Int(b), b == 1, x < 3)
03452     [b = 1, x = 2]
03453     """
03454     if __debug__:
03455         _z3_assert(is_bv(a), "Z3 bit-vector expression expected")
03456     ctx = a.ctx
03457     ## investigate problem with bv2int
03458     return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), 0), ctx)
03459 
03460 def BitVecSort(sz, ctx=None):
03461     """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
03462 
03463     >>> Byte = BitVecSort(8)
03464     >>> Word = BitVecSort(16)
03465     >>> Byte
03466     BitVec(8)
03467     >>> x = Const('x', Byte)
03468     >>> eq(x, BitVec('x', 8))
03469     True
03470     """
03471     ctx = _get_ctx(ctx)
03472     return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
03473 
03474 def BitVecVal(val, bv, ctx=None):
03475     """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
03476     
03477     >>> v = BitVecVal(10, 32)
03478     >>> v
03479     10
03480     >>> print("0x%.8x" % v.as_long())
03481     0x0000000a
03482     """
03483     if is_bv_sort(bv):
03484         ctx = bv.ctx
03485         return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
03486     else:
03487         ctx = _get_ctx(ctx)
03488         return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
03489 
03490 def BitVec(name, bv, ctx=None):
03491     """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
03492     If `ctx=None`, then the global context is used.
03493 
03494     >>> x  = BitVec('x', 16)
03495     >>> is_bv(x)
03496     True
03497     >>> x.size()
03498     16
03499     >>> x.sort()
03500     BitVec(16)
03501     >>> word = BitVecSort(16)
03502     >>> x2 = BitVec('x', word)
03503     >>> eq(x, x2)
03504     True
03505     """
03506     if isinstance(bv, BitVecSortRef):
03507         ctx = bv.ctx
03508     else:
03509         ctx = _get_ctx(ctx)
03510         bv = BitVecSort(bv, ctx)
03511     return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
03512 
03513 def BitVecs(names, bv, ctx=None):
03514     """Return a tuple of bit-vector constants of size bv. 
03515     
03516     >>> x, y, z = BitVecs('x y z', 16)
03517     >>> x.size()
03518     16
03519     >>> x.sort()
03520     BitVec(16)
03521     >>> Sum(x, y, z)
03522     0 + x + y + z
03523     >>> Product(x, y, z)
03524     1*x*y*z
03525     >>> simplify(Product(x, y, z))
03526     x*y*z
03527     """
03528     ctx = _get_ctx(ctx)
03529     if isinstance(names, str):
03530         names = names.split(" ")
03531     return [BitVec(name, bv, ctx) for name in names]
03532 
03533 def Concat(*args):
03534     """Create a Z3 bit-vector concatenation expression. 
03535     
03536     >>> v = BitVecVal(1, 4)
03537     >>> Concat(v, v+1, v)
03538     Concat(Concat(1, 1 + 1), 1)
03539     >>> simplify(Concat(v, v+1, v))
03540     289
03541     >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
03542     121
03543     """
03544     args = _get_args(args)
03545     if __debug__:
03546         _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
03547         _z3_assert(len(args) >= 2, "At least two arguments expected.")
03548     ctx = args[0].ctx
03549     r   = args[0]
03550     for i in range(len(args) - 1):
03551         r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i+1].as_ast()), ctx)
03552     return r
03553 
03554 def Extract(high, low, a):
03555     """Create a Z3 bit-vector extraction expression.
03556 
03557     >>> x = BitVec('x', 8)
03558     >>> Extract(6, 2, x)
03559     Extract(6, 2, x)
03560     >>> Extract(6, 2, x).sort()
03561     BitVec(5)
03562     """
03563     if __debug__:
03564         _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
03565         _z3_assert(isinstance(high, int) and high >= 0 and isinstance(low, int) and low >= 0, "First and second arguments must be non negative integers")
03566         _z3_assert(is_bv(a), "Third argument must be a Z3 Bitvector expression")
03567     return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
03568 
03569 def _check_bv_args(a, b):
03570     if __debug__:
03571         _z3_assert(is_bv(a) or is_bv(b), "At least one of the arguments must be a Z3 bit-vector expression")
03572 
03573 def ULE(a, b):
03574     """Create the Z3 expression (unsigned) `other <= self`.
03575     
03576     Use the operator <= for signed less than or equal to.
03577     
03578     >>> x, y = BitVecs('x y', 32)
03579     >>> ULE(x, y)
03580     ULE(x, y)
03581     >>> (x <= y).sexpr()
03582     '(bvsle x y)'
03583     >>> ULE(x, y).sexpr()
03584     '(bvule x y)'
03585     """
03586     _check_bv_args(a, b)
03587     a, b = _coerce_exprs(a, b)
03588     return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03589 
03590 def ULT(a, b):
03591     """Create the Z3 expression (unsigned) `other < self`.
03592     
03593     Use the operator < for signed less than.
03594     
03595     >>> x, y = BitVecs('x y', 32)
03596     >>> ULT(x, y)
03597     ULT(x, y)
03598     >>> (x < y).sexpr()
03599     '(bvslt x y)'
03600     >>> ULT(x, y).sexpr()
03601     '(bvult x y)'
03602     """
03603     _check_bv_args(a, b)
03604     a, b = _coerce_exprs(a, b)
03605     return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03606 
03607 def UGE(a, b):
03608     """Create the Z3 expression (unsigned) `other >= self`.
03609     
03610     Use the operator >= for signed greater than or equal to.
03611     
03612     >>> x, y = BitVecs('x y', 32)
03613     >>> UGE(x, y)
03614     UGE(x, y)
03615     >>> (x >= y).sexpr()
03616     '(bvsge x y)'
03617     >>> UGE(x, y).sexpr()
03618     '(bvuge x y)'
03619     """
03620     _check_bv_args(a, b)
03621     a, b = _coerce_exprs(a, b)
03622     return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03623 
03624 def UGT(a, b):
03625     """Create the Z3 expression (unsigned) `other > self`.
03626     
03627     Use the operator > for signed greater than.
03628     
03629     >>> x, y = BitVecs('x y', 32)
03630     >>> UGT(x, y)
03631     UGT(x, y)
03632     >>> (x > y).sexpr()
03633     '(bvsgt x y)'
03634     >>> UGT(x, y).sexpr()
03635     '(bvugt x y)'
03636     """
03637     _check_bv_args(a, b)
03638     a, b = _coerce_exprs(a, b)
03639     return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03640 
03641 def UDiv(a, b):
03642     """Create the Z3 expression (unsigned) division `self / other`.
03643     
03644     Use the operator / for signed division.
03645     
03646     >>> x = BitVec('x', 32)
03647     >>> y = BitVec('y', 32)
03648     >>> UDiv(x, y)
03649     UDiv(x, y)
03650     >>> UDiv(x, y).sort()
03651     BitVec(32)
03652     >>> (x / y).sexpr()
03653     '(bvsdiv x y)'
03654     >>> UDiv(x, y).sexpr()
03655     '(bvudiv x y)'
03656     """
03657     _check_bv_args(a, b)
03658     a, b = _coerce_exprs(a, b)
03659     return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03660 
03661 def URem(a, b):
03662     """Create the Z3 expression (unsigned) remainder `self % other`.
03663     
03664     Use the operator % for signed modulus, and SRem() for signed remainder.
03665     
03666     >>> x = BitVec('x', 32)
03667     >>> y = BitVec('y', 32)
03668     >>> URem(x, y)
03669     URem(x, y)
03670     >>> URem(x, y).sort()
03671     BitVec(32)
03672     >>> (x % y).sexpr()
03673     '(bvsmod x y)'
03674     >>> URem(x, y).sexpr()
03675     '(bvurem x y)'
03676     """
03677     _check_bv_args(a, b)
03678     a, b = _coerce_exprs(a, b)
03679     return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03680 
03681 def SRem(a, b):
03682     """Create the Z3 expression signed remainder.
03683     
03684     Use the operator % for signed modulus, and URem() for unsigned remainder.
03685     
03686     >>> x = BitVec('x', 32)
03687     >>> y = BitVec('y', 32)
03688     >>> SRem(x, y)
03689     SRem(x, y)
03690     >>> SRem(x, y).sort()
03691     BitVec(32)
03692     >>> (x % y).sexpr()
03693     '(bvsmod x y)'
03694     >>> SRem(x, y).sexpr()
03695     '(bvsrem x y)'
03696     """
03697     _check_bv_args(a, b)
03698     a, b = _coerce_exprs(a, b)
03699     return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03700 
03701 def LShR(a, b):
03702     """Create the Z3 expression logical right shift.
03703 
03704     Use the operator >> for the arithmetical right shift.
03705 
03706     >>> x, y = BitVecs('x y', 32)
03707     >>> LShR(x, y)
03708     LShR(x, y)
03709     >>> (x >> y).sexpr()
03710     '(bvashr x y)'
03711     >>> LShR(x, y).sexpr()
03712     '(bvlshr x y)'
03713     >>> BitVecVal(4, 3)
03714     4
03715     >>> BitVecVal(4, 3).as_signed_long()
03716     -4
03717     >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
03718     -2
03719     >>> simplify(BitVecVal(4, 3) >> 1)
03720     6
03721     >>> simplify(LShR(BitVecVal(4, 3), 1))
03722     2
03723     >>> simplify(BitVecVal(2, 3) >> 1)
03724     1
03725     >>> simplify(LShR(BitVecVal(2, 3), 1))
03726     1
03727     """
03728     _check_bv_args(a, b)
03729     a, b = _coerce_exprs(a, b)
03730     return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03731 
03732 def RotateLeft(a, b):
03733     """Return an expression representing `a` rotated to the left `b` times.
03734 
03735     >>> a, b = BitVecs('a b', 16)
03736     >>> RotateLeft(a, b)
03737     RotateLeft(a, b)
03738     >>> simplify(RotateLeft(a, 0))
03739     a
03740     >>> simplify(RotateLeft(a, 16))
03741     a
03742     """
03743     _check_bv_args(a, b)
03744     a, b = _coerce_exprs(a, b)
03745     return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03746 
03747 def RotateRight(a, b):
03748     """Return an expression representing `a` rotated to the right `b` times.
03749 
03750     >>> a, b = BitVecs('a b', 16)
03751     >>> RotateRight(a, b)
03752     RotateRight(a, b)
03753     >>> simplify(RotateRight(a, 0))
03754     a
03755     >>> simplify(RotateRight(a, 16))
03756     a
03757     """
03758     _check_bv_args(a, b)
03759     a, b = _coerce_exprs(a, b)
03760     return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
03761 
03762 def SignExt(n, a):
03763     """Return a bit-vector expression with `n` extra sign-bits.
03764 
03765     >>> x = BitVec('x', 16)
03766     >>> n = SignExt(8, x)
03767     >>> n.size()
03768     24
03769     >>> n
03770     SignExt(8, x)
03771     >>> n.sort()
03772     BitVec(24)
03773     >>> v0 = BitVecVal(2, 2)
03774     >>> v0
03775     2
03776     >>> v0.size()
03777     2
03778     >>> v  = simplify(SignExt(6, v0))
03779     >>> v
03780     254
03781     >>> v.size()
03782     8
03783     >>> print("%.x" % v.as_long())
03784     fe
03785     """
03786     if __debug__:
03787         _z3_assert(isinstance(n, int), "First argument must be an integer")
03788         _z3_assert(is_bv(a), "Second argument must be a Z3 Bitvector expression")
03789     return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
03790 
03791 def ZeroExt(n, a):
03792     """Return a bit-vector expression with `n` extra zero-bits.
03793 
03794     >>> x = BitVec('x', 16)
03795     >>> n = ZeroExt(8, x)
03796     >>> n.size()
03797     24
03798     >>> n
03799     ZeroExt(8, x)
03800     >>> n.sort()
03801     BitVec(24)
03802     >>> v0 = BitVecVal(2, 2)
03803     >>> v0
03804     2
03805     >>> v0.size()
03806     2
03807     >>> v  = simplify(ZeroExt(6, v0))
03808     >>> v
03809     2
03810     >>> v.size()
03811     8
03812     """
03813     if __debug__:
03814         _z3_assert(isinstance(n, int), "First argument must be an integer")
03815         _z3_assert(is_bv(a), "Second argument must be a Z3 Bitvector expression")
03816     return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
03817 
03818 def RepeatBitVec(n, a):
03819     """Return an expression representing `n` copies of `a`.
03820 
03821     >>> x = BitVec('x', 8)
03822     >>> n = RepeatBitVec(4, x)
03823     >>> n
03824     RepeatBitVec(4, x)
03825     >>> n.size()
03826     32
03827     >>> v0 = BitVecVal(10, 4)
03828     >>> print("%.x" % v0.as_long())
03829     a
03830     >>> v = simplify(RepeatBitVec(4, v0))
03831     >>> v.size()
03832     16
03833     >>> print("%.x" % v.as_long())
03834     aaaa
03835     """
03836     if __debug__:
03837         _z3_assert(isinstance(n, int), "First argument must be an integer")
03838         _z3_assert(is_bv(a), "Second argument must be a Z3 Bitvector expression")
03839     return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
03840 
03841 def BVRedAnd(a):
03842     """Return the reduction-and expression of `a`."""
03843     if __debug__:
03844         _z3_assert(is_bv(a), "First argument must be a Z3 Bitvector expression")
03845     return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
03846 
03847 def BVRedOr(a):
03848     """Return the reduction-or expression of `a`."""
03849     if __debug__:
03850         _z3_assert(is_bv(a), "First argument must be a Z3 Bitvector expression")
03851     return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
03852 
03853 #########################################
03854 #
03855 # Arrays
03856 #
03857 #########################################
03858 
03859 class ArraySortRef(SortRef):
03860     """Array sorts."""
03861 
03862     def domain(self):
03863         """Return the domain of the array sort `self`.
03864         
03865         >>> A = ArraySort(IntSort(), BoolSort())
03866         >>> A.domain()
03867         Int
03868         """
03869         return _to_sort_ref(Z3_get_array_sort_domain(self.ctx_ref(), self.ast), self.ctx)
03870     
03871     def range(self):
03872         """Return the range of the array sort `self`.
03873         
03874         >>> A = ArraySort(IntSort(), BoolSort())
03875         >>> A.range()
03876         Bool
03877         """
03878         return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
03879 
03880 class ArrayRef(ExprRef):
03881     """Array expressions. """
03882 
03883     def sort(self):
03884         """Return the array sort of the array expression `self`.
03885 
03886         >>> a = Array('a', IntSort(), BoolSort())
03887         >>> a.sort()
03888         Array(Int, Bool)
03889         """
03890         return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
03891     
03892     def domain(self):
03893         """Shorthand for `self.sort().domain()`.
03894 
03895         >>> a = Array('a', IntSort(), BoolSort())
03896         >>> a.domain()
03897         Int
03898         """
03899         return self.sort().domain()
03900         
03901     def range(self):
03902         """Shorthand for `self.sort().range()`.
03903 
03904         >>> a = Array('a', IntSort(), BoolSort())
03905         >>> a.range()
03906         Bool
03907         """
03908         return self.sort().range()
03909 
03910     def __getitem__(self, arg):
03911         """Return the Z3 expression `self[arg]`.
03912 
03913         >>> a = Array('a', IntSort(), BoolSort())
03914         >>> i = Int('i')
03915         >>> a[i]
03916         a[i]
03917         >>> a[i].sexpr()
03918         '(select a i)'
03919         """
03920         arg = self.domain().cast(arg)
03921         return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx)
03922 
03923     def mk_default(self):  
03924         return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)  
03925 
03926 
03927 def is_array(a):
03928     """Return `True` if `a` is a Z3 array expression.
03929     
03930     >>> a = Array('a', IntSort(), IntSort())
03931     >>> is_array(a)
03932     True
03933     >>> is_array(Store(a, 0, 1))
03934     True
03935     >>> is_array(a[0])
03936     False
03937     """
03938     return isinstance(a, ArrayRef)
03939 
03940 def is_const_array(a):
03941     """Return `True` if `a` is a Z3 constant array.
03942 
03943     >>> a = K(IntSort(), 10)
03944     >>> is_const_array(a)
03945     True
03946     >>> a = Array('a', IntSort(), IntSort())
03947     >>> is_const_array(a)
03948     False
03949     """
03950     return is_app_of(a, Z3_OP_CONST_ARRAY)
03951 
03952 def is_K(a):
03953     """Return `True` if `a` is a Z3 constant array.
03954 
03955     >>> a = K(IntSort(), 10)
03956     >>> is_K(a)
03957     True
03958     >>> a = Array('a', IntSort(), IntSort())
03959     >>> is_K(a)
03960     False
03961     """
03962     return is_app_of(a, Z3_OP_CONST_ARRAY)
03963 
03964 def is_map(a):
03965     """Return `True` if `a` is a Z3 map array expression. 
03966 
03967     >>> f = Function('f', IntSort(), IntSort())
03968     >>> b = Array('b', IntSort(), IntSort())
03969     >>> a  = Map(f, b)
03970     >>> a
03971     Map(f, b)
03972     >>> is_map(a)
03973     True
03974     >>> is_map(b)
03975     False
03976     """
03977     return is_app_of(a, Z3_OP_ARRAY_MAP)
03978 
03979 def is_default(a):
03980     """Return `True` if `a` is a Z3 default array expression.
03981     >>> d = Default(K(IntSort(), 10))
03982     >>> is_default(d)
03983     True
03984     """
03985     return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
03986 
03987 def get_map_func(a):
03988     """Return the function declaration associated with a Z3 map array expression.
03989 
03990     >>> f = Function('f', IntSort(), IntSort())
03991     >>> b = Array('b', IntSort(), IntSort())
03992     >>> a  = Map(f, b)
03993     >>> eq(f, get_map_func(a))
03994     True
03995     >>> get_map_func(a)
03996     f
03997     >>> get_map_func(a)(0)
03998     f(0)
03999     """
04000     if __debug__:
04001         _z3_assert(is_map(a), "Z3 array map expression expected.")
04002     return FuncDeclRef(Z3_to_func_decl(a.ctx_ref(), Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0)), a.ctx)
04003 
04004 def ArraySort(d, r):
04005     """Return the Z3 array sort with the given domain and range sorts.
04006     
04007     >>> A = ArraySort(IntSort(), BoolSort())
04008     >>> A
04009     Array(Int, Bool)
04010     >>> A.domain()
04011     Int
04012     >>> A.range()
04013     Bool
04014     >>> AA = ArraySort(IntSort(), A)
04015     >>> AA
04016     Array(Int, Array(Int, Bool))
04017     """
04018     if __debug__:
04019         _z3_assert(is_sort(d), "Z3 sort expected")
04020         _z3_assert(is_sort(r), "Z3 sort expected")
04021         _z3_assert(d.ctx == r.ctx, "Context mismatch")
04022     ctx = d.ctx
04023     return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
04024 
04025 def Array(name, dom, rng):
04026     """Return an array constant named `name` with the given domain and range sorts.
04027 
04028     >>> a = Array('a', IntSort(), IntSort())
04029     >>> a.sort()
04030     Array(Int, Int)
04031     >>> a[0]
04032     a[0]
04033     """
04034     s = ArraySort(dom, rng)
04035     ctx = s.ctx
04036     return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
04037 
04038 def Update(a, i, v):
04039     """Return a Z3 store array expression.
04040 
04041     >>> a    = Array('a', IntSort(), IntSort())
04042     >>> i, v = Ints('i v')
04043     >>> s    = Update(a, i, v)
04044     >>> s.sort()
04045     Array(Int, Int)
04046     >>> prove(s[i] == v)
04047     proved
04048     >>> j    = Int('j')
04049     >>> prove(Implies(i != j, s[j] == a[j]))
04050     proved
04051     """
04052     if __debug__:
04053         _z3_assert(is_array(a), "First argument must be a Z3 array expression")
04054     i = a.domain().cast(i)
04055     v = a.range().cast(v)
04056     ctx = a.ctx
04057     return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
04058 
04059 def Default(a):  
04060     """ Return a default value for array expression.  
04061     >>> b = K(IntSort(), 1)  
04062     >>> prove(Default(b) == 1)  
04063     proved
04064     """  
04065     if __debug__:  
04066         _z3_assert(is_array(a), "First argument must be a Z3 array expression")  
04067     return a.mk_default()  
04068 
04069 
04070 def Store(a, i, v):
04071     """Return a Z3 store array expression.
04072 
04073     >>> a    = Array('a', IntSort(), IntSort())
04074     >>> i, v = Ints('i v')
04075     >>> s    = Store(a, i, v)
04076     >>> s.sort()
04077     Array(Int, Int)
04078     >>> prove(s[i] == v)
04079     proved
04080     >>> j    = Int('j')
04081     >>> prove(Implies(i != j, s[j] == a[j]))
04082     proved
04083     """
04084     return Update(a, i, v)
04085 
04086 def Select(a, i):
04087     """Return a Z3 select array expression.
04088 
04089     >>> a = Array('a', IntSort(), IntSort())
04090     >>> i = Int('i')
04091     >>> Select(a, i)
04092     a[i]
04093     >>> eq(Select(a, i), a[i])
04094     True
04095     """
04096     if __debug__:
04097         _z3_assert(is_array(a), "First argument must be a Z3 array expression")
04098     return a[i]
04099 
04100 def Map(f, *args):
04101     """Return a Z3 map array expression. 
04102 
04103     >>> f = Function('f', IntSort(), IntSort(), IntSort())
04104     >>> a1 = Array('a1', IntSort(), IntSort())
04105     >>> a2 = Array('a2', IntSort(), IntSort())
04106     >>> b  = Map(f, a1, a2)
04107     >>> b
04108     Map(f, a1, a2)
04109     >>> prove(b[0] == f(a1[0], a2[0]))
04110     proved
04111     """
04112     args = _get_args(args)
04113     if __debug__:
04114         _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
04115         _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
04116         _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
04117         _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
04118     _args, sz = _to_ast_array(args)
04119     ctx = f.ctx
04120     return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
04121 
04122 def K(dom, v):
04123     """Return a Z3 constant array expression. 
04124     
04125     >>> a = K(IntSort(), 10)
04126     >>> a
04127     K(Int, 10)
04128     >>> a.sort()
04129     Array(Int, Int)
04130     >>> i = Int('i')
04131     >>> a[i]
04132     K(Int, 10)[i]
04133     >>> simplify(a[i])
04134     10
04135     """
04136     if __debug__:
04137         _z3_assert(is_sort(dom), "Z3 sort expected")
04138     ctx = dom.ctx
04139     if not is_expr(v):
04140         v = _py2expr(v, ctx)
04141     return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
04142 
04143 def is_select(a):
04144     """Return `True` if `a` is a Z3 array select application.
04145     
04146     >>> a = Array('a', IntSort(), IntSort())
04147     >>> is_select(a)
04148     False
04149     >>> i = Int('i')
04150     >>> is_select(a[i])
04151     True
04152     """
04153     return is_app_of(a, Z3_OP_SELECT)
04154 
04155 def is_store(a):
04156     """Return `True` if `a` is a Z3 array store application.
04157     
04158     >>> a = Array('a', IntSort(), IntSort())
04159     >>> is_store(a)
04160     False
04161     >>> is_store(Store(a, 0, 1))
04162     True
04163     """
04164     return is_app_of(a, Z3_OP_STORE)
04165 
04166 #########################################
04167 #
04168 # Datatypes
04169 #
04170 #########################################
04171 
04172 def _valid_accessor(acc):
04173     """Return `True` if acc is pair of the form (String, Datatype or Sort). """
04174     return isinstance(acc, tuple) and len(acc) == 2 and isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
04175 
04176 class Datatype:
04177     """Helper class for declaring Z3 datatypes. 
04178 
04179     >>> List = Datatype('List')
04180     >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
04181     >>> List.declare('nil')
04182     >>> List = List.create()
04183     >>> # List is now a Z3 declaration
04184     >>> List.nil
04185     nil
04186     >>> List.cons(10, List.nil)
04187     cons(10, nil)
04188     >>> List.cons(10, List.nil).sort()
04189     List
04190     >>> cons = List.cons
04191     >>> nil  = List.nil
04192     >>> car  = List.car
04193     >>> cdr  = List.cdr
04194     >>> n = cons(1, cons(0, nil))
04195     >>> n
04196     cons(1, cons(0, nil))
04197     >>> simplify(cdr(n))
04198     cons(0, nil)
04199     >>> simplify(car(n))
04200     1
04201     """
04202     def __init__(self, name, ctx=None):
04203         self.ctx          = _get_ctx(ctx)
04204         self.name         = name
04205         self.constructors = []
04206 
04207     def declare_core(self, name, rec_name, *args):
04208         if __debug__:
04209             _z3_assert(isinstance(name, str), "String expected")
04210             _z3_assert(isinstance(rec_name, str), "String expected")
04211             _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)")
04212         self.constructors.append((name, rec_name, args))
04213 
04214     def declare(self, name, *args):
04215         """Declare constructor named `name` with the given accessors `args`. 
04216         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. 
04217 
04218         In the followin example `List.declare('cons', ('car', IntSort()), ('cdr', List))` 
04219         declares the constructor named `cons` that builds a new List using an integer and a List. 
04220         It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer of a `cons` cell, 
04221         and `cdr` the list of a `cons` cell. After all constructors were declared, we use the method create() to create 
04222         the actual datatype in Z3.
04223         
04224         >>> List = Datatype('List')
04225         >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
04226         >>> List.declare('nil')
04227         >>> List = List.create()
04228         """
04229         if __debug__:
04230             _z3_assert(isinstance(name, str), "String expected")
04231             _z3_assert(name != "", "Constructor name cannot be empty")
04232         return self.declare_core(name, "is_" + name, *args)
04233 
04234     def __repr__(self):
04235         return "Datatype(%s, %s)" % (self.name, self.constructors)
04236 
04237     def create(self):
04238         """Create a Z3 datatype based on the constructors declared using the mehtod `declare()`.
04239         
04240         The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
04241 
04242         >>> List = Datatype('List')
04243         >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
04244         >>> List.declare('nil')
04245         >>> List = List.create()
04246         >>> List.nil
04247         nil
04248         >>> List.cons(10, List.nil)
04249         cons(10, nil)
04250         """
04251         return CreateDatatypes([self])[0]
04252 
04253 class ScopedConstructor:
04254     """Auxiliary object used to create Z3 datatypes."""
04255     def __init__(self, c, ctx):
04256         self.c   = c
04257         self.ctx = ctx
04258     def __del__(self):
04259         Z3_del_constructor(self.ctx.ref(), self.c)
04260 
04261 class ScopedConstructorList:
04262     """Auxiliary object used to create Z3 datatypes."""
04263     def __init__(self, c, ctx):
04264         self.c   = c
04265         self.ctx = ctx
04266     def __del__(self):
04267         Z3_del_constructor_list(self.ctx.ref(), self.c)
04268 
04269 def CreateDatatypes(*ds):
04270     """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
04271     
04272     In the following example we define a Tree-List using two mutually recursive datatypes.
04273 
04274     >>> TreeList = Datatype('TreeList')
04275     >>> Tree     = Datatype('Tree')
04276     >>> # Tree has two constructors: leaf and node
04277     >>> Tree.declare('leaf', ('val', IntSort()))
04278     >>> # a node contains a list of trees
04279     >>> Tree.declare('node', ('children', TreeList))
04280     >>> TreeList.declare('nil')
04281     >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
04282     >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
04283     >>> Tree.val(Tree.leaf(10))
04284     val(leaf(10))
04285     >>> simplify(Tree.val(Tree.leaf(10)))
04286     10
04287     >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
04288     >>> n1
04289     node(cons(leaf(10), cons(leaf(20), nil)))
04290     >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
04291     >>> simplify(n2 == n1)
04292     False
04293     >>> simplify(TreeList.car(Tree.children(n2)) == n1)
04294     True
04295     """
04296     ds = _get_args(ds)
04297     if __debug__:
04298         _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
04299         _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
04300         _z3_assert(all([d.ctx == ds[0].ctx for d in  ds]), "Context mismatch")
04301         _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
04302     ctx = ds[0].ctx
04303     num    = len(ds)
04304     names  = (Symbol * num)()
04305     out    = (Sort * num)()
04306     clists = (ConstructorList * num)()
04307     to_delete = []
04308     for i in range(num):
04309         d        = ds[i]
04310         names[i] = to_symbol(d.name, ctx)
04311         num_cs   = len(d.constructors)
04312         cs       = (Constructor * num_cs)()
04313         for j in range(num_cs):
04314             c      = d.constructors[j]
04315             cname  = to_symbol(c[0], ctx)
04316             rname  = to_symbol(c[1], ctx)
04317             fs     = c[2]
04318             num_fs = len(fs)
04319             fnames = (Symbol * num_fs)()
04320             sorts  = (Sort   * num_fs)()
04321             refs   = (ctypes.c_uint * num_fs)()
04322             for k in range(num_fs):
04323                 fname = fs[k][0]
04324                 ftype = fs[k][1]
04325                 fnames[k] = to_symbol(fname, ctx)
04326                 if isinstance(ftype, Datatype):
04327                     if __debug__:
04328                         _z3_assert(ds.count(ftype) == 1, "One and only one occurrence of each datatype is expected")
04329                     sorts[k] = None
04330                     refs[k]  = ds.index(ftype)
04331                 else:
04332                     if __debug__:
04333                         _z3_assert(is_sort(ftype), "Z3 sort expected")
04334                     sorts[k] = ftype.ast
04335                     refs[k]  = 0
04336             cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
04337             to_delete.append(ScopedConstructor(cs[j], ctx))
04338         clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
04339         to_delete.append(ScopedConstructorList(clists[i], ctx))
04340     Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
04341     result = []
04342     ## Create a field for every constructor, recognizer and accessor
04343     for i in range(num):
04344         dref = DatatypeSortRef(out[i], ctx)
04345         num_cs = dref.num_constructors()
04346         for j in range(num_cs):
04347             cref       = dref.constructor(j)
04348             cref_name  = cref.name()
04349             cref_arity = cref.arity()
04350             if cref.arity() == 0:
04351                 cref = cref()
04352             setattr(dref, cref_name, cref)
04353             rref  = dref.recognizer(j)
04354             setattr(dref, rref.name(), rref)
04355             for k in range(cref_arity):
04356                 aref = dref.accessor(j, k)
04357                 setattr(dref, aref.name(), aref)
04358         result.append(dref)
04359     return tuple(result)
04360 
04361 class DatatypeSortRef(SortRef):
04362     """Datatype sorts."""
04363     def num_constructors(self):
04364         """Return the number of constructors in the given Z3 datatype. 
04365         
04366         >>> List = Datatype('List')
04367         >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
04368         >>> List.declare('nil')
04369         >>> List = List.create()
04370         >>> # List is now a Z3 declaration
04371         >>> List.num_constructors()
04372         2
04373         """
04374         return int(Z3_get_datatype_sort_num_constructors(self.ctx_ref(), self.ast))
04375 
04376     def constructor(self, idx):
04377         """Return a constructor of the datatype `self`.
04378 
04379         >>> List = Datatype('List')
04380         >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
04381         >>> List.declare('nil')
04382         >>> List = List.create()
04383         >>> # List is now a Z3 declaration
04384         >>> List.num_constructors()
04385         2
04386         >>> List.constructor(0)
04387         cons
04388         >>> List.constructor(1)
04389         nil
04390         """
04391         if __debug__:
04392             _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
04393         return FuncDeclRef(Z3_get_datatype_sort_constructor(self.ctx_ref(), self.ast, idx), self.ctx)
04394     
04395     def recognizer(self, idx):
04396         """In Z3, each constructor has an associated recognizer predicate. 
04397 
04398         If the constructor is named `name`, then the recognizer `is_name`.
04399         
04400         >>> List = Datatype('List')
04401         >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
04402         >>> List.declare('nil')
04403         >>> List = List.create()
04404         >>> # List is now a Z3 declaration
04405         >>> List.num_constructors()
04406         2
04407         >>> List.recognizer(0)
04408         is_cons
04409         >>> List.recognizer(1)
04410         is_nil
04411         >>> simplify(List.is_nil(List.cons(10, List.nil)))
04412         False
04413         >>> simplify(List.is_cons(List.cons(10, List.nil)))
04414         True
04415         >>> l = Const('l', List)
04416         >>> simplify(List.is_cons(l))
04417         is_cons(l)
04418         """
04419         if __debug__:
04420             _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
04421         return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
04422 
04423     def accessor(self, i, j):
04424         """In Z3, each constructor has 0 or more accessor. The number of accessors is equal to the arity of the constructor.
04425         
04426         >>> List = Datatype('List')
04427         >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
04428         >>> List.declare('nil')
04429         >>> List = List.create()
04430         >>> List.num_constructors()
04431         2
04432         >>> List.constructor(0)
04433         cons
04434         >>> num_accs = List.constructor(0).arity()
04435         >>> num_accs
04436         2
04437         >>> List.accessor(0, 0)
04438         car
04439         >>> List.accessor(0, 1)
04440         cdr
04441         >>> List.constructor(1)
04442         nil
04443         >>> num_accs = List.constructor(1).arity()
04444         >>> num_accs
04445         0
04446         """
04447         if __debug__:
04448             _z3_assert(i < self.num_constructors(), "Invalid constructor index")
04449             _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
04450         return FuncDeclRef(Z3_get_datatype_sort_constructor_accessor(self.ctx_ref(), self.ast, i, j), self.ctx)
04451 
04452 class DatatypeRef(ExprRef):
04453     """Datatype expressions."""
04454     def sort(self):
04455         """Return the datatype sort of the datatype expression `self`."""
04456         return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
04457 
04458 def EnumSort(name, values, ctx=None):
04459     """Return a new enumeration sort named `name` containing the given values.
04460 
04461     The result is a pair (sort, list of constants).
04462     Example:
04463         >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
04464     """
04465     if __debug__:
04466         _z3_assert(isinstance(name, str), "Name must be a string")
04467         _z3_assert(all([isinstance(v, str) for v in values]), "Eumeration sort values must be strings")
04468         _z3_assert(len(values) > 0, "At least one value expected")
04469     ctx = _get_ctx(ctx)
04470     num = len(values)
04471     _val_names   = (Symbol * num)()
04472     for i in range(num):
04473         _val_names[i] = to_symbol(values[i])
04474     _values  = (FuncDecl * num)()
04475     _testers = (FuncDecl * num)() 
04476     name = to_symbol(name)
04477     S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
04478     V = []
04479     for i in range(num):
04480         V.append(FuncDeclRef(_values[i], ctx))
04481     V = [a() for a in V]
04482     return S, V
04483 
04484 #########################################
04485 #
04486 # Parameter Sets
04487 #
04488 #########################################
04489 
04490 class ParamsRef:
04491     """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
04492     
04493     Consider using the function `args2params` to create instances of this object.
04494     """
04495     def __init__(self, ctx=None):
04496         self.ctx    = _get_ctx(ctx)
04497         self.params = Z3_mk_params(self.ctx.ref())
04498         Z3_params_inc_ref(self.ctx.ref(), self.params)
04499 
04500     def __del__(self):
04501         Z3_params_dec_ref(self.ctx.ref(), self.params)
04502 
04503     def set(self, name, val):
04504         """Set parameter name with value val."""
04505         if __debug__:
04506             _z3_assert(isinstance(name, str), "parameter name must be a string")
04507         name_sym = to_symbol(name, self.ctx)
04508         if isinstance(val, bool):
04509             Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
04510         elif isinstance(val, int):
04511             Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
04512         elif isinstance(val, float):
04513             Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
04514         elif isinstance(val, str):
04515             Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
04516         else:
04517             if __debug__:
04518                 _z3_assert(False, "invalid parameter value")
04519 
04520     def __repr__(self):
04521         return Z3_params_to_string(self.ctx.ref(), self.params)
04522 
04523     def validate(self, ds):
04524         _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
04525         Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
04526 
04527 def args2params(arguments, keywords, ctx=None):
04528     """Convert python arguments into a Z3_params object.
04529     A ':' is added to the keywords, and '_' is replaced with '-'
04530 
04531     >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
04532     (params model true relevancy 2 elim_and true)
04533     """
04534     if __debug__:
04535         _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
04536     prev = None
04537     r    = ParamsRef(ctx)
04538     for a in arguments:
04539         if prev == None:
04540             prev = a
04541         else:
04542             r.set(prev, a)
04543             prev = None
04544     for k in keywords:
04545         v = keywords[k]
04546         r.set(k, v)
04547     return r
04548 
04549 class ParamDescrsRef:
04550     """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
04551     """
04552     def __init__(self, descr, ctx=None):
04553         _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
04554         self.ctx    = _get_ctx(ctx)
04555         self.descr  = descr
04556         Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
04557 
04558     def __del__(self):
04559         Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
04560 
04561     def size(self):
04562         """Return the size of in the parameter description `self`.
04563         """
04564         return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
04565 
04566     def __len__(self):
04567         """Return the size of in the parameter description `self`.
04568         """
04569         return self.size()
04570 
04571     def get_name(self, i):
04572         """Return the i-th parameter name in the parameter description `self`.
04573         """
04574         return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
04575     
04576     def get_kind(self, n):
04577         """Return the kind of the parameter named `n`.
04578         """
04579         return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
04580     
04581     def __getitem__(self, arg):
04582         if _is_int(arg):
04583             return self.get_name(arg)
04584         else:
04585             return self.get_kind(arg)
04586 
04587     def __repr__(self):
04588         return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
04589 
04590 #########################################
04591 #
04592 # Goals
04593 #
04594 #########################################
04595 
04596 class Goal(Z3PPObject):
04597     """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
04598     
04599     Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
04600     A goal has a solution if one of its subgoals has a solution.
04601     A goal is unsatisfiable if all subgoals are unsatisfiable.
04602     """
04603 
04604     def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
04605         if __debug__:
04606             _z3_assert(goal == None or ctx != None, "If goal is different from None, then ctx must be also different from None")
04607         self.ctx    = _get_ctx(ctx)
04608         self.goal   = goal
04609         if self.goal == None:
04610             self.goal   = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
04611         Z3_goal_inc_ref(self.ctx.ref(), self.goal)
04612 
04613     def __del__(self):
04614         if self.goal != None:
04615             Z3_goal_dec_ref(self.ctx.ref(), self.goal)
04616 
04617     def depth(self):
04618         """Return the depth of the goal `self`. The depth corresponds to the number of tactics applied to `self`.
04619 
04620         >>> x, y = Ints('x y')
04621         >>> g = Goal()
04622         >>> g.add(x == 0, y >= x + 1)
04623         >>> g.depth()
04624         0
04625         >>> r = Then('simplify', 'solve-eqs')(g)
04626         >>> # r has 1 subgoal
04627         >>> len(r)
04628         1
04629         >>> r[0].depth()
04630         2
04631         """
04632         return int(Z3_goal_depth(self.ctx.ref(), self.goal))
04633 
04634     def inconsistent(self):
04635         """Return `True` if `self` contains the `False` constraints.
04636         
04637         >>> x, y = Ints('x y')
04638         >>> g = Goal()
04639         >>> g.inconsistent()
04640         False
04641         >>> g.add(x == 0, x == 1)
04642         >>> g 
04643         [x == 0, x == 1]
04644         >>> g.inconsistent()
04645         False
04646         >>> g2 = Tactic('propagate-values')(g)[0]
04647         >>> g2.inconsistent()
04648         True
04649         """
04650         return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
04651 
04652     def prec(self):
04653         """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
04654         
04655         >>> g = Goal()
04656         >>> g.prec() == Z3_GOAL_PRECISE
04657         True
04658         >>> x, y = Ints('x y')
04659         >>> g.add(x == y + 1)
04660         >>> g.prec() == Z3_GOAL_PRECISE
04661         True
04662         >>> t  = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
04663         >>> g2 = t(g)[0]
04664         >>> g2
04665         [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
04666         >>> g2.prec() == Z3_GOAL_PRECISE
04667         False
04668         >>> g2.prec() == Z3_GOAL_UNDER
04669         True
04670         """
04671         return Z3_goal_precision(self.ctx.ref(), self.goal)
04672 
04673     def precision(self):
04674         """Alias for `prec()`.
04675 
04676         >>> g = Goal()
04677         >>> g.precision() == Z3_GOAL_PRECISE
04678         True
04679         """
04680         return self.prec()
04681 
04682     def size(self):
04683         """Return the number of constraints in the goal `self`.
04684         
04685         >>> g = Goal()
04686         >>> g.size()
04687         0
04688         >>> x, y = Ints('x y')
04689         >>> g.add(x == 0, y > x)
04690         >>> g.size()
04691         2
04692         """
04693         return int(Z3_goal_size(self.ctx.ref(), self.goal))
04694 
04695     def __len__(self):
04696         """Return the number of constraints in the goal `self`.
04697 
04698         >>> g = Goal()
04699         >>> len(g)
04700         0
04701         >>> x, y = Ints('x y')
04702         >>> g.add(x == 0, y > x)
04703         >>> len(g)
04704         2
04705         """
04706         return self.size()
04707 
04708     def get(self, i):
04709         """Return a constraint in the goal `self`.
04710         
04711         >>> g = Goal()
04712         >>> x, y = Ints('x y')
04713         >>> g.add(x == 0, y > x)
04714         >>> g.get(0)
04715         x == 0
04716         >>> g.get(1)
04717         y > x
04718         """
04719         return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
04720 
04721     def __getitem__(self, arg):
04722         """Return a constraint in the goal `self`.
04723         
04724         >>> g = Goal()
04725         >>> x, y = Ints('x y')
04726         >>> g.add(x == 0, y > x)
04727         >>> g[0]
04728         x == 0
04729         >>> g[1]
04730         y > x
04731         """
04732         if arg >= len(self):
04733             raise IndexError
04734         return self.get(arg)
04735 
04736     def assert_exprs(self, *args):
04737         """Assert constraints into the goal.
04738         
04739         >>> x = Int('x')
04740         >>> g = Goal()
04741         >>> g.assert_exprs(x > 0, x < 2)
04742         >>> g
04743         [x > 0, x < 2]
04744         """
04745         args = _get_args(args)
04746         s    = BoolSort(self.ctx)
04747         for arg in args:
04748             arg = s.cast(arg)
04749             Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
04750 
04751     def append(self, *args):
04752         """Add constraints.
04753         
04754         >>> x = Int('x')
04755         >>> g = Goal()
04756         >>> g.append(x > 0, x < 2)
04757         >>> g
04758         [x > 0, x < 2]
04759         """
04760         self.assert_exprs(*args)
04761         
04762     def insert(self, *args):
04763         """Add constraints.
04764         
04765         >>> x = Int('x')
04766         >>> g = Goal()
04767         >>> g.insert(x > 0, x < 2)
04768         >>> g
04769         [x > 0, x < 2]
04770         """
04771         self.assert_exprs(*args)
04772 
04773     def add(self, *args):
04774         """Add constraints.
04775         
04776         >>> x = Int('x')
04777         >>> g = Goal()
04778         >>> g.add(x > 0, x < 2)
04779         >>> g
04780         [x > 0, x < 2]
04781         """
04782         self.assert_exprs(*args)
04783 
04784     def __repr__(self):
04785         return obj_to_string(self)
04786 
04787     def sexpr(self):
04788         """Return a textual representation of the s-expression representing the goal."""
04789         return Z3_goal_to_string(self.ctx.ref(), self.goal)
04790 
04791     def translate(self, target):
04792         """Copy goal `self` to context `target`.
04793         
04794         >>> x = Int('x')
04795         >>> g = Goal()
04796         >>> g.add(x > 10)
04797         >>> g
04798         [x > 10]
04799         >>> c2 = Context()
04800         >>> g2 = g.translate(c2)
04801         >>> g2
04802         [x > 10]
04803         >>> g.ctx == main_ctx()
04804         True
04805         >>> g2.ctx == c2
04806         True
04807         >>> g2.ctx == main_ctx()
04808         False
04809         """
04810         if __debug__:
04811             _z3_assert(isinstance(target, Context), "target must be a context")
04812         return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
04813 
04814     def simplify(self, *arguments, **keywords):
04815         """Return a new simplified goal.
04816         
04817         This method is essentially invoking the simplify tactic.
04818         
04819         >>> g = Goal()
04820         >>> x = Int('x')
04821         >>> g.add(x + 1 >= 2)
04822         >>> g
04823         [x + 1 >= 2]
04824         >>> g2 = g.simplify()
04825         >>> g2
04826         [x >= 1]
04827         >>> # g was not modified
04828         >>> g
04829         [x + 1 >= 2]
04830         """
04831         t = Tactic('simplify')
04832         return t.apply(self, *arguments, **keywords)[0]
04833 
04834     def as_expr(self):
04835         """Return goal `self` as a single Z3 expression.
04836         
04837         >>> x = Int('x')
04838         >>> g = Goal()
04839         >>> g.as_expr()
04840         True
04841         >>> g.add(x > 1)
04842         >>> g.as_expr()
04843         x > 1
04844         >>> g.add(x < 10)
04845         >>> g.as_expr()
04846         And(x > 1, x < 10)
04847         """
04848         sz = len(self)
04849         if sz == 0:
04850             return BoolVal(True, self.ctx)
04851         elif sz == 1:
04852             return self.get(0)
04853         else:
04854             return And([ self.get(i) for i in range(len(self)) ])
04855 
04856 #########################################
04857 #
04858 # AST Vector
04859 #
04860 #########################################
04861 class AstVector(Z3PPObject):
04862     """A collection (vector) of ASTs."""
04863 
04864     def __init__(self, v=None, ctx=None):
04865         self.vector = None
04866         if v == None:
04867             self.ctx = _get_ctx(ctx)
04868             self.vector = Z3_mk_ast_vector(self.ctx.ref())
04869         else:
04870             self.vector = v
04871             assert ctx != None
04872             self.ctx    = ctx
04873         Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
04874 
04875     def __del__(self):
04876         if self.vector != None:
04877             Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
04878         
04879     def __len__(self):
04880         """Return the size of the vector `self`.
04881 
04882         >>> A = AstVector()
04883         >>> len(A)
04884         0
04885         >>> A.push(Int('x'))
04886         >>> A.push(Int('x'))
04887         >>> len(A)
04888         2
04889         """
04890         return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
04891 
04892     def __getitem__(self, i):
04893         """Return the AST at position `i`.
04894 
04895         >>> A = AstVector()
04896         >>> A.push(Int('x') + 1)
04897         >>> A.push(Int('y'))
04898         >>> A[0]
04899         x + 1
04900         >>> A[1]
04901         y
04902         """
04903         if i >= self.__len__():
04904             raise IndexError
04905         return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
04906 
04907     def __setitem__(self, i, v):
04908         """Update AST at position `i`.
04909         
04910         >>> A = AstVector()
04911         >>> A.push(Int('x') + 1)
04912         >>> A.push(Int('y'))
04913         >>> A[0]
04914         x + 1
04915         >>> A[0] = Int('x')
04916         >>> A[0]
04917         x
04918         """
04919         if i >= self.__len__():
04920             raise IndexError
04921         Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
04922         
04923     def push(self, v):
04924         """Add `v` in the end of the vector.
04925 
04926         >>> A = AstVector()
04927         >>> len(A)
04928         0
04929         >>> A.push(Int('x'))
04930         >>> len(A)
04931         1
04932         """
04933         Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
04934 
04935     def resize(self, sz):
04936         """Resize the vector to `sz` elements.
04937 
04938         >>> A = AstVector()
04939         >>> A.resize(10)
04940         >>> len(A)
04941         10
04942         >>> for i in range(10): A[i] = Int('x')
04943         >>> A[5]
04944         x
04945         """
04946         Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
04947 
04948     def __contains__(self, item):
04949         """Return `True` if the vector contains `item`.
04950 
04951         >>> x = Int('x')
04952         >>> A = AstVector()
04953         >>> x in A
04954         False
04955         >>> A.push(x)
04956         >>> x in A
04957         True
04958         >>> (x+1) in A
04959         False
04960         >>> A.push(x+1)
04961         >>> (x+1) in A
04962         True
04963         >>> A
04964         [x, x + 1]
04965         """
04966         for elem in self:
04967             if elem.eq(item):
04968                 return True
04969         return False
04970         
04971     def translate(self, other_ctx):
04972         """Copy vector `self` to context `other_ctx`.
04973 
04974         >>> x = Int('x')
04975         >>> A = AstVector()
04976         >>> A.push(x)
04977         >>> c2 = Context()
04978         >>> B = A.translate(c2)
04979         >>> B
04980         [x]
04981         """
04982         return AstVector(Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()), other_ctx)
04983 
04984     def __repr__(self):
04985         return obj_to_string(self)
04986 
04987     def sexpr(self):
04988         """Return a textual representation of the s-expression representing the vector."""
04989         return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
04990 
04991 #########################################
04992 #
04993 # AST Map
04994 #
04995 #########################################
04996 class AstMap:
04997     """A mapping from ASTs to ASTs."""
04998 
04999     def __init__(self, m=None, ctx=None):
05000         self.map = None
05001         if m == None:
05002             self.ctx = _get_ctx(ctx)
05003             self.map = Z3_mk_ast_map(self.ctx.ref())
05004         else:
05005             self.map = m
05006             assert ctx != None
05007             self.ctx    = ctx
05008         Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
05009 
05010     def __del__(self):
05011         if self.map != None:
05012             Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
05013 
05014     def __len__(self):
05015         """Return the size of the map. 
05016 
05017         >>> M = AstMap()
05018         >>> len(M)
05019         0
05020         >>> x = Int('x')
05021         >>> M[x] = IntVal(1)
05022         >>> len(M)
05023         1
05024         """
05025         return int(Z3_ast_map_size(self.ctx.ref(), self.map))
05026 
05027     def __contains__(self, key):
05028         """Return `True` if the map contains key `key`.
05029 
05030         >>> M = AstMap()
05031         >>> x = Int('x')
05032         >>> M[x] = x + 1
05033         >>> x in M
05034         True
05035         >>> x+1 in M
05036         False
05037         """
05038         return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
05039         
05040     def __getitem__(self, key):
05041         """Retrieve the value associated with key `key`.
05042 
05043         >>> M = AstMap()
05044         >>> x = Int('x')
05045         >>> M[x] = x + 1
05046         >>> M[x]
05047         x + 1
05048         """
05049         return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
05050 
05051     def __setitem__(self, k, v):
05052         """Add/Update key `k` with value `v`.
05053 
05054         >>> M = AstMap()
05055         >>> x = Int('x')
05056         >>> M[x] = x + 1
05057         >>> len(M)
05058         1
05059         >>> M[x]
05060         x + 1
05061         >>> M[x] = IntVal(1)
05062         >>> M[x]
05063         1
05064         """
05065         Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
05066 
05067     def __repr__(self):
05068         return Z3_ast_map_to_string(self.ctx.ref(), self.map)
05069 
05070     def erase(self, k):
05071         """Remove the entry associated with key `k`.
05072 
05073         >>> M = AstMap()
05074         >>> x = Int('x')
05075         >>> M[x] = x + 1
05076         >>> len(M)
05077         1
05078         >>> M.erase(x)
05079         >>> len(M)
05080         0
05081         """
05082         Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
05083 
05084     def reset(self):
05085         """Remove all entries from the map.
05086 
05087         >>> M = AstMap()
05088         >>> x = Int('x')
05089         >>> M[x]   = x + 1
05090         >>> M[x+x] = IntVal(1)
05091         >>> len(M)
05092         2
05093         >>> M.reset()
05094         >>> len(M)
05095         0
05096         """
05097         Z3_ast_map_reset(self.ctx.ref(), self.map)
05098 
05099     def keys(self):
05100         """Return an AstVector containing all keys in the map.
05101 
05102         >>> M = AstMap()
05103         >>> x = Int('x')
05104         >>> M[x]   = x + 1
05105         >>> M[x+x] = IntVal(1)
05106         >>> M.keys()
05107         [x, x + x]
05108         """
05109         return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
05110 
05111 #########################################
05112 #
05113 # Model
05114 #
05115 #########################################
05116 
05117 class FuncEntry:
05118     """Store the value of the interpretation of a function in a particular point."""
05119 
05120     def __init__(self, entry, ctx):
05121         self.entry = entry
05122         self.ctx   = ctx
05123         Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
05124 
05125     def __del__(self):
05126         Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
05127 
05128     def num_args(self):
05129         """Return the number of arguments in the given entry.
05130         
05131         >>> f = Function('f', IntSort(), IntSort(), IntSort())
05132         >>> s = Solver()
05133         >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
05134         >>> s.check()
05135         sat
05136         >>> m = s.model()
05137         >>> f_i = m[f]
05138         >>> f_i.num_entries()
05139         3
05140         >>> e = f_i.entry(0)
05141         >>> e.num_args()
05142         2
05143         """
05144         return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
05145 
05146     def arg_value(self, idx):
05147         """Return the value of argument `idx`.
05148         
05149         >>> f = Function('f', IntSort(), IntSort(), IntSort())
05150         >>> s = Solver()
05151         >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
05152         >>> s.check()
05153         sat
05154         >>> m = s.model()
05155         >>> f_i = m[f]
05156         >>> f_i.num_entries()
05157         3
05158         >>> e = f_i.entry(0)
05159         >>> e
05160         [0, 1, 10]
05161         >>> e.num_args()
05162         2
05163         >>> e.arg_value(0)
05164         0
05165         >>> e.arg_value(1)
05166         1
05167         >>> try:
05168         ...   e.arg_value(2)
05169         ... except IndexError:
05170         ...   print("index error")
05171         index error
05172         """
05173         if idx >= self.num_args():
05174             raise IndexError
05175         return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
05176 
05177     def value(self):
05178         """Return the value of the function at point `self`.
05179         
05180         >>> f = Function('f', IntSort(), IntSort(), IntSort())
05181         >>> s = Solver()
05182         >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
05183         >>> s.check()
05184         sat
05185         >>> m = s.model()
05186         >>> f_i = m[f]
05187         >>> f_i.num_entries()
05188         3
05189         >>> e = f_i.entry(0)
05190         >>> e
05191         [0, 1, 10]
05192         >>> e.num_args()
05193         2
05194         >>> e.value()
05195         10
05196         """
05197         return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
05198     
05199     def as_list(self):
05200         """Return entry `self` as a Python list.
05201         >>> f = Function('f', IntSort(), IntSort(), IntSort())
05202         >>> s = Solver()
05203         >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
05204         >>> s.check()
05205         sat
05206         >>> m = s.model()
05207         >>> f_i = m[f]
05208         >>> f_i.num_entries()
05209         3
05210         >>> e = f_i.entry(0)
05211         >>> e.as_list()
05212         [0, 1, 10]
05213         """
05214         args = [ self.arg_value(i) for i in range(self.num_args())]
05215         args.append(self.value())
05216         return args
05217 
05218     def __repr__(self):
05219         return repr(self.as_list())
05220     
05221 class FuncInterp(Z3PPObject):
05222     """Stores the interpretation of a function in a Z3 model."""
05223 
05224     def __init__(self, f, ctx):
05225         self.f   = f
05226         self.ctx = ctx
05227         if self.f != None:
05228             Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
05229 
05230     def __del__(self):
05231         if self.f != None:
05232             Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
05233 
05234     def else_value(self):
05235         """
05236         Return the `else` value for a function interpretation.
05237         Return None if Z3 did not specify the `else` value for
05238         this object.
05239 
05240         >>> f = Function('f', IntSort(), IntSort())
05241         >>> s = Solver()
05242         >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
05243         >>> s.check()
05244         sat
05245         >>> m = s.model()
05246         >>> m[f]
05247         [0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
05248         >>> m[f].else_value()
05249         1
05250         """
05251         r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
05252         if r:
05253             return _to_expr_ref(r, self.ctx)
05254         else:
05255             return None
05256 
05257     def num_entries(self):
05258         """Return the number of entries/points in the function interpretation `self`.
05259 
05260         >>> f = Function('f', IntSort(), IntSort())
05261         >>> s = Solver()
05262         >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
05263         >>> s.check()
05264         sat
05265         >>> m = s.model()
05266         >>> m[f]
05267         [0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
05268         >>> m[f].num_entries()
05269         3
05270         """
05271         return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
05272 
05273     def arity(self):
05274         """Return the number of arguments for each entry in the function interpretation `self`.
05275 
05276         >>> f = Function('f', IntSort(), IntSort())
05277         >>> s = Solver()
05278         >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
05279         >>> s.check()
05280         sat
05281         >>> m = s.model()
05282         >>> m[f].arity()
05283         1
05284         """
05285         return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
05286     
05287     def entry(self, idx):
05288         """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
05289 
05290         >>> f = Function('f', IntSort(), IntSort())
05291         >>> s = Solver()
05292         >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
05293         >>> s.check()
05294         sat
05295         >>> m = s.model()
05296         >>> m[f]
05297         [0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
05298         >>> m[f].num_entries()
05299         3
05300         >>> m[f].entry(0)
05301         [0, 1]
05302         >>> m[f].entry(1)
05303         [1, 1]
05304         >>> m[f].entry(2)
05305         [2, 0]
05306         """
05307         if idx >= self.num_entries():
05308             raise IndexError
05309         return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
05310     
05311     def as_list(self):
05312         """Return the function interpretation as a Python list.
05313         >>> f = Function('f', IntSort(), IntSort())
05314         >>> s = Solver()
05315         >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
05316         >>> s.check()
05317         sat
05318         >>> m = s.model()
05319         >>> m[f]
05320         [0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
05321         >>> m[f].as_list()
05322         [[0, 1], [1, 1], [2, 0], 1]
05323         """
05324         r = [ self.entry(i).as_list() for i in range(self.num_entries())]
05325         r.append(self.else_value())
05326         return r
05327 
05328     def __repr__(self):
05329         return obj_to_string(self)
05330 
05331 class ModelRef(Z3PPObject):
05332     """Model/Solution of a satisfiability problem (aka system of constraints)."""
05333 
05334     def __init__(self, m, ctx):
05335         assert ctx != None
05336         self.model = m
05337         self.ctx   = ctx
05338         Z3_model_inc_ref(self.ctx.ref(), self.model)
05339 
05340     def __del__(self):
05341         Z3_model_dec_ref(self.ctx.ref(), self.model)
05342 
05343     def __repr__(self):
05344         return obj_to_string(self)
05345 
05346     def sexpr(self):
05347         """Return a textual representation of the s-expression representing the model."""
05348         return Z3_model_to_string(self.ctx.ref(), self.model)
05349 
05350     def eval(self, t, model_completion=False):
05351         """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`.
05352 
05353         >>> x = Int('x')
05354         >>> s = Solver()
05355         >>> s.add(x > 0, x < 2)
05356         >>> s.check()
05357         sat
05358         >>> m = s.model()
05359         >>> m.eval(x + 1)
05360         2
05361         >>> m.eval(x == 1)
05362         True
05363         >>> y = Int('y')
05364         >>> m.eval(y + x)
05365         1 + y
05366         >>> m.eval(y)
05367         y
05368         >>> m.eval(y, model_completion=True)
05369         0
05370         >>> # Now, m contains an interpretation for y
05371         >>> m.eval(y + x)
05372         1
05373         """
05374         r = (Ast * 1)()
05375         if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
05376             return _to_expr_ref(r[0], self.ctx)
05377         raise Z3Exception("failed to evaluate expression in the model")
05378 
05379     def evaluate(self, t, model_completion=False):
05380         """Alias for `eval`.
05381         
05382         >>> x = Int('x')
05383         >>> s = Solver()
05384         >>> s.add(x > 0, x < 2)
05385         >>> s.check()
05386         sat
05387         >>> m = s.model()
05388         >>> m.evaluate(x + 1)
05389         2
05390         >>> m.evaluate(x == 1)
05391         True
05392         >>> y = Int('y')
05393         >>> m.evaluate(y + x)
05394         1 + y
05395         >>> m.evaluate(y)
05396         y
05397         >>> m.evaluate(y, model_completion=True)
05398         0
05399         >>> # Now, m contains an interpretation for y
05400         >>> m.evaluate(y + x)
05401         1
05402         """
05403         return self.eval(t, model_completion)
05404 
05405     def __len__(self):
05406         """Return the number of constant and function declarations in the model `self`.
05407 
05408         >>> f = Function('f', IntSort(), IntSort())
05409         >>> x = Int('x')
05410         >>> s = Solver()
05411         >>> s.add(x > 0, f(x) != x)
05412         >>> s.check()
05413         sat
05414         >>> m = s.model()
05415         >>> len(m)
05416         2
05417         """
05418         return int(Z3_model_get_num_consts(self.ctx.ref(), self.model)) + int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
05419 
05420     def get_interp(self, decl):
05421         """Return the interpretation for a given declaration or constant.
05422 
05423         >>> f = Function('f', IntSort(), IntSort())
05424         >>> x = Int('x')
05425         >>> s = Solver()
05426         >>> s.add(x > 0, x < 2, f(x) == 0)
05427         >>> s.check()
05428         sat
05429         >>> m = s.model()
05430         >>> m[x]
05431         1
05432         >>> m[f]
05433         [1 -> 0, else -> 0]
05434         """
05435         if __debug__:
05436             _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
05437         if is_const(decl):
05438             decl = decl.decl()
05439         try:
05440             if decl.arity() == 0:
05441                 r = _to_expr_ref(Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
05442                 if is_as_array(r):
05443                     return self.get_interp(get_as_array_func(r))
05444                 else:
05445                     return r
05446             else:
05447                 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
05448         except Z3Exception:
05449             return None
05450 
05451     def num_sorts(self):
05452         """Return the number of unintepreted sorts that contain an interpretation in the model `self`.
05453         
05454         >>> A = DeclareSort('A')
05455         >>> a, b = Consts('a b', A)
05456         >>> s = Solver()
05457         >>> s.add(a != b)
05458         >>> s.check()
05459         sat
05460         >>> m = s.model()
05461         >>> m.num_sorts()
05462         1
05463         """
05464         return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
05465 
05466     def get_sort(self, idx):
05467         """Return the unintepreted sort at position `idx` < self.num_sorts().
05468         
05469         >>> A = DeclareSort('A')
05470         >>> B = DeclareSort('B')
05471         >>> a1, a2 = Consts('a1 a2', A)
05472         >>> b1, b2 = Consts('b1 b2', B)
05473         >>> s = Solver()
05474         >>> s.add(a1 != a2, b1 != b2)
05475         >>> s.check()
05476         sat
05477         >>> m = s.model()
05478         >>> m.num_sorts()
05479         2
05480         >>> m.get_sort(0)
05481         A
05482         >>> m.get_sort(1)
05483         B
05484         """
05485         if idx >= self.num_sorts():
05486             raise IndexError
05487         return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
05488     
05489     def sorts(self):
05490         """Return all uninterpreted sorts that have an interpretation in the model `self`.
05491 
05492         >>> A = DeclareSort('A')
05493         >>> B = DeclareSort('B')
05494         >>> a1, a2 = Consts('a1 a2', A)
05495         >>> b1, b2 = Consts('b1 b2', B)
05496         >>> s = Solver()
05497         >>> s.add(a1 != a2, b1 != b2)
05498         >>> s.check()
05499         sat
05500         >>> m = s.model()
05501         >>> m.sorts()
05502         [A, B]
05503         """
05504         return [ self.get_sort(i) for i in range(self.num_sorts()) ]
05505 
05506     def get_universe(self, s):
05507         """Return the intepretation for the uninterpreted sort `s` in the model `self`.
05508 
05509         >>> A = DeclareSort('A')
05510         >>> a, b = Consts('a b', A)
05511         >>> s = Solver()
05512         >>> s.add(a != b)
05513         >>> s.check()
05514         sat
05515         >>> m = s.model()
05516         >>> m.get_universe(A)
05517         [A!val!0, A!val!1]
05518         """
05519         if __debug__:
05520             _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
05521         try:
05522             return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
05523         except Z3Exception:
05524             return None
05525 
05526     def __getitem__(self, idx):
05527         """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 interpreation is returned.
05528         
05529         The elements can be retrieved using position or the actual declaration.
05530 
05531         >>> f = Function('f', IntSort(), IntSort())
05532         >>> x = Int('x')
05533         >>> s = Solver()
05534         >>> s.add(x > 0, x < 2, f(x) == 0)
05535         >>> s.check()
05536         sat
05537         >>> m = s.model()
05538         >>> len(m)
05539         2
05540         >>> m[0]
05541         x
05542         >>> m[1]
05543         f
05544         >>> m[x]
05545         1
05546         >>> m[f]
05547         [1 -> 0, else -> 0]
05548         >>> for d in m: print("%s -> %s" % (d, m[d]))
05549         x -> 1
05550         f -> [1 -> 0, else -> 0]
05551         """
05552         if isinstance(idx, int):
05553             if idx >= len(self):
05554                 raise IndexError
05555             num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
05556             if (idx < num_consts):
05557                 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
05558             else:
05559                 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
05560         if isinstance(idx, FuncDeclRef):
05561             return self.get_interp(idx)
05562         if is_const(idx):
05563             return self.get_interp(idx.decl())
05564         if isinstance(idx, SortRef):
05565             return self.get_universe(idx)
05566         if __debug__:
05567             _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
05568         return None
05569 
05570     def decls(self):
05571         """Return a list with all symbols that have an interpreation in the model `self`.
05572         >>> f = Function('f', IntSort(), IntSort())
05573         >>> x = Int('x')
05574         >>> s = Solver()
05575         >>> s.add(x > 0, x < 2, f(x) == 0)
05576         >>> s.check()
05577         sat
05578         >>> m = s.model()
05579         >>> m.decls()
05580         [x, f]
05581         """
05582         r = []
05583         for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
05584             r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
05585         for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
05586             r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
05587         return r
05588 
05589 def is_as_array(n):
05590     """Return true if n is a Z3 expression of the form (_ as-array f)."""
05591     return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
05592 
05593 def get_as_array_func(n):
05594     """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
05595     if __debug__:
05596         _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
05597     return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
05598 
05599 #########################################
05600 #
05601 # Statistics
05602 #
05603 #########################################
05604 class Statistics:
05605     """Statistics for `Solver.check()`."""
05606 
05607     def __init__(self, stats, ctx):
05608         self.stats = stats
05609         self.ctx   = ctx
05610         Z3_stats_inc_ref(self.ctx.ref(), self.stats)
05611 
05612     def __del__(self):
05613         Z3_stats_dec_ref(self.ctx.ref(), self.stats)
05614 
05615     def __repr__(self):
05616         if in_html_mode():
05617             out = io.StringIO()
05618             even = True
05619             out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
05620             for k, v in self:
05621                 if even:
05622                     out.write(u('<tr style="background-color:#CFCFCF">'))
05623                     even = False
05624                 else:
05625                     out.write(u('<tr>'))
05626                     even = True
05627                 out.write(u('<td>%s</td><td>%s</td></tr>' % (k, v)))
05628             out.write(u('</table>'))
05629             return out.getvalue()
05630         else:
05631             return Z3_stats_to_string(self.ctx.ref(), self.stats)
05632 
05633     def __len__(self):
05634         """Return the number of statistical counters. 
05635 
05636         >>> x = Int('x') 
05637         >>> s = Then('simplify', 'nlsat').solver()
05638         >>> s.add(x > 0)
05639         >>> s.check()
05640         sat
05641         >>> st = s.statistics()
05642         >>> len(st)
05643         6
05644         """
05645         return int(Z3_stats_size(self.ctx.ref(), self.stats))
05646 
05647     def __getitem__(self, idx):
05648         """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
05649 
05650         >>> x = Int('x') 
05651         >>> s = Then('simplify', 'nlsat').solver()
05652         >>> s.add(x > 0)
05653         >>> s.check()
05654         sat
05655         >>> st = s.statistics()
05656         >>> len(st)
05657         6
05658         >>> st[0]
05659         ('nlsat propagations', 2)
05660         >>> st[1]
05661         ('nlsat stages', 2)
05662         """
05663         if idx >= len(self):
05664             raise IndexError
05665         if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
05666             val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
05667         else:
05668             val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
05669         return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
05670     
05671     def keys(self):
05672         """Return the list of statistical counters.
05673         
05674         >>> x = Int('x') 
05675         >>> s = Then('simplify', 'nlsat').solver()
05676         >>> s.add(x > 0)
05677         >>> s.check()
05678         sat
05679         >>> st = s.statistics()
05680         >>> st.keys()
05681         ['nlsat propagations', 'nlsat stages', 'rlimit count', 'max memory', 'memory', 'num allocs']
05682         """
05683         return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
05684 
05685     def get_key_value(self, key):
05686         """Return the value of a particular statistical counter.
05687 
05688         >>> x = Int('x') 
05689         >>> s = Then('simplify', 'nlsat').solver()
05690         >>> s.add(x > 0)
05691         >>> s.check()
05692         sat
05693         >>> st = s.statistics()
05694         >>> st.get_key_value('nlsat propagations')
05695         2
05696         """
05697         for idx in range(len(self)):
05698             if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
05699                 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
05700                     return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
05701                 else:
05702                     return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
05703         raise Z3Exception("unknown key")
05704                
05705     def __getattr__(self, name):
05706         """Access the value of statistical using attributes.
05707         
05708         Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
05709         we should use '_' (e.g., 'nlsat_propagations').
05710 
05711         >>> x = Int('x') 
05712         >>> s = Then('simplify', 'nlsat').solver()
05713         >>> s.add(x > 0)
05714         >>> s.check()
05715         sat
05716         >>> st = s.statistics() 
05717         >>> st.keys()
05718         ['nlsat propagations', 'nlsat stages', 'rlimit count', 'max memory', 'memory', 'num allocs']
05719         >>> st.nlsat_propagations
05720         2
05721         >>> st.nlsat_stages
05722         2
05723         """
05724         key = name.replace('_', ' ')
05725         try:
05726             return self.get_key_value(key)
05727         except Z3Exception:
05728             raise AttributeError
05729             
05730 #########################################
05731 #
05732 # Solver
05733 #
05734 #########################################
05735 class CheckSatResult:
05736     """Represents the result of a satisfiability check: sat, unsat, unknown.
05737     
05738     >>> s = Solver()
05739     >>> s.check()
05740     sat
05741     >>> r = s.check()
05742     >>> isinstance(r, CheckSatResult)
05743     True
05744     """
05745 
05746     def __init__(self, r):
05747         self.r = r
05748 
05749     def __eq__(self, other):
05750         return isinstance(other, CheckSatResult) and self.r == other.r
05751 
05752     def __ne__(self, other):
05753         return not self.__eq__(other)
05754 
05755     def __repr__(self):
05756         if in_html_mode():
05757             if self.r == Z3_L_TRUE:
05758                 return "<b>sat</b>"
05759             elif self.r == Z3_L_FALSE:
05760                 return "<b>unsat</b>"
05761             else:
05762                 return "<b>unknown</b>"
05763         else:
05764             if self.r == Z3_L_TRUE:
05765                 return "sat"
05766             elif self.r == Z3_L_FALSE:
05767                 return "unsat"
05768             else:
05769                 return "unknown"
05770 
05771 sat     = CheckSatResult(Z3_L_TRUE)
05772 unsat   = CheckSatResult(Z3_L_FALSE)
05773 unknown = CheckSatResult(Z3_L_UNDEF) 
05774 
05775 class Solver(Z3PPObject):
05776     """Solver API provides methods for implementing the main SMT 2.0 commands: push, pop, check, get-model, etc."""
05777 
05778     def __init__(self, solver=None, ctx=None):
05779         assert solver == None or ctx != None
05780         self.ctx    = _get_ctx(ctx)
05781         self.solver = None
05782         if solver == None:
05783             self.solver = Z3_mk_solver(self.ctx.ref())
05784         else:
05785             self.solver = solver
05786         Z3_solver_inc_ref(self.ctx.ref(), self.solver)
05787 
05788     def __del__(self):
05789         if self.solver != None:
05790             Z3_solver_dec_ref(self.ctx.ref(), self.solver)
05791 
05792     def set(self, *args, **keys):
05793         """Set a configuration option. The method `help()` return a string containing all available options.
05794         
05795         >>> s = Solver()
05796         >>> # The option MBQI can be set using three different approaches.
05797         >>> s.set(mbqi=True)
05798         >>> s.set('MBQI', True)
05799         >>> s.set(':mbqi', True)
05800         """
05801         p = args2params(args, keys, self.ctx)
05802         Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
05803 
05804     def push(self):
05805         """Create a backtracking point.
05806 
05807         >>> x = Int('x')
05808         >>> s = Solver()
05809         >>> s.add(x > 0)
05810         >>> s
05811         [x > 0]
05812         >>> s.push()
05813         >>> s.add(x < 1)
05814         >>> s
05815         [x > 0, x < 1]
05816         >>> s.check()
05817         unsat
05818         >>> s.pop()
05819         >>> s.check()
05820         sat
05821         >>> s
05822         [x > 0]
05823         """
05824         Z3_solver_push(self.ctx.ref(), self.solver)
05825 
05826     def pop(self, num=1):
05827         """Backtrack \c num backtracking points.
05828         
05829         >>> x = Int('x')
05830         >>> s = Solver()
05831         >>> s.add(x > 0)
05832         >>> s
05833         [x > 0]
05834         >>> s.push()
05835         >>> s.add(x < 1)
05836         >>> s
05837         [x > 0, x < 1]
05838         >>> s.check()
05839         unsat
05840         >>> s.pop()
05841         >>> s.check()
05842         sat
05843         >>> s
05844         [x > 0]
05845         """
05846         Z3_solver_pop(self.ctx.ref(), self.solver, num)
05847 
05848     def reset(self):
05849         """Remove all asserted constraints and backtracking points created using `push()`.
05850         
05851         >>> x = Int('x')
05852         >>> s = Solver()
05853         >>> s.add(x > 0)
05854         >>> s
05855         [x > 0]
05856         >>> s.reset()
05857         >>> s
05858         []
05859         """
05860         Z3_solver_reset(self.ctx.ref(), self.solver)
05861     
05862     def assert_exprs(self, *args):
05863         """Assert constraints into the solver.
05864         
05865         >>> x = Int('x')
05866         >>> s = Solver()
05867         >>> s.assert_exprs(x > 0, x < 2)
05868         >>> s
05869         [x > 0, x < 2]
05870         """
05871         args = _get_args(args)
05872         s    = BoolSort(self.ctx)
05873         for arg in args:
05874             if isinstance(arg, Goal) or isinstance(arg, AstVector):
05875                 for f in arg:
05876                     Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
05877             else:
05878                 arg = s.cast(arg)
05879                 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
05880 
05881     def add(self, *args):
05882         """Assert constraints into the solver.
05883         
05884         >>> x = Int('x')
05885         >>> s = Solver()
05886         >>> s.add(x > 0, x < 2)
05887         >>> s
05888         [x > 0, x < 2]
05889         """
05890         self.assert_exprs(*args)
05891 
05892     def append(self, *args):
05893         """Assert constraints into the solver.
05894         
05895         >>> x = Int('x')
05896         >>> s = Solver()
05897         >>> s.append(x > 0, x < 2)
05898         >>> s
05899         [x > 0, x < 2]
05900         """
05901         self.assert_exprs(*args)
05902 
05903     def insert(self, *args):
05904         """Assert constraints into the solver.
05905         
05906         >>> x = Int('x')
05907         >>> s = Solver()
05908         >>> s.insert(x > 0, x < 2)
05909         >>> s
05910         [x > 0, x < 2]
05911         """
05912         self.assert_exprs(*args)
05913 
05914     def assert_and_track(self, a, p):
05915         """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
05916         
05917         If `p` is a string, it will be automatically converted into a Boolean constant.
05918         
05919         >>> x = Int('x')
05920         >>> p3 = Bool('p3')
05921         >>> s = Solver()
05922         >>> s.set(unsat_core=True)
05923         >>> s.assert_and_track(x > 0,  'p1')
05924         >>> s.assert_and_track(x != 1, 'p2')
05925         >>> s.assert_and_track(x < 0,  p3)
05926         >>> print(s.check())
05927         unsat
05928         >>> c = s.unsat_core()
05929         >>> len(c)
05930         2
05931         >>> Bool('p1') in c
05932         True
05933         >>> Bool('p2') in c
05934         False
05935         >>> p3 in c
05936         True
05937         """
05938         if isinstance(p, str):
05939             p = Bool(p, self.ctx)
05940         _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
05941         _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
05942         Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
05943 
05944     def check(self, *assumptions):
05945         """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
05946         
05947         >>> x = Int('x')
05948         >>> s = Solver()
05949         >>> s.check()
05950         sat
05951         >>> s.add(x > 0, x < 2)
05952         >>> s.check()
05953         sat
05954         >>> s.model()
05955         [x = 1]
05956         >>> s.add(x < 1)
05957         >>> s.check()
05958         unsat
05959         >>> s.reset()
05960         >>> s.add(2**x == 4)
05961         >>> s.check()
05962         unknown
05963         """
05964         assumptions = _get_args(assumptions)
05965         num = len(assumptions)
05966         _assumptions = (Ast * num)()
05967         for i in range(num):
05968             _assumptions[i] = assumptions[i].as_ast()
05969         r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
05970         return CheckSatResult(r)
05971 
05972     def model(self):
05973         """Return a model for the last `check()`. 
05974         
05975         This function raises an exception if 
05976         a model is not available (e.g., last `check()` returned unsat).
05977 
05978         >>> s = Solver()
05979         >>> a = Int('a')
05980         >>> s.add(a + 2 == 0)
05981         >>> s.check()
05982         sat
05983         >>> s.model()
05984         [a = -2]
05985         """
05986         try:
05987             return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
05988         except Z3Exception:
05989             raise Z3Exception("model is not available")
05990 
05991     def unsat_core(self):
05992         """Return a subset (as an AST vector) of the assumptions provided to the last check().
05993         
05994         These are the assumptions Z3 used in the unsatisfiability proof.
05995         Assumptions are available in Z3. They are used to extract unsatisfiable cores. 
05996         They may be also used to "retract" assumptions. Note that, assumptions are not really 
05997         "soft constraints", but they can be used to implement them. 
05998 
05999         >>> p1, p2, p3 = Bools('p1 p2 p3')
06000         >>> x, y       = Ints('x y')
06001         >>> s          = Solver()
06002         >>> s.add(Implies(p1, x > 0))
06003         >>> s.add(Implies(p2, y > x))
06004         >>> s.add(Implies(p2, y < 1))
06005         >>> s.add(Implies(p3, y > -3))
06006         >>> s.check(p1, p2, p3)
06007         unsat
06008         >>> core = s.unsat_core()
06009         >>> len(core)
06010         2
06011         >>> p1 in core
06012         True
06013         >>> p2 in core
06014         True
06015         >>> p3 in core
06016         False
06017         >>> # "Retracting" p2
06018         >>> s.check(p1, p3)
06019         sat
06020         """
06021         return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
06022 
06023     def proof(self):
06024         """Return a proof for the last `check()`. Proof construction must be enabled."""
06025         return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
06026 
06027     def assertions(self):
06028         """Return an AST vector containing all added constraints.
06029         
06030         >>> s = Solver()
06031         >>> s.assertions()
06032         []
06033         >>> a = Int('a')
06034         >>> s.add(a > 0)
06035         >>> s.add(a < 10)
06036         >>> s.assertions()
06037         [a > 0, a < 10]
06038         """
06039         return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
06040 
06041     def statistics(self):
06042         """Return statistics for the last `check()`.
06043         
06044         >>> s = SimpleSolver()
06045         >>> x = Int('x')
06046         >>> s.add(x > 0)
06047         >>> s.check()
06048         sat
06049         >>> st = s.statistics()
06050         >>> st.get_key_value('final checks')
06051         1
06052         >>> len(st) > 0
06053         True
06054         >>> st[0] != 0
06055         True
06056         """
06057         return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
06058 
06059     def reason_unknown(self):
06060         """Return a string describing why the last `check()` returned `unknown`.
06061         
06062         >>> x = Int('x')
06063         >>> s = SimpleSolver()
06064         >>> s.add(2**x == 4)
06065         >>> s.check()
06066         unknown
06067         >>> s.reason_unknown()
06068         '(incomplete (theory arithmetic))'
06069         """
06070         return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
06071     
06072     def help(self):
06073         """Display a string describing all available options."""
06074         print(Z3_solver_get_help(self.ctx.ref(), self.solver))
06075 
06076     def param_descrs(self):
06077         """Return the parameter description set."""
06078         return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
06079 
06080     def __repr__(self):
06081         """Return a formatted string with all added constraints."""
06082         return obj_to_string(self)
06083 
06084     def sexpr(self):
06085         """Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
06086         
06087         >>> x = Int('x')
06088         >>> s = Solver()
06089         >>> s.add(x > 0)
06090         >>> s.add(x < 2)
06091         >>> r = s.sexpr()
06092         """
06093         return Z3_solver_to_string(self.ctx.ref(), self.solver)
06094 
06095     def to_smt2(self):
06096         """return SMTLIB2 formatted benchmark for solver's assertions"""
06097         es = self.assertions()
06098         sz = len(es)
06099         sz1 = sz
06100         if sz1 > 0:
06101             sz1 -= 1
06102         v = (Ast * sz1)()
06103         for i in range(sz1):
06104             v[i] = es[i].as_ast()
06105         if sz > 0:
06106             e = es[sz1].as_ast()
06107         else:
06108             e = BoolVal(True, self.ctx).as_ast()
06109         return Z3_benchmark_to_smtlib_string(self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e)
06110 
06111 def SolverFor(logic, ctx=None):
06112     """Create a solver customized for the given logic. 
06113 
06114     The parameter `logic` is a string. It should be contains
06115     the name of a SMT-LIB logic.
06116     See http://www.smtlib.org/ for the name of all available logics.
06117 
06118     >>> s = SolverFor("QF_LIA")
06119     >>> x = Int('x')
06120     >>> s.add(x > 0)
06121     >>> s.add(x < 2)
06122     >>> s.check()
06123     sat
06124     >>> s.model()
06125     [x = 1]
06126     """
06127     ctx = _get_ctx(ctx)
06128     logic = to_symbol(logic)
06129     return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx)
06130 
06131 def SimpleSolver(ctx=None):
06132     """Return a simple general purpose solver with limited amount of preprocessing.
06133     
06134     >>> s = SimpleSolver()
06135     >>> x = Int('x')
06136     >>> s.add(x > 0)
06137     >>> s.check()
06138     sat
06139     """
06140     ctx = _get_ctx(ctx)
06141     return Solver(Z3_mk_simple_solver(ctx.ref()), ctx)
06142 
06143 #########################################
06144 #
06145 # Fixedpoint
06146 #
06147 #########################################
06148 
06149 class Fixedpoint(Z3PPObject):
06150     """Fixedpoint API provides methods for solving with recursive predicates"""
06151     
06152     def __init__(self, fixedpoint=None, ctx=None):
06153         assert fixedpoint == None or ctx != None
06154         self.ctx    = _get_ctx(ctx)
06155         self.fixedpoint = None
06156         if fixedpoint == None:
06157             self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
06158         else:
06159             self.fixedpoint = fixedpoint
06160         Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
06161         self.vars = []
06162 
06163     def __del__(self):
06164         if self.fixedpoint != None:
06165             Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
06166 
06167     def set(self, *args, **keys):
06168         """Set a configuration option. The method `help()` return a string containing all available options.        
06169         """
06170         p = args2params(args, keys, self.ctx)
06171         Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
06172 
06173     def help(self):
06174         """Display a string describing all available options."""
06175         print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
06176             
06177     def param_descrs(self):
06178         """Return the parameter description set."""
06179         return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
06180     
06181     def assert_exprs(self, *args):
06182         """Assert constraints as background axioms for the fixedpoint solver."""
06183         args = _get_args(args)
06184         s    = BoolSort(self.ctx)
06185         for arg in args:
06186             if isinstance(arg, Goal) or isinstance(arg, AstVector):
06187                 for f in arg:
06188                     f = self.abstract(f)
06189                     Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
06190             else:
06191                 arg = s.cast(arg)
06192                 arg = self.abstract(arg)
06193                 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
06194 
06195     def add(self, *args):
06196         """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
06197         self.assert_exprs(*args)
06198 
06199     def append(self, *args):
06200         """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
06201         self.assert_exprs(*args)
06202 
06203     def insert(self, *args):
06204         """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
06205         self.assert_exprs(*args)
06206 
06207     def add_rule(self, head, body = None, name = None):
06208         """Assert rules defining recursive predicates to the fixedpoint solver.
06209         >>> a = Bool('a')
06210         >>> b = Bool('b')
06211         >>> s = Fixedpoint()
06212         >>> s.register_relation(a.decl())
06213         >>> s.register_relation(b.decl())
06214         >>> s.fact(a)
06215         >>> s.rule(b, a)
06216         >>> s.query(b)
06217         sat
06218         """
06219         if name == None:
06220             name = ""
06221         name = to_symbol(name, self.ctx)
06222         if body == None:
06223             head = self.abstract(head)
06224             Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)            
06225         else:
06226             body = _get_args(body)
06227             f    = self.abstract(Implies(And(body, self.ctx),head))
06228             Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
06229         
06230     def rule(self, head, body = None, name = None):
06231         """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
06232         self.add_rule(head, body, name)
06233         
06234     def fact(self, head, name = None):
06235         """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
06236         self.add_rule(head, None, name)
06237 
06238     def query(self, *query):
06239         """Query the fixedpoint engine whether formula is derivable.
06240            You can also pass an tuple or list of recursive predicates.
06241         """
06242         query = _get_args(query)
06243         sz = len(query)
06244         if sz >= 1 and isinstance(query[0], FuncDeclRef):            
06245             _decls = (FuncDecl * sz)()
06246             i = 0
06247             for q in query:
06248                 _decls[i] = q.ast
06249                 i = i + 1
06250             r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
06251         else:
06252             if sz == 1:
06253                 query = query[0]
06254             else:
06255                 query = And(query, self.ctx)
06256             query = self.abstract(query, False)
06257             r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
06258         return CheckSatResult(r)
06259 
06260     def push(self):
06261         """create a backtracking point for added rules, facts and assertions"""
06262         Z3_fixedpoint_push(self.ctx.ref(), self.fixedpoint)
06263 
06264     def pop(self):
06265         """restore to previously created backtracking point"""
06266         Z3_fixedpoint_pop(self.ctx.ref(), self.fixedpoint)
06267 
06268     def update_rule(self, head, body, name):
06269         """update rule"""
06270         if name == None:
06271             name = ""
06272         name = to_symbol(name, self.ctx)
06273         body = _get_args(body)
06274         f    = self.abstract(Implies(And(body, self.ctx),head))
06275         Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
06276 
06277     def get_answer(self):       
06278         """Retrieve answer from last query call."""
06279         r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
06280         return _to_expr_ref(r, self.ctx)
06281 
06282     def get_num_levels(self, predicate):
06283         """Retrieve number of levels used for predicate in PDR engine"""
06284         return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
06285 
06286     def get_cover_delta(self, level, predicate):
06287         """Retrieve properties known about predicate for the level'th unfolding. -1 is treated as the limit (infinity)"""
06288         r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
06289         return _to_expr_ref(r, self.ctx)
06290     
06291     def add_cover(self, level, predicate, property):
06292         """Add property to predicate for the level'th unfolding. -1 is treated as infinity (infinity)"""
06293         Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
06294 
06295     def register_relation(self, *relations):
06296         """Register relation as recursive"""
06297         relations = _get_args(relations)
06298         for f in relations:
06299             Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
06300 
06301     def set_predicate_representation(self, f, *representations):
06302         """Control how relation is represented"""
06303         representations = _get_args(representations)
06304         representations = [to_symbol(s) for s in representations]
06305         sz = len(representations)
06306         args = (Symbol * sz)()
06307         for i in range(sz):
06308             args[i] = representations[i]
06309         Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
06310 
06311     def parse_string(self, s):
06312         """Parse rules and queries from a string"""
06313         return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
06314         
06315     def parse_file(self, f):
06316         """Parse rules and queries from a file"""
06317         return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
06318 
06319     def get_rules(self):
06320         """retrieve rules that have been added to fixedpoint context"""
06321         return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
06322 
06323     def get_assertions(self):
06324         """retrieve assertions that have been added to fixedpoint context"""
06325         return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
06326 
06327     def __repr__(self):
06328         """Return a formatted string with all added rules and constraints."""
06329         return self.sexpr()
06330 
06331     def sexpr(self):
06332         """Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.        
06333         """
06334         return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
06335 
06336     def to_string(self, queries):
06337         """Return a formatted string (in Lisp-like format) with all added constraints.
06338            We say the string is in s-expression format.
06339            Include also queries.
06340         """
06341         args, len = _to_ast_array(queries)
06342         return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
06343     
06344     def statistics(self):
06345         """Return statistics for the last `query()`.
06346         """
06347         return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
06348 
06349     def reason_unknown(self):
06350         """Return a string describing why the last `query()` returned `unknown`.
06351         """
06352         return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
06353 
06354     def declare_var(self, *vars):
06355         """Add variable or several variables.
06356         The added variable or variables will be bound in the rules
06357         and queries
06358         """
06359         vars = _get_args(vars)
06360         for v in vars:
06361             self.vars += [v]
06362         
06363     def abstract(self, fml, is_forall=True):
06364         if self.vars == []:
06365             return fml
06366         if is_forall:
06367             return ForAll(self.vars, fml)
06368         else:
06369             return Exists(self.vars, fml)
06370 
06371 
06372 #########################################
06373 #
06374 # Finite domain sorts
06375 #
06376 #########################################
06377 
06378 class FiniteDomainSortRef(SortRef):
06379     """Finite domain sort."""
06380 
06381     def size(self):
06382         """Return the size of the finite domain sort"""
06383         r = (ctype.c_ulonglong * 1)()
06384         if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast(), r):
06385             return r[0]
06386         else:
06387             raise Z3Exception("Failed to retrieve finite domain sort size")
06388 
06389 def FiniteDomainSort(name, sz, ctx=None):
06390     """Create a named finite domain sort of a given size sz"""
06391     ctx = _get_ctx(ctx)
06392     return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
06393 
06394 #########################################
06395 #
06396 # Optimize
06397 #
06398 #########################################
06399 
06400 class OptimizeObjective:
06401     def __init__(self, opt, value, is_max):
06402         self._opt = opt
06403         self._value = value
06404         self._is_max = is_max
06405 
06406     def lower(self):
06407         opt = self._opt
06408         return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
06409     
06410     def upper(self):
06411         opt = self._opt
06412         return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
06413 
06414     def value(self):
06415         if self._is_max:
06416             return self.upper()
06417         else:
06418             return self.lower()
06419 
06420 class Optimize(Z3PPObject):
06421     """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
06422      
06423     def __init__(self, ctx=None):
06424         self.ctx    = _get_ctx(ctx)
06425         self.optimize = Z3_mk_optimize(self.ctx.ref())
06426         Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
06427 
06428     def __del__(self):
06429         if self.optimize != None:
06430             Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
06431 
06432     def set(self, *args, **keys):
06433         """Set a configuration option. The method `help()` return a string containing all available options.        
06434         """
06435         p = args2params(args, keys, self.ctx)
06436         Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
06437 
06438     def help(self):
06439         """Display a string describing all available options."""
06440         print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
06441             
06442     def param_descrs(self):
06443         """Return the parameter description set."""
06444         return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
06445     
06446     def assert_exprs(self, *args):
06447         """Assert constraints as background axioms for the optimize solver."""
06448         args = _get_args(args)
06449         for arg in args:
06450             if isinstance(arg, Goal) or isinstance(arg, AstVector):
06451                 for f in arg:
06452                     Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
06453             else:
06454                 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
06455 
06456     def add(self, *args):
06457         """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
06458         self.assert_exprs(*args)
06459 
06460     def add_soft(self, arg, weight = "1", id = None):
06461         """Add soft constraint with optional weight and optional identifier.
06462            If no weight is supplied, then the penalty for violating the soft constraint
06463            is 1.
06464            Soft constraints are grouped by identifiers. Soft constraints that are
06465            added without identifiers are grouped by default.
06466         """
06467         if _is_int(weight):
06468             weight = "%d" % weight
06469         if not isinstance(weight, str):
06470             raise Z3Exception("weight should be a string or an integer")
06471         if id == None:
06472             id = ""
06473         id = to_symbol(id, self.ctx)
06474         v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, arg.as_ast(), weight, id)
06475         return OptimizeObjective(self, v, False)
06476 
06477     def maximize(self, arg):
06478         """Add objective function to maximize."""
06479         return OptimizeObjective(self, Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()), True)
06480 
06481     def minimize(self, arg):
06482         """Add objective function to minimize."""
06483         return OptimizeObjective(self, Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()), False)
06484 
06485     def push(self):
06486         """create a backtracking point for added rules, facts and assertions"""
06487         Z3_optimize_push(self.ctx.ref(), self.optimize)
06488 
06489     def pop(self):
06490         """restore to previously created backtracking point"""
06491         Z3_optimize_pop(self.ctx.ref(), self.optimize)
06492 
06493     def check(self):
06494         """Check satisfiability while optimizing objective functions."""
06495         return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize))
06496 
06497     def reason_unknown(self):
06498         """Return a string that describes why the last `check()` returned `unknown`."""
06499         return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
06500 
06501     def model(self):
06502         """Return a model for the last check()."""
06503         try:
06504             return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
06505         except Z3Exception:
06506             raise Z3Exception("model is not available")
06507 
06508     def lower(self, obj):
06509         if not isinstance(obj, OptimizeObjective):
06510             raise Z3Exception("Expecting objective handle returned by maximize/minimize")
06511         return obj.lower()
06512 
06513     def upper(self, obj):
06514         if not isinstance(obj, OptimizeObjective):
06515             raise Z3Exception("Expecting objective handle returned by maximize/minimize")
06516         return obj.upper()
06517     
06518     def __repr__(self):
06519         """Return a formatted string with all added rules and constraints."""
06520         return self.sexpr()
06521 
06522     def sexpr(self):
06523         """Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.        
06524         """
06525         return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
06526     
06527     def statistics(self):
06528         """Return statistics for the last `query()`.
06529         """
06530         return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
06531 
06532 
06533         
06534 
06535 #########################################
06536 #
06537 # ApplyResult
06538 #
06539 #########################################
06540 class ApplyResult(Z3PPObject):
06541     """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal. It also contains model and proof converters."""
06542     
06543     def __init__(self, result, ctx):
06544         self.result = result
06545         self.ctx    = ctx
06546         Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
06547 
06548     def __del__(self):
06549         Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
06550 
06551     def __len__(self):
06552         """Return the number of subgoals in `self`.
06553         
06554         >>> a, b = Ints('a b')
06555         >>> g = Goal()
06556         >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
06557         >>> t = Tactic('split-clause')
06558         >>> r = t(g)
06559         >>> len(r)
06560         2
06561         >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
06562         >>> len(t(g))
06563         4
06564         >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
06565         >>> len(t(g))
06566         1
06567         """
06568         return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
06569 
06570     def __getitem__(self, idx):
06571         """Return one of the subgoals stored in ApplyResult object `self`.
06572 
06573         >>> a, b = Ints('a b')
06574         >>> g = Goal()
06575         >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
06576         >>> t = Tactic('split-clause')
06577         >>> r = t(g)
06578         >>> r[0]        
06579         [a == 0, Or(b == 0, b == 1), a > b]
06580         >>> r[1]
06581         [a == 1, Or(b == 0, b == 1), a > b]
06582         """
06583         if idx >= len(self):
06584             raise IndexError
06585         return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
06586 
06587     def __repr__(self):
06588         return obj_to_string(self)
06589 
06590     def sexpr(self):
06591         """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
06592         return Z3_apply_result_to_string(self.ctx.ref(), self.result)
06593 
06594     def convert_model(self, model, idx=0):
06595         """Convert a model for a subgoal into a model for the original goal.
06596 
06597         >>> a, b = Ints('a b')
06598         >>> g = Goal()
06599         >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
06600         >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
06601         >>> r = t(g)
06602         >>> r[0]        
06603         [Or(b == 0, b == 1), Not(0 <= b)]
06604         >>> r[1]
06605         [Or(b == 0, b == 1), Not(1 <= b)]
06606         >>> # Remark: the subgoal r[0] is unsatisfiable
06607         >>> # Creating a solver for solving the second subgoal
06608         >>> s = Solver()
06609         >>> s.add(r[1])
06610         >>> s.check()
06611         sat
06612         >>> s.model()
06613         [b = 0]
06614         >>> # Model s.model() does not assign a value to `a`
06615         >>> # It is a model for subgoal `r[1]`, but not for goal `g`
06616         >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
06617         >>> r.convert_model(s.model(), 1)
06618         [b = 0, a = 1]
06619         """
06620         if __debug__:
06621             _z3_assert(idx < len(self), "index out of bounds")
06622             _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
06623         return ModelRef(Z3_apply_result_convert_model(self.ctx.ref(), self.result, idx, model.model), self.ctx)
06624 
06625     def as_expr(self):
06626         """Return a Z3 expression consisting of all subgoals.
06627         
06628         >>> x = Int('x')
06629         >>> g = Goal()
06630         >>> g.add(x > 1)
06631         >>> g.add(Or(x == 2, x == 3))
06632         >>> r = Tactic('simplify')(g)
06633         >>> r
06634         [[Not(x <= 1), Or(x == 2, x == 3)]]
06635         >>> r.as_expr()
06636         And(Not(x <= 1), Or(x == 2, x == 3))
06637         >>> r = Tactic('split-clause')(g)
06638         >>> r
06639         [[x > 1, x == 2], [x > 1, x == 3]]
06640         >>> r.as_expr()
06641         Or(And(x > 1, x == 2), And(x > 1, x == 3))
06642         """
06643         sz = len(self)
06644         if sz == 0:
06645             return BoolVal(False, self.ctx)
06646         elif sz == 1:
06647             return self[0].as_expr()
06648         else:
06649             return Or([ self[i].as_expr() for i in range(len(self)) ])
06650         
06651 #########################################
06652 #
06653 # Tactics
06654 #
06655 #########################################
06656 class Tactic:
06657     """Tactics transform, solver and/or simplify sets of constraints (Goal). A Tactic can be converted into a Solver using the method solver().
06658 
06659     Several combinators are available for creating new tactics using the built-in ones: Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
06660     """
06661     def __init__(self, tactic, ctx=None):
06662         self.ctx    = _get_ctx(ctx)
06663         self.tactic = None
06664         if isinstance(tactic, TacticObj):
06665             self.tactic = tactic
06666         else:
06667             if __debug__:
06668                 _z3_assert(isinstance(tactic, str), "tactic name expected")
06669             try:
06670                 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
06671             except Z3Exception:
06672                 raise Z3Exception("unknown tactic '%s'" % tactic)
06673         Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
06674 
06675     def __del__(self):
06676         if self.tactic != None:
06677             Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
06678 
06679     def solver(self):
06680         """Create a solver using the tactic `self`.
06681 
06682         The solver supports the methods `push()` and `pop()`, but it
06683         will always solve each `check()` from scratch.
06684         
06685         >>> t = Then('simplify', 'nlsat')
06686         >>> s = t.solver()
06687         >>> x = Real('x')
06688         >>> s.add(x**2 == 2, x > 0)
06689         >>> s.check()
06690         sat
06691         >>> s.model()
06692         [x = 1.4142135623?]
06693         """
06694         return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx)
06695 
06696     def apply(self, goal, *arguments, **keywords):
06697         """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
06698         
06699         >>> x, y = Ints('x y')
06700         >>> t = Tactic('solve-eqs')
06701         >>> t.apply(And(x == 0, y >= x + 1))
06702         [[y >= 1]]
06703         """
06704         if __debug__:
06705             _z3_assert(isinstance(goal, Goal) or isinstance(goal, BoolRef), "Z3 Goal or Boolean expressions expected")
06706         goal = _to_goal(goal)
06707         if len(arguments) > 0 or len(keywords) > 0:
06708             p = args2params(arguments, keywords, self.ctx)
06709             return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
06710         else:
06711             return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
06712 
06713     def __call__(self, goal, *arguments, **keywords):
06714         """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
06715         
06716         >>> x, y = Ints('x y')
06717         >>> t = Tactic('solve-eqs')
06718         >>> t(And(x == 0, y >= x + 1))
06719         [[y >= 1]]
06720         """
06721         return self.apply(goal, *arguments, **keywords)
06722 
06723     def help(self):
06724         """Display a string containing a description of the available options for the `self` tactic."""
06725         print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
06726 
06727     def param_descrs(self):
06728         """Return the parameter description set."""
06729         return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
06730 
06731 def _to_goal(a):
06732     if isinstance(a, BoolRef):
06733         goal = Goal(ctx = a.ctx)
06734         goal.add(a)
06735         return goal
06736     else:
06737         return a
06738 
06739 def _to_tactic(t, ctx=None):
06740     if isinstance(t, Tactic):
06741         return t
06742     else:
06743         return Tactic(t, ctx)
06744 
06745 def _and_then(t1, t2, ctx=None):
06746     t1 = _to_tactic(t1, ctx)
06747     t2 = _to_tactic(t2, ctx)
06748     if __debug__:
06749         _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
06750     return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
06751 
06752 def _or_else(t1, t2, ctx=None):
06753     t1 = _to_tactic(t1, ctx)
06754     t2 = _to_tactic(t2, ctx)
06755     if __debug__:
06756         _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
06757     return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
06758 
06759 def AndThen(*ts, **ks):
06760     """Return a tactic that applies the tactics in `*ts` in sequence.
06761     
06762     >>> x, y = Ints('x y')
06763     >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
06764     >>> t(And(x == 0, y > x + 1))
06765     [[Not(y <= 1)]]
06766     >>> t(And(x == 0, y > x + 1)).as_expr()
06767     Not(y <= 1)
06768     """
06769     if __debug__:
06770         _z3_assert(len(ts) >= 2, "At least two arguments expected")
06771     ctx = ks.get('ctx', None)
06772     num = len(ts)
06773     r = ts[0]
06774     for i in range(num - 1):
06775         r = _and_then(r, ts[i+1], ctx)
06776     return r
06777 
06778 def Then(*ts, **ks):
06779     """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
06780     
06781     >>> x, y = Ints('x y')
06782     >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
06783     >>> t(And(x == 0, y > x + 1))
06784     [[Not(y <= 1)]]
06785     >>> t(And(x == 0, y > x + 1)).as_expr()
06786     Not(y <= 1)
06787     """
06788     return AndThen(*ts, **ks)
06789     
06790 def OrElse(*ts, **ks):
06791     """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
06792 
06793     >>> x = Int('x')
06794     >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
06795     >>> # Tactic split-clause fails if there is no clause in the given goal.
06796     >>> t(x == 0)
06797     [[x == 0]]
06798     >>> t(Or(x == 0, x == 1))
06799     [[x == 0], [x == 1]]
06800     """
06801     if __debug__:
06802         _z3_assert(len(ts) >= 2, "At least two arguments expected")
06803     ctx = ks.get('ctx', None)
06804     num = len(ts)
06805     r = ts[0]
06806     for i in range(num - 1):
06807         r = _or_else(r, ts[i+1], ctx)
06808     return r
06809 
06810 def ParOr(*ts, **ks):
06811     """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
06812 
06813     >>> x = Int('x')
06814     >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
06815     >>> t(x + 1 == 2)
06816     [[x == 1]]
06817     """
06818     if __debug__:
06819         _z3_assert(len(ts) >= 2, "At least two arguments expected")
06820     ctx = _get_ctx(ks.get('ctx', None))
06821     ts  = [ _to_tactic(t, ctx) for t in ts ]
06822     sz  = len(ts)
06823     _args = (TacticObj * sz)()
06824     for i in range(sz):
06825         _args[i] = ts[i].tactic
06826     return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
06827 
06828 def ParThen(t1, t2, ctx=None):
06829     """Return a tactic that applies t1 and then t2 to every subgoal produced by t1. The subgoals are processed in parallel.
06830     
06831     >>> x, y = Ints('x y')
06832     >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
06833     >>> t(And(Or(x == 1, x == 2), y == x + 1))
06834     [[x == 1, y == 2], [x == 2, y == 3]]
06835     """
06836     t1 = _to_tactic(t1, ctx)
06837     t2 = _to_tactic(t2, ctx)
06838     if __debug__:
06839         _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
06840     return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
06841 
06842 def ParAndThen(t1, t2, ctx=None):
06843     """Alias for ParThen(t1, t2, ctx)."""
06844     return ParThen(t1, t2, ctx)
06845 
06846 def With(t, *args, **keys):
06847     """Return a tactic that applies tactic `t` using the given configuration options.
06848     
06849     >>> x, y = Ints('x y')
06850     >>> t = With(Tactic('simplify'), som=True)
06851     >>> t((x + 1)*(y + 2) == 0)
06852     [[2*x + y + x*y == -2]]
06853     """
06854     ctx = keys.get('ctx', None)
06855     t = _to_tactic(t, ctx)
06856     p = args2params(args, keys, t.ctx)
06857     return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
06858 
06859 def Repeat(t, max=4294967295, ctx=None):
06860     """Return a tactic that keeps applying `t` until the goal is not modified anymore or the maximum number of iterations `max` is reached.
06861 
06862     >>> x, y = Ints('x y')
06863     >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
06864     >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
06865     >>> r = t(c)
06866     >>> for subgoal in r: print(subgoal)
06867     [x == 0, y == 0, x > y]
06868     [x == 0, y == 1, x > y]
06869     [x == 1, y == 0, x > y]
06870     [x == 1, y == 1, x > y]
06871     >>> t = Then(t, Tactic('propagate-values'))
06872     >>> t(c)
06873     [[x == 1, y == 0]]
06874     """
06875     t = _to_tactic(t, ctx)
06876     return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
06877 
06878 def TryFor(t, ms, ctx=None):
06879     """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
06880     
06881     If `t` does not terminate in `ms` milliseconds, then it fails.
06882     """
06883     t = _to_tactic(t, ctx)
06884     return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
06885 
06886 def tactics(ctx=None):
06887     """Return a list of all available tactics in Z3.
06888     
06889     >>> l = tactics()
06890     >>> l.count('simplify') == 1
06891     True
06892     """
06893     ctx = _get_ctx(ctx)
06894     return [ Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref())) ]
06895 
06896 def tactic_description(name, ctx=None):
06897     """Return a short description for the tactic named `name`.
06898 
06899     >>> d = tactic_description('simplify')
06900     """
06901     ctx = _get_ctx(ctx)
06902     return Z3_tactic_get_descr(ctx.ref(), name)
06903 
06904 def describe_tactics():
06905     """Display a (tabular) description of all available tactics in Z3."""
06906     if in_html_mode():
06907         even = True
06908         print('<table border="1" cellpadding="2" cellspacing="0">')
06909         for t in tactics():
06910             if even:
06911                 print('<tr style="background-color:#CFCFCF">')
06912                 even = False
06913             else:
06914                 print('<tr>')
06915                 even = True
06916             print('<td>%s</td><td>%s</td></tr>' % (t, insert_line_breaks(tactic_description(t), 40)))
06917         print('</table>')
06918     else:
06919         for t in tactics():
06920             print('%s : %s' % (t, tactic_description(t)))
06921 
06922 class Probe:
06923     """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."""
06924     def __init__(self, probe, ctx=None):
06925         self.ctx    = _get_ctx(ctx)
06926         self.probe  = None
06927         if isinstance(probe, ProbeObj):
06928             self.probe = probe
06929         elif isinstance(probe, float):
06930             self.probe = Z3_probe_const(self.ctx.ref(), probe)
06931         elif _is_int(probe):
06932             self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
06933         elif isinstance(probe, bool):
06934             if probe:
06935                 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
06936             else:
06937                 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
06938         else:
06939             if __debug__:
06940                 _z3_assert(isinstance(probe, str), "probe name expected")
06941             try:
06942                 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
06943             except Z3Exception:
06944                 raise Z3Exception("unknown probe '%s'" % probe)
06945         Z3_probe_inc_ref(self.ctx.ref(), self.probe)
06946 
06947     def __del__(self):
06948         if self.probe != None:
06949             Z3_probe_dec_ref(self.ctx.ref(), self.probe)
06950 
06951     def __lt__(self, other):
06952         """Return a probe that evaluates to "true" when the value returned by `self` is less than the value returned by `other`.
06953 
06954         >>> p = Probe('size') < 10
06955         >>> x = Int('x')
06956         >>> g = Goal()
06957         >>> g.add(x > 0)
06958         >>> g.add(x < 10)
06959         >>> p(g)
06960         1.0
06961         """
06962         return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
06963 
06964     def __gt__(self, other):
06965         """Return a probe that evaluates to "true" when the value returned by `self` is greater than the value returned by `other`.
06966 
06967         >>> p = Probe('size') > 10
06968         >>> x = Int('x')
06969         >>> g = Goal()
06970         >>> g.add(x > 0)
06971         >>> g.add(x < 10)
06972         >>> p(g)
06973         0.0
06974         """
06975         return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
06976 
06977     def __le__(self, other):
06978         """Return a probe that evaluates to "true" when the value returned by `self` is less than or equal to the value returned by `other`.
06979 
06980         >>> p = Probe('size') <= 2
06981         >>> x = Int('x')
06982         >>> g = Goal()
06983         >>> g.add(x > 0)
06984         >>> g.add(x < 10)
06985         >>> p(g)
06986         1.0
06987         """
06988         return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
06989 
06990     def __ge__(self, other):
06991         """Return a probe that evaluates to "true" when the value returned by `self` is greater than or equal to the value returned by `other`.
06992 
06993         >>> p = Probe('size') >= 2
06994         >>> x = Int('x')
06995         >>> g = Goal()
06996         >>> g.add(x > 0)
06997         >>> g.add(x < 10)
06998         >>> p(g)
06999         1.0
07000         """
07001         return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
07002 
07003     def __eq__(self, other):
07004         """Return a probe that evaluates to "true" when the value returned by `self` is equal to the value returned by `other`.
07005 
07006         >>> p = Probe('size') == 2
07007         >>> x = Int('x')
07008         >>> g = Goal()
07009         >>> g.add(x > 0)
07010         >>> g.add(x < 10)
07011         >>> p(g)
07012         1.0
07013         """
07014         return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
07015 
07016     def __ne__(self, other):
07017         """Return a probe that evaluates to "true" when the value returned by `self` is not equal to the value returned by `other`.
07018 
07019         >>> p = Probe('size') != 2
07020         >>> x = Int('x')
07021         >>> g = Goal()
07022         >>> g.add(x > 0)
07023         >>> g.add(x < 10)
07024         >>> p(g)
07025         0.0
07026         """
07027         p = self.__eq__(other)
07028         return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
07029 
07030     def __call__(self, goal):
07031         """Evaluate the probe `self` in the given goal.
07032         
07033         >>> p = Probe('size')
07034         >>> x = Int('x')
07035         >>> g = Goal()
07036         >>> g.add(x > 0)
07037         >>> g.add(x < 10)
07038         >>> p(g)
07039         2.0
07040         >>> g.add(x < 20)
07041         >>> p(g)
07042         3.0
07043         >>> p = Probe('num-consts')
07044         >>> p(g)
07045         1.0
07046         >>> p = Probe('is-propositional')
07047         >>> p(g)
07048         0.0
07049         >>> p = Probe('is-qflia')
07050         >>> p(g)
07051         1.0
07052         """
07053         if __debug__:
07054             _z3_assert(isinstance(goal, Goal) or isinstance(goal, BoolRef), "Z3 Goal or Boolean expression expected") 
07055         goal = _to_goal(goal)
07056         return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
07057 
07058 def is_probe(p):
07059     """Return `True` if `p` is a Z3 probe.
07060     
07061     >>> is_probe(Int('x'))
07062     False
07063     >>> is_probe(Probe('memory'))
07064     True
07065     """
07066     return isinstance(p, Probe)
07067 
07068 def _to_probe(p, ctx=None):
07069     if is_probe(p):
07070         return p
07071     else:
07072         return Probe(p, ctx)
07073 
07074 def probes(ctx=None):
07075     """Return a list of all available probes in Z3.
07076     
07077     >>> l = probes()
07078     >>> l.count('memory') == 1
07079     True
07080     """
07081     ctx = _get_ctx(ctx)
07082     return [ Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref())) ]
07083 
07084 def probe_description(name, ctx=None):
07085     """Return a short description for the probe named `name`.
07086     
07087     >>> d = probe_description('memory')
07088     """
07089     ctx = _get_ctx(ctx)
07090     return Z3_probe_get_descr(ctx.ref(), name)
07091 
07092 def describe_probes():
07093     """Display a (tabular) description of all available probes in Z3."""
07094     if in_html_mode():
07095         even = True
07096         print('<table border="1" cellpadding="2" cellspacing="0">')
07097         for p in probes():
07098             if even:
07099                 print('<tr style="background-color:#CFCFCF">')
07100                 even = False
07101             else:
07102                 print('<tr>')
07103                 even = True
07104             print('<td>%s</td><td>%s</td></tr>' % (p, insert_line_breaks(probe_description(p), 40)))
07105         print('</table>')
07106     else:
07107         for p in probes():
07108             print('%s : %s' % (p, probe_description(p)))
07109 
07110 def _probe_nary(f, args, ctx):
07111     if __debug__:
07112         _z3_assert(len(args) > 0, "At least one argument expected")
07113     num = len(args)
07114     r = _to_probe(args[0], ctx)
07115     for i in range(num - 1):
07116         r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i+1], ctx).probe), ctx)
07117     return r
07118 
07119 def _probe_and(args, ctx):
07120     return _probe_nary(Z3_probe_and, args, ctx)
07121 
07122 def _probe_or(args, ctx):
07123     return _probe_nary(Z3_probe_or, args, ctx)
07124 
07125 def FailIf(p, ctx=None):
07126     """Return a tactic that fails if the probe `p` evaluates to true. Otherwise, it returns the input goal unmodified.
07127 
07128     In the following example, the tactic applies 'simplify' if and only if there are more than 2 constraints in the goal.
07129 
07130     >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
07131     >>> x, y = Ints('x y')
07132     >>> g = Goal()
07133     >>> g.add(x > 0)
07134     >>> g.add(y > 0)
07135     >>> t(g)
07136     [[x > 0, y > 0]]
07137     >>> g.add(x == y + 1)
07138     >>> t(g)
07139     [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
07140     """
07141     p = _to_probe(p, ctx)
07142     return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
07143 
07144 def When(p, t, ctx=None):
07145     """Return a tactic that applies tactic `t` only if probe `p` evaluates to true. Otherwise, it returns the input goal unmodified.
07146     
07147     >>> t = When(Probe('size') > 2, Tactic('simplify'))
07148     >>> x, y = Ints('x y')
07149     >>> g = Goal()
07150     >>> g.add(x > 0)
07151     >>> g.add(y > 0)
07152     >>> t(g)
07153     [[x > 0, y > 0]]
07154     >>> g.add(x == y + 1)
07155     >>> t(g)
07156     [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
07157     """
07158     p = _to_probe(p, ctx)
07159     t = _to_tactic(t, ctx)
07160     return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
07161 
07162 def Cond(p, t1, t2, ctx=None):
07163     """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
07164     
07165     >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
07166     """
07167     p = _to_probe(p, ctx)
07168     t1 = _to_tactic(t1, ctx)
07169     t2 = _to_tactic(t2, ctx)
07170     return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
07171 
07172 #########################################
07173 #
07174 # Utils
07175 #
07176 #########################################
07177 
07178 def simplify(a, *arguments, **keywords):
07179     """Simplify the expression `a` using the given options.
07180 
07181     This function has many options. Use `help_simplify` to obtain the complete list.
07182     
07183     >>> x = Int('x')
07184     >>> y = Int('y')
07185     >>> simplify(x + 1 + y + x + 1)
07186     2 + 2*x + y
07187     >>> simplify((x + 1)*(y + 1), som=True)
07188     1 + x + y + x*y
07189     >>> simplify(Distinct(x, y, 1), blast_distinct=True)
07190     And(Not(x == y), Not(x == 1), Not(y == 1))
07191     >>> simplify(And(x == 0, y == 1), elim_and=True)
07192     Not(Or(Not(x == 0), Not(y == 1)))
07193     """
07194     if __debug__:
07195         _z3_assert(is_expr(a), "Z3 expression expected")
07196     if len(arguments) > 0 or len(keywords) > 0:
07197         p = args2params(arguments, keywords, a.ctx)
07198         return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
07199     else:
07200         return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
07201 
07202 def help_simplify():
07203     """Return a string describing all options available for Z3 `simplify` procedure."""
07204     print(Z3_simplify_get_help(main_ctx().ref()))
07205 
07206 def simplify_param_descrs():
07207     """Return the set of parameter descriptions for Z3 `simplify` procedure."""
07208     return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
07209 
07210 def substitute(t, *m):
07211     """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.
07212     
07213     >>> x = Int('x')
07214     >>> y = Int('y')
07215     >>> substitute(x + 1, (x, y + 1))
07216     y + 1 + 1
07217     >>> f = Function('f', IntSort(), IntSort())
07218     >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
07219     1 + 1
07220     """
07221     if isinstance(m, tuple):
07222         m1 = _get_args(m)
07223         if isinstance(m1, list):
07224             m = m1
07225     if __debug__:
07226         _z3_assert(is_expr(t), "Z3 expression expected")
07227         _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.")
07228     num = len(m)
07229     _from = (Ast * num)()
07230     _to   = (Ast * num)()
07231     for i in range(num):
07232         _from[i] = m[i][0].as_ast()
07233         _to[i]   = m[i][1].as_ast()
07234     return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
07235 
07236 def substitute_vars(t, *m):
07237     """Substitute the free variables in t with the expression in m.
07238     
07239     >>> v0 = Var(0, IntSort())
07240     >>> v1 = Var(1, IntSort())
07241     >>> x  = Int('x')
07242     >>> f  = Function('f', IntSort(), IntSort(), IntSort())
07243     >>> # replace v0 with x+1 and v1 with x
07244     >>> substitute_vars(f(v0, v1), x + 1, x)
07245     f(x + 1, x)
07246     """
07247     if __debug__:
07248         _z3_assert(is_expr(t), "Z3 expression expected")
07249         _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
07250     num = len(m)
07251     _to   = (Ast * num)()
07252     for i in range(num):
07253         _to[i] = m[i].as_ast()
07254     return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
07255 
07256 def Sum(*args):
07257     """Create the sum of the Z3 expressions. 
07258     
07259     >>> a, b, c = Ints('a b c')
07260     >>> Sum(a, b, c)
07261     a + b + c
07262     >>> Sum([a, b, c])
07263     a + b + c
07264     >>> A = IntVector('a', 5)
07265     >>> Sum(A)
07266     a__0 + a__1 + a__2 + a__3 + a__4
07267     """
07268     args  = _get_args(args)
07269     if __debug__:
07270         _z3_assert(len(args) > 0, "Non empty list of arguments expected")
07271     ctx   = _ctx_from_ast_arg_list(args)
07272     if __debug__:
07273         _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression")
07274     args  = _coerce_expr_list(args, ctx)
07275     if is_bv(args[0]):
07276         return _reduce(lambda a, b: a + b, args, 0)
07277     else:
07278         _args, sz = _to_ast_array(args)
07279         return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
07280 
07281 def Product(*args):
07282     """Create the product of the Z3 expressions. 
07283     
07284     >>> a, b, c = Ints('a b c')
07285     >>> Product(a, b, c)
07286     a*b*c
07287     >>> Product([a, b, c])
07288     a*b*c
07289     >>> A = IntVector('a', 5)
07290     >>> Product(A)
07291     a__0*a__1*a__2*a__3*a__4
07292     """
07293     args  = _get_args(args)
07294     if __debug__:
07295         _z3_assert(len(args) > 0, "Non empty list of arguments expected")
07296     ctx   = _ctx_from_ast_arg_list(args)
07297     if __debug__:
07298         _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression")
07299     args  = _coerce_expr_list(args, ctx)
07300     if is_bv(args[0]):
07301         return _reduce(lambda a, b: a * b, args, 1)
07302     else:
07303         _args, sz = _to_ast_array(args)
07304         return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
07305 
07306 def solve(*args, **keywords):
07307     """Solve the constraints `*args`.
07308     
07309     This is a simple function for creating demonstrations. It creates a solver,
07310     configure it using the options in `keywords`, adds the constraints
07311     in `args`, and invokes check.
07312     
07313     >>> a = Int('a')
07314     >>> solve(a > 0, a < 2)
07315     [a = 1]
07316     """
07317     s = Solver()
07318     s.set(**keywords)
07319     s.add(*args)
07320     if keywords.get('show', False):
07321         print(s)
07322     r = s.check()
07323     if r == unsat:
07324         print("no solution")
07325     elif r == unknown:
07326         print("failed to solve")
07327         try:
07328             print(s.model())
07329         except Z3Exception:
07330             return
07331     else:
07332         print(s.model())
07333 
07334 def solve_using(s, *args, **keywords):
07335     """Solve the constraints `*args` using solver `s`.
07336     
07337     This is a simple function for creating demonstrations. It is similar to `solve`,
07338     but it uses the given solver `s`.
07339     It configures solver `s` using the options in `keywords`, adds the constraints
07340     in `args`, and invokes check.
07341     """
07342     if __debug__:
07343         _z3_assert(isinstance(s, Solver), "Solver object expected")
07344     s.set(**keywords)
07345     s.add(*args)
07346     if keywords.get('show', False):
07347         print("Problem:")
07348         print(s)
07349     r = s.check()
07350     if r == unsat:
07351         print("no solution")
07352     elif r == unknown:
07353         print("failed to solve")
07354         try:
07355             print(s.model())
07356         except Z3Exception:
07357             return
07358     else:
07359         if keywords.get('show', False):
07360             print("Solution:")
07361         print(s.model())
07362 
07363 def prove(claim, **keywords):
07364     """Try to prove the given claim.
07365 
07366     This is a simple function for creating demonstrations.  It tries to prove
07367     `claim` by showing the negation is unsatisfiable.
07368 
07369     >>> p, q = Bools('p q')
07370     >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
07371     proved
07372     """
07373     if __debug__:
07374         _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
07375     s = Solver()
07376     s.set(**keywords)
07377     s.add(Not(claim))
07378     if keywords.get('show', False):
07379         print(s)
07380     r = s.check()
07381     if r == unsat:
07382         print("proved")
07383     elif r == unknown:
07384         print("failed to prove")
07385         print(s.model())
07386     else:
07387         print("counterexample")
07388         print(s.model())
07389 
07390 def _solve_html(*args, **keywords):
07391     """Version of funcion `solve` used in RiSE4Fun."""
07392     s = Solver()
07393     s.set(**keywords)
07394     s.add(*args)
07395     if keywords.get('show', False):
07396         print("<b>Problem:</b>")
07397         print(s)
07398     r = s.check()
07399     if r == unsat:
07400         print("<b>no solution</b>")
07401     elif r == unknown:
07402         print("<b>failed to solve</b>")
07403         try:
07404             print(s.model())
07405         except Z3Exception:
07406             return
07407     else:
07408         if keywords.get('show', False):
07409             print("<b>Solution:</b>")
07410         print(s.model())
07411 
07412 def _solve_using_html(s, *args, **keywords):
07413     """Version of funcion `solve_using` used in RiSE4Fun."""
07414     if __debug__:
07415         _z3_assert(isinstance(s, Solver), "Solver object expected")
07416     s.set(**keywords)
07417     s.add(*args)
07418     if keywords.get('show', False):
07419         print("<b>Problem:</b>")
07420         print(s)
07421     r = s.check()
07422     if r == unsat:
07423         print("<b>no solution</b>")
07424     elif r == unknown:
07425         print("<b>failed to solve</b>")
07426         try:
07427             print(s.model())
07428         except Z3Exception:
07429             return
07430     else:
07431         if keywords.get('show', False):
07432             print("<b>Solution:</b>")
07433         print(s.model())
07434 
07435 def _prove_html(claim, **keywords):
07436     """Version of funcion `prove` used in RiSE4Fun."""
07437     if __debug__:
07438         _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
07439     s = Solver()
07440     s.set(**keywords)
07441     s.add(Not(claim))
07442     if keywords.get('show', False):
07443         print(s)
07444     r = s.check()
07445     if r == unsat:
07446         print("<b>proved</b>")
07447     elif r == unknown:
07448         print("<b>failed to prove</b>")
07449         print(s.model())
07450     else:
07451         print("<b>counterexample</b>")
07452         print(s.model())
07453 
07454 def _dict2sarray(sorts, ctx):
07455     sz = len(sorts)
07456     _names = (Symbol * sz)()
07457     _sorts = (Sort * sz) ()
07458     i = 0
07459     for k in sorts:
07460         v = sorts[k]
07461         if __debug__:
07462             _z3_assert(isinstance(k, str), "String expected")
07463             _z3_assert(is_sort(v), "Z3 sort expected")
07464         _names[i] = to_symbol(k, ctx)
07465         _sorts[i] = v.ast
07466         i = i + 1
07467     return sz, _names, _sorts
07468 
07469 def _dict2darray(decls, ctx):
07470     sz = len(decls)
07471     _names = (Symbol * sz)()
07472     _decls = (FuncDecl * sz) ()
07473     i = 0
07474     for k in decls:
07475         v = decls[k]
07476         if __debug__:
07477             _z3_assert(isinstance(k, str), "String expected")
07478             _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
07479         _names[i] = to_symbol(k, ctx)
07480         if is_const(v):
07481             _decls[i] = v.decl().ast
07482         else:
07483             _decls[i] = v.ast
07484         i = i + 1
07485     return sz, _names, _decls
07486 
07487 def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
07488     """Parse a string in SMT 2.0 format using the given sorts and decls.
07489     
07490     The arguments sorts and decls are Python dictionaries used to initialize
07491     the symbol table used for the SMT 2.0 parser.
07492 
07493     >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
07494     And(x > 0, x < 10)
07495     >>> x, y = Ints('x y')
07496     >>> f = Function('f', IntSort(), IntSort())
07497     >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
07498     x + f(y) > 0
07499     >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
07500     a > 0
07501     """
07502     ctx = _get_ctx(ctx)
07503     ssz, snames, ssorts = _dict2sarray(sorts, ctx)
07504     dsz, dnames, ddecls = _dict2darray(decls, ctx)
07505     return _to_expr_ref(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
07506 
07507 def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
07508     """Parse a file in SMT 2.0 format using the given sorts and decls.
07509     
07510     This function is similar to parse_smt2_string().
07511     """
07512     ctx = _get_ctx(ctx)
07513     ssz, snames, ssorts = _dict2sarray(sorts, ctx)
07514     dsz, dnames, ddecls = _dict2darray(decls, ctx)
07515     return _to_expr_ref(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
07516    
07517 def Interpolant(a,ctx=None):
07518     """Create an interpolation operator.
07519     
07520     The argument is an interpolation pattern (see tree_interpolant). 
07521 
07522     >>> x = Int('x')
07523     >>> print Interpolant(x>0)
07524     interp(x > 0)
07525     """
07526     ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
07527     s = BoolSort(ctx)
07528     a = s.cast(a)
07529     return BoolRef(Z3_mk_interpolant(ctx.ref(), a.as_ast()), ctx)
07530 
07531 def tree_interpolant(pat,p=None,ctx=None):
07532     """Compute interpolant for a tree of formulas.
07533 
07534     The input is an interpolation pattern over a set of formulas C.
07535     The pattern pat is a formula combining the formulas in C using
07536     logical conjunction and the "interp" operator (see Interp). This
07537     interp operator is logically the identity operator. It marks the
07538     sub-formulas of the pattern for which interpolants should be
07539     computed. The interpolant is a map sigma from marked subformulas
07540     to formulas, such that, for each marked subformula phi of pat
07541     (where phi sigma is phi with sigma(psi) substituted for each
07542     subformula psi of phi such that psi in dom(sigma)):
07543 
07544       1) phi sigma implies sigma(phi), and
07545 
07546       2) sigma(phi) is in the common uninterpreted vocabulary between
07547       the formulas of C occurring in phi and those not occurring in
07548       phi
07549 
07550       and moreover pat sigma implies false. In the simplest case
07551       an interpolant for the pattern "(and (interp A) B)" maps A
07552       to an interpolant for A /\ B. 
07553 
07554       The return value is a vector of formulas representing sigma. This
07555       vector contains sigma(phi) for each marked subformula of pat, in
07556       pre-order traversal. This means that subformulas of phi occur before phi
07557       in the vector. Also, subformulas that occur multiply in pat will
07558       occur multiply in the result vector.
07559 
07560     If pat is satisfiable, raises an object of class ModelRef
07561     that represents a model of pat.
07562 
07563     If parameters p are supplied, these are used in creating the
07564     solver that determines satisfiability.
07565 
07566     >>> x = Int('x')
07567     >>> y = Int('y')
07568     >>> print tree_interpolant(And(Interpolant(x < 0), Interpolant(y > 2), x == y))
07569     [Not(x >= 0), Not(y <= 2)]
07570 
07571     >>> g = And(Interpolant(x<0),x<2)
07572     >>> try:
07573     ...     print tree_interpolant(g).sexpr()
07574     ... except ModelRef as m:
07575     ...     print m.sexpr()
07576     (define-fun x () Int
07577       (- 1))
07578     """
07579     f = pat
07580     ctx = _get_ctx(_ctx_from_ast_arg_list([f], ctx))
07581     ptr = (AstVectorObj * 1)()
07582     mptr = (Model * 1)()
07583     if p == None:
07584         p = ParamsRef(ctx)
07585     res = Z3_compute_interpolant(ctx.ref(),f.as_ast(),p.params,ptr,mptr)
07586     if res == Z3_L_FALSE:
07587         return AstVector(ptr[0],ctx)
07588     raise ModelRef(mptr[0], ctx)
07589 
07590 def binary_interpolant(a,b,p=None,ctx=None):
07591     """Compute an interpolant for a binary conjunction.
07592 
07593     If a & b is unsatisfiable, returns an interpolant for a & b.
07594     This is a formula phi such that
07595 
07596     1) a implies phi
07597     2) b implies not phi
07598     3) All the uninterpreted symbols of phi occur in both a and b.
07599 
07600     If a & b is satisfiable, raises an object of class ModelRef
07601     that represents a model of a &b.
07602 
07603     If parameters p are supplied, these are used in creating the
07604     solver that determines satisfiability.
07605 
07606     x = Int('x')
07607     print binary_interpolant(x<0,x>2)
07608     Not(x >= 0)
07609     """
07610     f = And(Interpolant(a),b)
07611     return tree_interpolant(f,p,ctx)[0]
07612 
07613 def sequence_interpolant(v,p=None,ctx=None):
07614     """Compute interpolant for a sequence of formulas.
07615 
07616     If len(v) == N, and if the conjunction of the formulas in v is
07617     unsatisfiable, the interpolant is a sequence of formulas w
07618     such that len(w) = N-1 and v[0] implies w[0] and for i in 0..N-1:
07619 
07620     1) w[i] & v[i+1] implies w[i+1] (or false if i+1 = N)
07621     2) All uninterpreted symbols in w[i] occur in both v[0]..v[i]
07622     and v[i+1]..v[n]
07623     
07624     Requires len(v) >= 1. 
07625 
07626     If a & b is satisfiable, raises an object of class ModelRef
07627     that represents a model of a & b.
07628 
07629     If parameters p are supplied, these are used in creating the
07630     solver that determines satisfiability.
07631 
07632     >>> x = Int('x')
07633     >>> y = Int('y')
07634     >>> print sequence_interpolant([x < 0, y == x , y > 2])
07635     [Not(x >= 0), Not(y >= 0)]
07636     """
07637     f = v[0]
07638     for i in range(1,len(v)):
07639         f = And(Interpolant(f),v[i])
07640     return tree_interpolant(f,p,ctx)
07641 
07642 #########################################
07643 #
07644 # Floating-Point Arithmetic
07645 #
07646 #########################################
07647 
07648     
07649 # Global default rounding mode
07650 _dflt_rounding_mode = Z3_OP_FPA_RM_TOWARD_ZERO
07651 _dflt_fpsort_ebits = 11
07652 _dflt_fpsort_sbits = 53
07653 
07654 def get_default_rounding_mode(ctx=None):
07655     """Retrieves the global default rounding mode."""
07656     global _dflt_rounding_mode
07657     if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
07658         return RTZ(ctx)
07659     elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
07660         return RTN(ctx)
07661     elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
07662         return RTP(ctx)
07663     elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
07664         return RNE(ctx)
07665     elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
07666         return RNA(ctx)
07667 
07668 def set_default_rounding_mode(rm, ctx=None):
07669     global _dflt_rounding_mode
07670     if is_fprm_value(rm):
07671         _dflt_rounding_mode = rm.decl().kind()
07672     else:
07673         _z3_assert(_dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO or
07674                    _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE or
07675                    _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE or
07676                    _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN or
07677                    _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY,
07678                    "illegal rounding mode")
07679         _dflt_rounding_mode = rm
07680 
07681 def get_default_fp_sort(ctx=None):
07682     return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
07683 
07684 def set_default_fp_sort(ebits, sbits, ctx=None):
07685     global _dflt_fpsort_ebits
07686     global _dflt_fpsort_sbits
07687     _dflt_fpsort_ebits = ebits
07688     _dflt_fpsort_sbits = sbits
07689 
07690 def _dflt_rm(ctx=None):
07691     return get_default_rounding_mode(ctx)
07692 
07693 def _dflt_fps(ctx=None):
07694     return get_default_fp_sort(ctx)
07695 
07696 ### FP Sorts
07697     
07698 class FPSortRef(SortRef):
07699     """Floating-point sort."""
07700 
07701     def ebits(self):
07702        """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
07703        >>> b = FPSort(8, 24)
07704        >>> b.ebits()
07705        8
07706        """
07707        return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
07708 
07709     def sbits(self):
07710        """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
07711        >>> b = FPSort(8, 24)
07712        >>> b.sbits()
07713        24
07714        """
07715        return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
07716 
07717     def cast(self, val):
07718         """Try to cast `val` as a Floating-point expression
07719 
07720         >>> b = FPSort(8, 24)
07721         >>> b.cast(1.0)
07722         1
07723         >>> b.cast(1.0).sexpr()
07724         '(fp #b0 #x7f #b00000000000000000000000)'
07725         """
07726         if is_expr(val):
07727             if __debug__:
07728                 _z3_assert(self.ctx == val.ctx, "Context mismatch")
07729             return val
07730         else:
07731             return FPVal(val, None, self, self.ctx)
07732 
07733 
07734 def Float16(ctx=None):
07735     """Floating-point 16-bit (half) sort."""
07736     ctx = _get_ctx(ctx)
07737     return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
07738 
07739 def FloatHalf(ctx=None):
07740     """Floating-point 16-bit (half) sort."""
07741     ctx = _get_ctx(ctx)
07742     return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
07743 
07744 def Float32(ctx=None):
07745     """Floating-point 32-bit (single) sort."""
07746     ctx = _get_ctx(ctx)
07747     return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
07748 
07749 def FloatSingle(ctx=None):
07750     """Floating-point 32-bit (single) sort."""
07751     ctx = _get_ctx(ctx)
07752     return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
07753 
07754 def Float64(ctx=None):
07755     """Floating-point 64-bit (double) sort."""
07756     ctx = _get_ctx(ctx)
07757     return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
07758 
07759 def FloatSingle(ctx=None):
07760     """Floating-point 64-bit (double) sort."""
07761     ctx = _get_ctx(ctx)
07762     return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
07763 
07764 def Float128(ctx=None):
07765     """Floating-point 128-bit (quadruple) sort."""
07766     ctx = _get_ctx(ctx)
07767     return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
07768 
07769 def FloatSingle(ctx=None):
07770     """Floating-point 128-bit (quadruple) sort."""
07771     ctx = _get_ctx(ctx)
07772     return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
07773 
07774 class FPRMSortRef(SortRef):
07775     """"Floating-point rounding mode sort."""
07776 
07777 
07778 def is_fp_sort(s):
07779     """Return True if `s` is a Z3 floating-point sort.
07780 
07781     >>> is_fp_sort(FPSort(8, 24))
07782     True
07783     >>> is_fp_sort(IntSort())
07784     False
07785     """
07786     return isinstance(s, FPSortRef)
07787 
07788 def is_fprm_sort(s):
07789     """Return True if `s` is a Z3 floating-point rounding mode sort.
07790 
07791     >>> is_fprm_sort(FPSort(8, 24))
07792     False
07793     >>> is_fprm_sort(RNE().sort())
07794     True
07795     """
07796     return isinstance(s, FPRMSortRef)
07797 
07798 ### FP Expressions
07799     
07800 class FPRef(ExprRef):
07801     """Floating-point expressions."""
07802         
07803     def sort(self):
07804         """Return the sort of the floating-point expression `self`.
07805 
07806         >>> x = FP('1.0', FPSort(8, 24))
07807         >>> x.sort()
07808         FPSort(8, 24)
07809         >>> x.sort() == FPSort(8, 24)
07810         True
07811         """
07812         return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
07813 
07814     def ebits(self):
07815        """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
07816        >>> b = FPSort(8, 24)
07817        >>> b.ebits()
07818        8
07819        """
07820        return self.sort().ebits();
07821 
07822     def sbits(self):
07823        """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
07824        >>> b = FPSort(8, 24)
07825        >>> b.sbits()
07826        24
07827        """
07828        return self.sort().sbits();
07829 
07830     def as_string(self):
07831         """Return a Z3 floating point expression as a Python string."""
07832         return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
07833 
07834     def __le__(self, other):
07835         return fpLEQ(self, other)
07836 
07837     def __lt__(self, other):
07838         return fpLEQ(self, other)
07839 
07840     def __ge__(self, other):
07841         return fpGEQ(self, other)
07842     
07843     def __gt__(self, other):
07844         return fpGT(self, other)
07845 
07846     def __ne__(self, other):
07847         return fpNEQ(self, other)
07848 
07849 
07850     def __add__(self, other):
07851         """Create the Z3 expression `self + other`.
07852         
07853         >>> x = FP('x', FPSort(8, 24))
07854         >>> y = FP('y', FPSort(8, 24))
07855         >>> x + y
07856         x + y
07857         >>> (x + y).sort()
07858         FPSort(8, 24)
07859         """
07860         a, b = z3._coerce_exprs(self, other)
07861         return fpAdd(_dflt_rm(), self, other)
07862 
07863     def __radd__(self, other):
07864         """Create the Z3 expression `other + self`.
07865         
07866         >>> x = FP('x', FPSort(8, 24))
07867         >>> 10 + x
07868         1.25*(2**3) + x
07869         """
07870         a, b = _coerce_exprs(self, other)
07871         return fpAdd(_dflt_rm(), other, self)
07872 
07873     def __sub__(self, other):
07874         """Create the Z3 expression `self - other`.
07875         
07876         >>> x = FP('x', FPSort(8, 24))
07877         >>> y = FP('y', FPSort(8, 24))
07878         >>> x - y
07879         x - y
07880         >>> (x - y).sort()
07881         FPSort(8, 24)
07882         """
07883         a, b = z3._coerce_exprs(self, other)
07884         return fpSub(_dflt_rm(), self, other)
07885 
07886     def __rsub__(self, other):
07887         """Create the Z3 expression `other - self`.
07888         
07889         >>> x = FP('x', FPSort(8, 24))
07890         >>> 10 - x
07891         1.25*(2**3) - x
07892         """
07893         a, b = _coerce_exprs(self, other)
07894         return fpSub(_dflt_rm(), other, self)
07895 
07896     def __mul__(self, other):
07897         """Create the Z3 expression `self * other`.
07898         
07899         >>> x = FP('x', FPSort(8, 24))
07900         >>> y = FP('y', FPSort(8, 24))
07901         >>> x * y
07902         x * y
07903         >>> (x * y).sort()
07904         FPSort(8, 24)
07905         >>> 10 * y
07906         1.25*(2**3) * y
07907         """
07908         a, b = z3._coerce_exprs(self, other)
07909         return fpMul(_dflt_rm(), self, other)
07910 
07911     def __rmul__(self, other):
07912         """Create the Z3 expression `other * self`.
07913         
07914         >>> x = FP('x', FPSort(8, 24))
07915         >>> y = FP('y', FPSort(8, 24))
07916         >>> x * y
07917         x * y
07918         >>> x * 10
07919         x * 1.25*(2**3)
07920         """
07921         a, b = _coerce_exprs(self, other)
07922         return fpMul(_dflt_rm(), other, self)
07923 
07924     def __pos__(self):
07925         """Create the Z3 expression `+self`."""
07926         return self
07927     
07928     def __neg__(self):
07929         """Create the Z3 expression `-self`."""
07930         return FPRef(fpNeg(self))
07931 
07932     def __truediv__(self, other):
07933         """Create the Z3 expression division `self / other`."""
07934         return self.__div__(other)
07935 
07936     def __rtruediv__(self, other):
07937         """Create the Z3 expression division `other / self`."""
07938         return self.__rdiv__(other)
07939 
07940     def __mod__(self, other):
07941         """Create the Z3 expression mod `self % other`."""
07942         return fpRem(self, other)
07943 
07944     def __rmod__(self, other):
07945         """Create the Z3 expression mod `other % self`."""
07946         return fpRem(other, self)
07947 
07948 class FPRMRef(ExprRef):
07949     """Floating-point rounding mode expressions"""
07950 
07951     def as_string(self):
07952         """Return a Z3 floating point expression as a Python string."""
07953         return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
07954 
07955   
07956 def RoundNearestTiesToEven(ctx=None):
07957     ctx = _get_ctx(ctx)
07958     return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
07959 
07960 def RNE (ctx=None):
07961     ctx = _get_ctx(ctx)
07962     return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
07963 
07964 def RoundNearestTiesToAway(ctx=None):
07965     ctx = _get_ctx(ctx)
07966     return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
07967 
07968 def RNA (ctx=None):
07969     ctx = _get_ctx(ctx)
07970     return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
07971 
07972 def RoundTowardPositive(ctx=None):
07973     ctx = _get_ctx(ctx)
07974     return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
07975 
07976 def RTP(ctx=None):
07977     ctx = _get_ctx(ctx)
07978     return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
07979 
07980 def RoundTowardNegative(ctx=None):
07981     ctx = _get_ctx(ctx)
07982     return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
07983 
07984 def RTN(ctx=None):
07985     ctx = _get_ctx(ctx)
07986     return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
07987 
07988 def RoundTowardZero(ctx=None):
07989     ctx = _get_ctx(ctx)
07990     return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
07991 
07992 def RTZ(ctx=None):
07993     ctx = _get_ctx(ctx)
07994     return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
07995 
07996 def is_fprm(a):
07997     """Return `True` if `a` is a Z3 floating-point rounding mode expression.
07998 
07999     >>> rm = RNE()
08000     >>> is_fprm(rm)
08001     True
08002     >>> rm = 1.0
08003     >>> is_fprm(rm)
08004     False
08005     """
08006     return isinstance(a, FPRMRef)
08007 
08008 def is_fprm_value(a):
08009     """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
08010     return is_fprm(a) and _is_numeral(a.ctx, a.ast)
08011     
08012 ### FP Numerals
08013 
08014 class FPNumRef(FPRef):
08015     def isNaN(self):
08016         return self.decl().kind() == Z3_OP_FPA_NAN
08017     
08018     def isInf(self):
08019         return self.decl().kind() == Z3_OP_FPA_PLUS_INF or self.decl().kind() == Z3_OP_FPA_MINUS_INF
08020 
08021     def isZero(self):
08022         return self.decl().kind() == Z3_OP_FPA_PLUS_ZERO or self.decl().kind() == Z3_OP_FPA_MINUS_ZERO
08023 
08024     def isNegative(self):
08025         k = self.decl().kind()
08026         return (self.num_args() == 0 and (k == Z3_OP_FPA_MINUS_INF or k == Z3_OP_FPA_MINUS_ZERO)) or (self.sign() == True)
08027 
08028     """
08029     The sign of the numeral
08030 
08031     >>> x = FPNumRef(+1.0, FPSort(8, 24))
08032     >>> x.sign()
08033     False
08034     >>> x = FPNumRef(-1.0, FPSort(8, 24))
08035     >>> x.sign()
08036     True
08037     """
08038     def sign(self):
08039         l = (ctypes.c_int)()
08040         if Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(l)) == False:
08041             raise Z3Exception("error retrieving the sign of a numeral.")
08042         return l.value != 0
08043     
08044     """
08045     The significand of the numeral
08046 
08047     >>> x = FPNumRef(2.5, FPSort(8, 24))
08048     1.25
08049     """
08050     def significand(self):
08051         return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
08052 
08053     """
08054     The exponent of the numeral
08055 
08056     >>> x = FPNumRef(2.5, FPSort(8, 24))
08057     >>> 
08058     1
08059     """
08060     def exponent(self):
08061         return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast())
08062 
08063     """
08064     The exponent of the numeral as a long
08065 
08066     >>> x = FPNumRef(2.5, FPSort(8, 24))
08067     1
08068     """
08069     def exponent_as_long(self):
08070         ptr = (ctypes.c_longlong * 1)()
08071         if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr):
08072             raise Z3Exception("error retrieving the exponent of a numeral.") 
08073         return ptr[0]
08074     
08075     """
08076     The string representation of the numeral
08077 
08078     >>> x = FPNumRef(20, FPSort(8, 24))
08079     1.25*(2**4)
08080     """
08081     def as_string(self):
08082         s = Z3_fpa_get_numeral_string(self.ctx.ref(), self.as_ast())
08083         return ("FPVal(%s, %s)" % (s, FPSortRef(self.sort()).as_string()))
08084 
08085 
08086 def _to_fpnum(num, ctx=None):
08087     if isinstance(num, FPNum):
08088         return num
08089     else:
08090         return FPNum(num, ctx)
08091 
08092 def is_fp(a):
08093     """Return `True` if `a` is a Z3 floating-point expression.
08094     
08095     >>> b = FP('b', FPSort(8, 24))
08096     >>> is_fp(b)
08097     True
08098     >>> is_fp(b + 1.0)
08099     True
08100     >>> is_fp(Int('x'))
08101     False
08102     """
08103     return isinstance(a, FPRef)
08104 
08105 def is_fp_value(a):
08106     """Return `True` if `a` is a Z3 floating-point numeral value.
08107 
08108     >>> b = FP('b', FPSort(8, 24))
08109     >>> is_fp_value(b)
08110     False
08111     >>> b = FPVal(1.0, FPSort(8, 24))
08112     >>> b
08113     1
08114     >>> is_fp_value(b)
08115     True
08116     """
08117     return is_fp(a) and _is_numeral(a.ctx, a.ast)
08118 
08119 def FPSort(ebits, sbits, ctx=None):
08120     """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
08121 
08122     >>> Single = FPSort(8, 24)
08123     >>> Double = FPSort(11, 53)
08124     >>> Single
08125     FPSort(8, 24)
08126     >>> x = Const('x', Single)
08127     >>> eq(x, FP('x', FPSort(8, 24)))
08128     True
08129     """
08130     ctx = z3._get_ctx(ctx)
08131     return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
08132 
08133 def _to_float_str(val):
08134     if isinstance(val, float):
08135         return str(val)
08136     elif isinstance(val, bool):
08137         if val:
08138             return "1.0"
08139         else:
08140             return "0.0"
08141     elif _is_int(val):
08142         return str(val)
08143     elif isinstance(val, str):
08144         return val
08145     if __debug__:
08146         _z3_assert(False, "Python value cannot be used as a double")
08147 
08148 def fpNaN(s):
08149     _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
08150     return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
08151 
08152 def fpPlusInfinity(s):
08153     _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
08154     return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
08155 
08156 def fpMinusInfinity(s):
08157     _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
08158     return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
08159 
08160 def fpInfinity(s, negative):
08161     _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
08162     _z3_assert(isinstance(negative, bool), "expected Boolean flag")
08163     return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
08164 
08165 def fpPlusZero(s):
08166     _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
08167     return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
08168 
08169 def fpMinusZero(s):
08170     _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
08171     return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
08172 
08173 def fpZero(s, negative):
08174     _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
08175     _z3_assert(isinstance(negative, bool), "expected Boolean flag")
08176     return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
08177 
08178 def FPVal(sig, exp=None, fps=None, ctx=None):
08179     """Return a floating-point value of value `val` and sort `fps`. If `ctx=None`, then the global context is used.
08180     
08181     >>> v = FPVal(20.0, FPSort(8, 24))
08182     >>> v
08183     1.25*(2**4)
08184     >>> print("0x%.8x" % v.exponent_as_long())
08185     0x00000004
08186     >>> v = FPVal(2.25, FPSort(8, 24))
08187     >>> v
08188     1.125*(2**1)
08189     >>> v = FPVal(-2.25, FPSort(8, 24))
08190     >>> v
08191     -1.125*(2**1)
08192     """
08193     ctx = _get_ctx(ctx)
08194     if is_fp_sort(exp):
08195         fps = exp
08196         exp = None
08197     elif fps == None:
08198         fps = _dflt_fps(ctx)
08199     _z3_assert(is_fp_sort(fps), "sort mismatch")
08200     if exp == None:
08201         exp = 0    
08202     val = _to_float_str(sig)
08203     val = val + 'p'
08204     val = val + _to_int_str(exp)
08205     return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
08206         
08207 def FP(name, fpsort, ctx=None):
08208     """Return a floating-point constant named `name`. 
08209     `fpsort` is the floating-point sort.
08210     If `ctx=None`, then the global context is used.
08211 
08212     >>> x  = FP('x', FPSort(8, 24))
08213     >>> is_fp(x)
08214     True
08215     >>> x.ebits()
08216     8
08217     >>> x.sort()
08218     FPSort(8, 24)
08219     >>> word = FPSort(8, 24)
08220     >>> x2 = FP('x', word)
08221     >>> eq(x, x2)
08222     True
08223     """ 
08224     if isinstance(fpsort, FPSortRef):
08225         ctx = fpsort.ctx
08226     else:
08227         ctx = _get_ctx(ctx)
08228     return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
08229 
08230 def FPs(names, fpsort, ctx=None):
08231     """Return an array of floating-point constants.
08232     
08233     >>> x, y, z = FPs('x y z', FPSort(8, 24))
08234     >>> x.sort()
08235     FPSort(8, 24)
08236     >>> x.sbits()
08237     24
08238     >>> x.ebits()
08239     8
08240     >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
08241     fpMul(RNE(), fpAdd(RNE(), x, y), z)
08242     """
08243     ctx = z3._get_ctx(ctx)
08244     if isinstance(names, str):
08245         names = names.split(" ")
08246     return [FP(name, fpsort, ctx) for name in names]
08247 
08248 def fpAbs(a):
08249     """Create a Z3 floating-point absolute value expression.
08250 
08251     >>> s = FPSort(8, 24)
08252     >>> rm = RNE()
08253     >>> x = FPVal(1.0, s)
08254     >>> fpAbs(x)
08255     fpAbs(1)
08256     >>> y = FPVal(-20.0, s)
08257     >>> y
08258     -1.25*(2**4)
08259     >>> fpAbs(y)
08260     fpAbs(-1.25*(2**4))
08261     >>> fpAbs(-1.25*(2**4))
08262     fpAbs(-1.25*(2**4))
08263     >>> fpAbs(x).sort()
08264     FPSort(8, 24)
08265     """
08266     ctx = None
08267     if not is_expr(a):
08268         ctx =_get_ctx(ctx)
08269         s = get_default_fp_sort(ctx)
08270         a = FPVal(a, s)
08271     else:
08272         ctx = a.ctx
08273     if __debug__:     
08274         _z3_assert(is_fp(a), "First argument must be Z3 floating-point expression")
08275     return FPRef(Z3_mk_fpa_abs(a.ctx_ref(), a.as_ast()), a.ctx)
08276 
08277 def fpNeg(a):
08278     """Create a Z3 floating-point addition expression.
08279 
08280     >>> s = FPSort(8, 24)
08281     >>> rm = RNE()
08282     >>> x = FP('x', s)
08283     >>> fpNeg(x)
08284     -x
08285     >>> fpNeg(x).sort()
08286     FPSort(8, 24)
08287     """
08288     ctx = None
08289     if not is_expr(a):
08290         ctx =_get_ctx(ctx)
08291         s = get_default_fp_sort(ctx)
08292         a = FPVal(a, s)
08293     else:
08294         ctx = a.ctx
08295     if __debug__:        
08296         _z3_assert(is_fp(a), "First argument must be Z3 floating-point expression")
08297     return FPRef(Z3_mk_fpa_neg(a.ctx_ref(), a.as_ast()), a.ctx)
08298 
08299 def fpAdd(rm, a, b):
08300     """Create a Z3 floating-point addition expression.
08301 
08302     >>> s = FPSort(8, 24)
08303     >>> rm = RNE()
08304     >>> x = FP('x', s)
08305     >>> y = FP('y', s)
08306     >>> fpAdd(rm, x, y)
08307     fpAdd(RNE(), x, y)
08308     >>> fpAdd(rm, x, y).sort()
08309     FPSort(8, 24)
08310     """
08311     if __debug__:
08312         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08313         _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
08314     a, b = _coerce_exprs(a, b)
08315     return FPRef(Z3_mk_fpa_add(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx)
08316 
08317 def fpSub(rm, a, b):
08318     """Create a Z3 floating-point subtraction expression.
08319 
08320     >>> s = FPSort(8, 24)
08321     >>> rm = RNE()
08322     >>> x = FP('x', s)
08323     >>> y = FP('y', s)
08324     >>> fpSub(rm, x, y)
08325     fpSub(RNE(), x, y)
08326     >>> fpSub(rm, x, y).sort()
08327     FPSort(8, 24)
08328     """
08329     if __debug__:
08330         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08331         _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
08332     a, b = _coerce_exprs(a, b)
08333     return FPRef(Z3_mk_fpa_sub(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx)
08334 
08335 def fpMul(rm, a, b):
08336     """Create a Z3 floating-point multiplication expression.
08337 
08338     >>> s = FPSort(8, 24)
08339     >>> rm = RNE()
08340     >>> x = FP('x', s)
08341     >>> y = FP('y', s)
08342     >>> fpMul(rm, x, y)
08343     fpMul(RNE(), x, y)
08344     >>> fpMul(rm, x, y).sort()
08345     FPSort(8, 24)
08346     """
08347     if __debug__:
08348         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08349         _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
08350     a, b = _coerce_exprs(a, b)
08351     return FPRef(Z3_mk_fpa_mul(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx)
08352 
08353 def fpDiv(rm, a, b):
08354     """Create a Z3 floating-point divison expression.
08355 
08356     >>> s = FPSort(8, 24)
08357     >>> rm = RNE()
08358     >>> x = FP('x', s)
08359     >>> y = FP('y', s)
08360     >>> fpDiv(rm, x, y)
08361     fpDiv(RNE(), x, y)
08362     >>> fpDiv(rm, x, y).sort()
08363     FPSort(8, 24)
08364     """
08365     if __debug__:
08366         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08367         _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
08368     a, b = _coerce_exprs(a, b)
08369     return FPRef(Z3_mk_fpa_div(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx)
08370 
08371 def fpRem(a, b):
08372     """Create a Z3 floating-point remainder expression.
08373 
08374     >>> s = FPSort(8, 24)
08375     >>> x = FP('x', s)
08376     >>> y = FP('y', s)
08377     >>> fpRem(x, y)
08378     fpRem(x, y)
08379     >>> fpRem(x, y).sort()
08380     FPSort(8, 24)
08381     """
08382     if __debug__:        
08383         _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
08384     a, b = _coerce_exprs(a, b)
08385     return FPRef(Z3_mk_fpa_rem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
08386 
08387 def fpMin(a, b):
08388     """Create a Z3 floating-point minimium expression.
08389 
08390     >>> s = FPSort(8, 24)
08391     >>> rm = RNE()
08392     >>> x = FP('x', s)
08393     >>> y = FP('y', s)
08394     >>> fpMin(x, y)
08395     fpMin(x, y)
08396     >>> fpMin(x, y).sort()
08397     FPSort(8, 24)
08398     """
08399     if __debug__:        
08400         _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
08401     a, b = _coerce_exprs(a, b)
08402     return FPRef(Z3_mk_fpa_min(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
08403 
08404 def fpMax(a, b):
08405     """Create a Z3 floating-point maximum expression.
08406 
08407     >>> s = FPSort(8, 24)
08408     >>> rm = RNE()
08409     >>> x = FP('x', s)
08410     >>> y = FP('y', s)
08411     >>> fpMax(x, y)
08412     fpMax(x, y)
08413     >>> fpMax(x, y).sort()
08414     FPSort(8, 24)
08415     """
08416     if __debug__:        
08417         _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
08418     a, b = _coerce_exprs(a, b)
08419     return FPRef(Z3_mk_fpa_max(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
08420 
08421 def fpFMA(rm, a, b, c):
08422     """Create a Z3 floating-point fused multiply-add expression.
08423     """
08424     if __debug__:
08425         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08426         _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")
08427     a, b, c = _coerce_expr_list([a, b, c])
08428     return FPRef(Z3_mk_fpa_fma(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), rm.ctx)    
08429 
08430 def fpSqrt(rm, a):
08431     """Create a Z3 floating-point square root expression.
08432     """
08433     ctx = None
08434     if not is_expr(a):
08435         ctx =_get_ctx(ctx)
08436         s = get_default_fp_sort(ctx)
08437         a = FPVal(a, s)
08438     else:
08439         ctx = a.ctx
08440     if __debug__:
08441         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08442         _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expressions")
08443     return FPRef(Z3_mk_fpa_sqrt(rm.ctx_ref(), rm.as_ast(), a.as_ast()), rm.ctx)    
08444 
08445 def fpRoundToIntegral(rm, a):
08446     """Create a Z3 floating-point roundToIntegral expression.
08447     """
08448     ctx = None
08449     if not is_expr(a):
08450         ctx =_get_ctx(ctx)
08451         s = get_default_fp_sort(ctx)
08452         a = FPVal(a, s)
08453     else:
08454         ctx = a.ctx
08455     if __debug__:
08456         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08457         _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expressions")
08458     return FPRef(Z3_mk_fpa_round_to_integral(rm.ctx_ref(), rm.as_ast(), a.as_ast()), rm.ctx)    
08459 
08460 def fpIsNaN(a):
08461     """Create a Z3 floating-point isNaN expression.
08462     """
08463     if __debug__:        
08464         _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions")
08465     return FPRef(Z3_mk_fpa_is_nan(a.ctx_ref(), a.as_ast()), a.ctx) 
08466 
08467 def fpIsInfinite(a):
08468     """Create a Z3 floating-point isNaN expression.
08469     """
08470     if __debug__:        
08471         _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions")
08472     return FPRef(Z3_mk_fpa_is_infinite(a.ctx_ref(), a.as_ast()), a.ctx) 
08473 
08474 def fpIsZero(a):
08475     """Create a Z3 floating-point isNaN expression.
08476     """
08477     if __debug__:        
08478         _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions")
08479     return FPRef(Z3_mk_fpa_is_zero(a.ctx_ref(), a.as_ast()), a.ctx) 
08480 
08481 def fpIsNormal(a):
08482     """Create a Z3 floating-point isNaN expression.
08483     """
08484     if __debug__:        
08485         _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions")
08486     return FPRef(Z3_mk_fpa_is_normal(a.ctx_ref(), a.as_ast()), a.ctx) 
08487 
08488 def fpIsSubnormal(a):
08489     """Create a Z3 floating-point isNaN expression.
08490     """
08491     if __debug__:        
08492         _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions")
08493     return FPRef(Z3_mk_fpa_is_subnormal(a.ctx_ref(), a.as_ast()), a.ctx) 
08494 
08495 def fpIsNegative(a):
08496     """Create a Z3 floating-point isNaN expression.
08497     """
08498     if __debug__:        
08499         _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions")
08500     return FPRef(Z3_mk_fpa_is_negative(a.ctx_ref(), a.as_ast()), a.ctx) 
08501 
08502 def fpIsPositive(a):
08503     """Create a Z3 floating-point isNaN expression.
08504     """
08505     if __debug__:        
08506         _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions")
08507     return FPRef(Z3_mk_fpa_is_positive(a.ctx_ref(), a.as_ast()), a.ctx) 
08508     
08509 def _check_fp_args(a, b):
08510     if __debug__:
08511         _z3_assert(is_fp(a) or is_fp(b), "At least one of the arguments must be a Z3 floating-point expression")
08512 
08513 def fpLT(a, b):
08514     """Create the Z3 floating-point expression `other <= self`.
08515     
08516     >>> x, y = FPs('x y', FPSort(8, 24))
08517     >>> fpLT(x, y)
08518     x < y
08519     >>> (x <= y).sexpr()
08520     '(fp.leq x y)'
08521     """
08522     _check_fp_args(a, b)
08523     a, b = _coerce_exprs(a, b)
08524     return BoolRef(Z3_mk_fpa_lt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
08525 
08526 def fpLEQ(a, b):
08527     """Create the Z3 floating-point expression `other <= self`.
08528     
08529     >>> x, y = FPs('x y', FPSort(8, 24))
08530     >>> fpLEQ(x, y)
08531     x <= y
08532     >>> (x <= y).sexpr()
08533     '(fp.leq x y)'
08534     """
08535     _check_fp_args(a, b)
08536     a, b = _coerce_exprs(a, b)
08537     return BoolRef(Z3_mk_fpa_leq(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
08538 
08539 def fpGT(a, b):
08540     """Create the Z3 floating-point expression `other <= self`.
08541     
08542     >>> x, y = FPs('x y', FPSort(8, 24))
08543     >>> fpGT(x, y)
08544     x > y
08545     >>> (x > y).sexpr()
08546     '(fp.gt x y)'
08547     """
08548     _check_fp_args(a, b)
08549     a, b = _coerce_exprs(a, b)
08550     return BoolRef(Z3_mk_fpa_gt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
08551 
08552 
08553 def fpGEQ(a, b):
08554     """Create the Z3 floating-point expression `other <= self`.
08555     
08556     >>> x, y = FPs('x y', FPSort(8, 24))
08557     >>> x + y
08558     x + y
08559     >>> fpGEQ(x, y)
08560     x >= y
08561     >>> (x >= y).sexpr()
08562     '(fp.geq x y)'
08563     """
08564     _check_fp_args(a, b)
08565     a, b = _coerce_exprs(a, b)
08566     return BoolRef(Z3_mk_fpa_geq(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
08567 
08568 def fpEQ(a, b):
08569     """Create the Z3 floating-point expression `other <= self`.
08570     
08571     >>> x, y = FPs('x y', FPSort(8, 24))
08572     >>> fpEQ(x, y)
08573     fpEQ(x, y)
08574     >>> fpEQ(x, y).sexpr()
08575     '(fp.eq x y)'
08576     """
08577     _check_fp_args(a, b)
08578     a, b = _coerce_exprs(a, b)
08579     return BoolRef(Z3_mk_fpa_eq(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
08580 
08581 def fpNEQ(a, b):
08582     """Create the Z3 floating-point expression `other <= self`.
08583     
08584     >>> x, y = FPs('x y', FPSort(8, 24))
08585     >>> fpNEQ(x, y)
08586     Not(fpEQ(x, y))
08587     >>> (x != y).sexpr()
08588     '(not (fp.eq x y))'
08589     """
08590     _check_fp_args(a, b)
08591     a, b = _coerce_exprs(a, b)
08592     return Not(BoolRef(Z3_mk_fpa_eq(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx), a.ctx)
08593 
08594 
08595 
08596 def fpFP(sgn, exp, sig):
08597     """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectorssgn, sig, and exp."""    
08598     _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
08599     _z3_assert(sgn.sort().size() == 1, "sort mismatch")
08600     return FPRef(Z3_mk_fpa_fp(sgn.ctx_ref(), sgn.ast, exp.ast, sig.ast), sgn.ctx)
08601     
08602 
08603 def fpToFP(a1, a2=None, a3=None):
08604     """Create a Z3 floating-point conversion expression from other terms."""
08605     if is_bv(a1) and is_fp_sort(a2):
08606         return FPRef(Z3_mk_fpa_to_fp_bv(a1.ctx_ref(), a1.ast, a2.ast), a1.ctx)
08607     elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
08608         return FPRef(Z3_mk_fpa_to_fp_float(a1.ctx_ref(), a1.ast, a2.ast, a3.ast), a1.ctx)
08609     elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
08610         return FPRef(Z3_mk_fpa_to_fp_real(a1.ctx_ref(), a1.ast, a2.ast, a3.ast), a1.ctx)
08611     elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
08612         return FPRef(Z3_mk_fpa_to_fp_signed(a1.ctx_ref(), a1.ast, a2.ast, a3.ast), a1.ctx)
08613     else:
08614         raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
08615 
08616 def fpToFPUnsigned(rm, x, s):
08617     """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
08618     if __debug__:
08619         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08620         _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
08621         _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
08622     return FPRef(Z3_mk_fpa_to_fp_unsigned(rm.ctx_ref(), rm.ast, x.ast, s.ast), rm.ctx)
08623 
08624 def fpToSBV(rm, x, s):
08625     """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
08626 
08627     >>> x = FP('x', FPSort(8, 24))
08628     >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
08629     >>> print is_fp(x)
08630     True
08631     >>> print is_bv(y)
08632     True
08633     >>> print is_fp(y)
08634     False
08635     >>> print is_bv(x)
08636     False
08637     """
08638     if __debug__:
08639         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08640         _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
08641         _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
08642     return BitVecRef(Z3_mk_fpa_to_sbv(rm.ctx_ref(), rm.ast, x.ast, s.size()), rm.ctx)
08643 
08644 def fpToUBV(rm, x, s):
08645     """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
08646 
08647     >>> x = FP('x', FPSort(8, 24))
08648     >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
08649     >>> print is_fp(x)
08650     True
08651     >>> print is_bv(y)
08652     True
08653     >>> print is_fp(y)
08654     False
08655     >>> print is_bv(x)
08656     False
08657     """
08658     if __debug__:
08659         _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
08660         _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
08661         _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
08662     return BitVecRef(Z3_mk_fpa_to_ubv(rm.ctx_ref(), rm.ast, x.ast, s.size()), rm.ctx)
08663 
08664 def fpToReal(x):
08665     """Create a Z3 floating-point conversion expression, from floating-point expression to real.
08666 
08667     >>> x = FP('x', FPSort(8, 24))
08668     >>> y = fpToReal(x)
08669     >>> print is_fp(x)
08670     True
08671     >>> print is_real(y)
08672     True
08673     >>> print is_fp(y)
08674     False
08675     >>> print is_real(x)
08676     False
08677     """
08678     if __debug__:
08679         _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
08680     return ArithRef(Z3_mk_fpa_to_real(x.ctx_ref(), x.ast), x.ctx)
08681 
08682 def fpToIEEEBV(x):
08683     """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
08684     
08685     The size of the resulting bit-vector is automatically determined. 
08686     
08687     Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion 
08688     knows only one NaN and it will always produce the same bit-vector represenatation of 
08689     that NaN.
08690 
08691     >>> x = FP('x', FPSort(8, 24))
08692     >>> y = fpToIEEEBV(x)
08693     >>> print is_fp(x)
08694     True
08695     >>> print is_bv(y)
08696     True
08697     >>> print is_fp(y)
08698     False
08699     >>> print is_bv(x)
08700     False
08701     """
08702     if __debug__:
08703         _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
08704     return BitVecRef(Z3_mk_fpa_to_ieee_bv(x.ctx_ref(), x.ast), x.ctx)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines