9 """Z3 is a high performance theorem prover developed at Microsoft Research. Z3 is used in many applications such as: software/hardware verification and testing, constraint solving, analysis of hybrid systems, security, biology (in silico analysis), and geometrical problems.
11 Several online tutorials for Z3Py are available at:
12 http://rise4fun.com/Z3Py/tutorial/guide
14 Please send feedback, comments and/or corrections to leonardo@microsoft.com. Your comments are very valuable.
34 ... # the expression x + y is type incorrect
36 ... except Z3Exception as ex:
37 ... print "failed:", ex
38 failed: 'sort mismatch'
42 from z3consts
import *
43 from z3printer
import *
53 major = ctypes.c_uint(0)
54 minor = ctypes.c_uint(0)
55 build = ctypes.c_uint(0)
56 rev = ctypes.c_uint(0)
58 return "%s.%s.%s" % (major.value, minor.value, build.value)
61 major = ctypes.c_uint(0)
62 minor = ctypes.c_uint(0)
63 build = ctypes.c_uint(0)
64 rev = ctypes.c_uint(0)
66 return (major.value, minor.value, build.value, rev.value)
70 def _z3_assert(cond, msg):
72 raise Z3Exception(msg)
75 """Log interaction to a file. This function must be invoked immediately after init(). """
79 """Append user-defined string to interaction log. """
83 """Convert an integer or string into a Z3 symbol."""
84 if isinstance(s, int):
89 def _symbol2py(ctx, s):
90 """Convert a Z3 symbol back into a Python object. """
96 _error_handler_fptr = ctypes.CFUNCTYPE(
None, ctypes.c_void_p, ctypes.c_uint)
102 if len(args) == 1
and (isinstance(args[0], tuple)
or isinstance(args[0], list)):
109 def _Z3python_error_handler_core(c, e):
116 def _to_param_value(val):
117 if isinstance(val, bool):
126 """A Context manages all other Z3 objects, global configuration options, etc.
128 Z3Py uses a default global context. For most applications this is sufficient.
129 An application may use multiple Z3 contexts. Objects created in one context
130 cannot be used in another one. However, several objects may be "translated" from
131 one context to another. It is not safe to access Z3 objects from multiple threads.
132 The only exception is the method `interrupt()` that can be used to interrupt() a long
134 The initialization method receives global configuration options for the new context.
138 _z3_assert(len(args) % 2 == 0,
"Argument list must have an even number of elements.")
140 for key, value
in kws.iteritems():
152 lib().Z3_set_error_handler.restype =
None
153 lib().Z3_set_error_handler.argtypes = [ContextObj, _error_handler_fptr]
158 self.lib.Z3_del_context(self.
ctx)
161 """Return a reference to the actual C pointer to the Z3 context."""
165 """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
167 This method can be invoked from a thread different from the one executing the
168 interruptable procedure.
172 def set(self, *args, **kws):
173 """Set global configuration options.
175 Z3 command line options can be set using this method.
176 The option names can be specified in different ways:
179 >>> ctx.set('WELL_SORTED_CHECK', True)
180 >>> ctx.set(':well-sorted-check', True)
181 >>> ctx.set(well_sorted_check=True)
184 _z3_assert(len(args) % 2 == 0,
"Argument list must have an even number of elements.")
185 for key, value
in kws.iteritems():
198 """Return a reference to the global Z3 context.
201 >>> x.ctx == main_ctx()
206 >>> x2 = Real('x', c)
213 if _main_ctx ==
None:
224 """Update parameters of the global context `main_ctx()`, and global configuration options of Z3Py. See `Context.set()`.
226 >>> set_option(precision=10)
229 for k, v
in kws.iteritems():
230 if not set_pp_option(k, v):
242 """Superclass for all Z3 objects that have support for pretty printing."""
247 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
257 return obj_to_string(self)
260 return obj_to_string(self)
263 """Return an string representing the AST node in s-expression notation.
266 >>> ((x + 1)*x).sexpr()
272 """Return a pointer to the corresponding C Z3_ast object."""
276 """Return a reference to the C context where this AST node is stored."""
277 return self.ctx.ref()
280 """Return `True` if `self` and `other` are structurally identical.
287 >>> n1 = simplify(n1)
288 >>> n2 = simplify(n2)
293 _z3_assert(
is_ast(other),
"Z3 AST expected")
297 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
303 >>> # Nodes in different contexts can't be mixed.
304 >>> # However, we can translate nodes from one context to another.
305 >>> x.translate(c2) + y
309 _z3_assert(isinstance(target, Context),
"argument must be a Z3 context")
313 """Return a hashcode for the `self`.
315 >>> n1 = simplify(Int('x') + 1)
316 >>> n2 = simplify(2 + Int('x') - 1)
317 >>> n1.hash() == n2.hash()
323 """Return `True` if `a` is an AST node.
327 >>> is_ast(IntVal(10))
331 >>> is_ast(BoolSort())
333 >>> is_ast(Function('f', IntSort(), IntSort()))
340 return isinstance(a, AstRef)
343 """Return `True` if `a` and `b` are structurally identical AST nodes.
353 >>> eq(simplify(x + 1), simplify(1 + x))
360 def _ast_kind(ctx, a):
365 def _ctx_from_ast_arg_list(args, default_ctx=None):
373 _z3_assert(ctx == a.ctx,
"Context mismatch")
378 def _ctx_from_ast_args(*args):
379 return _ctx_from_ast_arg_list(args)
381 def _to_func_decl_array(args):
383 _args = (FuncDecl * sz)()
385 _args[i] = args[i].as_func_decl()
388 def _to_ast_array(args):
392 _args[i] = args[i].as_ast()
395 def _to_ref_array(ref, args):
399 _args[i] = args[i].as_ast()
402 def _to_ast_ref(a, ctx):
403 k = _ast_kind(ctx, a)
405 return _to_sort_ref(a, ctx)
406 elif k == Z3_FUNC_DECL_AST:
407 return _to_func_decl_ref(a, ctx)
409 return _to_expr_ref(a, ctx)
417 def _sort_kind(ctx, s):
421 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
426 """Return the Z3 internal kind of a sort. This method can be used to test if `self` is one of the Z3 builtin sorts.
429 >>> b.kind() == Z3_BOOL_SORT
431 >>> b.kind() == Z3_INT_SORT
433 >>> A = ArraySort(IntSort(), IntSort())
434 >>> A.kind() == Z3_ARRAY_SORT
436 >>> A.kind() == Z3_INT_SORT
439 return _sort_kind(self.
ctx, self.
ast)
442 """Return `True` if `self` is a subsort of `other`.
444 >>> IntSort().subsort(RealSort())
450 """Try to cast `val` as an element of sort `self`.
452 This method is used in Z3Py to convert Python objects such as integers,
453 floats, longs and strings into Z3 expressions.
456 >>> RealSort().cast(x)
460 _z3_assert(
is_expr(val),
"Z3 expression expected")
461 _z3_assert(self.
eq(val.sort()),
"Sort mismatch")
465 """Return the name (string) of sort `self`.
467 >>> BoolSort().name()
469 >>> ArraySort(IntSort(), IntSort()).name()
475 """Return `True` if `self` and `other` are the same Z3 sort.
478 >>> p.sort() == BoolSort()
480 >>> p.sort() == IntSort()
488 """Return `True` if `self` and `other` are not the same Z3 sort.
491 >>> p.sort() != BoolSort()
493 >>> p.sort() != IntSort()
499 """Return `True` if `s` is a Z3 sort.
501 >>> is_sort(IntSort())
503 >>> is_sort(Int('x'))
505 >>> is_expr(Int('x'))
508 return isinstance(s, SortRef)
510 def _to_sort_ref(s, ctx):
512 _z3_assert(isinstance(s, Sort),
"Z3 Sort expected")
513 k = _sort_kind(ctx, s)
514 if k == Z3_BOOL_SORT:
516 elif k == Z3_INT_SORT
or k == Z3_REAL_SORT:
518 elif k == Z3_BV_SORT:
520 elif k == Z3_ARRAY_SORT:
522 elif k == Z3_DATATYPE_SORT:
527 return _to_sort_ref(
Z3_get_sort(ctx.ref(), a), ctx)
530 """Create a new uninterpred sort named `name`.
532 If `ctx=None`, then the new sort is declared in the global Z3Py context.
534 >>> A = DeclareSort('A')
535 >>> a = Const('a', A)
536 >>> b = Const('b', A)
554 """Function declaration. Every constant and function have an associated declaration.
556 The declaration assigns a name, a sort (i.e., type), and for function
557 the sort (i.e., type) of each of its arguments. Note that, in Z3,
558 a constant is a function with 0 arguments.
564 """Return the name of the function declaration `self`.
566 >>> f = Function('f', IntSort(), IntSort())
569 >>> isinstance(f.name(), str)
575 """Return the number of arguments of a function declaration. If `self` is a constant, then `self.arity()` is 0.
577 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
584 """Return the sort of the argument `i` of a function declaration. This method assumes that `0 <= i < self.arity()`.
586 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
593 _z3_assert(i < self.
arity(),
"Index out of bounds")
597 """Return the sort of the range of a function declaration. For constants, this is the sort of the constant.
599 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
606 """Return the internal kind of a function declaration. It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
609 >>> d = (x + 1).decl()
610 >>> d.kind() == Z3_OP_ADD
612 >>> d.kind() == Z3_OP_MUL
618 """Create a Z3 application expression using the function `self`, and the given arguments.
620 The arguments must be Z3 expressions. This method assumes that
621 the sorts of the elements in `args` match the sorts of the
622 domain. Limited coersion is supported. For example, if
623 args[0] is a Python integer, and the function expects a Z3
624 integer, then the argument is automatically converted into a
627 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
635 args = _get_args(args)
638 _z3_assert(num == self.arity(),
"Incorrect number of arguments")
639 _args = (Ast * num)()
644 tmp = self.domain(i).cast(args[i])
646 _args[i] = tmp.as_ast()
647 return _to_expr_ref(
Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
650 """Return `True` if `a` is a Z3 function declaration.
652 >>> f = Function('f', IntSort(), IntSort())
659 return isinstance(a, FuncDeclRef)
662 """Create a new Z3 uninterpreted function with the given sorts.
664 >>> f = Function('f', IntSort(), IntSort())
670 _z3_assert(len(sig) > 0,
"At least two arguments expected")
674 _z3_assert(
is_sort(rng),
"Z3 sort expected")
675 dom = (Sort * arity)()
676 for i
in range(arity):
678 _z3_assert(
is_sort(sig[i]),
"Z3 sort expected")
683 def _to_func_decl_ref(a, ctx):
693 """Constraints, formulas and terms are expressions in Z3.
695 Expressions are ASTs. Every expression has a sort.
696 There are three main kinds of expressions:
697 function applications, quantifiers and bounded variables.
698 A constant is a function application with 0 arguments.
699 For quantifier free problems, all expressions are
700 function applications.
706 """Return the sort of expression `self`.
718 """Shorthand for `self.sort().kind()`.
720 >>> a = Array('a', IntSort(), IntSort())
721 >>> a.sort_kind() == Z3_ARRAY_SORT
723 >>> a.sort_kind() == Z3_INT_SORT
726 return self.
sort().kind()
729 """Return a Z3 expression that represents the constraint `self == other`.
731 If `other` is `None`, then this method simply returns `False`.
742 a, b = _coerce_exprs(self, other)
746 """Return a Z3 expression that represents the constraint `self != other`.
748 If `other` is `None`, then this method simply returns `True`.
759 a, b = _coerce_exprs(self, other)
760 _args, sz = _to_ast_array((a, b))
764 """Return the Z3 function declaration associated with a Z3 application.
766 >>> f = Function('f', IntSort(), IntSort())
775 _z3_assert(
is_app(self),
"Z3 application expected")
779 """Return the number of arguments of a Z3 application.
783 >>> (a + b).num_args()
785 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
791 _z3_assert(
is_app(self),
"Z3 application expected")
795 """Return argument `idx` of the application `self`.
797 This method assumes that `self` is a function application with at least `idx+1` arguments.
801 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
811 _z3_assert(
is_app(self),
"Z3 application expected")
812 _z3_assert(idx < self.
num_args(),
"Invalid argument index")
816 """Return a list containing the children of the given expression
820 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
826 return [self.
arg(i)
for i
in range(self.
num_args())]
830 def _to_expr_ref(a, ctx):
831 if isinstance(a, Pattern):
835 if k == Z3_QUANTIFIER_AST:
838 if sk == Z3_BOOL_SORT:
840 if sk == Z3_INT_SORT:
841 if k == Z3_NUMERAL_AST:
844 if sk == Z3_REAL_SORT:
845 if k == Z3_NUMERAL_AST:
847 if _is_algebraic(ctx, a):
851 if k == Z3_NUMERAL_AST:
855 if sk == Z3_ARRAY_SORT:
857 if sk == Z3_DATATYPE_SORT:
861 def _coerce_expr_merge(s, a):
874 _z3_assert(
False,
"sort mismatch")
878 def _coerce_exprs(a, b, ctx=None):
883 s = _coerce_expr_merge(s, a)
884 s = _coerce_expr_merge(s, b)
889 def _coerce_expr_list(alist, ctx=None):
890 if filter(is_expr, alist) == []:
891 alist = map(
lambda a: _py2expr(a, ctx), alist)
892 s = reduce(_coerce_expr_merge, alist,
None)
893 return map(
lambda a: s.cast(a), alist)
896 """Return `True` if `a` is a Z3 expression.
903 >>> is_expr(IntSort())
907 >>> is_expr(IntVal(1))
910 >>> is_expr(ForAll(x, x >= 0))
913 return isinstance(a, ExprRef)
916 """Return `True` if `a` is a Z3 function application.
918 Note that, constants are function applications with 0 arguments.
925 >>> is_app(IntSort())
929 >>> is_app(IntVal(1))
932 >>> is_app(ForAll(x, x >= 0))
935 if not isinstance(a, ExprRef):
937 k = _ast_kind(a.ctx, a)
938 return k == Z3_NUMERAL_AST
or k == Z3_APP_AST
941 """Return `True` if `a` is Z3 constant/variable expression.
950 >>> is_const(IntVal(1))
953 >>> is_const(ForAll(x, x >= 0))
956 return is_app(a)
and a.num_args() == 0
959 """Return `True` if `a` is variable.
961 Z3 uses de-Bruijn indices for representing bound variables in
969 >>> f = Function('f', IntSort(), IntSort())
970 >>> # Z3 replaces x with bound variables when ForAll is executed.
971 >>> q = ForAll(x, f(x) == x)
980 return is_expr(a)
and _ast_kind(a.ctx, a) == Z3_VAR_AST
983 """Return the de-Bruijn index of the Z3 bounded variable `a`.
991 >>> f = Function('f', IntSort(), IntSort(), IntSort())
992 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
993 >>> q = ForAll([x, y], f(x, y) == x + y)
995 f(Var(1), Var(0)) == Var(1) + Var(0)
999 >>> v1 = b.arg(0).arg(0)
1000 >>> v2 = b.arg(0).arg(1)
1005 >>> get_var_index(v1)
1007 >>> get_var_index(v2)
1011 _z3_assert(
is_var(a),
"Z3 bound variable expected")
1015 """Return `True` if `a` is an application of the given kind `k`.
1019 >>> is_app_of(n, Z3_OP_ADD)
1021 >>> is_app_of(n, Z3_OP_MUL)
1024 return is_app(a)
and a.decl().kind() == k
1026 def If(a, b, c, ctx=None):
1027 """Create a Z3 if-then-else expression.
1031 >>> max = If(x > y, x, y)
1037 if isinstance(a, Probe)
or isinstance(b, Tactic)
or isinstance(c, Tactic):
1038 return Cond(a, b, c, ctx)
1040 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1043 b, c = _coerce_exprs(b, c, ctx)
1045 _z3_assert(a.ctx == b.ctx,
"Context mismatch")
1046 return _to_expr_ref(
Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1049 """Create a Z3 distinct expression.
1056 >>> Distinct(x, y, z)
1058 >>> simplify(Distinct(x, y, z))
1060 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1061 And(Not(x == y), Not(x == z), Not(y == z))
1063 args = _get_args(args)
1064 ctx = _ctx_from_ast_arg_list(args)
1066 _z3_assert(ctx !=
None,
"At least one of the arguments must be a Z3 expression")
1067 args = _coerce_expr_list(args, ctx)
1068 _args, sz = _to_ast_array(args)
1071 def _mk_bin(f, a, b):
1074 _z3_assert(a.ctx == b.ctx,
"Context mismatch")
1075 args[0] = a.as_ast()
1076 args[1] = b.as_ast()
1077 return f(a.ctx.ref(), 2, args)
1080 """Create a constant of the given sort.
1082 >>> Const('x', IntSort())
1086 _z3_assert(isinstance(sort, SortRef),
"Z3 sort expected")
1091 """Create a several constants of the given sort.
1093 `names` is a string containing the names of all constants to be created.
1094 Blank spaces separate the names of different constants.
1096 >>> x, y, z = Consts('x y z', IntSort())
1100 if isinstance(names, str):
1101 names = names.split(
" ")
1102 return [
Const(name, sort)
for name
in names]
1105 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1107 >>> Var(0, IntSort())
1109 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1113 _z3_assert(
is_sort(s),
"Z3 sort expected")
1114 return _to_expr_ref(
Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1125 """Try to cast `val` as a Boolean.
1127 >>> x = BoolSort().cast(True)
1137 if isinstance(val, bool):
1140 _z3_assert(
is_expr(val),
"True, False or Z3 Boolean expression expected")
1141 _z3_assert(self.
eq(val.sort()),
"Value cannot be converted into a Z3 Boolean value")
1145 """All Boolean expressions are instances of this class."""
1150 """Return `True` if `a` is a Z3 Boolean expression.
1156 >>> is_bool(And(p, q))
1164 return isinstance(a, BoolRef)
1167 """Return `True` if `a` is the Z3 true expression.
1172 >>> is_true(simplify(p == p))
1177 >>> # True is a Python Boolean expression
1184 """Return `True` if `a` is the Z3 false expression.
1191 >>> is_false(BoolVal(False))
1197 """Return `True` if `a` is a Z3 and expression.
1199 >>> p, q = Bools('p q')
1200 >>> is_and(And(p, q))
1202 >>> is_and(Or(p, q))
1208 """Return `True` if `a` is a Z3 or expression.
1210 >>> p, q = Bools('p q')
1213 >>> is_or(And(p, q))
1219 """Return `True` if `a` is a Z3 not expression.
1230 """Return `True` if `a` is a Z3 equality expression.
1232 >>> x, y = Ints('x y')
1239 """Return `True` if `a` is a Z3 distinct expression.
1241 >>> x, y, z = Ints('x y z')
1242 >>> is_distinct(x == y)
1244 >>> is_distinct(Distinct(x, y, z))
1250 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1254 >>> p = Const('p', BoolSort())
1257 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1264 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1266 def BoolVal(val, ctx=None):
1267 """Return the Boolean value `
True`
or `
False`. If `ctx=
None`, then the
global context
is used.
1280 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1282 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1284 def Bool(name, ctx=None):
1285 """Return a Boolean constant named `name`. If `ctx=
None`, then the
global context
is used.
1293 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1295 def Bools(names, ctx=None):
1296 """Return a tuple of Boolean constants.
1298 `names`
is a single string containing all names separated by blank spaces.
1299 If `ctx=
None`, then the
global context
is used.
1301 >>> p, q, r =
Bools(
'p q r')
1302 >>>
And(p,
Or(q, r))
1306 if isinstance(names, str):
1307 names = names.split(" ")
1308 return [Bool(name, ctx) for name in names]
1310 def BoolVector(prefix, sz, ctx=None):
1311 """Return a list of Boolean constants of size `sz`.
1313 The constants are named using the given prefix.
1314 If `ctx=
None`, then the
global context
is used.
1320 And(p__0, p__1, p__2)
1322 return [ Bool('%s__%s' % (prefix, i)) for i in range(sz) ]
1324 def FreshBool(prefix='b', ctx=None):
1325 """Return a fresh Bolean constant
in the given context using the given prefix.
1327 If `ctx=
None`, then the
global context
is used.
1335 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1337 def Implies(a, b, ctx=None):
1338 """Create a Z3 implies expression.
1340 >>> p, q =
Bools(
'p q')
1346 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1350 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1352 def Xor(a, b, ctx=None):
1353 """Create a Z3 Xor expression.
1355 >>> p, q =
Bools(
'p q')
1361 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1365 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1367 def Not(a, ctx=None):
1368 """Create a Z3
not expression
or probe.
1376 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1378 # Not is also used to build probes
1379 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1383 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1385 def _has_probe(args):
1386 """Return `
True`
if one of the elements of the given collection
is a Z3 probe.
"""
1393 """Create a Z3
and-expression
or and-probe.
1395 >>> p, q, r =
Bools(
'p q r')
1400 And(p__0, p__1, p__2, p__3, p__4)
1402 args = _get_args(args)
1403 ctx = _ctx_from_ast_arg_list(args)
1405 _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
1406 if _has_probe(args):
1407 return _probe_and(args, ctx)
1409 args = _coerce_expr_list(args, ctx)
1410 _args, sz = _to_ast_array(args)
1411 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
1414 """Create a Z3
or-expression
or or-probe.
1416 >>> p, q, r =
Bools(
'p q r')
1421 Or(p__0, p__1, p__2, p__3, p__4)
1423 args = _get_args(args)
1424 ctx = _ctx_from_ast_arg_list(args)
1426 _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
1427 if _has_probe(args):
1428 return _probe_or(args, ctx)
1430 args = _coerce_expr_list(args, ctx)
1431 _args, sz = _to_ast_array(args)
1432 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
1434 #########################################
1438 #########################################
1440 class PatternRef(ExprRef):
1441 """Patterns are hints
for quantifier instantiation.
1443 See http://rise4fun.com/Z3Py/tutorial/advanced
for more details.
1446 return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
1449 """Return `
True`
if `a`
is a Z3 pattern (hint
for quantifier instantiation.
1451 See http://rise4fun.com/Z3Py/tutorial/advanced
for more details.
1455 >>> q =
ForAll(x, f(x) == 0, patterns = [ f(x) ])
1458 >>> q.num_patterns()
1465 return isinstance(a, PatternRef)
1467 def MultiPattern(*args):
1468 """Create a Z3 multi-pattern using the given expressions `*args`
1470 See http://rise4fun.com/Z3Py/tutorial/advanced
for more details.
1478 >>> q.num_patterns()
1486 _z3_assert(len(args) > 0, "At least one argument expected")
1487 _z3_assert(all(map(is_expr, args)), "Z3 expressions expected")
1489 args, sz = _to_ast_array(args)
1490 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
1492 def _to_pattern(arg):
1496 return MultiPattern(arg)
1498 #########################################
1502 #########################################
1504 class QuantifierRef(BoolRef):
1505 """Universally
and Existentially quantified formulas.
"""
1511 """Return the Boolean sort.
"""
1512 return BoolSort(self.ctx)
1514 def is_forall(self):
1515 """Return `
True`
if `self`
is a universal quantifier.
1519 >>> q =
ForAll(x, f(x) == 0)
1522 >>> q =
Exists(x, f(x) != 0)
1526 return Z3_is_quantifier_forall(self.ctx_ref(), self.ast)
1529 """Return the weight annotation of `self`.
1533 >>> q =
ForAll(x, f(x) == 0)
1536 >>> q =
ForAll(x, f(x) == 0, weight=10)
1540 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
1542 def num_patterns(self):
1543 """Return the number of patterns (i.e., quantifier instantiation hints)
in `self`.
1548 >>> q =
ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
1549 >>> q.num_patterns()
1552 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
1554 def pattern(self, idx):
1555 """Return a pattern (i.e., quantifier instantiation hints)
in `self`.
1560 >>> q =
ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
1561 >>> q.num_patterns()
1569 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
1570 return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
1572 def num_no_patterns(self):
1573 """Return the number of no-patterns.
"""
1574 return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
1576 def no_pattern(self, idx):
1577 """Return a no-pattern.
"""
1579 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
1580 return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
1583 """Return the expression being quantified.
1587 >>> q =
ForAll(x, f(x) == 0)
1591 return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
1594 """Return the number of variables bounded by this quantifier.
1599 >>> q =
ForAll([x, y], f(x, y) >= x)
1603 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
1605 def var_name(self, idx):
1606 """Return a string representing a name used when displaying the quantifier.
1611 >>> q =
ForAll([x, y], f(x, y) >= x)
1618 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
1619 return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
1621 def var_sort(self, idx):
1622 """Return the sort of a bound variable.
1627 >>> q =
ForAll([x, y], f(x, y) >= x)
1634 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
1635 return SortRef(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
1638 """Return a list containing a single element self.
body()
1642 >>> q =
ForAll(x, f(x) == 0)
1646 return [ self.body() ]
1648 def is_quantifier(a):
1649 """Return `
True`
if `a`
is a Z3 quantifier.
1653 >>> q =
ForAll(x, f(x) == 0)
1659 return isinstance(a, QuantifierRef)
1661 def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
1663 _z3_assert(is_bool(body), "Z3 expression expected")
1664 _z3_assert(is_const(vs) or (len(vs) > 0 and all(map(is_const, vs))), "Invalid bounded variable(s)")
1665 _z3_assert(all(map(lambda a: is_pattern(a) or is_expr(a), patterns)), "Z3 patterns expected")
1666 _z3_assert(all(map(is_expr, no_patterns)), "no patterns are Z3 expressions")
1671 _vs = (Ast * num_vars)()
1672 for i in range(num_vars):
1673 ## TODO: Check if is constant
1674 _vs[i] = vs[i].as_ast()
1675 patterns = map(_to_pattern, patterns)
1676 num_pats = len(patterns)
1677 _pats = (Pattern * num_pats)()
1678 for i in range(num_pats):
1679 _pats[i] = patterns[i].ast
1680 _no_pats, num_no_pats = _to_ast_array(no_patterns)
1681 qid = to_symbol(qid, ctx)
1682 skid = to_symbol(skid, ctx)
1683 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
1686 num_no_pats, _no_pats,
1687 body.as_ast()), ctx)
1689 def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
1690 """Create a Z3 forall formula.
1692 The parameters `weight`, `qif`, `skid`, `patterns`
and `no_patterns` are optional annotations.
1694 See http://rise4fun.com/Z3Py/tutorial/advanced
for more details.
1699 >>>
ForAll([x, y], f(x, y) >= x)
1700 ForAll([x, y], f(x, y) >= x)
1701 >>>
ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
1702 ForAll([x, y], f(x, y) >= x)
1703 >>>
ForAll([x, y], f(x, y) >= x, weight=10)
1704 ForAll([x, y], f(x, y) >= x)
1706 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
1708 def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
1709 """Create a Z3 exists formula.
1711 The parameters `weight`, `qif`, `skid`, `patterns`
and `no_patterns` are optional annotations.
1713 See http://rise4fun.com/Z3Py/tutorial/advanced
for more details.
1718 >>> q =
Exists([x, y], f(x, y) >= x, skid=
"foo")
1720 Exists([x, y], f(x, y) >= x)
1722 [[f(x!foo!1, y!foo!0) >= x!foo!1]]
1723 >>>
Tactic(
'nnf')(q).as_expr()
1724 f(x!foo!3, y!foo!2) >= x!foo!3
1726 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
1728 #########################################
1732 #########################################
1734 class ArithSortRef(SortRef):
1735 """Real
and Integer sorts.
"""
1738 """Return `
True`
if `self`
is the integer sort.
1749 return self.kind() == Z3_REAL_SORT
1752 """Return `
True`
if `self`
is the real sort.
1763 return self.kind() == Z3_INT_SORT
1765 def subsort(self, other):
1766 """Return `
True`
if `self`
is a subsort of `other`.
"""
1767 return self.is_int() and is_arith_sort(other) and other.is_real()
1769 def cast(self, val):
1770 """Try to cast `val`
as an Integer
or Real.
1785 _z3_assert(self.ctx == val.ctx, "Context mismatch")
1789 if val_s.is_int() and self.is_real():
1792 _z3_assert(False, "Z3 Integer/Real expression expected" )
1795 return IntVal(val, self.ctx)
1797 return RealVal(val, self.ctx)
1799 _z3_assert(False, "int, long, float, string (numeral), or Z3 Integer/Real expression expected")
1801 def is_arith_sort(s):
1802 """Return `
True`
if s
is an arithmetical sort (type).
1810 >>> n =
Int(
'x') + 1
1814 return isinstance(s, ArithSortRef)
1816 class ArithRef(ExprRef):
1817 """Integer
and Real expressions.
"""
1820 """Return the sort (type) of the arithmetical expression `self`.
1827 return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
1830 """Return `
True`
if `self`
is an integer expression.
1841 return self.sort().is_int()
1844 """Return `
True`
if `self`
is an real expression.
1852 return self.sort().is_real()
1854 def __add__(self, other):
1855 """Create the Z3 expression `self + other`.
1864 a, b = _coerce_exprs(self, other)
1865 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctx)
1867 def __radd__(self, other):
1868 """Create the Z3 expression `other + self`.
1874 a, b = _coerce_exprs(self, other)
1875 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctx)
1877 def __mul__(self, other):
1878 """Create the Z3 expression `self * other`.
1887 a, b = _coerce_exprs(self, other)
1888 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
1890 def __rmul__(self, other):
1891 """Create the Z3 expression `other * self`.
1897 a, b = _coerce_exprs(self, other)
1898 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctx)
1900 def __sub__(self, other):
1901 """Create the Z3 expression `self - other`.
1910 a, b = _coerce_exprs(self, other)
1911 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctx)
1913 def __rsub__(self, other):
1914 """Create the Z3 expression `other - self`.
1920 a, b = _coerce_exprs(self, other)
1921 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctx)
1923 def __pow__(self, other):
1924 """Create the Z3 expression `self**other` (**
is the power operator).
1934 a, b = _coerce_exprs(self, other)
1935 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
1937 def __rpow__(self, other):
1938 """Create the Z3 expression `other**self` (**
is the power operator).
1948 a, b = _coerce_exprs(self, other)
1949 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
1951 def __div__(self, other):
1952 """Create the Z3 expression `other/self`.
1971 a, b = _coerce_exprs(self, other)
1972 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
1974 def __truediv__(self, other):
1975 """Create the Z3 expression `other/self`.
"""
1978 def __rdiv__(self, other):
1979 """Create the Z3 expression `other/self`.
1992 a, b = _coerce_exprs(self, other)
1993 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
1995 def __rtruediv__(self, other):
1996 """Create the Z3 expression `other/self`.
"""
1997 self.__rdiv__(other)
1999 def __mod__(self, other):
2000 """Create the Z3 expression `other%self`.
2009 a, b = _coerce_exprs(self, other)
2011 _z3_assert(a.is_int(), "Z3 integer expression expected")
2012 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2014 def __rmod__(self, other):
2015 """Create the Z3 expression `other%self`.
2021 a, b = _coerce_exprs(self, other)
2023 _z3_assert(a.is_int(), "Z3 integer expression expected")
2024 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2027 """Return an expression representing `-self`.
2035 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
2046 def __le__(self, other):
2047 """Create the Z3 expression `other <= self`.
2049 >>> x, y =
Ints(
'x y')
2056 a, b = _coerce_exprs(self, other)
2057 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2059 def __lt__(self, other):
2060 """Create the Z3 expression `other < self`.
2062 >>> x, y =
Ints(
'x y')
2069 a, b = _coerce_exprs(self, other)
2070 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2072 def __gt__(self, other):
2073 """Create the Z3 expression `other > self`.
2075 >>> x, y =
Ints(
'x y')
2082 a, b = _coerce_exprs(self, other)
2083 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2085 def __ge__(self, other):
2086 """Create the Z3 expression `other >= self`.
2088 >>> x, y =
Ints(
'x y')
2095 a, b = _coerce_exprs(self, other)
2096 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2099 """Return `
True`
if `a`
is an arithmetical expression.
2116 return isinstance(a, ArithRef)
2119 """Return `
True`
if `a`
is an integer expression.
2134 return is_arith(a) and a.is_int()
2137 """Return `
True`
if `a`
is a real expression.
2152 return is_arith(a) and a.is_real()
2154 def _is_numeral(ctx, a):
2155 return Z3_is_numeral_ast(ctx.ref(), a)
2157 def _is_algebraic(ctx, a):
2158 return Z3_is_algebraic_number(ctx.ref(), a)
2160 def is_int_value(a):
2161 """Return `
True`
if `a`
is an integer value of sort Int.
2169 >>> n =
Int(
'x') + 1
2181 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2183 def is_rational_value(a):
2184 """Return `
True`
if `a`
is rational value of sort Real.
2194 >>> n =
Real(
'x') + 1
2202 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2204 def is_algebraic_value(a):
2205 """Return `
True`
if `a`
is an algerbraic value of sort Real.
2215 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2218 """Return `
True`
if `a`
is an expression of the form b + c.
2220 >>> x, y =
Ints(
'x y')
2226 return is_app_of(a, Z3_OP_ADD)
2229 """Return `
True`
if `a`
is an expression of the form b * c.
2231 >>> x, y =
Ints(
'x y')
2237 return is_app_of(a, Z3_OP_MUL)
2240 """Return `
True`
if `a`
is an expression of the form b - c.
2242 >>> x, y =
Ints(
'x y')
2248 return is_app_of(a, Z3_OP_SUB)
2251 """Return `
True`
if `a`
is an expression of the form b / c.
2253 >>> x, y =
Reals(
'x y')
2258 >>> x, y =
Ints(
'x y')
2264 return is_app_of(a, Z3_OP_DIV)
2267 """Return `
True`
if `a`
is an expression of the form b div c.
2269 >>> x, y =
Ints(
'x y')
2275 return is_app_of(a, Z3_OP_IDIV)
2278 """Return `
True`
if `a`
is an expression of the form b % c.
2280 >>> x, y =
Ints(
'x y')
2286 return is_app_of(a, Z3_OP_MOD)
2289 """Return `
True`
if `a`
is an expression of the form b <= c.
2291 >>> x, y =
Ints(
'x y')
2297 return is_app_of(a, Z3_OP_LE)
2300 """Return `
True`
if `a`
is an expression of the form b < c.
2302 >>> x, y =
Ints(
'x y')
2308 return is_app_of(a, Z3_OP_LT)
2311 """Return `
True`
if `a`
is an expression of the form b >= c.
2313 >>> x, y =
Ints(
'x y')
2319 return is_app_of(a, Z3_OP_GE)
2322 """Return `
True`
if `a`
is an expression of the form b > c.
2324 >>> x, y =
Ints(
'x y')
2330 return is_app_of(a, Z3_OP_GT)
2333 """Return `
True`
if `a`
is an expression of the form
IsInt(b).
2341 return is_app_of(a, Z3_OP_IS_INT)
2344 """Return `
True`
if `a`
is an expression of the form
ToReal(b).
2355 return is_app_of(a, Z3_OP_TO_REAL)
2358 """Return `
True`
if `a`
is an expression of the form
ToInt(b).
2369 return is_app_of(a, Z3_OP_TO_INT)
2371 class IntNumRef(ArithRef):
2372 """Integer values.
"""
2375 """Return a Z3 integer numeral
as a Python long (bignum) numeral.
2384 _z3_assert(self.is_int(), "Integer value expected")
2385 return long(self.as_string())
2387 def as_string(self):
2388 """Return a Z3 integer numeral
as a Python string.
2393 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
2395 class RatNumRef(ArithRef):
2396 """Rational values.
"""
2398 def numerator(self):
2399 """ Return the numerator of a Z3 rational numeral.
2411 return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
2413 def denominator(self):
2414 """ Return the denominator of a Z3 rational numeral.
2422 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
2424 def numerator_as_long(self):
2425 """ Return the numerator
as a Python long.
2432 >>> v.numerator_as_long() + 1
2435 return self.numerator().as_long()
2437 def denominator_as_long(self):
2438 """ Return the denominator
as a Python long.
2443 >>> v.denominator_as_long()
2446 return self.denominator().as_long()
2448 def as_decimal(self, prec):
2449 """ Return a Z3 rational value
as a string
in decimal notation using at most `prec` decimal places.
2458 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
2460 def as_string(self):
2461 """Return a Z3 rational numeral
as a Python string.
2467 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
2469 class AlgebraicNumRef(ArithRef):
2470 """Algebraic irrational values.
"""
2472 def approx(self, precision=10):
2473 """Return a Z3 rational number that approximates the algebraic number `self`.
2474 The result `r`
is such that |r - self| <= 1/10^precision
2478 6838717160008073720548335/4835703278458516698824704
2482 return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
2483 def as_decimal(self, prec):
2484 """Return a string representation of the algebraic number `self`
in decimal notation using `prec` decimal places
2487 >>> x.as_decimal(10)
2489 >>> x.as_decimal(20)
2490 '1.41421356237309504880?'
2492 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
2494 def _py2expr(a, ctx=None):
2495 if isinstance(a, bool):
2496 return BoolVal(a, ctx)
2497 if isinstance(a, int) or isinstance(a, long):
2498 return IntVal(a, ctx)
2499 if isinstance(a, float):
2500 return RealVal(a, ctx)
2502 _z3_assert(False, "Python bool, int, long or float expected")
2504 def IntSort(ctx=None):
2505 """Return the interger sort
in the given context. If `ctx=
None`, then the
global context
is used.
2518 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
2520 def RealSort(ctx=None):
2521 """Return the real sort
in the given context. If `ctx=
None`, then the
global context
is used.
2534 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
2536 def _to_int_str(val):
2537 if isinstance(val, float):
2538 return str(int(val))
2539 elif isinstance(val, bool):
2544 elif isinstance(val, int):
2546 elif isinstance(val, long):
2548 elif isinstance(val, str):
2551 _z3_assert(False, "Python value cannot be used as a Z3 integer")
2553 def IntVal(val, ctx=None):
2554 """Return a Z3 integer value. If `ctx=
None`, then the
global context
is used.
2562 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
2564 def RealVal(val, ctx=None):
2565 """Return a Z3 real value.
2567 `val` may be a Python int, long, float
or string representing a number
in decimal
or rational notation.
2568 If `ctx=
None`, then the
global context
is used.
2580 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
2582 def RatVal(a, b, ctx=None):
2583 """Return a Z3 rational a/b.
2585 If `ctx=
None`, then the
global context
is used.
2593 _z3_assert(isinstance(a, int) or isinstance(a, str) or isinstance(a, long), "First argument cannot be converted into an integer")
2594 _z3_assert(isinstance(b, int) or isinstance(b, str) or isinstance(a, long), "Second argument cannot be converted into an integer")
2595 return simplify(RealVal(a, ctx)/RealVal(b, ctx))
2597 def Q(a, b, ctx=None):
2598 """Return a Z3 rational a/b.
2600 If `ctx=
None`, then the
global context
is used.
2607 return simplify(RatVal(a, b))
2609 def Int(name, ctx=None):
2610 """Return an integer constant named `name`. If `ctx=
None`, then the
global context
is used.
2619 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
2621 def Ints(names, ctx=None):
2622 """Return a tuple of Integer constants.
2624 >>> x, y, z =
Ints(
'x y z')
2629 if isinstance(names, str):
2630 names = names.split(" ")
2631 return [Int(name, ctx) for name in names]
2633 def IntVector(prefix, sz, ctx=None):
2634 """Return a list of integer constants of size `sz`.
2642 return [ Int('%s__%s' % (prefix, i)) for i in range(sz) ]
2644 def FreshInt(prefix='x', ctx=None):
2645 """Return a fresh integer constant
in the given context using the given prefix.
2655 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
2657 def Real(name, ctx=None):
2658 """Return a real constant named `name`. If `ctx=
None`, then the
global context
is used.
2667 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
2669 def Reals(names, ctx=None):
2670 """Return a tuple of real constants.
2672 >>> x, y, z =
Reals(
'x y z')
2675 >>>
Sum(x, y, z).sort()
2679 if isinstance(names, str):
2680 names = names.split(" ")
2681 return [Real(name, ctx) for name in names]
2683 def RealVector(prefix, sz, ctx=None):
2684 """Return a list of real constants of size `sz`.
2694 return [ Real('%s__%s' % (prefix, i)) for i in range(sz) ]
2696 def FreshReal(prefix='b', ctx=None):
2697 """Return a fresh real constant
in the given context using the given prefix.
2707 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
2710 """ Return the Z3 expression
ToReal(a).
2722 _z3_assert(a.is_int(), "Z3 integer expression expected.")
2724 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
2727 """ Return the Z3 expression
ToInt(a).
2739 _z3_assert(a.is_real(), "Z3 real expression expected.")
2741 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
2744 """ Return the Z3 predicate
IsInt(a).
2747 >>>
IsInt(x +
"1/2")
2751 >>>
solve(
IsInt(x +
"1/2"), x > 0, x < 1, x !=
"1/2")
2755 _z3_assert(a.is_real(), "Z3 real expression expected.")
2757 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
2759 def Sqrt(a, ctx=None):
2760 """ Return a Z3 expression which represents the square root of a.
2771 def Cbrt(a, ctx=None):
2772 """ Return a Z3 expression which represents the cubic root of a.
2783 #########################################
2787 #########################################
2789 class BitVecSortRef(SortRef):
2790 """Bit-vector sort.
"""
2793 """Return the size (number of bits) of the bit-vector sort `self`.
2799 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
2801 def subsort(self, other):
2802 return is_bv_sort(other) and self.size() < other.size()
2804 def cast(self, val):
2805 """Try to cast `val`
as a Bit-Vector.
2810 >>> b.cast(10).
sexpr()
2815 _z3_assert(self.ctx == val.ctx, "Context mismatch")
2816 # Idea: use sign_extend if sort of val is a bitvector of smaller size
2819 return BitVecVal(val, self)
2822 """Return
True if `s`
is a Z3 bit-vector sort.
2829 return isinstance(s, BitVecSortRef)
2831 class BitVecRef(ExprRef):
2832 """Bit-vector expressions.
"""
2835 """Return the sort of the bit-vector expression `self`.
2843 return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
2846 """Return the number of bits of the bit-vector expression `self`.
2854 return self.sort().size()
2856 def __add__(self, other):
2857 """Create the Z3 expression `self + other`.
2866 a, b = _coerce_exprs(self, other)
2867 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2869 def __radd__(self, other):
2870 """Create the Z3 expression `other + self`.
2876 a, b = _coerce_exprs(self, other)
2877 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2879 def __mul__(self, other):
2880 """Create the Z3 expression `self * other`.
2889 a, b = _coerce_exprs(self, other)
2890 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2892 def __rmul__(self, other):
2893 """Create the Z3 expression `other * self`.
2899 a, b = _coerce_exprs(self, other)
2900 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2902 def __sub__(self, other):
2903 """Create the Z3 expression `self - other`.
2912 a, b = _coerce_exprs(self, other)
2913 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2915 def __rsub__(self, other):
2916 """Create the Z3 expression `other - self`.
2922 a, b = _coerce_exprs(self, other)
2923 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2925 def __or__(self, other):
2926 """Create the Z3 expression bitwise-
or `self | other`.
2935 a, b = _coerce_exprs(self, other)
2936 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2938 def __ror__(self, other):
2939 """Create the Z3 expression bitwise-
or `other | self`.
2945 a, b = _coerce_exprs(self, other)
2946 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2948 def __and__(self, other):
2949 """Create the Z3 expression bitwise-
and `self & other`.
2958 a, b = _coerce_exprs(self, other)
2959 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2961 def __rand__(self, other):
2962 """Create the Z3 expression bitwise-
or `other & self`.
2968 a, b = _coerce_exprs(self, other)
2969 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2971 def __xor__(self, other):
2972 """Create the Z3 expression bitwise-xor `self ^ other`.
2981 a, b = _coerce_exprs(self, other)
2982 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2984 def __rxor__(self, other):
2985 """Create the Z3 expression bitwise-xor `other ^ self`.
2991 a, b = _coerce_exprs(self, other)
2992 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3004 """Return an expression representing `-self`.
3012 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3014 def __invert__(self):
3015 """Create the Z3 expression bitwise-
not `~self`.
3023 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3025 def __div__(self, other):
3026 """Create the Z3 expression (signed) division `self / other`.
3028 Use the function
UDiv()
for unsigned division.
3041 a, b = _coerce_exprs(self, other)
3042 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3044 def __truediv__(self, other):
3045 """Create the Z3 expression (signed) division `self / other`.
"""
3048 def __rdiv__(self, other):
3049 """Create the Z3 expression (signed) division `other / self`.
3051 Use the function
UDiv()
for unsigned division.
3056 >>> (10 / x).
sexpr()
3057 '(bvsdiv #x0000000a x)'
3059 '(bvudiv #x0000000a x)'
3061 a, b = _coerce_exprs(self, other)
3062 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3064 def __rtruediv__(self, other):
3065 """Create the Z3 expression (signed) division `other / self`.
"""
3066 self.__rdiv__(other)
3068 def __mod__(self, other):
3069 """Create the Z3 expression (signed) mod `self % other`.
3071 Use the function
URem()
for unsigned remainder,
and SRem()
for signed remainder.
3086 a, b = _coerce_exprs(self, other)
3087 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3089 def __rmod__(self, other):
3090 """Create the Z3 expression (signed) mod `other % self`.
3092 Use the function
URem()
for unsigned remainder,
and SRem()
for signed remainder.
3097 >>> (10 % x).
sexpr()
3098 '(bvsmod #x0000000a x)'
3100 '(bvurem #x0000000a x)'
3102 '(bvsrem #x0000000a x)'
3104 a, b = _coerce_exprs(self, other)
3105 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3107 def __le__(self, other):
3108 """Create the Z3 expression (signed) `other <= self`.
3110 Use the function
ULE()
for unsigned less than
or equal to.
3115 >>> (x <= y).
sexpr()
3120 a, b = _coerce_exprs(self, other)
3121 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3123 def __lt__(self, other):
3124 """Create the Z3 expression (signed) `other < self`.
3126 Use the function
ULT()
for unsigned less than.
3136 a, b = _coerce_exprs(self, other)
3137 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3139 def __gt__(self, other):
3140 """Create the Z3 expression (signed) `other > self`.
3142 Use the function
UGT()
for unsigned greater than.
3152 a, b = _coerce_exprs(self, other)
3153 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3155 def __ge__(self, other):
3156 """Create the Z3 expression (signed) `other >= self`.
3158 Use the function
UGE()
for unsigned greater than
or equal to.
3163 >>> (x >= y).
sexpr()
3168 a, b = _coerce_exprs(self, other)
3169 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3171 def __rshift__(self, other):
3172 """Create the Z3 expression (arithmetical) right shift `self >> other`
3174 Use the function
LShR()
for the right logical shift
3179 >>> (x >> y).
sexpr()
3198 a, b = _coerce_exprs(self, other)
3199 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3201 def __lshift__(self, other):
3202 """Create the Z3 expression left shift `self << other`
3207 >>> (x << y).
sexpr()
3212 a, b = _coerce_exprs(self, other)
3213 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3215 def __rrshift__(self, other):
3216 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
3218 Use the function
LShR()
for the right logical shift
3223 >>> (10 >> x).
sexpr()
3224 '(bvashr #x0000000a x)'
3226 a, b = _coerce_exprs(self, other)
3227 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3229 def __rlshift__(self, other):
3230 """Create the Z3 expression left shift `other << self`.
3232 Use the function
LShR()
for the right logical shift
3237 >>> (10 << x).
sexpr()
3238 '(bvshl #x0000000a x)'
3240 a, b = _coerce_exprs(self, other)
3241 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3243 class BitVecNumRef(BitVecRef):
3244 """Bit-vector values.
"""
3247 """Return a Z3 bit-vector numeral
as a Python long (bignum) numeral.
3252 >>>
print "0x%.8x" % v.as_long()
3255 return long(self.as_string())
3257 def as_signed_long(self):
3258 """Return a Z3 bit-vector numeral
as a Python long (bignum) numeral. The most significant bit
is assumed to be the sign.
3271 sz = long(self.size())
3272 val = self.as_long()
3273 if val >= 2L**(sz - 1):
3275 if val < -2L**(sz - 1):
3279 def as_string(self):
3280 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3283 """Return `
True`
if `a`
is a Z3 bit-vector expression.
3293 return isinstance(a, BitVecRef)
3296 """Return `
True`
if `a`
is a Z3 bit-vector numeral value.
3307 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
3310 """Return the Z3 expression
BV2Int(a).
3322 _z3_assert(is_bv(a), "Z3 bit-vector expression expected")
3324 ## investigate problem with bv2int
3325 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), 0), ctx)
3327 def BitVecSort(sz, ctx=None):
3328 """Return a Z3 bit-vector sort of the given size. If `ctx=
None`, then the
global context
is used.
3334 >>> x =
Const(
'x', Byte)
3339 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
3341 def BitVecVal(val, bv, ctx=None):
3342 """Return a bit-vector value with the given number of bits. If `ctx=
None`, then the
global context
is used.
3347 >>>
print "0x%.8x" % v.as_long()
3352 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
3355 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
3357 def BitVec(name, bv, ctx=None):
3358 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
3359 If `ctx=
None`, then the
global context
is used.
3369 >>> x2 =
BitVec(
'x', word)
3373 if isinstance(bv, BitVecSortRef):
3377 bv = BitVecSort(bv, ctx)
3378 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
3380 def BitVecs(names, bv, ctx=None):
3381 """Return a tuple of bit-vector constants of size bv.
3383 >>> x, y, z =
BitVecs(
'x y z', 16)
3396 if isinstance(names, str):
3397 names = names.split(" ")
3398 return [BitVec(name, bv, ctx) for name in names]
3401 """Create a Z3 bit-vector concatenation expression.
3411 args = _get_args(args)
3413 _z3_assert(all(map(is_bv, args)), "All arguments must be Z3 bit-vector expressions.")
3414 _z3_assert(len(args) >= 2, "At least two arguments expected.")
3417 for i in range(len(args) - 1):
3418 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i+1].as_ast()), ctx)
3421 def Extract(high, low, a):
3422 """Create a Z3 bit-vector extraction expression.
3431 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
3432 _z3_assert(isinstance(high, int) and high >= 0 and isinstance(low, int) and low >= 0, "First and second arguments must be non negative integers")
3433 _z3_assert(is_bv(a), "Third argument must be a Z3 Bitvector expression")
3434 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
3436 def _check_bv_args(a, b):
3438 _z3_assert(is_bv(a) or is_bv(b), "At least one of the arguments must be a Z3 bit-vector expression")
3441 """Create the Z3 expression (unsigned) `other <= self`.
3443 Use the operator <=
for signed less than
or equal to.
3448 >>> (x <= y).sexpr()
3450 >>>
ULE(x, y).sexpr()
3453 _check_bv_args(a, b)
3454 a, b = _coerce_exprs(a, b)
3455 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3458 """Create the Z3 expression (unsigned) `other < self`.
3460 Use the operator <
for signed less than.
3467 >>>
ULT(x, y).sexpr()
3470 _check_bv_args(a, b)
3471 a, b = _coerce_exprs(a, b)
3472 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3475 """Create the Z3 expression (unsigned) `other >= self`.
3477 Use the operator >=
for signed greater than
or equal to.
3482 >>> (x >= y).sexpr()
3484 >>>
UGE(x, y).sexpr()
3487 _check_bv_args(a, b)
3488 a, b = _coerce_exprs(a, b)
3489 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3492 """Create the Z3 expression (unsigned) `other > self`.
3494 Use the operator >
for signed greater than.
3501 >>>
UGT(x, y).sexpr()
3504 _check_bv_args(a, b)
3505 a, b = _coerce_exprs(a, b)
3506 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3509 """Create the Z3 expression (unsigned) division `self / other`.
3511 Use the operator /
for signed division.
3517 >>>
UDiv(x, y).sort()
3521 >>>
UDiv(x, y).sexpr()
3524 _check_bv_args(a, b)
3525 a, b = _coerce_exprs(a, b)
3526 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3529 """Create the Z3 expression (unsigned) remainder `self % other`.
3531 Use the operator %
for signed modulus,
and SRem()
for signed remainder.
3537 >>>
URem(x, y).sort()
3541 >>>
URem(x, y).sexpr()
3544 _check_bv_args(a, b)
3545 a, b = _coerce_exprs(a, b)
3546 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3549 """Create the Z3 expression signed remainder.
3551 Use the operator %
for signed modulus,
and URem()
for unsigned remainder.
3557 >>>
SRem(x, y).sort()
3561 >>>
SRem(x, y).sexpr()
3564 _check_bv_args(a, b)
3565 a, b = _coerce_exprs(a, b)
3566 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3569 """Create the Z3 expression logical right shift.
3571 Use the operator >>
for the arithmetical right shift.
3576 >>> (x >> y).sexpr()
3578 >>>
LShR(x, y).sexpr()
3595 _check_bv_args(a, b)
3596 a, b = _coerce_exprs(a, b)
3597 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3599 def RotateLeft(a, b):
3600 """Return an expression representing `a` rotated to the left `b` times.
3610 _check_bv_args(a, b)
3611 a, b = _coerce_exprs(a, b)
3612 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3614 def RotateRight(a, b):
3615 """Return an expression representing `a` rotated to the right `b` times.
3625 _check_bv_args(a, b)
3626 a, b = _coerce_exprs(a, b)
3627 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
3630 """Return a bit-vector expression with `n` extra sign-bits.
3650 >>>
print "%.x" % v.as_long()
3654 _z3_assert(isinstance(n, int), "First argument must be an integer")
3655 _z3_assert(is_bv(a), "Second argument must be a Z3 Bitvector expression")
3656 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
3659 """Return a bit-vector expression with `n` extra zero-bits.
3681 _z3_assert(isinstance(n, int), "First argument must be an integer")
3682 _z3_assert(is_bv(a), "Second argument must be a Z3 Bitvector expression")
3683 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
3685 def RepeatBitVec(n, a):
3686 """Return an expression representing `n` copies of `a`.
3695 >>>
print "%.x" % v0.as_long()
3700 >>>
print "%.x" % v.as_long()
3704 _z3_assert(isinstance(n, int), "First argument must be an integer")
3705 _z3_assert(is_bv(a), "Second argument must be a Z3 Bitvector expression")
3706 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
3708 #########################################
3712 #########################################
3714 class ArraySortRef(SortRef):
3718 """Return the domain of the array sort `self`.
3724 return _to_sort_ref(Z3_get_array_sort_domain(self.ctx_ref(), self.ast), self.ctx)
3727 """Return the range of the array sort `self`.
3733 return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
3735 class ArrayRef(ExprRef):
3736 """Array expressions.
"""
3739 """Return the array sort of the array expression `self`.
3745 return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3754 return self.sort().domain()
3763 return self.sort().range()
3765 def __getitem__(self, arg):
3766 """Return the Z3 expression `self[arg]`.
3775 arg = self.domain().cast(arg)
3776 return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx)
3779 """Return `
True`
if `a`
is a Z3 array expression.
3789 return isinstance(a, ArrayRef)
3792 """Return `
True`
if `a`
is a Z3 array select.
3801 return is_app_of(a, Z3_OP_SELECT)
3804 """Return `
True`
if `a`
is a Z3 array store.
3815 return is_app_of(a, Z3_OP_STORE)
3817 def is_const_array(a):
3818 """Return `
True`
if `a`
is a Z3 constant array.
3827 return is_app_of(a, Z3_OP_CONST_ARRAY)
3830 """Return `
True`
if `a`
is a Z3 constant array.
3839 return is_app_of(a, Z3_OP_CONST_ARRAY)
3842 """Return `
True`
if `a`
is a Z3 map array expression.
3854 return is_app_of(a, Z3_OP_ARRAY_MAP)
3856 def get_map_func(a):
3857 """Return the function declaration associated with a Z3 map array expression.
3870 _z3_assert(is_map(a), "Z3 array map expression expected.")
3871 return FuncDeclRef(Z3_to_func_decl(a.ctx_ref(), Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0)), a.ctx)
3873 def ArraySort(d, r):
3874 """Return the Z3 array sort with the given domain
and range sorts.
3888 _z3_assert(is_sort(d), "Z3 sort expected")
3889 _z3_assert(is_sort(r), "Z3 sort expected")
3890 _z3_assert(d.ctx == r.ctx, "Context mismatch")
3892 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
3894 def Array(name, dom, rng):
3895 """Return an array constant named `name` with the given domain
and range sorts.
3903 s = ArraySort(dom, rng)
3905 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
3907 def Update(a, i, v):
3908 """Return a Z3 store array expression.
3911 >>> i, v =
Ints(
'i v')
3915 >>>
prove(s[i] == v)
3922 _z3_assert(is_array(a), "First argument must be a Z3 array expression")
3923 i = a.domain().cast(i)
3924 v = a.range().cast(v)
3926 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
3929 """Return a Z3 store array expression.
3932 >>> i, v =
Ints(
'i v')
3933 >>> s =
Store(a, i, v)
3936 >>>
prove(s[i] == v)
3942 return Update(a, i, v)
3945 """Return a Z3 select array expression.
3955 _z3_assert(is_array(a), "First argument must be a Z3 array expression")
3959 """Return a Z3 map array expression.
3964 >>> b =
Map(f, a1, a2)
3967 >>>
prove(b[0] == f(a1[0], a2[0]))
3970 args = _get_args(args)
3972 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
3973 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
3974 _z3_assert(all(map(is_array, args)), "Z3 array expected expected")
3975 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
3976 _args, sz = _to_ast_array(args)
3978 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
3981 """Return a Z3 constant array expression.
3995 _z3_assert(is_sort(dom), "Z3 sort expected")
3998 v = _py2expr(v, ctx)
3999 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
4002 """Return `
True`
if `a`
is a Z3 array select application.
4010 return is_app_of(a, Z3_OP_SELECT)
4013 """Return `
True`
if `a`
is a Z3 array store application.
4021 return is_app_of(a, Z3_OP_STORE)
4023 #########################################
4027 #########################################
4029 def _valid_accessor(acc):
4030 """Return `
True`
if acc
is pair of the form (String, Datatype
or Sort).
"""
4031 return isinstance(acc, tuple) and len(acc) == 2 and isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
4034 """Helper
class for declaring Z3 datatypes.
4037 >>> List.declare(
'cons', (
'car',
IntSort()), (
'cdr', List))
4038 >>> List.declare(
'nil')
4039 >>> List = List.create()
4043 >>> List.cons(10, List.nil)
4045 >>> List.cons(10, List.nil).sort()
4047 >>> cons = List.cons
4051 >>> n = cons(1, cons(0, nil))
4053 cons(1, cons(0, nil))
4059 def __init__(self, name, ctx=None):
4060 self.ctx = _get_ctx(ctx)
4062 self.constructors = []
4064 def declare_core(self, name, rec_name, *args):
4066 _z3_assert(isinstance(name, str), "String expected")
4067 _z3_assert(isinstance(rec_name, str), "String expected")
4068 _z3_assert(all(map(_valid_accessor, args)), "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)")
4069 self.constructors.append((name, rec_name, args))
4071 def declare(self, name, *args):
4072 """Declare constructor named `name` with the given accessors `args`.
4073 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.
4075 In the followin example `List.declare(
'cons', (
'car',
IntSort()), (
'cdr', List))`
4076 declares the constructor named `cons` that builds a new List using an integer
and a List.
4077 It also declares the accessors `car`
and `cdr`. The accessor `car` extracts the integer of a `cons` cell,
4078 and `cdr` the list of a `cons` cell. After all constructors were declared, we use the method
create() to create
4079 the actual datatype
in Z3.
4082 >>> List.declare(
'cons', (
'car',
IntSort()), (
'cdr', List))
4083 >>> List.declare(
'nil')
4084 >>> List = List.create()
4087 _z3_assert(isinstance(name, str), "String expected")
4088 return self.declare_core(name, "is_" + name, *args)
4091 return "Datatype(%s, %s)" % (self.name, self.constructors)
4094 """Create a Z3 datatype based on the constructors declared using the mehtod `
declare()`.
4096 The function `
CreateDatatypes()` must be used to define mutually recursive datatypes.
4099 >>> List.declare(
'cons', (
'car',
IntSort()), (
'cdr', List))
4100 >>> List.declare(
'nil')
4101 >>> List = List.create()
4104 >>> List.cons(10, List.nil)
4107 return CreateDatatypes([self])[0]
4109 class ScopedConstructor:
4110 """Auxiliary object used to create Z3 datatypes.
"""
4111 def __init__(self, c, ctx):
4115 Z3_del_constructor(self.ctx.ref(), self.c)
4117 class ScopedConstructorList:
4118 """Auxiliary object used to create Z3 datatypes.
"""
4119 def __init__(self, c, ctx):
4123 Z3_del_constructor_list(self.ctx.ref(), self.c)
4125 def CreateDatatypes(*ds):
4126 """Create mutually recursive Z3 datatypes using 1
or more Datatype helper objects.
4128 In the following example we define a Tree-List using two mutually recursive datatypes.
4130 >>> TreeList =
Datatype(
'TreeList')
4133 >>> Tree.declare(
'leaf', (
'val',
IntSort()))
4135 >>> Tree.declare(
'node', (
'children', TreeList))
4136 >>> TreeList.declare(
'nil')
4137 >>> TreeList.declare(
'cons', (
'car', Tree), (
'cdr', TreeList))
4139 >>> Tree.val(Tree.leaf(10))
4141 >>>
simplify(Tree.val(Tree.leaf(10)))
4143 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
4145 node(cons(leaf(10), cons(leaf(20), nil)))
4146 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
4149 >>>
simplify(TreeList.car(Tree.children(n2)) == n1)
4154 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
4155 _z3_assert(all(map(lambda d: isinstance(d, Datatype), ds)), "Arguments must be Datatypes")
4156 _z3_assert(all(map(lambda d: d.ctx == ds[0].ctx, ds)), "Context mismatch")
4157 _z3_assert(all(map(lambda d: d.constructors != [], ds)), "Non-empty Datatypes expected")
4160 names = (Symbol * num)()
4161 out = (Sort * num)()
4162 clists = (ConstructorList * num)()
4164 for i in range(num):
4166 names[i] = to_symbol(d.name, ctx)
4167 num_cs = len(d.constructors)
4168 cs = (Constructor * num_cs)()
4169 for j in range(num_cs):
4170 c = d.constructors[j]
4171 cname = to_symbol(c[0], ctx)
4172 rname = to_symbol(c[1], ctx)
4175 fnames = (Symbol * num_fs)()
4176 sorts = (Sort * num_fs)()
4177 refs = (ctypes.c_uint * num_fs)()
4178 for k in range(num_fs):
4181 fnames[k] = to_symbol(fname, ctx)
4182 if isinstance(ftype, Datatype):
4184 _z3_assert(ds.count(ftype) == 1, "One and only one occurrence of each datatype is expected")
4186 refs[k] = ds.index(ftype)
4189 _z3_assert(is_sort(ftype), "Z3 sort expected")
4190 sorts[k] = ftype.ast
4192 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
4193 to_delete.append(ScopedConstructor(cs[j], ctx))
4194 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
4195 to_delete.append(ScopedConstructorList(clists[i], ctx))
4196 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
4198 ## Create a field for every constructor, recognizer and accessor
4199 for i in range(num):
4200 dref = DatatypeSortRef(out[i], ctx)
4201 num_cs = dref.num_constructors()
4202 for j in range(num_cs):
4203 cref = dref.constructor(j)
4204 cref_name = cref.name()
4205 cref_arity = cref.arity()
4206 if cref.arity() == 0:
4208 setattr(dref, cref_name, cref)
4209 rref = dref.recognizer(j)
4210 setattr(dref, rref.name(), rref)
4211 for k in range(cref_arity):
4212 aref = dref.accessor(j, k)
4213 setattr(dref, aref.name(), aref)
4215 return tuple(result)
4217 class DatatypeSortRef(SortRef):
4218 """Datatype sorts.
"""
4219 def num_constructors(self):
4220 """Return the number of constructors
in the given Z3 datatype.
4223 >>> List.declare(
'cons', (
'car',
IntSort()), (
'cdr', List))
4224 >>> List.declare(
'nil')
4225 >>> List = List.create()
4227 >>> List.num_constructors()
4230 return int(Z3_get_datatype_sort_num_constructors(self.ctx_ref(), self.ast))
4232 def constructor(self, idx):
4233 """Return a constructor of the datatype `self`.
4236 >>> List.declare(
'cons', (
'car',
IntSort()), (
'cdr', List))
4237 >>> List.declare(
'nil')
4238 >>> List = List.create()
4240 >>> List.num_constructors()
4242 >>> List.constructor(0)
4244 >>> List.constructor(1)
4248 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
4249 return FuncDeclRef(Z3_get_datatype_sort_constructor(self.ctx_ref(), self.ast, idx), self.ctx)
4251 def recognizer(self, idx):
4252 """In Z3, each constructor has an associated recognizer predicate.
4254 If the constructor
is named `name`, then the recognizer `is_name`.
4257 >>> List.declare(
'cons', (
'car',
IntSort()), (
'cdr', List))
4258 >>> List.declare(
'nil')
4259 >>> List = List.create()
4261 >>> List.num_constructors()
4263 >>> List.recognizer(0)
4265 >>> List.recognizer(1)
4267 >>>
simplify(List.is_nil(List.cons(10, List.nil)))
4269 >>>
simplify(List.is_cons(List.cons(10, List.nil)))
4271 >>> l =
Const(
'l', List)
4276 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
4277 return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
4279 def accessor(self, i, j):
4280 """In Z3, each constructor has 0
or more accessor. The number of accessors
is equal to the arity of the constructor.
4283 >>> List.declare(
'cons', (
'car',
IntSort()), (
'cdr', List))
4284 >>> List.declare(
'nil')
4285 >>> List = List.create()
4286 >>> List.num_constructors()
4288 >>> List.constructor(0)
4290 >>> num_accs = List.constructor(0).arity()
4293 >>> List.accessor(0, 0)
4295 >>> List.accessor(0, 1)
4297 >>> List.constructor(1)
4299 >>> num_accs = List.constructor(1).arity()
4304 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
4305 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
4306 return FuncDeclRef(Z3_get_datatype_sort_constructor_accessor(self.ctx_ref(), self.ast, i, j), self.ctx)
4308 class DatatypeRef(ExprRef):
4309 """Datatype expressions.
"""
4311 """Return the datatype sort of the datatype expression `self`.
"""
4312 return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4314 def EnumSort(name, values, ctx=None):
4315 """Return a new enumeration sort named `name` containing the given values.
4317 The result
is a pair (sort, list of constants).
4319 >>> Color, (red, green, blue) =
EnumSort(
'Color', [
'red',
'green',
'blue'])
4322 _z3_assert(isinstance(name, str), "Name must be a string")
4323 _z3_assert(all(map(lambda v: isinstance(v, str), values)), "Eumeration sort values must be strings")
4324 _z3_assert(len(values) > 0, "At least one value expected")
4327 _val_names = (Symbol * num)()
4328 for i in range(num):
4329 _val_names[i] = to_symbol(values[i])
4330 _values = (FuncDecl * num)()
4331 _testers = (FuncDecl * num)()
4332 name = to_symbol(name)
4333 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
4335 for i in range(num):
4336 V.append(FuncDeclRef(_values[i], ctx))
4337 V = map(lambda a: a(), V)
4340 #########################################
4344 #########################################
4347 """Set of parameters used to configure Solvers, Tactics
and Simplifiers
in Z3.
4349 Consider using the function `args2params` to create instances of this object.
4351 def __init__(self, ctx=None):
4352 self.ctx = _get_ctx(ctx)
4353 self.params = Z3_mk_params(self.ctx.ref())
4354 Z3_params_inc_ref(self.ctx.ref(), self.params)
4357 Z3_params_dec_ref(self.ctx.ref(), self.params)
4359 def set(self, name, val):
4360 """Set parameter name with value val.
"""
4362 _z3_assert(isinstance(name, str), "parameter name must be a string")
4363 name_sym = to_symbol(name, self.ctx)
4364 if isinstance(val, bool):
4365 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
4366 elif isinstance(val, int):
4367 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
4368 elif isinstance(val, float):
4369 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
4370 elif isinstance(val, str):
4371 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
4374 _z3_assert(False, "invalid parameter value")
4377 return Z3_params_to_string(self.ctx.ref(), self.params)
4379 def validate(self, ds):
4380 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
4381 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
4383 def args2params(arguments, keywords, ctx=None):
4384 """Convert python arguments into a Z3_params object.
4385 A
':' is added to the keywords,
and '_' is replaced with
'-'
4387 >>>
args2params([
':model',
True,
':relevancy', 2], {
'elim_and' :
True})
4388 (params :model 1 :relevancy 2 :elim-
and 1)
4391 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
4400 for k, v in keywords.iteritems():
4401 k = ':' + k.replace('_', '-')
4405 class ParamDescrsRef:
4406 """Set of parameter descriptions
for Solvers, Tactics
and Simplifiers
in Z3.
4408 def __init__(self, descr, ctx=None):
4409 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
4410 self.ctx = _get_ctx(ctx)
4412 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
4415 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
4418 """Return the size of
in the parameter description `self`.
4420 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
4423 """Return the size of
in the parameter description `self`.
4427 def get_name(self, i):
4428 """Return the i-th parameter name
in the parameter description `self`.
4430 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
4432 def get_kind(self, n):
4433 """Return the kind of the parameter named `n`.
4435 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
4437 def __getitem__(self, arg):
4438 if isinstance(arg, int) or isinstance(arg, long):
4439 return self.get_name(arg)
4441 return self.get_kind(arg)
4444 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
4446 #########################################
4450 #########################################
4452 class Goal(Z3PPObject):
4453 """Goal
is a collection of constraints we want to find a solution
or show to be unsatisfiable (infeasible).
4455 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
4456 A goal has a solution
if one of its subgoals has a solution.
4457 A goal
is unsatisfiable
if all subgoals are unsatisfiable.
4460 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
4462 _z3_assert(goal == None or ctx != None, "If goal is different from None, then ctx must be also different from None")
4463 self.ctx = _get_ctx(ctx)
4465 if self.goal == None:
4466 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
4467 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
4470 if self.goal != None:
4471 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
4474 """Return the depth of the goal `self`. The depth corresponds to the number of tactics applied to `self`.
4476 >>> x, y =
Ints(
'x y')
4478 >>> g.add(x == 0, y >= x + 1)
4481 >>> r =
Then(
'simplify',
'solve-eqs')(g)
4488 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
4490 def inconsistent(self):
4491 """Return `
True`
if `self` contains the `
False` constraints.
4493 >>> x, y =
Ints(
'x y')
4495 >>> g.inconsistent()
4497 >>> g.add(x == 0, x == 1)
4500 >>> g.inconsistent()
4502 >>> g2 =
Tactic(
'propagate-values')(g)[0]
4503 >>> g2.inconsistent()
4506 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
4509 """Return the precision (under-approximation, over-approximation,
or precise) of the goal `self`.
4512 >>> g.prec() == Z3_GOAL_PRECISE
4514 >>> x, y =
Ints(
'x y')
4515 >>> g.add(x == y + 1)
4516 >>> g.prec() == Z3_GOAL_PRECISE
4518 >>> t =
With(
Tactic(
'add-bounds'), add_bound_lower=0, add_bound_upper=10)
4521 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
4522 >>> g2.prec() == Z3_GOAL_PRECISE
4524 >>> g2.prec() == Z3_GOAL_UNDER
4527 return Z3_goal_precision(self.ctx.ref(), self.goal)
4529 def precision(self):
4530 """Alias
for `
prec()`.
4533 >>> g.precision() == Z3_GOAL_PRECISE
4539 """Return the number of constraints
in the goal `self`.
4544 >>> x, y =
Ints(
'x y')
4545 >>> g.add(x == 0, y > x)
4549 return int(Z3_goal_size(self.ctx.ref(), self.goal))
4552 """Return the number of constraints
in the goal `self`.
4557 >>> x, y =
Ints(
'x y')
4558 >>> g.add(x == 0, y > x)
4565 """Return a constraint
in the goal `self`.
4568 >>> x, y =
Ints(
'x y')
4569 >>> g.add(x == 0, y > x)
4575 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
4577 def __getitem__(self, arg):
4578 """Return a constraint
in the goal `self`.
4581 >>> x, y =
Ints(
'x y')
4582 >>> g.add(x == 0, y > x)
4588 if arg >= len(self):
4590 return self.get(arg)
4592 def assert_exprs(self, *args):
4593 """Assert constraints into the goal.
4597 >>> g.assert_exprs(x > 0, x < 2)
4601 args = _get_args(args)
4602 s = BoolSort(self.ctx)
4605 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
4607 def append(self, *args):
4612 >>> g.append(x > 0, x < 2)
4616 self.assert_exprs(*args)
4618 def insert(self, *args):
4623 >>> g.insert(x > 0, x < 2)
4627 self.assert_exprs(*args)
4629 def add(self, *args):
4634 >>> g.add(x > 0, x < 2)
4638 self.assert_exprs(*args)
4641 return obj_to_string(self)
4644 """Return a textual representation of the s-expression representing the goal.
"""
4645 return Z3_goal_to_string(self.ctx.ref(), self.goal)
4647 def translate(self, target):
4648 """Copy goal `self` to context `target`.
4656 >>> g2 = g.translate(c2)
4667 _z3_assert(isinstance(target, Context), "target must be a context")
4668 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
4670 def simplify(self, *arguments, **keywords):
4671 """Return a new simplified goal.
4673 This method
is essentially invoking the simplify tactic.
4677 >>> g.add(x + 1 >= 2)
4680 >>> g2 = g.simplify()
4687 t = Tactic('simplify')
4688 return t.apply(self, *arguments, **keywords)[0]
4691 """Return goal `self`
as a single Z3 expression.
4706 return BoolVal(True, self.ctx)
4710 return And([ self.get(i) for i in range(len(self)) ])
4712 #########################################
4716 #########################################
4717 class AstVector(Z3PPObject):
4718 """A collection (vector) of ASTs.
"""
4720 def __init__(self, v=None, ctx=None):
4723 self.ctx = _get_ctx(ctx)
4724 self.vector = Z3_mk_ast_vector(self.ctx.ref())
4729 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
4732 if self.vector != None:
4733 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
4736 """Return the size of the vector `self`.
4741 >>> A.push(
Int(
'x'))
4742 >>> A.push(
Int(
'x'))
4746 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
4748 def __getitem__(self, i):
4749 """Return the AST at position `i`.
4752 >>> A.push(
Int(
'x') + 1)
4753 >>> A.push(
Int(
'y'))
4759 if i >= self.__len__():
4761 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
4763 def __setitem__(self, i, v):
4764 """Update AST at position `i`.
4767 >>> A.push(
Int(
'x') + 1)
4768 >>> A.push(
Int(
'y'))
4775 if i >= self.__len__():
4777 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
4780 """Add `v`
in the end of the vector.
4785 >>> A.push(
Int(
'x'))
4789 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
4791 def resize(self, sz):
4792 """Resize the vector to `sz` elements.
4798 >>>
for i
in range(10): A[i] =
Int(
'x')
4802 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
4804 def __contains__(self, item):
4805 """Return `
True`
if the vector contains `item`.
4827 def translate(self, other_ctx):
4828 """Copy vector `self` to context `other_ctx`.
4834 >>> B = A.translate(c2)
4838 return AstVector(Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()), other_ctx)
4841 return obj_to_string(self)
4844 """Return a textual representation of the s-expression representing the vector.
"""
4845 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
4847 #########################################
4851 #########################################
4853 """A mapping
from ASTs to ASTs.
"""
4855 def __init__(self, m=None, ctx=None):
4858 self.ctx = _get_ctx(ctx)
4859 self.map = Z3_mk_ast_map(self.ctx.ref())
4864 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
4867 if self.map != None:
4868 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
4871 """Return the size of the map.
4881 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
4883 def __contains__(self, key):
4884 """Return `
True`
if the map contains key `key`.
4894 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
4896 def __getitem__(self, key):
4897 """Retrieve the value associated with key `key`.
4905 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
4907 def __setitem__(self, k, v):
4908 """Add/Update key `k` with value `v`.
4921 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
4924 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
4927 """Remove the entry associated with key `k`.
4938 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
4941 """Remove all entries
from the map.
4953 Z3_ast_map_reset(self.ctx.ref(), self.map)
4956 """Return an AstVector containing all keys
in the map.
4965 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
4967 #########################################
4971 #########################################
4974 """Store the value of the interpretation of a function
in a particular point.
"""
4976 def __init__(self, entry, ctx):
4979 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
4982 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
4985 """Return the number of arguments
in the given entry.
4989 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
4994 >>> f_i.num_entries()
4996 >>> e = f_i.entry(0)
5000 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
5002 def arg_value(self, idx):
5003 """Return the value of argument `idx`.
5007 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
5012 >>> f_i.num_entries()
5014 >>> e = f_i.entry(0)
5025 ...
except IndexError:
5026 ...
print "index error"
5029 if idx >= self.num_args():
5031 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
5034 """Return the value of the function at point `self`.
5038 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
5043 >>> f_i.num_entries()
5045 >>> e = f_i.entry(0)
5053 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
5056 """Return entry `self`
as a Python list.
5059 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
5064 >>> f_i.num_entries()
5066 >>> e = f_i.entry(0)
5070 args = [ self.arg_value(i) for i in range(self.num_args())]
5071 args.append(self.value())
5075 return repr(self.as_list())
5077 class FuncInterp(Z3PPObject):
5078 """Stores the interpretation of a function
in a Z3 model.
"""
5080 def __init__(self, f, ctx):
5084 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
5088 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
5090 def else_value(self):
5091 """Return the `
else` value
for a function interpretation.
5095 >>> s.add(
f(0) == 1,
f(1) == 1,
f(2) == 0)
5100 [0 -> 1, 1 -> 1, 2 -> 0,
else -> 1]
5104 return _to_expr_ref(Z3_func_interp_get_else(self.ctx.ref(), self.f), self.ctx)
5106 def num_entries(self):
5107 """Return the number of entries/points
in the function interpretation `self`.
5111 >>> s.add(
f(0) == 1,
f(1) == 1,
f(2) == 0)
5116 [0 -> 1, 1 -> 1, 2 -> 0,
else -> 1]
5120 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
5123 """Return the number of arguments
for each entry
in the function interpretation `self`.
5127 >>> s.add(
f(0) == 1,
f(1) == 1,
f(2) == 0)
5134 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
5136 def entry(self, idx):
5137 """Return an entry at position `idx < self.
num_entries()`
in the function interpretation `self`.
5141 >>> s.add(
f(0) == 1,
f(1) == 1,
f(2) == 0)
5146 [0 -> 1, 1 -> 1, 2 -> 0,
else -> 1]
5156 if idx >= self.num_entries():
5158 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
5161 """Return the function interpretation
as a Python list.
5164 >>> s.add(
f(0) == 1,
f(1) == 1,
f(2) == 0)
5169 [0 -> 1, 1 -> 1, 2 -> 0,
else -> 1]
5171 [[0, 1], [1, 1], [2, 0], 1]
5173 r = [ self.entry(i).as_list() for i in range(self.num_entries())]
5174 r.append(self.else_value())
5178 return obj_to_string(self)
5180 class ModelRef(Z3PPObject):
5181 """Model/Solution of a satisfiability problem (aka system of constraints).
"""
5183 def __init__(self, m, ctx):
5187 Z3_model_inc_ref(self.ctx.ref(), self.model)
5190 Z3_model_dec_ref(self.ctx.ref(), self.model)
5193 return obj_to_string(self)
5196 """Return a textual representation of the s-expression representing the model.
"""
5197 return Z3_model_to_string(self.ctx.ref(), self.model)
5199 def eval(self, t, model_completion=False):
5200 """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`.
5204 >>> s.add(x > 0, x < 2)
5217 >>> m.eval(y, model_completion=
True)
5224 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
5225 return _to_expr_ref(r[0], self.ctx)
5226 raise Z3Exception("failed to evaluate expression in the model")
5228 def evaluate(self, t, model_completion=False):
5229 """Alias
for `eval`.
5233 >>> s.add(x > 0, x < 2)
5237 >>> m.evaluate(x + 1)
5239 >>> m.evaluate(x == 1)
5242 >>> m.evaluate(y + x)
5246 >>> m.evaluate(y, model_completion=
True)
5249 >>> m.evaluate(y + x)
5252 return self.eval(t, model_completion)
5255 """Return the number of constant
and function declarations
in the model `self`.
5260 >>> s.add(x > 0, f(x) != x)
5267 return int(Z3_model_get_num_consts(self.ctx.ref(), self.model)) + int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
5269 def get_interp(self, decl):
5270 """Return the interpretation
for a given declaration
or constant.
5275 >>> s.add(x > 0, x < 2, f(x) == 0)
5285 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
5289 if decl.arity() == 0:
5290 r = _to_expr_ref(Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
5292 return self.get_interp(get_as_array_func(r))
5296 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
5300 def num_sorts(self):
5301 """Return the number of unintepreted sorts that contain an interpretation
in the model `self`.
5304 >>> a, b =
Consts(
'a b', A)
5313 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
5315 def get_sort(self, idx):
5316 """Return the unintepreted sort at position `idx` < self.
num_sorts().
5320 >>> a1, a2 =
Consts(
'a1 a2', A)
5321 >>> b1, b2 =
Consts(
'b1 b2', B)
5323 >>> s.add(a1 != a2, b1 != b2)
5334 if idx >= self.num_sorts():
5336 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
5339 """Return all uninterpreted sorts that have an interpretation
in the model `self`.
5343 >>> a1, a2 =
Consts(
'a1 a2', A)
5344 >>> b1, b2 =
Consts(
'b1 b2', B)
5346 >>> s.add(a1 != a2, b1 != b2)
5353 return [ self.get_sort(i) for i in range(self.num_sorts()) ]
5355 def get_universe(self, s):
5356 """Return the intepretation
for the uninterpreted sort `s`
in the model `self`.
5359 >>> a, b =
Consts(
'a b', A)
5365 >>> m.get_universe(A)
5369 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
5371 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
5375 def __getitem__(self, idx):
5376 """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.
5378 The elements can be retrieved using position
or the actual declaration.
5383 >>> s.add(x > 0, x < 2, f(x) == 0)
5397 >>>
for d
in m:
print "%s -> %s" % (d, m[d])
5399 f -> [1 -> 0,
else -> 0]
5401 if isinstance(idx, int):
5402 if idx >= len(self):
5404 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
5405 if (idx < num_consts):
5406 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
5408 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
5409 if isinstance(idx, FuncDeclRef):
5410 return self.get_interp(idx)
5412 return self.get_interp(idx.decl())
5413 if isinstance(idx, SortRef):
5414 return self.get_universe(idx)
5416 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
5420 """Return a list with all symbols that have an interpreation
in the model `self`.
5424 >>> s.add(x > 0, x < 2, f(x) == 0)
5432 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
5433 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
5434 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
5435 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
5439 """Return true
if n
is a Z3 expression of the form (_
as-array f).
"""
5440 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
5442 def get_as_array_func(n):
5443 """Return the function declaration f associated with a Z3 expression of the form (_
as-array f).
"""
5445 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
5446 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
5448 #########################################
5452 #########################################
5454 """Statistics
for `Solver.check()`.
"""
5456 def __init__(self, stats, ctx):
5459 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
5462 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
5468 out.write(u'<table border="1" cellpadding="2" cellspacing="0">')
5471 out.write(u'<tr style="background-color:#CFCFCF">')
5476 out.write(u'<td>%s</td><td>%s</td></tr>' % (k, v))
5477 out.write(u'</table>')
5478 return out.getvalue()
5480 return Z3_stats_to_string(self.ctx.ref(), self.stats)
5483 """Return the number of statistical counters.
5486 >>> s =
Then(
'simplify',
'nlsat').solver()
5490 >>> st = s.statistics()
5494 return int(Z3_stats_size(self.ctx.ref(), self.stats))
5496 def __getitem__(self, idx):
5497 """Return the value of statistical counter at position `idx`. The result
is a pair (key, value).
5500 >>> s =
Then(
'simplify',
'nlsat').solver()
5504 >>> st = s.statistics()
5508 (
'nlsat propagations', 2)
5512 if idx >= len(self):
5514 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
5515 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
5517 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
5518 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
5521 """Return the list of statistical counters.
5524 >>> s =
Then(
'simplify',
'nlsat').solver()
5528 >>> st = s.statistics()
5530 [
'nlsat propagations',
'nlsat stages']
5532 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
5534 def get_key_value(self, key):
5535 """Return the value of a particular statistical counter.
5538 >>> s =
Then(
'simplify',
'nlsat').solver()
5542 >>> st = s.statistics()
5543 >>> st.get_key_value(
'nlsat propagations')
5546 for idx in range(len(self)):
5547 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
5548 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
5549 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
5551 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
5552 raise Z3Exception("unknown key")
5554 def __getattr__(self, name):
5555 """Access the value of statistical using attributes.
5557 Remark: to access a counter containing blank spaces (e.g.,
'nlsat propagations'),
5558 we should use
'_' (e.g.,
'nlsat_propagations').
5561 >>> s =
Then(
'simplify',
'nlsat').solver()
5565 >>> st = s.statistics()
5567 [
'nlsat propagations',
'nlsat stages']
5568 >>> st.nlsat_propagations
5573 key = name.replace('_', ' ')
5575 return self.get_key_value(key)
5577 raise AttributeError
5579 #########################################
5583 #########################################
5584 class CheckSatResult:
5585 """Represents the result of a satisfiability check: sat, unsat, unknown.
5591 >>> isinstance(r, CheckSatResult)
5595 def __init__(self, r):
5598 def __eq__(self, other):
5599 return isinstance(other, CheckSatResult) and self.r == other.r
5601 def __ne__(self, other):
5602 return not self.__eq__(other)
5606 if self.r == Z3_L_TRUE:
5608 elif self.r == Z3_L_FALSE:
5609 return "<b>unsat</b>"
5611 return "<b>unknown</b>"
5613 if self.r == Z3_L_TRUE:
5615 elif self.r == Z3_L_FALSE:
5620 sat = CheckSatResult(Z3_L_TRUE)
5621 unsat = CheckSatResult(Z3_L_FALSE)
5622 unknown = CheckSatResult(Z3_L_UNDEF)
5624 class Solver(Z3PPObject):
5625 """Solver API provides methods
for implementing the main SMT 2.0 commands: push, pop, check, get-model, etc.
"""
5627 def __init__(self, solver=None, ctx=None):
5628 assert solver == None or ctx != None
5629 self.ctx = _get_ctx(ctx)
5632 self.solver = Z3_mk_solver(self.ctx.ref())
5634 self.solver = solver
5635 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
5638 if self.solver != None:
5639 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
5641 def set(self, *args, **keys):
5642 """Set a configuration option. The method `
help()`
return a string containing all available options.
5646 >>> s.set(mbqi=
True)
5647 >>> s.set(
'MBQI',
True)
5648 >>> s.set(
':mbqi',
True)
5650 p = args2params(args, keys, self.ctx)
5651 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
5654 """Create a backtracking point.
5673 Z3_solver_push(self.ctx.ref(), self.solver)
5675 def pop(self, num=1):
5676 """Backtrack \c num backtracking points.
5695 Z3_solver_pop(self.ctx.ref(), self.solver, num)
5698 """Remove all asserted constraints
and backtracking points created using `
push()`.
5709 Z3_solver_reset(self.ctx.ref(), self.solver)
5711 def assert_exprs(self, *args):
5712 """Assert constraints into the solver.
5716 >>> s.assert_exprs(x > 0, x < 2)
5720 args = _get_args(args)
5721 s = BoolSort(self.ctx)
5723 if isinstance(arg, Goal) or isinstance(arg, AstVector):
5725 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
5728 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
5730 def add(self, *args):
5731 """Assert constraints into the solver.
5735 >>> s.add(x > 0, x < 2)
5739 self.assert_exprs(*args)
5741 def append(self, *args):
5742 """Assert constraints into the solver.
5746 >>> s.append(x > 0, x < 2)
5750 self.assert_exprs(*args)
5752 def insert(self, *args):
5753 """Assert constraints into the solver.
5757 >>> s.insert(x > 0, x < 2)
5761 self.assert_exprs(*args)
5763 def assert_and_track(self, a, p):
5764 """Assert constraint `a`
and track it
in the unsat core using the Boolean constant `p`.
5766 If `p`
is a string, it will be automatically converted into a Boolean constant.
5771 >>> s.set(unsat_core=
True)
5772 >>> s.assert_and_track(x > 0,
'p1')
5773 >>> s.assert_and_track(x != 1,
'p2')
5774 >>> s.assert_and_track(x < 0, p3)
5777 >>>
print s.unsat_core()
5780 if isinstance(p, str):
5781 p = Bool(p, self.ctx)
5782 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
5783 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
5784 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
5786 def check(self, *assumptions):
5787 """Check whether the assertions
in the given solver plus the optional assumptions are consistent
or not.
5793 >>> s.add(x > 0, x < 2)
5802 >>> s.add(2**x == 4)
5806 assumptions = _get_args(assumptions)
5807 num = len(assumptions)
5808 _assumptions = (Ast * num)()
5809 for i in range(num):
5810 _assumptions[i] = assumptions[i].as_ast()
5811 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
5812 return CheckSatResult(r)
5815 """Return a model
for the last `
check()`.
5817 This function raises an exception
if
5818 a model
is not available (e.g., last `
check()` returned unsat).
5822 >>> s.add(a + 2 == 0)