Z3
 
Loading...
Searching...
No Matches
z3py.py
Go to the documentation of this file.
8
9"""Z3 is a high performance theorem prover developed at Microsoft Research.
10
11Z3 is used in many applications such as: software/hardware verification and testing,
12constraint solving, analysis of hybrid systems, security, biology (in silico analysis),
13and geometrical problems.
14
15
16Please send feedback, comments and/or corrections on the Issue tracker for
17https://github.com/Z3prover/z3.git. Your comments are very valuable.
18
19Small example:
20
21>>> x = Int('x')
22>>> y = Int('y')
23>>> s = Solver()
24>>> s.add(x > 0)
25>>> s.add(x < 2)
26>>> s.add(y == x + 1)
27>>> s.check()
28sat
29>>> m = s.model()
30>>> m[x]
311
32>>> m[y]
332
34
35Z3 exceptions:
36
37>>> try:
38... x = BitVec('x', 32)
39... y = Bool('y')
40... # the expression x + y is type incorrect
41... n = x + y
42... except Z3Exception as ex:
43... print("failed: %s" % ex)
44failed: sort mismatch
45"""
46from . import z3core
47from .z3core import *
48from .z3types import *
49from .z3consts import *
50from .z3printer import *
51from fractions import Fraction
52import sys
53import io
54import math
55import copy
56if sys.version_info.major >= 3:
57 from typing import Iterable
58
59Z3_DEBUG = __debug__
60
61
63 global Z3_DEBUG
64 return Z3_DEBUG
65
66
67if sys.version_info.major < 3:
68 def _is_int(v):
69 return isinstance(v, (int, long))
70else:
71 def _is_int(v):
72 return isinstance(v, int)
73
74
75def enable_trace(msg):
77
78
81
82
84 major = ctypes.c_uint(0)
85 minor = ctypes.c_uint(0)
86 build = ctypes.c_uint(0)
87 rev = ctypes.c_uint(0)
88 Z3_get_version(major, minor, build, rev)
89 return "%s.%s.%s" % (major.value, minor.value, build.value)
90
91
93 major = ctypes.c_uint(0)
94 minor = ctypes.c_uint(0)
95 build = ctypes.c_uint(0)
96 rev = ctypes.c_uint(0)
97 Z3_get_version(major, minor, build, rev)
98 return (major.value, minor.value, build.value, rev.value)
99
100
102 return Z3_get_full_version()
103
104
105def _z3_assert(cond, msg):
106 if not cond:
107 raise Z3Exception(msg)
108
109
111 _z3_assert(ctypes.c_int(n).value == n, name + " is too large")
112
113
114def open_log(fname):
115 """Log interaction to a file. This function must be invoked immediately after init(). """
116 Z3_open_log(fname)
117
118
120 """Append user-defined string to interaction log. """
122
123
124def to_symbol(s, ctx=None):
125 """Convert an integer or string into a Z3 symbol."""
126 if _is_int(s):
127 return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
128 else:
129 return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
130
131
132def _symbol2py(ctx, s):
133 """Convert a Z3 symbol back into a Python object. """
134 if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
135 return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
136 else:
137 return Z3_get_symbol_string(ctx.ref(), s)
138
139# Hack for having nary functions that can receive one argument that is the
140# list of arguments.
141# Use this when function takes a single list of arguments
142
143
144def _get_args(args):
145 try:
146 if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
147 return args[0]
148 elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)):
149 return [arg for arg in args[0]]
150 else:
151 return args
152 except TypeError: # len is not necessarily defined when args is not a sequence (use reflection?)
153 return args
154
155# Use this when function takes multiple arguments
156
157
159 try:
160 if isinstance(args, (set, AstVector, tuple)):
161 return [arg for arg in args]
162 else:
163 return args
164 except Exception:
165 return args
166
167
169 if isinstance(val, bool):
170 return "true" if val else "false"
171 return str(val)
172
173
175 # Do nothing error handler, just avoid exit(0)
176 # The wrappers in z3core.py will raise a Z3Exception if an error is detected
177 return
178
179
180class Context:
181 """A Context manages all other Z3 objects, global configuration options, etc.
182
183 Z3Py uses a default global context. For most applications this is sufficient.
184 An application may use multiple Z3 contexts. Objects created in one context
185 cannot be used in another one. However, several objects may be "translated" from
186 one context to another. It is not safe to access Z3 objects from multiple threads.
187 The only exception is the method `interrupt()` that can be used to interrupt() a long
188 computation.
189 The initialization method receives global configuration options for the new context.
190 """
191
192 def __init__(self, *args, **kws):
193 if z3_debug():
194 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
195 conf = Z3_mk_config()
196 for key in kws:
197 value = kws[key]
198 Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
199 prev = None
200 for a in args:
201 if prev is None:
202 prev = a
203 else:
204 Z3_set_param_value(conf, str(prev), _to_param_value(a))
205 prev = None
207 self.owner = True
208 self.eh = Z3_set_error_handler(self.ctx, z3_error_handler)
209 Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
210 Z3_del_config(conf)
211
212 def __del__(self):
213 if Z3_del_context is not None and self.owner:
214 Z3_del_context(self.ctx)
215 self.ctx = None
216 self.eh = None
217
218 def ref(self):
219 """Return a reference to the actual C pointer to the Z3 context."""
220 return self.ctx
221
222 def interrupt(self):
223 """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
224
225 This method can be invoked from a thread different from the one executing the
226 interruptible procedure.
227 """
228 Z3_interrupt(self.ref())
229
230 def param_descrs(self):
231 """Return the global parameter description set."""
232 return ParamDescrsRef(Z3_get_global_param_descrs(self.ref()), self)
233
234
235# Global Z3 context
236_main_ctx = None
237
238
240 """Return a reference to the global Z3 context.
241
242 >>> x = Real('x')
243 >>> x.ctx == main_ctx()
244 True
245 >>> c = Context()
246 >>> c == main_ctx()
247 False
248 >>> x2 = Real('x', c)
249 >>> x2.ctx == c
250 True
251 >>> eq(x, x2)
252 False
253 """
254 global _main_ctx
255 if _main_ctx is None:
256 _main_ctx = Context()
257 return _main_ctx
258
259
260def _get_ctx(ctx):
261 if ctx is None:
262 return main_ctx()
263 else:
264 return ctx
265
266
267def get_ctx(ctx):
268 return _get_ctx(ctx)
269
270
271def set_param(*args, **kws):
272 """Set Z3 global (or module) parameters.
273
274 >>> set_param(precision=10)
275 """
276 if z3_debug():
277 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
278 new_kws = {}
279 for k in kws:
280 v = kws[k]
281 if not set_pp_option(k, v):
282 new_kws[k] = v
283 for key in new_kws:
284 value = new_kws[key]
285 Z3_global_param_set(str(key).upper(), _to_param_value(value))
286 prev = None
287 for a in args:
288 if prev is None:
289 prev = a
290 else:
292 prev = None
293
294
296 """Reset all global (or module) parameters.
297 """
299
300
301def set_option(*args, **kws):
302 """Alias for 'set_param' for backward compatibility.
303 """
304 return set_param(*args, **kws)
305
306
307def get_param(name):
308 """Return the value of a Z3 global (or module) parameter
309
310 >>> get_param('nlsat.reorder')
311 'true'
312 """
313 ptr = (ctypes.c_char_p * 1)()
314 if Z3_global_param_get(str(name), ptr):
315 r = z3core._to_pystr(ptr[0])
316 return r
317 raise Z3Exception("failed to retrieve value for '%s'" % name)
318
319
324
325# Mark objects that use pretty printer
326
327
329 """Superclass for all Z3 objects that have support for pretty printing."""
330
331 def use_pp(self):
332 return True
333
334 def _repr_html_(self):
335 in_html = in_html_mode()
336 set_html_mode(True)
337 res = repr(self)
338 set_html_mode(in_html)
339 return res
340
341
343 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
344
345 def __init__(self, ast, ctx=None):
346 self.ast = ast
347 self.ctx = _get_ctx(ctx)
348 Z3_inc_ref(self.ctx.ref(), self.as_ast())
349
350 def __del__(self):
351 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
352 Z3_dec_ref(self.ctx.ref(), self.as_ast())
353 self.ast = None
354
355 def __deepcopy__(self, memo={}):
356 return _to_ast_ref(self.ast, self.ctx)
357
358 def __str__(self):
359 return obj_to_string(self)
360
361 def __repr__(self):
362 return obj_to_string(self)
363
364 def __eq__(self, other):
365 return self.eq(other)
366
367 def __hash__(self):
368 return self.hash()
369
370 def __nonzero__(self):
371 return self.__bool__()
372
373 def __bool__(self):
374 if is_true(self):
375 return True
376 elif is_false(self):
377 return False
378 elif is_eq(self) and self.num_args() == 2:
379 return self.arg(0).eq(self.arg(1))
380 else:
381 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
382
383 def sexpr(self):
384 """Return a string representing the AST node in s-expression notation.
385
386 >>> x = Int('x')
387 >>> ((x + 1)*x).sexpr()
388 '(* (+ x 1) x)'
389 """
390 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
391
392 def as_ast(self):
393 """Return a pointer to the corresponding C Z3_ast object."""
394 return self.ast
395
396 def get_id(self):
397 """Return unique identifier for object. It can be used for hash-tables and maps."""
398 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
399
400 def ctx_ref(self):
401 """Return a reference to the C context where this AST node is stored."""
402 return self.ctx.ref()
403
404 def eq(self, other):
405 """Return `True` if `self` and `other` are structurally identical.
406
407 >>> x = Int('x')
408 >>> n1 = x + 1
409 >>> n2 = 1 + x
410 >>> n1.eq(n2)
411 False
412 >>> n1 = simplify(n1)
413 >>> n2 = simplify(n2)
414 >>> n1.eq(n2)
415 True
416 """
417 if z3_debug():
418 _z3_assert(is_ast(other), "Z3 AST expected")
419 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
420
421 def translate(self, target):
422 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
423
424 >>> c1 = Context()
425 >>> c2 = Context()
426 >>> x = Int('x', c1)
427 >>> y = Int('y', c2)
428 >>> # Nodes in different contexts can't be mixed.
429 >>> # However, we can translate nodes from one context to another.
430 >>> x.translate(c2) + y
431 x + y
432 """
433 if z3_debug():
434 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
435 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
436
437 def __copy__(self):
438 return self.translate(self.ctx)
439
440 def hash(self):
441 """Return a hashcode for the `self`.
442
443 >>> n1 = simplify(Int('x') + 1)
444 >>> n2 = simplify(2 + Int('x') - 1)
445 >>> n1.hash() == n2.hash()
446 True
447 """
448 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
449
450
451def is_ast(a):
452 """Return `True` if `a` is an AST node.
453
454 >>> is_ast(10)
455 False
456 >>> is_ast(IntVal(10))
457 True
458 >>> is_ast(Int('x'))
459 True
460 >>> is_ast(BoolSort())
461 True
462 >>> is_ast(Function('f', IntSort(), IntSort()))
463 True
464 >>> is_ast("x")
465 False
466 >>> is_ast(Solver())
467 False
468 """
469 return isinstance(a, AstRef)
470
471
472def eq(a, b):
473 """Return `True` if `a` and `b` are structurally identical AST nodes.
474
475 >>> x = Int('x')
476 >>> y = Int('y')
477 >>> eq(x, y)
478 False
479 >>> eq(x + 1, x + 1)
480 True
481 >>> eq(x + 1, 1 + x)
482 False
483 >>> eq(simplify(x + 1), simplify(1 + x))
484 True
485 """
486 if z3_debug():
487 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
488 return a.eq(b)
489
490
491def _ast_kind(ctx, a):
492 if is_ast(a):
493 a = a.as_ast()
494 return Z3_get_ast_kind(ctx.ref(), a)
495
496
497def _ctx_from_ast_arg_list(args, default_ctx=None):
498 ctx = None
499 for a in args:
500 if is_ast(a) or is_probe(a):
501 if ctx is None:
502 ctx = a.ctx
503 else:
504 if z3_debug():
505 _z3_assert(ctx == a.ctx, "Context mismatch")
506 if ctx is None:
507 ctx = default_ctx
508 return ctx
509
510
512 return _ctx_from_ast_arg_list(args)
513
514
516 sz = len(args)
517 _args = (FuncDecl * sz)()
518 for i in range(sz):
519 _args[i] = args[i].as_func_decl()
520 return _args, sz
521
522
524 sz = len(args)
525 _args = (Ast * sz)()
526 for i in range(sz):
527 _args[i] = args[i].as_ast()
528 return _args, sz
529
530
531def _to_ref_array(ref, args):
532 sz = len(args)
533 _args = (ref * sz)()
534 for i in range(sz):
535 _args[i] = args[i].as_ast()
536 return _args, sz
537
538
539def _to_ast_ref(a, ctx):
540 k = _ast_kind(ctx, a)
541 if k == Z3_SORT_AST:
542 return _to_sort_ref(a, ctx)
543 elif k == Z3_FUNC_DECL_AST:
544 return _to_func_decl_ref(a, ctx)
545 else:
546 return _to_expr_ref(a, ctx)
547
548
549
554
555def _sort_kind(ctx, s):
556 return Z3_get_sort_kind(ctx.ref(), s)
557
558
560 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
561
562 def as_ast(self):
563 return Z3_sort_to_ast(self.ctx_ref(), self.astast)
564
565 def get_id(self):
566 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
567
568 def kind(self):
569 """Return the Z3 internal kind of a sort.
570 This method can be used to test if `self` is one of the Z3 builtin sorts.
571
572 >>> b = BoolSort()
573 >>> b.kind() == Z3_BOOL_SORT
574 True
575 >>> b.kind() == Z3_INT_SORT
576 False
577 >>> A = ArraySort(IntSort(), IntSort())
578 >>> A.kind() == Z3_ARRAY_SORT
579 True
580 >>> A.kind() == Z3_INT_SORT
581 False
582 """
583 return _sort_kind(self.ctxctx, self.astast)
584
585 def subsort(self, other):
586 """Return `True` if `self` is a subsort of `other`.
587
588 >>> IntSort().subsort(RealSort())
589 True
590 """
591 return False
592
593 def cast(self, val):
594 """Try to cast `val` as an element of sort `self`.
595
596 This method is used in Z3Py to convert Python objects such as integers,
597 floats, longs and strings into Z3 expressions.
598
599 >>> x = Int('x')
600 >>> RealSort().cast(x)
601 ToReal(x)
602 """
603 if z3_debug():
604 _z3_assert(is_expr(val), "Z3 expression expected")
605 _z3_assert(self.eq(val.sort()), "Sort mismatch")
606 return val
607
608 def name(self):
609 """Return the name (string) of sort `self`.
610
611 >>> BoolSort().name()
612 'Bool'
613 >>> ArraySort(IntSort(), IntSort()).name()
614 'Array'
615 """
616 return _symbol2py(self.ctxctx, Z3_get_sort_name(self.ctx_ref(), self.astast))
617
618 def __eq__(self, other):
619 """Return `True` if `self` and `other` are the same Z3 sort.
620
621 >>> p = Bool('p')
622 >>> p.sort() == BoolSort()
623 True
624 >>> p.sort() == IntSort()
625 False
626 """
627 if other is None:
628 return False
629 return Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
630
631 def __ne__(self, other):
632 """Return `True` if `self` and `other` are not the same Z3 sort.
633
634 >>> p = Bool('p')
635 >>> p.sort() != BoolSort()
636 False
637 >>> p.sort() != IntSort()
638 True
639 """
640 return not Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
641
642 def __hash__(self):
643 """ Hash code. """
644 return AstRef.__hash__(self)
645
646
647def is_sort(s):
648 """Return `True` if `s` is a Z3 sort.
649
650 >>> is_sort(IntSort())
651 True
652 >>> is_sort(Int('x'))
653 False
654 >>> is_expr(Int('x'))
655 True
656 """
657 return isinstance(s, SortRef)
658
659
660def _to_sort_ref(s, ctx):
661 if z3_debug():
662 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
663 k = _sort_kind(ctx, s)
664 if k == Z3_BOOL_SORT:
665 return BoolSortRef(s, ctx)
666 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
667 return ArithSortRef(s, ctx)
668 elif k == Z3_BV_SORT:
669 return BitVecSortRef(s, ctx)
670 elif k == Z3_ARRAY_SORT:
671 return ArraySortRef(s, ctx)
672 elif k == Z3_DATATYPE_SORT:
673 return DatatypeSortRef(s, ctx)
674 elif k == Z3_FINITE_DOMAIN_SORT:
675 return FiniteDomainSortRef(s, ctx)
676 elif k == Z3_FLOATING_POINT_SORT:
677 return FPSortRef(s, ctx)
678 elif k == Z3_ROUNDING_MODE_SORT:
679 return FPRMSortRef(s, ctx)
680 elif k == Z3_RE_SORT:
681 return ReSortRef(s, ctx)
682 elif k == Z3_SEQ_SORT:
683 return SeqSortRef(s, ctx)
684 elif k == Z3_CHAR_SORT:
685 return CharSortRef(s, ctx)
686 elif k == Z3_TYPE_VAR:
687 return TypeVarRef(s, ctx)
688 return SortRef(s, ctx)
689
690
691def _sort(ctx, a):
692 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
693
694
695def DeclareSort(name, ctx=None):
696 """Create a new uninterpreted sort named `name`.
697
698 If `ctx=None`, then the new sort is declared in the global Z3Py context.
699
700 >>> A = DeclareSort('A')
701 >>> a = Const('a', A)
702 >>> b = Const('b', A)
703 >>> a.sort() == A
704 True
705 >>> b.sort() == A
706 True
707 >>> a == b
708 a == b
709 """
710 ctx = _get_ctx(ctx)
711 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
712
714 """Type variable reference"""
715
716 def subsort(self, other):
717 return True
718
719 def cast(self, val):
720 return val
721
722
723def DeclareTypeVar(name, ctx=None):
724 """Create a new type variable named `name`.
725
726 If `ctx=None`, then the new sort is declared in the global Z3Py context.
727
728 """
729 ctx = _get_ctx(ctx)
730 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
731
732
733
738
739
741 """Function declaration. Every constant and function have an associated declaration.
742
743 The declaration assigns a name, a sort (i.e., type), and for function
744 the sort (i.e., type) of each of its arguments. Note that, in Z3,
745 a constant is a function with 0 arguments.
746 """
747
748 def as_ast(self):
749 return Z3_func_decl_to_ast(self.ctx_ref(), self.astast)
750
751 def get_id(self):
752 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
753
754 def as_func_decl(self):
755 return self.astast
756
757 def name(self):
758 """Return the name of the function declaration `self`.
759
760 >>> f = Function('f', IntSort(), IntSort())
761 >>> f.name()
762 'f'
763 >>> isinstance(f.name(), str)
764 True
765 """
766 return _symbol2py(self.ctxctx, Z3_get_decl_name(self.ctx_ref(), self.astast))
767
768 def arity(self):
769 """Return the number of arguments of a function declaration.
770 If `self` is a constant, then `self.arity()` is 0.
771
772 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
773 >>> f.arity()
774 2
775 """
776 return int(Z3_get_arity(self.ctx_ref(), self.astast))
777
778 def domain(self, i):
779 """Return the sort of the argument `i` of a function declaration.
780 This method assumes that `0 <= i < self.arity()`.
781
782 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
783 >>> f.domain(0)
784 Int
785 >>> f.domain(1)
786 Real
787 """
788 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.astast, i), self.ctxctx)
789
790 def range(self):
791 """Return the sort of the range of a function declaration.
792 For constants, this is the sort of the constant.
793
794 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
795 >>> f.range()
796 Bool
797 """
798 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.astast), self.ctxctx)
799
800 def kind(self):
801 """Return the internal kind of a function declaration.
802 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
803
804 >>> x = Int('x')
805 >>> d = (x + 1).decl()
806 >>> d.kind() == Z3_OP_ADD
807 True
808 >>> d.kind() == Z3_OP_MUL
809 False
810 """
811 return Z3_get_decl_kind(self.ctx_ref(), self.astast)
812
813 def params(self):
814 ctx = self.ctxctx
816 result = [None for i in range(n)]
817 for i in range(n):
818 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.astast, i)
819 if k == Z3_PARAMETER_INT:
820 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.astast, i)
821 elif k == Z3_PARAMETER_DOUBLE:
822 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.astast, i)
823 elif k == Z3_PARAMETER_RATIONAL:
824 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.astast, i)
825 elif k == Z3_PARAMETER_SYMBOL:
826 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.astast, i)
827 elif k == Z3_PARAMETER_SORT:
828 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.astast, i), ctx)
829 elif k == Z3_PARAMETER_AST:
830 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.astast, i), ctx)
831 elif k == Z3_PARAMETER_FUNC_DECL:
832 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.astast, i), ctx)
833 else:
834 assert(False)
835 return result
836
837 def __call__(self, *args):
838 """Create a Z3 application expression using the function `self`, and the given arguments.
839
840 The arguments must be Z3 expressions. This method assumes that
841 the sorts of the elements in `args` match the sorts of the
842 domain. Limited coercion is supported. For example, if
843 args[0] is a Python integer, and the function expects a Z3
844 integer, then the argument is automatically converted into a
845 Z3 integer.
846
847 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
848 >>> x = Int('x')
849 >>> y = Real('y')
850 >>> f(x, y)
851 f(x, y)
852 >>> f(x, x)
853 f(x, ToReal(x))
854 """
855 args = _get_args(args)
856 num = len(args)
857 _args = (Ast * num)()
858 saved = []
859 for i in range(num):
860 # self.domain(i).cast(args[i]) may create a new Z3 expression,
861 # then we must save in 'saved' to prevent it from being garbage collected.
862 tmp = self.domain(i).cast(args[i])
863 saved.append(tmp)
864 _args[i] = tmp.as_ast()
865 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.astast, len(args), _args), self.ctxctx)
866
867
869 """Return `True` if `a` is a Z3 function declaration.
870
871 >>> f = Function('f', IntSort(), IntSort())
872 >>> is_func_decl(f)
873 True
874 >>> x = Real('x')
875 >>> is_func_decl(x)
876 False
877 """
878 return isinstance(a, FuncDeclRef)
879
880
881def Function(name, *sig):
882 """Create a new Z3 uninterpreted function with the given sorts.
883
884 >>> f = Function('f', IntSort(), IntSort())
885 >>> f(f(0))
886 f(f(0))
887 """
888 sig = _get_args(sig)
889 if z3_debug():
890 _z3_assert(len(sig) > 0, "At least two arguments expected")
891 arity = len(sig) - 1
892 rng = sig[arity]
893 if z3_debug():
894 _z3_assert(is_sort(rng), "Z3 sort expected")
895 dom = (Sort * arity)()
896 for i in range(arity):
897 if z3_debug():
898 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
899 dom[i] = sig[i].ast
900 ctx = rng.ctx
901 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
902
903
905 """Create a new fresh Z3 uninterpreted function with the given sorts.
906 """
907 sig = _get_args(sig)
908 if z3_debug():
909 _z3_assert(len(sig) > 0, "At least two arguments expected")
910 arity = len(sig) - 1
911 rng = sig[arity]
912 if z3_debug():
913 _z3_assert(is_sort(rng), "Z3 sort expected")
914 dom = (z3.Sort * arity)()
915 for i in range(arity):
916 if z3_debug():
917 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
918 dom[i] = sig[i].ast
919 ctx = rng.ctx
920 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
921
922
924 return FuncDeclRef(a, ctx)
925
926
927def RecFunction(name, *sig):
928 """Create a new Z3 recursive with the given sorts."""
929 sig = _get_args(sig)
930 if z3_debug():
931 _z3_assert(len(sig) > 0, "At least two arguments expected")
932 arity = len(sig) - 1
933 rng = sig[arity]
934 if z3_debug():
935 _z3_assert(is_sort(rng), "Z3 sort expected")
936 dom = (Sort * arity)()
937 for i in range(arity):
938 if z3_debug():
939 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
940 dom[i] = sig[i].ast
941 ctx = rng.ctx
942 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
943
944
945def RecAddDefinition(f, args, body):
946 """Set the body of a recursive function.
947 Recursive definitions can be simplified if they are applied to ground
948 arguments.
949 >>> ctx = Context()
950 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
951 >>> n = Int('n', ctx)
952 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
953 >>> simplify(fac(5))
954 120
955 >>> s = Solver(ctx=ctx)
956 >>> s.add(fac(n) < 3)
957 >>> s.check()
958 sat
959 >>> s.model().eval(fac(5))
960 120
961 """
962 if is_app(args):
963 args = [args]
964 ctx = body.ctx
965 args = _get_args(args)
966 n = len(args)
967 _args = (Ast * n)()
968 for i in range(n):
969 _args[i] = args[i].ast
970 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
971
972
977
978
980 """Constraints, formulas and terms are expressions in Z3.
981
982 Expressions are ASTs. Every expression has a sort.
983 There are three main kinds of expressions:
984 function applications, quantifiers and bounded variables.
985 A constant is a function application with 0 arguments.
986 For quantifier free problems, all expressions are
987 function applications.
988 """
989
990 def as_ast(self):
991 return self.ast
992
993 def get_id(self):
994 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
995
996 def sort(self):
997 """Return the sort of expression `self`.
998
999 >>> x = Int('x')
1000 >>> (x + 1).sort()
1001 Int
1002 >>> y = Real('y')
1003 >>> (x + y).sort()
1004 Real
1005 """
1006 return _sort(self.ctxctx, self.as_astas_ast())
1007
1008 def sort_kind(self):
1009 """Shorthand for `self.sort().kind()`.
1010
1011 >>> a = Array('a', IntSort(), IntSort())
1012 >>> a.sort_kind() == Z3_ARRAY_SORT
1013 True
1014 >>> a.sort_kind() == Z3_INT_SORT
1015 False
1016 """
1017 return self.sort().kind()
1018
1019 def __eq__(self, other):
1020 """Return a Z3 expression that represents the constraint `self == other`.
1021
1022 If `other` is `None`, then this method simply returns `False`.
1023
1024 >>> a = Int('a')
1025 >>> b = Int('b')
1026 >>> a == b
1027 a == b
1028 >>> a is None
1029 False
1030 """
1031 if other is None:
1032 return False
1033 a, b = _coerce_exprs(self, other)
1034 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctx)
1035
1036 def __hash__(self):
1037 """ Hash code. """
1038 return AstRef.__hash__(self)
1039
1040 def __ne__(self, other):
1041 """Return a Z3 expression that represents the constraint `self != other`.
1042
1043 If `other` is `None`, then this method simply returns `True`.
1044
1045 >>> a = Int('a')
1046 >>> b = Int('b')
1047 >>> a != b
1048 a != b
1049 >>> a is not None
1050 True
1051 """
1052 if other is None:
1053 return True
1054 a, b = _coerce_exprs(self, other)
1055 _args, sz = _to_ast_array((a, b))
1056 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctxctx)
1057
1058 def params(self):
1059 return self.decl().params()
1060
1061 def decl(self):
1062 """Return the Z3 function declaration associated with a Z3 application.
1063
1064 >>> f = Function('f', IntSort(), IntSort())
1065 >>> a = Int('a')
1066 >>> t = f(a)
1067 >>> eq(t.decl(), f)
1068 True
1069 >>> (a + 1).decl()
1070 +
1071 """
1072 if z3_debug():
1073 _z3_assert(is_app(self), "Z3 application expected")
1074 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_astas_ast()), self.ctxctx)
1075
1076 def num_args(self):
1077 """Return the number of arguments of a Z3 application.
1078
1079 >>> a = Int('a')
1080 >>> b = Int('b')
1081 >>> (a + b).num_args()
1082 2
1083 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1084 >>> t = f(a, b, 0)
1085 >>> t.num_args()
1086 3
1087 """
1088 if z3_debug():
1089 _z3_assert(is_app(self), "Z3 application expected")
1090 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_astas_ast()))
1091
1092 def arg(self, idx):
1093 """Return argument `idx` of the application `self`.
1094
1095 This method assumes that `self` is a function application with at least `idx+1` arguments.
1096
1097 >>> a = Int('a')
1098 >>> b = Int('b')
1099 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1100 >>> t = f(a, b, 0)
1101 >>> t.arg(0)
1102 a
1103 >>> t.arg(1)
1104 b
1105 >>> t.arg(2)
1106 0
1107 """
1108 if z3_debug():
1109 _z3_assert(is_app(self), "Z3 application expected")
1110 _z3_assert(idx < self.num_args(), "Invalid argument index")
1111 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_astas_ast(), idx), self.ctxctx)
1112
1113 def children(self):
1114 """Return a list containing the children of the given expression
1115
1116 >>> a = Int('a')
1117 >>> b = Int('b')
1118 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1119 >>> t = f(a, b, 0)
1120 >>> t.children()
1121 [a, b, 0]
1122 """
1123 if is_app(self):
1124 return [self.arg(i) for i in range(self.num_args())]
1125 else:
1126 return []
1127
1128 def from_string(self, s):
1129 pass
1130
1131 def serialize(self):
1132 s = Solver()
1133 f = Function('F', self.sort(), BoolSort(self.ctx))
1134 s.add(f(self))
1135 return s.sexpr()
1136
1138 """inverse function to the serialize method on ExprRef.
1139 It is made available to make it easier for users to serialize expressions back and forth between
1140 strings. Solvers can be serialized using the 'sexpr()' method.
1141 """
1142 s = Solver()
1143 s.from_string(st)
1144 if len(s.assertions()) != 1:
1145 raise Z3Exception("single assertion expected")
1146 fml = s.assertions()[0]
1147 if fml.num_args() != 1:
1148 raise Z3Exception("dummy function 'F' expected")
1149 return fml.arg(0)
1150
1151def _to_expr_ref(a, ctx):
1152 if isinstance(a, Pattern):
1153 return PatternRef(a, ctx)
1154 ctx_ref = ctx.ref()
1155 k = Z3_get_ast_kind(ctx_ref, a)
1156 if k == Z3_QUANTIFIER_AST:
1157 return QuantifierRef(a, ctx)
1158 sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1159 if sk == Z3_BOOL_SORT:
1160 return BoolRef(a, ctx)
1161 if sk == Z3_INT_SORT:
1162 if k == Z3_NUMERAL_AST:
1163 return IntNumRef(a, ctx)
1164 return ArithRef(a, ctx)
1165 if sk == Z3_REAL_SORT:
1166 if k == Z3_NUMERAL_AST:
1167 return RatNumRef(a, ctx)
1168 if _is_algebraic(ctx, a):
1169 return AlgebraicNumRef(a, ctx)
1170 return ArithRef(a, ctx)
1171 if sk == Z3_BV_SORT:
1172 if k == Z3_NUMERAL_AST:
1173 return BitVecNumRef(a, ctx)
1174 else:
1175 return BitVecRef(a, ctx)
1176 if sk == Z3_ARRAY_SORT:
1177 return ArrayRef(a, ctx)
1178 if sk == Z3_DATATYPE_SORT:
1179 return DatatypeRef(a, ctx)
1180 if sk == Z3_FLOATING_POINT_SORT:
1181 if k == Z3_APP_AST and _is_numeral(ctx, a):
1182 return FPNumRef(a, ctx)
1183 else:
1184 return FPRef(a, ctx)
1185 if sk == Z3_FINITE_DOMAIN_SORT:
1186 if k == Z3_NUMERAL_AST:
1187 return FiniteDomainNumRef(a, ctx)
1188 else:
1189 return FiniteDomainRef(a, ctx)
1190 if sk == Z3_ROUNDING_MODE_SORT:
1191 return FPRMRef(a, ctx)
1192 if sk == Z3_SEQ_SORT:
1193 return SeqRef(a, ctx)
1194 if sk == Z3_CHAR_SORT:
1195 return CharRef(a, ctx)
1196 if sk == Z3_RE_SORT:
1197 return ReRef(a, ctx)
1198 return ExprRef(a, ctx)
1199
1200
1202 if is_expr(a):
1203 s1 = a.sort()
1204 if s is None:
1205 return s1
1206 if s1.eq(s):
1207 return s
1208 elif s.subsort(s1):
1209 return s1
1210 elif s1.subsort(s):
1211 return s
1212 else:
1213 if z3_debug():
1214 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1215 _z3_assert(False, "sort mismatch")
1216 else:
1217 return s
1218
1219
1220def _coerce_exprs(a, b, ctx=None):
1221 if not is_expr(a) and not is_expr(b):
1222 a = _py2expr(a, ctx)
1223 b = _py2expr(b, ctx)
1224 if isinstance(a, str) and isinstance(b, SeqRef):
1225 a = StringVal(a, b.ctx)
1226 if isinstance(b, str) and isinstance(a, SeqRef):
1227 b = StringVal(b, a.ctx)
1228 if isinstance(a, float) and isinstance(b, ArithRef):
1229 a = RealVal(a, b.ctx)
1230 if isinstance(b, float) and isinstance(a, ArithRef):
1231 b = RealVal(b, a.ctx)
1232
1233 s = None
1234 s = _coerce_expr_merge(s, a)
1235 s = _coerce_expr_merge(s, b)
1236 a = s.cast(a)
1237 b = s.cast(b)
1238 return (a, b)
1239
1240
1241def _reduce(func, sequence, initial):
1242 result = initial
1243 for element in sequence:
1244 result = func(result, element)
1245 return result
1246
1247
1248def _coerce_expr_list(alist, ctx=None):
1249 has_expr = False
1250 for a in alist:
1251 if is_expr(a):
1252 has_expr = True
1253 break
1254 if not has_expr:
1255 alist = [_py2expr(a, ctx) for a in alist]
1256 s = _reduce(_coerce_expr_merge, alist, None)
1257 return [s.cast(a) for a in alist]
1258
1259
1260def is_expr(a):
1261 """Return `True` if `a` is a Z3 expression.
1262
1263 >>> a = Int('a')
1264 >>> is_expr(a)
1265 True
1266 >>> is_expr(a + 1)
1267 True
1268 >>> is_expr(IntSort())
1269 False
1270 >>> is_expr(1)
1271 False
1272 >>> is_expr(IntVal(1))
1273 True
1274 >>> x = Int('x')
1275 >>> is_expr(ForAll(x, x >= 0))
1276 True
1277 >>> is_expr(FPVal(1.0))
1278 True
1279 """
1280 return isinstance(a, ExprRef)
1281
1282
1283def is_app(a):
1284 """Return `True` if `a` is a Z3 function application.
1285
1286 Note that, constants are function applications with 0 arguments.
1287
1288 >>> a = Int('a')
1289 >>> is_app(a)
1290 True
1291 >>> is_app(a + 1)
1292 True
1293 >>> is_app(IntSort())
1294 False
1295 >>> is_app(1)
1296 False
1297 >>> is_app(IntVal(1))
1298 True
1299 >>> x = Int('x')
1300 >>> is_app(ForAll(x, x >= 0))
1301 False
1302 """
1303 if not isinstance(a, ExprRef):
1304 return False
1305 k = _ast_kind(a.ctx, a)
1306 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1307
1308
1310 """Return `True` if `a` is Z3 constant/variable expression.
1311
1312 >>> a = Int('a')
1313 >>> is_const(a)
1314 True
1315 >>> is_const(a + 1)
1316 False
1317 >>> is_const(1)
1318 False
1319 >>> is_const(IntVal(1))
1320 True
1321 >>> x = Int('x')
1322 >>> is_const(ForAll(x, x >= 0))
1323 False
1324 """
1325 return is_app(a) and a.num_args() == 0
1326
1327
1328def is_var(a):
1329 """Return `True` if `a` is variable.
1330
1331 Z3 uses de-Bruijn indices for representing bound variables in
1332 quantifiers.
1333
1334 >>> x = Int('x')
1335 >>> is_var(x)
1336 False
1337 >>> is_const(x)
1338 True
1339 >>> f = Function('f', IntSort(), IntSort())
1340 >>> # Z3 replaces x with bound variables when ForAll is executed.
1341 >>> q = ForAll(x, f(x) == x)
1342 >>> b = q.body()
1343 >>> b
1344 f(Var(0)) == Var(0)
1345 >>> b.arg(1)
1346 Var(0)
1347 >>> is_var(b.arg(1))
1348 True
1349 """
1350 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1351
1352
1354 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1355
1356 >>> x = Int('x')
1357 >>> y = Int('y')
1358 >>> is_var(x)
1359 False
1360 >>> is_const(x)
1361 True
1362 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1363 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1364 >>> q = ForAll([x, y], f(x, y) == x + y)
1365 >>> q.body()
1366 f(Var(1), Var(0)) == Var(1) + Var(0)
1367 >>> b = q.body()
1368 >>> b.arg(0)
1369 f(Var(1), Var(0))
1370 >>> v1 = b.arg(0).arg(0)
1371 >>> v2 = b.arg(0).arg(1)
1372 >>> v1
1373 Var(1)
1374 >>> v2
1375 Var(0)
1376 >>> get_var_index(v1)
1377 1
1378 >>> get_var_index(v2)
1379 0
1380 """
1381 if z3_debug():
1382 _z3_assert(is_var(a), "Z3 bound variable expected")
1383 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1384
1385
1386def is_app_of(a, k):
1387 """Return `True` if `a` is an application of the given kind `k`.
1388
1389 >>> x = Int('x')
1390 >>> n = x + 1
1391 >>> is_app_of(n, Z3_OP_ADD)
1392 True
1393 >>> is_app_of(n, Z3_OP_MUL)
1394 False
1395 """
1396 return is_app(a) and a.decl().kind() == k
1397
1398
1399def If(a, b, c, ctx=None):
1400 """Create a Z3 if-then-else expression.
1401
1402 >>> x = Int('x')
1403 >>> y = Int('y')
1404 >>> max = If(x > y, x, y)
1405 >>> max
1406 If(x > y, x, y)
1407 >>> simplify(max)
1408 If(x <= y, y, x)
1409 """
1410 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1411 return Cond(a, b, c, ctx)
1412 else:
1413 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1414 s = BoolSort(ctx)
1415 a = s.cast(a)
1416 b, c = _coerce_exprs(b, c, ctx)
1417 if z3_debug():
1418 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1419 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1420
1421
1422def Distinct(*args):
1423 """Create a Z3 distinct expression.
1424
1425 >>> x = Int('x')
1426 >>> y = Int('y')
1427 >>> Distinct(x, y)
1428 x != y
1429 >>> z = Int('z')
1430 >>> Distinct(x, y, z)
1431 Distinct(x, y, z)
1432 >>> simplify(Distinct(x, y, z))
1433 Distinct(x, y, z)
1434 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1435 And(Not(x == y), Not(x == z), Not(y == z))
1436 """
1437 args = _get_args(args)
1438 ctx = _ctx_from_ast_arg_list(args)
1439 if z3_debug():
1440 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1441 args = _coerce_expr_list(args, ctx)
1442 _args, sz = _to_ast_array(args)
1443 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1444
1445
1446def _mk_bin(f, a, b):
1447 args = (Ast * 2)()
1448 if z3_debug():
1449 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1450 args[0] = a.as_ast()
1451 args[1] = b.as_ast()
1452 return f(a.ctx.ref(), 2, args)
1453
1454
1455def Const(name, sort):
1456 """Create a constant of the given sort.
1457
1458 >>> Const('x', IntSort())
1459 x
1460 """
1461 if z3_debug():
1462 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1463 ctx = sort.ctx
1464 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1465
1466
1467def Consts(names, sort):
1468 """Create several constants of the given sort.
1469
1470 `names` is a string containing the names of all constants to be created.
1471 Blank spaces separate the names of different constants.
1472
1473 >>> x, y, z = Consts('x y z', IntSort())
1474 >>> x + y + z
1475 x + y + z
1476 """
1477 if isinstance(names, str):
1478 names = names.split(" ")
1479 return [Const(name, sort) for name in names]
1480
1481
1482def FreshConst(sort, prefix="c"):
1483 """Create a fresh constant of a specified sort"""
1484 ctx = _get_ctx(sort.ctx)
1485 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1486
1487
1488def Var(idx, s):
1489 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1490 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1491 declarations.
1492
1493 >>> Var(0, IntSort())
1494 Var(0)
1495 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1496 False
1497 """
1498 if z3_debug():
1499 _z3_assert(is_sort(s), "Z3 sort expected")
1500 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1501
1502
1503def RealVar(idx, ctx=None):
1504 """
1505 Create a real free variable. Free variables are used to create quantified formulas.
1506 They are also used to create polynomials.
1507
1508 >>> RealVar(0)
1509 Var(0)
1510 """
1511 return Var(idx, RealSort(ctx))
1512
1513
1514def RealVarVector(n, ctx=None):
1515 """
1516 Create a list of Real free variables.
1517 The variables have ids: 0, 1, ..., n-1
1518
1519 >>> x0, x1, x2, x3 = RealVarVector(4)
1520 >>> x2
1521 Var(2)
1522 """
1523 return [RealVar(i, ctx) for i in range(n)]
1524
1525
1530
1531
1533 """Boolean sort."""
1534
1535 def cast(self, val):
1536 """Try to cast `val` as a Boolean.
1537
1538 >>> x = BoolSort().cast(True)
1539 >>> x
1540 True
1541 >>> is_expr(x)
1542 True
1543 >>> is_expr(True)
1544 False
1545 >>> x.sort()
1546 Bool
1547 """
1548 if isinstance(val, bool):
1549 return BoolVal(val, self.ctxctxctx)
1550 if z3_debug():
1551 if not is_expr(val):
1552 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1553 _z3_assert(is_expr(val), msg % (val, type(val)))
1554 if not self.eq(val.sort()):
1555 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1556 return val
1557
1558 def subsort(self, other):
1559 return isinstance(other, ArithSortRef)
1560
1561 def is_int(self):
1562 return True
1563
1564 def is_bool(self):
1565 return True
1566
1567
1569 """All Boolean expressions are instances of this class."""
1570
1571 def sort(self):
1573
1574 def __add__(self, other):
1575 if isinstance(other, BoolRef):
1576 other = If(other, 1, 0)
1577 return If(self, 1, 0) + other
1578
1579 def __radd__(self, other):
1580 return self + other
1581
1582 def __rmul__(self, other):
1583 return self * other
1584
1585 def __mul__(self, other):
1586 """Create the Z3 expression `self * other`.
1587 """
1588 if isinstance(other, int) and other == 1:
1589 return If(self, 1, 0)
1590 if isinstance(other, int) and other == 0:
1591 return IntVal(0, self.ctxctxctx)
1592 if isinstance(other, BoolRef):
1593 other = If(other, 1, 0)
1594 return If(self, other, 0)
1595
1596 def __and__(self, other):
1597 return And(self, other)
1598
1599 def __or__(self, other):
1600 return Or(self, other)
1601
1602 def __xor__(self, other):
1603 return Xor(self, other)
1604
1605 def __invert__(self):
1606 return Not(self)
1607
1608
1609
1610
1611def is_bool(a):
1612 """Return `True` if `a` is a Z3 Boolean expression.
1613
1614 >>> p = Bool('p')
1615 >>> is_bool(p)
1616 True
1617 >>> q = Bool('q')
1618 >>> is_bool(And(p, q))
1619 True
1620 >>> x = Real('x')
1621 >>> is_bool(x)
1622 False
1623 >>> is_bool(x == 0)
1624 True
1625 """
1626 return isinstance(a, BoolRef)
1627
1628
1629def is_true(a):
1630 """Return `True` if `a` is the Z3 true expression.
1631
1632 >>> p = Bool('p')
1633 >>> is_true(p)
1634 False
1635 >>> is_true(simplify(p == p))
1636 True
1637 >>> x = Real('x')
1638 >>> is_true(x == 0)
1639 False
1640 >>> # True is a Python Boolean expression
1641 >>> is_true(True)
1642 False
1643 """
1644 return is_app_of(a, Z3_OP_TRUE)
1645
1646
1648 """Return `True` if `a` is the Z3 false expression.
1649
1650 >>> p = Bool('p')
1651 >>> is_false(p)
1652 False
1653 >>> is_false(False)
1654 False
1655 >>> is_false(BoolVal(False))
1656 True
1657 """
1658 return is_app_of(a, Z3_OP_FALSE)
1659
1660
1661def is_and(a):
1662 """Return `True` if `a` is a Z3 and expression.
1663
1664 >>> p, q = Bools('p q')
1665 >>> is_and(And(p, q))
1666 True
1667 >>> is_and(Or(p, q))
1668 False
1669 """
1670 return is_app_of(a, Z3_OP_AND)
1671
1672
1673def is_or(a):
1674 """Return `True` if `a` is a Z3 or expression.
1675
1676 >>> p, q = Bools('p q')
1677 >>> is_or(Or(p, q))
1678 True
1679 >>> is_or(And(p, q))
1680 False
1681 """
1682 return is_app_of(a, Z3_OP_OR)
1683
1684
1686 """Return `True` if `a` is a Z3 implication expression.
1687
1688 >>> p, q = Bools('p q')
1689 >>> is_implies(Implies(p, q))
1690 True
1691 >>> is_implies(And(p, q))
1692 False
1693 """
1694 return is_app_of(a, Z3_OP_IMPLIES)
1695
1696
1697def is_not(a):
1698 """Return `True` if `a` is a Z3 not expression.
1699
1700 >>> p = Bool('p')
1701 >>> is_not(p)
1702 False
1703 >>> is_not(Not(p))
1704 True
1705 """
1706 return is_app_of(a, Z3_OP_NOT)
1707
1708
1709def is_eq(a):
1710 """Return `True` if `a` is a Z3 equality expression.
1711
1712 >>> x, y = Ints('x y')
1713 >>> is_eq(x == y)
1714 True
1715 """
1716 return is_app_of(a, Z3_OP_EQ)
1717
1718
1720 """Return `True` if `a` is a Z3 distinct expression.
1721
1722 >>> x, y, z = Ints('x y z')
1723 >>> is_distinct(x == y)
1724 False
1725 >>> is_distinct(Distinct(x, y, z))
1726 True
1727 """
1728 return is_app_of(a, Z3_OP_DISTINCT)
1729
1730
1731def BoolSort(ctx=None):
1732 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1733
1734 >>> BoolSort()
1735 Bool
1736 >>> p = Const('p', BoolSort())
1737 >>> is_bool(p)
1738 True
1739 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1740 >>> r(0, 1)
1741 r(0, 1)
1742 >>> is_bool(r(0, 1))
1743 True
1744 """
1745 ctx = _get_ctx(ctx)
1746 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1747
1748
1749def BoolVal(val, ctx=None):
1750 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1751
1752 >>> BoolVal(True)
1753 True
1754 >>> is_true(BoolVal(True))
1755 True
1756 >>> is_true(True)
1757 False
1758 >>> is_false(BoolVal(False))
1759 True
1760 """
1761 ctx = _get_ctx(ctx)
1762 if val:
1763 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1764 else:
1765 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1766
1767
1768def Bool(name, ctx=None):
1769 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1770
1771 >>> p = Bool('p')
1772 >>> q = Bool('q')
1773 >>> And(p, q)
1774 And(p, q)
1775 """
1776 ctx = _get_ctx(ctx)
1777 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1778
1779
1780def Bools(names, ctx=None):
1781 """Return a tuple of Boolean constants.
1782
1783 `names` is a single string containing all names separated by blank spaces.
1784 If `ctx=None`, then the global context is used.
1785
1786 >>> p, q, r = Bools('p q r')
1787 >>> And(p, Or(q, r))
1788 And(p, Or(q, r))
1789 """
1790 ctx = _get_ctx(ctx)
1791 if isinstance(names, str):
1792 names = names.split(" ")
1793 return [Bool(name, ctx) for name in names]
1794
1795
1796def BoolVector(prefix, sz, ctx=None):
1797 """Return a list of Boolean constants of size `sz`.
1798
1799 The constants are named using the given prefix.
1800 If `ctx=None`, then the global context is used.
1801
1802 >>> P = BoolVector('p', 3)
1803 >>> P
1804 [p__0, p__1, p__2]
1805 >>> And(P)
1806 And(p__0, p__1, p__2)
1807 """
1808 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1809
1810
1811def FreshBool(prefix="b", ctx=None):
1812 """Return a fresh Boolean constant in the given context using the given prefix.
1813
1814 If `ctx=None`, then the global context is used.
1815
1816 >>> b1 = FreshBool()
1817 >>> b2 = FreshBool()
1818 >>> eq(b1, b2)
1819 False
1820 """
1821 ctx = _get_ctx(ctx)
1822 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1823
1824
1825def Implies(a, b, ctx=None):
1826 """Create a Z3 implies expression.
1827
1828 >>> p, q = Bools('p q')
1829 >>> Implies(p, q)
1830 Implies(p, q)
1831 """
1832 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1833 s = BoolSort(ctx)
1834 a = s.cast(a)
1835 b = s.cast(b)
1836 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1837
1838
1839def Xor(a, b, ctx=None):
1840 """Create a Z3 Xor expression.
1841
1842 >>> p, q = Bools('p q')
1843 >>> Xor(p, q)
1844 Xor(p, q)
1845 >>> simplify(Xor(p, q))
1846 Not(p == q)
1847 """
1848 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1849 s = BoolSort(ctx)
1850 a = s.cast(a)
1851 b = s.cast(b)
1852 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1853
1854
1855def Not(a, ctx=None):
1856 """Create a Z3 not expression or probe.
1857
1858 >>> p = Bool('p')
1859 >>> Not(Not(p))
1860 Not(Not(p))
1861 >>> simplify(Not(Not(p)))
1862 p
1863 """
1864 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1865 if is_probe(a):
1866 # Not is also used to build probes
1867 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1868 else:
1869 s = BoolSort(ctx)
1870 a = s.cast(a)
1871 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1872
1873
1874def mk_not(a):
1875 if is_not(a):
1876 return a.arg(0)
1877 else:
1878 return Not(a)
1879
1880
1881def _has_probe(args):
1882 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1883 for arg in args:
1884 if is_probe(arg):
1885 return True
1886 return False
1887
1888
1889def And(*args):
1890 """Create a Z3 and-expression or and-probe.
1891
1892 >>> p, q, r = Bools('p q r')
1893 >>> And(p, q, r)
1894 And(p, q, r)
1895 >>> P = BoolVector('p', 5)
1896 >>> And(P)
1897 And(p__0, p__1, p__2, p__3, p__4)
1898 """
1899 last_arg = None
1900 if len(args) > 0:
1901 last_arg = args[len(args) - 1]
1902 if isinstance(last_arg, Context):
1903 ctx = args[len(args) - 1]
1904 args = args[:len(args) - 1]
1905 elif len(args) == 1 and isinstance(args[0], AstVector):
1906 ctx = args[0].ctx
1907 args = [a for a in args[0]]
1908 else:
1909 ctx = None
1910 args = _get_args(args)
1911 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1912 if z3_debug():
1913 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1914 if _has_probe(args):
1915 return _probe_and(args, ctx)
1916 else:
1917 args = _coerce_expr_list(args, ctx)
1918 _args, sz = _to_ast_array(args)
1919 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
1920
1921
1922def Or(*args):
1923 """Create a Z3 or-expression or or-probe.
1924
1925 >>> p, q, r = Bools('p q r')
1926 >>> Or(p, q, r)
1927 Or(p, q, r)
1928 >>> P = BoolVector('p', 5)
1929 >>> Or(P)
1930 Or(p__0, p__1, p__2, p__3, p__4)
1931 """
1932 last_arg = None
1933 if len(args) > 0:
1934 last_arg = args[len(args) - 1]
1935 if isinstance(last_arg, Context):
1936 ctx = args[len(args) - 1]
1937 args = args[:len(args) - 1]
1938 elif len(args) == 1 and isinstance(args[0], AstVector):
1939 ctx = args[0].ctx
1940 args = [a for a in args[0]]
1941 else:
1942 ctx = None
1943 args = _get_args(args)
1944 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1945 if z3_debug():
1946 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1947 if _has_probe(args):
1948 return _probe_or(args, ctx)
1949 else:
1950 args = _coerce_expr_list(args, ctx)
1951 _args, sz = _to_ast_array(args)
1952 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
1953
1954
1959
1960
1962 """Patterns are hints for quantifier instantiation.
1963
1964 """
1965
1966 def as_ast(self):
1967 return Z3_pattern_to_ast(self.ctx_ref(), self.astast)
1968
1969 def get_id(self):
1970 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
1971
1972
1974 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
1975
1976 >>> f = Function('f', IntSort(), IntSort())
1977 >>> x = Int('x')
1978 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
1979 >>> q
1980 ForAll(x, f(x) == 0)
1981 >>> q.num_patterns()
1982 1
1983 >>> is_pattern(q.pattern(0))
1984 True
1985 >>> q.pattern(0)
1986 f(Var(0))
1987 """
1988 return isinstance(a, PatternRef)
1989
1990
1991def MultiPattern(*args):
1992 """Create a Z3 multi-pattern using the given expressions `*args`
1993
1994 >>> f = Function('f', IntSort(), IntSort())
1995 >>> g = Function('g', IntSort(), IntSort())
1996 >>> x = Int('x')
1997 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
1998 >>> q
1999 ForAll(x, f(x) != g(x))
2000 >>> q.num_patterns()
2001 1
2002 >>> is_pattern(q.pattern(0))
2003 True
2004 >>> q.pattern(0)
2005 MultiPattern(f(Var(0)), g(Var(0)))
2006 """
2007 if z3_debug():
2008 _z3_assert(len(args) > 0, "At least one argument expected")
2009 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2010 ctx = args[0].ctx
2011 args, sz = _to_ast_array(args)
2012 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2013
2014
2016 if is_pattern(arg):
2017 return arg
2018 else:
2019 return MultiPattern(arg)
2020
2021
2026
2027
2029 """Universally and Existentially quantified formulas."""
2030
2031 def as_ast(self):
2032 return self.astast
2033
2034 def get_id(self):
2035 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2036
2037 def sort(self):
2038 """Return the Boolean sort or sort of Lambda."""
2039 if self.is_lambda():
2041 return BoolSort(self.ctxctxctxctx)
2042
2043 def is_forall(self):
2044 """Return `True` if `self` is a universal quantifier.
2045
2046 >>> f = Function('f', IntSort(), IntSort())
2047 >>> x = Int('x')
2048 >>> q = ForAll(x, f(x) == 0)
2049 >>> q.is_forall()
2050 True
2051 >>> q = Exists(x, f(x) != 0)
2052 >>> q.is_forall()
2053 False
2054 """
2056
2057 def is_exists(self):
2058 """Return `True` if `self` is an existential quantifier.
2059
2060 >>> f = Function('f', IntSort(), IntSort())
2061 >>> x = Int('x')
2062 >>> q = ForAll(x, f(x) == 0)
2063 >>> q.is_exists()
2064 False
2065 >>> q = Exists(x, f(x) != 0)
2066 >>> q.is_exists()
2067 True
2068 """
2069 return Z3_is_quantifier_exists(self.ctx_ref(), self.astast)
2070
2071 def is_lambda(self):
2072 """Return `True` if `self` is a lambda expression.
2073
2074 >>> f = Function('f', IntSort(), IntSort())
2075 >>> x = Int('x')
2076 >>> q = Lambda(x, f(x))
2077 >>> q.is_lambda()
2078 True
2079 >>> q = Exists(x, f(x) != 0)
2080 >>> q.is_lambda()
2081 False
2082 """
2083 return Z3_is_lambda(self.ctx_ref(), self.astast)
2084
2085 def __getitem__(self, arg):
2086 """Return the Z3 expression `self[arg]`.
2087 """
2088 if z3_debug():
2089 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2090 return _array_select(self, arg)
2091
2092 def weight(self):
2093 """Return the weight annotation of `self`.
2094
2095 >>> f = Function('f', IntSort(), IntSort())
2096 >>> x = Int('x')
2097 >>> q = ForAll(x, f(x) == 0)
2098 >>> q.weight()
2099 1
2100 >>> q = ForAll(x, f(x) == 0, weight=10)
2101 >>> q.weight()
2102 10
2103 """
2104 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.astast))
2105
2106 def skolem_id(self):
2107 """Return the skolem id of `self`.
2108 """
2110
2111 def qid(self):
2112 """Return the quantifier id of `self`.
2113 """
2114 return _symbol2py(self.ctxctxctxctx, Z3_get_quantifier_id(self.ctx_ref(), self.astast))
2115
2116 def num_patterns(self):
2117 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2118
2119 >>> f = Function('f', IntSort(), IntSort())
2120 >>> g = Function('g', IntSort(), IntSort())
2121 >>> x = Int('x')
2122 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2123 >>> q.num_patterns()
2124 2
2125 """
2126 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.astast))
2127
2128 def pattern(self, idx):
2129 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2130
2131 >>> f = Function('f', IntSort(), IntSort())
2132 >>> g = Function('g', IntSort(), IntSort())
2133 >>> x = Int('x')
2134 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2135 >>> q.num_patterns()
2136 2
2137 >>> q.pattern(0)
2138 f(Var(0))
2139 >>> q.pattern(1)
2140 g(Var(0))
2141 """
2142 if z3_debug():
2143 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2144 return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.astast, idx), self.ctxctxctxctx)
2145
2147 """Return the number of no-patterns."""
2149
2150 def no_pattern(self, idx):
2151 """Return a no-pattern."""
2152 if z3_debug():
2153 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2155
2156 def body(self):
2157 """Return the expression being quantified.
2158
2159 >>> f = Function('f', IntSort(), IntSort())
2160 >>> x = Int('x')
2161 >>> q = ForAll(x, f(x) == 0)
2162 >>> q.body()
2163 f(Var(0)) == 0
2164 """
2166
2167 def num_vars(self):
2168 """Return the number of variables bounded by this quantifier.
2169
2170 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2171 >>> x = Int('x')
2172 >>> y = Int('y')
2173 >>> q = ForAll([x, y], f(x, y) >= x)
2174 >>> q.num_vars()
2175 2
2176 """
2177 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.astast))
2178
2179 def var_name(self, idx):
2180 """Return a string representing a name used when displaying the quantifier.
2181
2182 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2183 >>> x = Int('x')
2184 >>> y = Int('y')
2185 >>> q = ForAll([x, y], f(x, y) >= x)
2186 >>> q.var_name(0)
2187 'x'
2188 >>> q.var_name(1)
2189 'y'
2190 """
2191 if z3_debug():
2192 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2193 return _symbol2py(self.ctxctxctxctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.astast, idx))
2194
2195 def var_sort(self, idx):
2196 """Return the sort of a bound variable.
2197
2198 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2199 >>> x = Int('x')
2200 >>> y = Real('y')
2201 >>> q = ForAll([x, y], f(x, y) >= x)
2202 >>> q.var_sort(0)
2203 Int
2204 >>> q.var_sort(1)
2205 Real
2206 """
2207 if z3_debug():
2208 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2210
2211 def children(self):
2212 """Return a list containing a single element self.body()
2213
2214 >>> f = Function('f', IntSort(), IntSort())
2215 >>> x = Int('x')
2216 >>> q = ForAll(x, f(x) == 0)
2217 >>> q.children()
2218 [f(Var(0)) == 0]
2219 """
2220 return [self.body()]
2221
2222
2224 """Return `True` if `a` is a Z3 quantifier.
2225
2226 >>> f = Function('f', IntSort(), IntSort())
2227 >>> x = Int('x')
2228 >>> q = ForAll(x, f(x) == 0)
2229 >>> is_quantifier(q)
2230 True
2231 >>> is_quantifier(f(x))
2232 False
2233 """
2234 return isinstance(a, QuantifierRef)
2235
2236
2237def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2238 if z3_debug():
2239 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2240 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2241 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2242 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2243 if is_app(vs):
2244 ctx = vs.ctx
2245 vs = [vs]
2246 else:
2247 ctx = vs[0].ctx
2248 if not is_expr(body):
2249 body = BoolVal(body, ctx)
2250 num_vars = len(vs)
2251 if num_vars == 0:
2252 return body
2253 _vs = (Ast * num_vars)()
2254 for i in range(num_vars):
2255 # TODO: Check if is constant
2256 _vs[i] = vs[i].as_ast()
2257 patterns = [_to_pattern(p) for p in patterns]
2258 num_pats = len(patterns)
2259 _pats = (Pattern * num_pats)()
2260 for i in range(num_pats):
2261 _pats[i] = patterns[i].ast
2262 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2263 qid = to_symbol(qid, ctx)
2264 skid = to_symbol(skid, ctx)
2265 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2266 num_vars, _vs,
2267 num_pats, _pats,
2268 num_no_pats, _no_pats,
2269 body.as_ast()), ctx)
2270
2271
2272def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2273 """Create a Z3 forall formula.
2274
2275 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2276
2277 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2278 >>> x = Int('x')
2279 >>> y = Int('y')
2280 >>> ForAll([x, y], f(x, y) >= x)
2281 ForAll([x, y], f(x, y) >= x)
2282 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2283 ForAll([x, y], f(x, y) >= x)
2284 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2285 ForAll([x, y], f(x, y) >= x)
2286 """
2287 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2288
2289
2290def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2291 """Create a Z3 exists formula.
2292
2293 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2294
2295
2296 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2297 >>> x = Int('x')
2298 >>> y = Int('y')
2299 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2300 >>> q
2301 Exists([x, y], f(x, y) >= x)
2302 >>> is_quantifier(q)
2303 True
2304 >>> r = Tactic('nnf')(q).as_expr()
2305 >>> is_quantifier(r)
2306 False
2307 """
2308 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2309
2310
2311def Lambda(vs, body):
2312 """Create a Z3 lambda expression.
2313
2314 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2315 >>> mem0 = Array('mem0', IntSort(), IntSort())
2316 >>> lo, hi, e, i = Ints('lo hi e i')
2317 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2318 >>> mem1
2319 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2320 """
2321 ctx = body.ctx
2322 if is_app(vs):
2323 vs = [vs]
2324 num_vars = len(vs)
2325 _vs = (Ast * num_vars)()
2326 for i in range(num_vars):
2327 # TODO: Check if is constant
2328 _vs[i] = vs[i].as_ast()
2329 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2330
2331
2336
2337
2339 """Real and Integer sorts."""
2340
2341 def is_real(self):
2342 """Return `True` if `self` is of the sort Real.
2343
2344 >>> x = Real('x')
2345 >>> x.is_real()
2346 True
2347 >>> (x + 1).is_real()
2348 True
2349 >>> x = Int('x')
2350 >>> x.is_real()
2351 False
2352 """
2353 return self.kind() == Z3_REAL_SORT
2354
2355 def is_int(self):
2356 """Return `True` if `self` is of the sort Integer.
2357
2358 >>> x = Int('x')
2359 >>> x.is_int()
2360 True
2361 >>> (x + 1).is_int()
2362 True
2363 >>> x = Real('x')
2364 >>> x.is_int()
2365 False
2366 """
2367 return self.kind() == Z3_INT_SORT
2368
2369 def is_bool(self):
2370 return False
2371
2372 def subsort(self, other):
2373 """Return `True` if `self` is a subsort of `other`."""
2374 return self.is_int() and is_arith_sort(other) and other.is_real()
2375
2376 def cast(self, val):
2377 """Try to cast `val` as an Integer or Real.
2378
2379 >>> IntSort().cast(10)
2380 10
2381 >>> is_int(IntSort().cast(10))
2382 True
2383 >>> is_int(10)
2384 False
2385 >>> RealSort().cast(10)
2386 10
2387 >>> is_real(RealSort().cast(10))
2388 True
2389 """
2390 if is_expr(val):
2391 if z3_debug():
2392 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
2393 val_s = val.sort()
2394 if self.eq(val_s):
2395 return val
2396 if val_s.is_int() and self.is_real():
2397 return ToReal(val)
2398 if val_s.is_bool() and self.is_int():
2399 return If(val, 1, 0)
2400 if val_s.is_bool() and self.is_real():
2401 return ToReal(If(val, 1, 0))
2402 if z3_debug():
2403 _z3_assert(False, "Z3 Integer/Real expression expected")
2404 else:
2405 if self.is_int():
2406 return IntVal(val, self.ctxctxctx)
2407 if self.is_real():
2408 return RealVal(val, self.ctxctxctx)
2409 if z3_debug():
2410 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2411 _z3_assert(False, msg % self)
2412
2413
2415 """Return `True` if s is an arithmetical sort (type).
2416
2417 >>> is_arith_sort(IntSort())
2418 True
2419 >>> is_arith_sort(RealSort())
2420 True
2421 >>> is_arith_sort(BoolSort())
2422 False
2423 >>> n = Int('x') + 1
2424 >>> is_arith_sort(n.sort())
2425 True
2426 """
2427 return isinstance(s, ArithSortRef)
2428
2429
2431 """Integer and Real expressions."""
2432
2433 def sort(self):
2434 """Return the sort (type) of the arithmetical expression `self`.
2435
2436 >>> Int('x').sort()
2437 Int
2438 >>> (Real('x') + 1).sort()
2439 Real
2440 """
2442
2443 def is_int(self):
2444 """Return `True` if `self` is an integer expression.
2445
2446 >>> x = Int('x')
2447 >>> x.is_int()
2448 True
2449 >>> (x + 1).is_int()
2450 True
2451 >>> y = Real('y')
2452 >>> (x + y).is_int()
2453 False
2454 """
2455 return self.sortsort().is_int()
2456
2457 def is_real(self):
2458 """Return `True` if `self` is an real expression.
2459
2460 >>> x = Real('x')
2461 >>> x.is_real()
2462 True
2463 >>> (x + 1).is_real()
2464 True
2465 """
2466 return self.sortsort().is_real()
2467
2468 def __add__(self, other):
2469 """Create the Z3 expression `self + other`.
2470
2471 >>> x = Int('x')
2472 >>> y = Int('y')
2473 >>> x + y
2474 x + y
2475 >>> (x + y).sort()
2476 Int
2477 """
2478 a, b = _coerce_exprs(self, other)
2479 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctxctxctx)
2480
2481 def __radd__(self, other):
2482 """Create the Z3 expression `other + self`.
2483
2484 >>> x = Int('x')
2485 >>> 10 + x
2486 10 + x
2487 """
2488 a, b = _coerce_exprs(self, other)
2489 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctxctxctx)
2490
2491 def __mul__(self, other):
2492 """Create the Z3 expression `self * other`.
2493
2494 >>> x = Real('x')
2495 >>> y = Real('y')
2496 >>> x * y
2497 x*y
2498 >>> (x * y).sort()
2499 Real
2500 """
2501 if isinstance(other, BoolRef):
2502 return If(other, self, 0)
2503 a, b = _coerce_exprs(self, other)
2504 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctxctxctx)
2505
2506 def __rmul__(self, other):
2507 """Create the Z3 expression `other * self`.
2508
2509 >>> x = Real('x')
2510 >>> 10 * x
2511 10*x
2512 """
2513 a, b = _coerce_exprs(self, other)
2514 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctxctxctx)
2515
2516 def __sub__(self, other):
2517 """Create the Z3 expression `self - other`.
2518
2519 >>> x = Int('x')
2520 >>> y = Int('y')
2521 >>> x - y
2522 x - y
2523 >>> (x - y).sort()
2524 Int
2525 """
2526 a, b = _coerce_exprs(self, other)
2527 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctxctxctx)
2528
2529 def __rsub__(self, other):
2530 """Create the Z3 expression `other - self`.
2531
2532 >>> x = Int('x')
2533 >>> 10 - x
2534 10 - x
2535 """
2536 a, b = _coerce_exprs(self, other)
2537 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctxctxctx)
2538
2539 def __pow__(self, other):
2540 """Create the Z3 expression `self**other` (** is the power operator).
2541
2542 >>> x = Real('x')
2543 >>> x**3
2544 x**3
2545 >>> (x**3).sort()
2546 Real
2547 >>> simplify(IntVal(2)**8)
2548 256
2549 """
2550 a, b = _coerce_exprs(self, other)
2551 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2552
2553 def __rpow__(self, other):
2554 """Create the Z3 expression `other**self` (** is the power operator).
2555
2556 >>> x = Real('x')
2557 >>> 2**x
2558 2**x
2559 >>> (2**x).sort()
2560 Real
2561 >>> simplify(2**IntVal(8))
2562 256
2563 """
2564 a, b = _coerce_exprs(self, other)
2565 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2566
2567 def __div__(self, other):
2568 """Create the Z3 expression `other/self`.
2569
2570 >>> x = Int('x')
2571 >>> y = Int('y')
2572 >>> x/y
2573 x/y
2574 >>> (x/y).sort()
2575 Int
2576 >>> (x/y).sexpr()
2577 '(div x y)'
2578 >>> x = Real('x')
2579 >>> y = Real('y')
2580 >>> x/y
2581 x/y
2582 >>> (x/y).sort()
2583 Real
2584 >>> (x/y).sexpr()
2585 '(/ x y)'
2586 """
2587 a, b = _coerce_exprs(self, other)
2588 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2589
2590 def __truediv__(self, other):
2591 """Create the Z3 expression `other/self`."""
2592 return self.__div__(other)
2593
2594 def __rdiv__(self, other):
2595 """Create the Z3 expression `other/self`.
2596
2597 >>> x = Int('x')
2598 >>> 10/x
2599 10/x
2600 >>> (10/x).sexpr()
2601 '(div 10 x)'
2602 >>> x = Real('x')
2603 >>> 10/x
2604 10/x
2605 >>> (10/x).sexpr()
2606 '(/ 10.0 x)'
2607 """
2608 a, b = _coerce_exprs(self, other)
2609 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2610
2611 def __rtruediv__(self, other):
2612 """Create the Z3 expression `other/self`."""
2613 return self.__rdiv__(other)
2614
2615 def __mod__(self, other):
2616 """Create the Z3 expression `other%self`.
2617
2618 >>> x = Int('x')
2619 >>> y = Int('y')
2620 >>> x % y
2621 x%y
2622 >>> simplify(IntVal(10) % IntVal(3))
2623 1
2624 """
2625 a, b = _coerce_exprs(self, other)
2626 if z3_debug():
2627 _z3_assert(a.is_int(), "Z3 integer expression expected")
2628 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2629
2630 def __rmod__(self, other):
2631 """Create the Z3 expression `other%self`.
2632
2633 >>> x = Int('x')
2634 >>> 10 % x
2635 10%x
2636 """
2637 a, b = _coerce_exprs(self, other)
2638 if z3_debug():
2639 _z3_assert(a.is_int(), "Z3 integer expression expected")
2640 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2641
2642 def __neg__(self):
2643 """Return an expression representing `-self`.
2644
2645 >>> x = Int('x')
2646 >>> -x
2647 -x
2648 >>> simplify(-(-x))
2649 x
2650 """
2651 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
2652
2653 def __pos__(self):
2654 """Return `self`.
2655
2656 >>> x = Int('x')
2657 >>> +x
2658 x
2659 """
2660 return self
2661
2662 def __le__(self, other):
2663 """Create the Z3 expression `other <= self`.
2664
2665 >>> x, y = Ints('x y')
2666 >>> x <= y
2667 x <= y
2668 >>> y = Real('y')
2669 >>> x <= y
2670 ToReal(x) <= y
2671 """
2672 a, b = _coerce_exprs(self, other)
2673 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2674
2675 def __lt__(self, other):
2676 """Create the Z3 expression `other < self`.
2677
2678 >>> x, y = Ints('x y')
2679 >>> x < y
2680 x < y
2681 >>> y = Real('y')
2682 >>> x < y
2683 ToReal(x) < y
2684 """
2685 a, b = _coerce_exprs(self, other)
2686 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2687
2688 def __gt__(self, other):
2689 """Create the Z3 expression `other > self`.
2690
2691 >>> x, y = Ints('x y')
2692 >>> x > y
2693 x > y
2694 >>> y = Real('y')
2695 >>> x > y
2696 ToReal(x) > y
2697 """
2698 a, b = _coerce_exprs(self, other)
2699 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2700
2701 def __ge__(self, other):
2702 """Create the Z3 expression `other >= self`.
2703
2704 >>> x, y = Ints('x y')
2705 >>> x >= y
2706 x >= y
2707 >>> y = Real('y')
2708 >>> x >= y
2709 ToReal(x) >= y
2710 """
2711 a, b = _coerce_exprs(self, other)
2712 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2713
2714
2716 """Return `True` if `a` is an arithmetical expression.
2717
2718 >>> x = Int('x')
2719 >>> is_arith(x)
2720 True
2721 >>> is_arith(x + 1)
2722 True
2723 >>> is_arith(1)
2724 False
2725 >>> is_arith(IntVal(1))
2726 True
2727 >>> y = Real('y')
2728 >>> is_arith(y)
2729 True
2730 >>> is_arith(y + 1)
2731 True
2732 """
2733 return isinstance(a, ArithRef)
2734
2735
2736def is_int(a):
2737 """Return `True` if `a` is an integer expression.
2738
2739 >>> x = Int('x')
2740 >>> is_int(x + 1)
2741 True
2742 >>> is_int(1)
2743 False
2744 >>> is_int(IntVal(1))
2745 True
2746 >>> y = Real('y')
2747 >>> is_int(y)
2748 False
2749 >>> is_int(y + 1)
2750 False
2751 """
2752 return is_arith(a) and a.is_int()
2753
2754
2755def is_real(a):
2756 """Return `True` if `a` is a real expression.
2757
2758 >>> x = Int('x')
2759 >>> is_real(x + 1)
2760 False
2761 >>> y = Real('y')
2762 >>> is_real(y)
2763 True
2764 >>> is_real(y + 1)
2765 True
2766 >>> is_real(1)
2767 False
2768 >>> is_real(RealVal(1))
2769 True
2770 """
2771 return is_arith(a) and a.is_real()
2772
2773
2774def _is_numeral(ctx, a):
2775 return Z3_is_numeral_ast(ctx.ref(), a)
2776
2777
2778def _is_algebraic(ctx, a):
2779 return Z3_is_algebraic_number(ctx.ref(), a)
2780
2781
2783 """Return `True` if `a` is an integer value of sort Int.
2784
2785 >>> is_int_value(IntVal(1))
2786 True
2787 >>> is_int_value(1)
2788 False
2789 >>> is_int_value(Int('x'))
2790 False
2791 >>> n = Int('x') + 1
2792 >>> n
2793 x + 1
2794 >>> n.arg(1)
2795 1
2796 >>> is_int_value(n.arg(1))
2797 True
2798 >>> is_int_value(RealVal("1/3"))
2799 False
2800 >>> is_int_value(RealVal(1))
2801 False
2802 """
2803 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2804
2805
2807 """Return `True` if `a` is rational value of sort Real.
2808
2809 >>> is_rational_value(RealVal(1))
2810 True
2811 >>> is_rational_value(RealVal("3/5"))
2812 True
2813 >>> is_rational_value(IntVal(1))
2814 False
2815 >>> is_rational_value(1)
2816 False
2817 >>> n = Real('x') + 1
2818 >>> n.arg(1)
2819 1
2820 >>> is_rational_value(n.arg(1))
2821 True
2822 >>> is_rational_value(Real('x'))
2823 False
2824 """
2825 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2826
2827
2829 """Return `True` if `a` is an algebraic value of sort Real.
2830
2831 >>> is_algebraic_value(RealVal("3/5"))
2832 False
2833 >>> n = simplify(Sqrt(2))
2834 >>> n
2835 1.4142135623?
2836 >>> is_algebraic_value(n)
2837 True
2838 """
2839 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2840
2841
2842def is_add(a):
2843 """Return `True` if `a` is an expression of the form b + c.
2844
2845 >>> x, y = Ints('x y')
2846 >>> is_add(x + y)
2847 True
2848 >>> is_add(x - y)
2849 False
2850 """
2851 return is_app_of(a, Z3_OP_ADD)
2852
2853
2854def is_mul(a):
2855 """Return `True` if `a` is an expression of the form b * c.
2856
2857 >>> x, y = Ints('x y')
2858 >>> is_mul(x * y)
2859 True
2860 >>> is_mul(x - y)
2861 False
2862 """
2863 return is_app_of(a, Z3_OP_MUL)
2864
2865
2866def is_sub(a):
2867 """Return `True` if `a` is an expression of the form b - c.
2868
2869 >>> x, y = Ints('x y')
2870 >>> is_sub(x - y)
2871 True
2872 >>> is_sub(x + y)
2873 False
2874 """
2875 return is_app_of(a, Z3_OP_SUB)
2876
2877
2878def is_div(a):
2879 """Return `True` if `a` is an expression of the form b / c.
2880
2881 >>> x, y = Reals('x y')
2882 >>> is_div(x / y)
2883 True
2884 >>> is_div(x + y)
2885 False
2886 >>> x, y = Ints('x y')
2887 >>> is_div(x / y)
2888 False
2889 >>> is_idiv(x / y)
2890 True
2891 """
2892 return is_app_of(a, Z3_OP_DIV)
2893
2894
2895def is_idiv(a):
2896 """Return `True` if `a` is an expression of the form b div c.
2897
2898 >>> x, y = Ints('x y')
2899 >>> is_idiv(x / y)
2900 True
2901 >>> is_idiv(x + y)
2902 False
2903 """
2904 return is_app_of(a, Z3_OP_IDIV)
2905
2906
2907def is_mod(a):
2908 """Return `True` if `a` is an expression of the form b % c.
2909
2910 >>> x, y = Ints('x y')
2911 >>> is_mod(x % y)
2912 True
2913 >>> is_mod(x + y)
2914 False
2915 """
2916 return is_app_of(a, Z3_OP_MOD)
2917
2918
2919def is_le(a):
2920 """Return `True` if `a` is an expression of the form b <= c.
2921
2922 >>> x, y = Ints('x y')
2923 >>> is_le(x <= y)
2924 True
2925 >>> is_le(x < y)
2926 False
2927 """
2928 return is_app_of(a, Z3_OP_LE)
2929
2930
2931def is_lt(a):
2932 """Return `True` if `a` is an expression of the form b < c.
2933
2934 >>> x, y = Ints('x y')
2935 >>> is_lt(x < y)
2936 True
2937 >>> is_lt(x == y)
2938 False
2939 """
2940 return is_app_of(a, Z3_OP_LT)
2941
2942
2943def is_ge(a):
2944 """Return `True` if `a` is an expression of the form b >= c.
2945
2946 >>> x, y = Ints('x y')
2947 >>> is_ge(x >= y)
2948 True
2949 >>> is_ge(x == y)
2950 False
2951 """
2952 return is_app_of(a, Z3_OP_GE)
2953
2954
2955def is_gt(a):
2956 """Return `True` if `a` is an expression of the form b > c.
2957
2958 >>> x, y = Ints('x y')
2959 >>> is_gt(x > y)
2960 True
2961 >>> is_gt(x == y)
2962 False
2963 """
2964 return is_app_of(a, Z3_OP_GT)
2965
2966
2968 """Return `True` if `a` is an expression of the form IsInt(b).
2969
2970 >>> x = Real('x')
2971 >>> is_is_int(IsInt(x))
2972 True
2973 >>> is_is_int(x)
2974 False
2975 """
2976 return is_app_of(a, Z3_OP_IS_INT)
2977
2978
2980 """Return `True` if `a` is an expression of the form ToReal(b).
2981
2982 >>> x = Int('x')
2983 >>> n = ToReal(x)
2984 >>> n
2985 ToReal(x)
2986 >>> is_to_real(n)
2987 True
2988 >>> is_to_real(x)
2989 False
2990 """
2991 return is_app_of(a, Z3_OP_TO_REAL)
2992
2993
2995 """Return `True` if `a` is an expression of the form ToInt(b).
2996
2997 >>> x = Real('x')
2998 >>> n = ToInt(x)
2999 >>> n
3000 ToInt(x)
3001 >>> is_to_int(n)
3002 True
3003 >>> is_to_int(x)
3004 False
3005 """
3006 return is_app_of(a, Z3_OP_TO_INT)
3007
3008
3010 """Integer values."""
3011
3012 def as_long(self):
3013 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3014
3015 >>> v = IntVal(1)
3016 >>> v + 1
3017 1 + 1
3018 >>> v.as_long() + 1
3019 2
3020 """
3021 if z3_debug():
3022 _z3_assert(self.is_int(), "Integer value expected")
3023 return int(self.as_string())
3024
3025 def as_string(self):
3026 """Return a Z3 integer numeral as a Python string.
3027 >>> v = IntVal(100)
3028 >>> v.as_string()
3029 '100'
3030 """
3031 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3032
3034 """Return a Z3 integer numeral as a Python binary string.
3035 >>> v = IntVal(10)
3036 >>> v.as_binary_string()
3037 '1010'
3038 """
3040
3041
3043 """Rational values."""
3044
3045 def numerator(self):
3046 """ Return the numerator of a Z3 rational numeral.
3047
3048 >>> is_rational_value(RealVal("3/5"))
3049 True
3050 >>> n = RealVal("3/5")
3051 >>> n.numerator()
3052 3
3053 >>> is_rational_value(Q(3,5))
3054 True
3055 >>> Q(3,5).numerator()
3056 3
3057 """
3059
3060 def denominator(self):
3061 """ Return the denominator of a Z3 rational numeral.
3062
3063 >>> is_rational_value(Q(3,5))
3064 True
3065 >>> n = Q(3,5)
3066 >>> n.denominator()
3067 5
3068 """
3069 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctxctx)
3070
3072 """ Return the numerator as a Python long.
3073
3074 >>> v = RealVal(10000000000)
3075 >>> v
3076 10000000000
3077 >>> v + 1
3078 10000000000 + 1
3079 >>> v.numerator_as_long() + 1 == 10000000001
3080 True
3081 """
3082 return self.numerator().as_long()
3083
3085 """ Return the denominator as a Python long.
3086
3087 >>> v = RealVal("1/3")
3088 >>> v
3089 1/3
3090 >>> v.denominator_as_long()
3091 3
3092 """
3093 return self.denominator().as_long()
3094
3095 def is_int(self):
3096 return False
3097
3098 def is_real(self):
3099 return True
3100
3101 def is_int_value(self):
3102 return self.denominator().is_int() and self.denominator_as_long() == 1
3103
3104 def as_long(self):
3105 _z3_assert(self.is_int_value(), "Expected integer fraction")
3106 return self.numerator_as_long()
3107
3108 def as_decimal(self, prec):
3109 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3110
3111 >>> v = RealVal("1/5")
3112 >>> v.as_decimal(3)
3113 '0.2'
3114 >>> v = RealVal("1/3")
3115 >>> v.as_decimal(3)
3116 '0.333?'
3117 """
3118 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3119
3120 def as_string(self):
3121 """Return a Z3 rational numeral as a Python string.
3122
3123 >>> v = Q(3,6)
3124 >>> v.as_string()
3125 '1/2'
3126 """
3127 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3128
3129 def as_fraction(self):
3130 """Return a Z3 rational as a Python Fraction object.
3131
3132 >>> v = RealVal("1/5")
3133 >>> v.as_fraction()
3134 Fraction(1, 5)
3135 """
3136 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3137
3138
3140 """Algebraic irrational values."""
3141
3142 def approx(self, precision=10):
3143 """Return a Z3 rational number that approximates the algebraic number `self`.
3144 The result `r` is such that |r - self| <= 1/10^precision
3145
3146 >>> x = simplify(Sqrt(2))
3147 >>> x.approx(20)
3148 6838717160008073720548335/4835703278458516698824704
3149 >>> x.approx(5)
3150 2965821/2097152
3151 """
3153
3154 def as_decimal(self, prec):
3155 """Return a string representation of the algebraic number `self` in decimal notation
3156 using `prec` decimal places.
3157
3158 >>> x = simplify(Sqrt(2))
3159 >>> x.as_decimal(10)
3160 '1.4142135623?'
3161 >>> x.as_decimal(20)
3162 '1.41421356237309504880?'
3163 """
3164 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3165
3166 def poly(self):
3168
3169 def index(self):
3170 return Z3_algebraic_get_i(self.ctx_ref(), self.as_astas_ast())
3171
3172
3173def _py2expr(a, ctx=None):
3174 if isinstance(a, bool):
3175 return BoolVal(a, ctx)
3176 if _is_int(a):
3177 return IntVal(a, ctx)
3178 if isinstance(a, float):
3179 return RealVal(a, ctx)
3180 if isinstance(a, str):
3181 return StringVal(a, ctx)
3182 if is_expr(a):
3183 return a
3184 if z3_debug():
3185 _z3_assert(False, "Python bool, int, long or float expected")
3186
3187
3188def IntSort(ctx=None):
3189 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3190
3191 >>> IntSort()
3192 Int
3193 >>> x = Const('x', IntSort())
3194 >>> is_int(x)
3195 True
3196 >>> x.sort() == IntSort()
3197 True
3198 >>> x.sort() == BoolSort()
3199 False
3200 """
3201 ctx = _get_ctx(ctx)
3202 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3203
3204
3205def RealSort(ctx=None):
3206 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3207
3208 >>> RealSort()
3209 Real
3210 >>> x = Const('x', RealSort())
3211 >>> is_real(x)
3212 True
3213 >>> is_int(x)
3214 False
3215 >>> x.sort() == RealSort()
3216 True
3217 """
3218 ctx = _get_ctx(ctx)
3219 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3220
3221
3223 if isinstance(val, float):
3224 return str(int(val))
3225 elif isinstance(val, bool):
3226 if val:
3227 return "1"
3228 else:
3229 return "0"
3230 else:
3231 return str(val)
3232
3233
3234def IntVal(val, ctx=None):
3235 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3236
3237 >>> IntVal(1)
3238 1
3239 >>> IntVal("100")
3240 100
3241 """
3242 ctx = _get_ctx(ctx)
3243 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3244
3245
3246def RealVal(val, ctx=None):
3247 """Return a Z3 real value.
3248
3249 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3250 If `ctx=None`, then the global context is used.
3251
3252 >>> RealVal(1)
3253 1
3254 >>> RealVal(1).sort()
3255 Real
3256 >>> RealVal("3/5")
3257 3/5
3258 >>> RealVal("1.5")
3259 3/2
3260 """
3261 ctx = _get_ctx(ctx)
3262 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3263
3264
3265def RatVal(a, b, ctx=None):
3266 """Return a Z3 rational a/b.
3267
3268 If `ctx=None`, then the global context is used.
3269
3270 >>> RatVal(3,5)
3271 3/5
3272 >>> RatVal(3,5).sort()
3273 Real
3274 """
3275 if z3_debug():
3276 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3277 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3278 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3279
3280
3281def Q(a, b, ctx=None):
3282 """Return a Z3 rational a/b.
3283
3284 If `ctx=None`, then the global context is used.
3285
3286 >>> Q(3,5)
3287 3/5
3288 >>> Q(3,5).sort()
3289 Real
3290 """
3291 return simplify(RatVal(a, b, ctx=ctx))
3292
3293
3294def Int(name, ctx=None):
3295 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3296
3297 >>> x = Int('x')
3298 >>> is_int(x)
3299 True
3300 >>> is_int(x + 1)
3301 True
3302 """
3303 ctx = _get_ctx(ctx)
3304 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3305
3306
3307def Ints(names, ctx=None):
3308 """Return a tuple of Integer constants.
3309
3310 >>> x, y, z = Ints('x y z')
3311 >>> Sum(x, y, z)
3312 x + y + z
3313 """
3314 ctx = _get_ctx(ctx)
3315 if isinstance(names, str):
3316 names = names.split(" ")
3317 return [Int(name, ctx) for name in names]
3318
3319
3320def IntVector(prefix, sz, ctx=None):
3321 """Return a list of integer constants of size `sz`.
3322
3323 >>> X = IntVector('x', 3)
3324 >>> X
3325 [x__0, x__1, x__2]
3326 >>> Sum(X)
3327 x__0 + x__1 + x__2
3328 """
3329 ctx = _get_ctx(ctx)
3330 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3331
3332
3333def FreshInt(prefix="x", ctx=None):
3334 """Return a fresh integer constant in the given context using the given prefix.
3335
3336 >>> x = FreshInt()
3337 >>> y = FreshInt()
3338 >>> eq(x, y)
3339 False
3340 >>> x.sort()
3341 Int
3342 """
3343 ctx = _get_ctx(ctx)
3344 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3345
3346
3347def Real(name, ctx=None):
3348 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3349
3350 >>> x = Real('x')
3351 >>> is_real(x)
3352 True
3353 >>> is_real(x + 1)
3354 True
3355 """
3356 ctx = _get_ctx(ctx)
3357 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3358
3359
3360def Reals(names, ctx=None):
3361 """Return a tuple of real constants.
3362
3363 >>> x, y, z = Reals('x y z')
3364 >>> Sum(x, y, z)
3365 x + y + z
3366 >>> Sum(x, y, z).sort()
3367 Real
3368 """
3369 ctx = _get_ctx(ctx)
3370 if isinstance(names, str):
3371 names = names.split(" ")
3372 return [Real(name, ctx) for name in names]
3373
3374
3375def RealVector(prefix, sz, ctx=None):
3376 """Return a list of real constants of size `sz`.
3377
3378 >>> X = RealVector('x', 3)
3379 >>> X
3380 [x__0, x__1, x__2]
3381 >>> Sum(X)
3382 x__0 + x__1 + x__2
3383 >>> Sum(X).sort()
3384 Real
3385 """
3386 ctx = _get_ctx(ctx)
3387 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3388
3389
3390def FreshReal(prefix="b", ctx=None):
3391 """Return a fresh real constant in the given context using the given prefix.
3392
3393 >>> x = FreshReal()
3394 >>> y = FreshReal()
3395 >>> eq(x, y)
3396 False
3397 >>> x.sort()
3398 Real
3399 """
3400 ctx = _get_ctx(ctx)
3401 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3402
3403
3404def ToReal(a):
3405 """ Return the Z3 expression ToReal(a).
3406
3407 >>> x = Int('x')
3408 >>> x.sort()
3409 Int
3410 >>> n = ToReal(x)
3411 >>> n
3412 ToReal(x)
3413 >>> n.sort()
3414 Real
3415 """
3416 if z3_debug():
3417 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3418 ctx = a.ctx
3419 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3420
3421
3422def ToInt(a):
3423 """ Return the Z3 expression ToInt(a).
3424
3425 >>> x = Real('x')
3426 >>> x.sort()
3427 Real
3428 >>> n = ToInt(x)
3429 >>> n
3430 ToInt(x)
3431 >>> n.sort()
3432 Int
3433 """
3434 if z3_debug():
3435 _z3_assert(a.is_real(), "Z3 real expression expected.")
3436 ctx = a.ctx
3437 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3438
3439
3440def IsInt(a):
3441 """ Return the Z3 predicate IsInt(a).
3442
3443 >>> x = Real('x')
3444 >>> IsInt(x + "1/2")
3445 IsInt(x + 1/2)
3446 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3447 [x = 1/2]
3448 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3449 no solution
3450 """
3451 if z3_debug():
3452 _z3_assert(a.is_real(), "Z3 real expression expected.")
3453 ctx = a.ctx
3454 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3455
3456
3457def Sqrt(a, ctx=None):
3458 """ Return a Z3 expression which represents the square root of a.
3459
3460 >>> x = Real('x')
3461 >>> Sqrt(x)
3462 x**(1/2)
3463 """
3464 if not is_expr(a):
3465 ctx = _get_ctx(ctx)
3466 a = RealVal(a, ctx)
3467 return a ** "1/2"
3468
3469
3470def Cbrt(a, ctx=None):
3471 """ Return a Z3 expression which represents the cubic root of a.
3472
3473 >>> x = Real('x')
3474 >>> Cbrt(x)
3475 x**(1/3)
3476 """
3477 if not is_expr(a):
3478 ctx = _get_ctx(ctx)
3479 a = RealVal(a, ctx)
3480 return a ** "1/3"
3481
3482
3487
3488
3490 """Bit-vector sort."""
3491
3492 def size(self):
3493 """Return the size (number of bits) of the bit-vector sort `self`.
3494
3495 >>> b = BitVecSort(32)
3496 >>> b.size()
3497 32
3498 """
3499 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.astastast))
3500
3501 def subsort(self, other):
3502 return is_bv_sort(other) and self.size() < other.size()
3503
3504 def cast(self, val):
3505 """Try to cast `val` as a Bit-Vector.
3506
3507 >>> b = BitVecSort(32)
3508 >>> b.cast(10)
3509 10
3510 >>> b.cast(10).sexpr()
3511 '#x0000000a'
3512 """
3513 if is_expr(val):
3514 if z3_debug():
3515 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
3516 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3517 return val
3518 else:
3519 return BitVecVal(val, self)
3520
3521
3523 """Return True if `s` is a Z3 bit-vector sort.
3524
3525 >>> is_bv_sort(BitVecSort(32))
3526 True
3527 >>> is_bv_sort(IntSort())
3528 False
3529 """
3530 return isinstance(s, BitVecSortRef)
3531
3532
3534 """Bit-vector expressions."""
3535
3536 def sort(self):
3537 """Return the sort of the bit-vector expression `self`.
3538
3539 >>> x = BitVec('x', 32)
3540 >>> x.sort()
3541 BitVec(32)
3542 >>> x.sort() == BitVecSort(32)
3543 True
3544 """
3546
3547 def size(self):
3548 """Return the number of bits of the bit-vector expression `self`.
3549
3550 >>> x = BitVec('x', 32)
3551 >>> (x + 1).size()
3552 32
3553 >>> Concat(x, x).size()
3554 64
3555 """
3556 return self.sortsort().size()
3557
3558 def __add__(self, other):
3559 """Create the Z3 expression `self + other`.
3560
3561 >>> x = BitVec('x', 32)
3562 >>> y = BitVec('y', 32)
3563 >>> x + y
3564 x + y
3565 >>> (x + y).sort()
3566 BitVec(32)
3567 """
3568 a, b = _coerce_exprs(self, other)
3569 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3570
3571 def __radd__(self, other):
3572 """Create the Z3 expression `other + self`.
3573
3574 >>> x = BitVec('x', 32)
3575 >>> 10 + x
3576 10 + x
3577 """
3578 a, b = _coerce_exprs(self, other)
3579 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3580
3581 def __mul__(self, other):
3582 """Create the Z3 expression `self * other`.
3583
3584 >>> x = BitVec('x', 32)
3585 >>> y = BitVec('y', 32)
3586 >>> x * y
3587 x*y
3588 >>> (x * y).sort()
3589 BitVec(32)
3590 """
3591 a, b = _coerce_exprs(self, other)
3592 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3593
3594 def __rmul__(self, other):
3595 """Create the Z3 expression `other * self`.
3596
3597 >>> x = BitVec('x', 32)
3598 >>> 10 * x
3599 10*x
3600 """
3601 a, b = _coerce_exprs(self, other)
3602 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3603
3604 def __sub__(self, other):
3605 """Create the Z3 expression `self - other`.
3606
3607 >>> x = BitVec('x', 32)
3608 >>> y = BitVec('y', 32)
3609 >>> x - y
3610 x - y
3611 >>> (x - y).sort()
3612 BitVec(32)
3613 """
3614 a, b = _coerce_exprs(self, other)
3615 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3616
3617 def __rsub__(self, other):
3618 """Create the Z3 expression `other - self`.
3619
3620 >>> x = BitVec('x', 32)
3621 >>> 10 - x
3622 10 - x
3623 """
3624 a, b = _coerce_exprs(self, other)
3625 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3626
3627 def __or__(self, other):
3628 """Create the Z3 expression bitwise-or `self | other`.
3629
3630 >>> x = BitVec('x', 32)
3631 >>> y = BitVec('y', 32)
3632 >>> x | y
3633 x | y
3634 >>> (x | y).sort()
3635 BitVec(32)
3636 """
3637 a, b = _coerce_exprs(self, other)
3638 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3639
3640 def __ror__(self, other):
3641 """Create the Z3 expression bitwise-or `other | self`.
3642
3643 >>> x = BitVec('x', 32)
3644 >>> 10 | x
3645 10 | x
3646 """
3647 a, b = _coerce_exprs(self, other)
3648 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3649
3650 def __and__(self, other):
3651 """Create the Z3 expression bitwise-and `self & other`.
3652
3653 >>> x = BitVec('x', 32)
3654 >>> y = BitVec('y', 32)
3655 >>> x & y
3656 x & y
3657 >>> (x & y).sort()
3658 BitVec(32)
3659 """
3660 a, b = _coerce_exprs(self, other)
3661 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3662
3663 def __rand__(self, other):
3664 """Create the Z3 expression bitwise-or `other & self`.
3665
3666 >>> x = BitVec('x', 32)
3667 >>> 10 & x
3668 10 & x
3669 """
3670 a, b = _coerce_exprs(self, other)
3671 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3672
3673 def __xor__(self, other):
3674 """Create the Z3 expression bitwise-xor `self ^ other`.
3675
3676 >>> x = BitVec('x', 32)
3677 >>> y = BitVec('y', 32)
3678 >>> x ^ y
3679 x ^ y
3680 >>> (x ^ y).sort()
3681 BitVec(32)
3682 """
3683 a, b = _coerce_exprs(self, other)
3684 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3685
3686 def __rxor__(self, other):
3687 """Create the Z3 expression bitwise-xor `other ^ self`.
3688
3689 >>> x = BitVec('x', 32)
3690 >>> 10 ^ x
3691 10 ^ x
3692 """
3693 a, b = _coerce_exprs(self, other)
3694 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3695
3696 def __pos__(self):
3697 """Return `self`.
3698
3699 >>> x = BitVec('x', 32)
3700 >>> +x
3701 x
3702 """
3703 return self
3704
3705 def __neg__(self):
3706 """Return an expression representing `-self`.
3707
3708 >>> x = BitVec('x', 32)
3709 >>> -x
3710 -x
3711 >>> simplify(-(-x))
3712 x
3713 """
3714 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3715
3716 def __invert__(self):
3717 """Create the Z3 expression bitwise-not `~self`.
3718
3719 >>> x = BitVec('x', 32)
3720 >>> ~x
3721 ~x
3722 >>> simplify(~(~x))
3723 x
3724 """
3725 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3726
3727 def __div__(self, other):
3728 """Create the Z3 expression (signed) division `self / other`.
3729
3730 Use the function UDiv() for unsigned division.
3731
3732 >>> x = BitVec('x', 32)
3733 >>> y = BitVec('y', 32)
3734 >>> x / y
3735 x/y
3736 >>> (x / y).sort()
3737 BitVec(32)
3738 >>> (x / y).sexpr()
3739 '(bvsdiv x y)'
3740 >>> UDiv(x, y).sexpr()
3741 '(bvudiv x y)'
3742 """
3743 a, b = _coerce_exprs(self, other)
3744 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3745
3746 def __truediv__(self, other):
3747 """Create the Z3 expression (signed) division `self / other`."""
3748 return self.__div__(other)
3749
3750 def __rdiv__(self, other):
3751 """Create the Z3 expression (signed) division `other / self`.
3752
3753 Use the function UDiv() for unsigned division.
3754
3755 >>> x = BitVec('x', 32)
3756 >>> 10 / x
3757 10/x
3758 >>> (10 / x).sexpr()
3759 '(bvsdiv #x0000000a x)'
3760 >>> UDiv(10, x).sexpr()
3761 '(bvudiv #x0000000a x)'
3762 """
3763 a, b = _coerce_exprs(self, other)
3764 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3765
3766 def __rtruediv__(self, other):
3767 """Create the Z3 expression (signed) division `other / self`."""
3768 return self.__rdiv__(other)
3769
3770 def __mod__(self, other):
3771 """Create the Z3 expression (signed) mod `self % other`.
3772
3773 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3774
3775 >>> x = BitVec('x', 32)
3776 >>> y = BitVec('y', 32)
3777 >>> x % y
3778 x%y
3779 >>> (x % y).sort()
3780 BitVec(32)
3781 >>> (x % y).sexpr()
3782 '(bvsmod x y)'
3783 >>> URem(x, y).sexpr()
3784 '(bvurem x y)'
3785 >>> SRem(x, y).sexpr()
3786 '(bvsrem x y)'
3787 """
3788 a, b = _coerce_exprs(self, other)
3789 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3790
3791 def __rmod__(self, other):
3792 """Create the Z3 expression (signed) mod `other % self`.
3793
3794 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3795
3796 >>> x = BitVec('x', 32)
3797 >>> 10 % x
3798 10%x
3799 >>> (10 % x).sexpr()
3800 '(bvsmod #x0000000a x)'
3801 >>> URem(10, x).sexpr()
3802 '(bvurem #x0000000a x)'
3803 >>> SRem(10, x).sexpr()
3804 '(bvsrem #x0000000a x)'
3805 """
3806 a, b = _coerce_exprs(self, other)
3807 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3808
3809 def __le__(self, other):
3810 """Create the Z3 expression (signed) `other <= self`.
3811
3812 Use the function ULE() for unsigned less than or equal to.
3813
3814 >>> x, y = BitVecs('x y', 32)
3815 >>> x <= y
3816 x <= y
3817 >>> (x <= y).sexpr()
3818 '(bvsle x y)'
3819 >>> ULE(x, y).sexpr()
3820 '(bvule x y)'
3821 """
3822 a, b = _coerce_exprs(self, other)
3823 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3824
3825 def __lt__(self, other):
3826 """Create the Z3 expression (signed) `other < self`.
3827
3828 Use the function ULT() for unsigned less than.
3829
3830 >>> x, y = BitVecs('x y', 32)
3831 >>> x < y
3832 x < y
3833 >>> (x < y).sexpr()
3834 '(bvslt x y)'
3835 >>> ULT(x, y).sexpr()
3836 '(bvult x y)'
3837 """
3838 a, b = _coerce_exprs(self, other)
3839 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3840
3841 def __gt__(self, other):
3842 """Create the Z3 expression (signed) `other > self`.
3843
3844 Use the function UGT() for unsigned greater than.
3845
3846 >>> x, y = BitVecs('x y', 32)
3847 >>> x > y
3848 x > y
3849 >>> (x > y).sexpr()
3850 '(bvsgt x y)'
3851 >>> UGT(x, y).sexpr()
3852 '(bvugt x y)'
3853 """
3854 a, b = _coerce_exprs(self, other)
3855 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3856
3857 def __ge__(self, other):
3858 """Create the Z3 expression (signed) `other >= self`.
3859
3860 Use the function UGE() for unsigned greater than or equal to.
3861
3862 >>> x, y = BitVecs('x y', 32)
3863 >>> x >= y
3864 x >= y
3865 >>> (x >= y).sexpr()
3866 '(bvsge x y)'
3867 >>> UGE(x, y).sexpr()
3868 '(bvuge x y)'
3869 """
3870 a, b = _coerce_exprs(self, other)
3871 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3872
3873 def __rshift__(self, other):
3874 """Create the Z3 expression (arithmetical) right shift `self >> other`
3875
3876 Use the function LShR() for the right logical shift
3877
3878 >>> x, y = BitVecs('x y', 32)
3879 >>> x >> y
3880 x >> y
3881 >>> (x >> y).sexpr()
3882 '(bvashr x y)'
3883 >>> LShR(x, y).sexpr()
3884 '(bvlshr x y)'
3885 >>> BitVecVal(4, 3)
3886 4
3887 >>> BitVecVal(4, 3).as_signed_long()
3888 -4
3889 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3890 -2
3891 >>> simplify(BitVecVal(4, 3) >> 1)
3892 6
3893 >>> simplify(LShR(BitVecVal(4, 3), 1))
3894 2
3895 >>> simplify(BitVecVal(2, 3) >> 1)
3896 1
3897 >>> simplify(LShR(BitVecVal(2, 3), 1))
3898 1
3899 """
3900 a, b = _coerce_exprs(self, other)
3901 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3902
3903 def __lshift__(self, other):
3904 """Create the Z3 expression left shift `self << other`
3905
3906 >>> x, y = BitVecs('x y', 32)
3907 >>> x << y
3908 x << y
3909 >>> (x << y).sexpr()
3910 '(bvshl x y)'
3911 >>> simplify(BitVecVal(2, 3) << 1)
3912 4
3913 """
3914 a, b = _coerce_exprs(self, other)
3915 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3916
3917 def __rrshift__(self, other):
3918 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
3919
3920 Use the function LShR() for the right logical shift
3921
3922 >>> x = BitVec('x', 32)
3923 >>> 10 >> x
3924 10 >> x
3925 >>> (10 >> x).sexpr()
3926 '(bvashr #x0000000a x)'
3927 """
3928 a, b = _coerce_exprs(self, other)
3929 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3930
3931 def __rlshift__(self, other):
3932 """Create the Z3 expression left shift `other << self`.
3933
3934 Use the function LShR() for the right logical shift
3935
3936 >>> x = BitVec('x', 32)
3937 >>> 10 << x
3938 10 << x
3939 >>> (10 << x).sexpr()
3940 '(bvshl #x0000000a x)'
3941 """
3942 a, b = _coerce_exprs(self, other)
3943 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3944
3945
3947 """Bit-vector values."""
3948
3949 def as_long(self):
3950 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3951
3952 >>> v = BitVecVal(0xbadc0de, 32)
3953 >>> v
3954 195936478
3955 >>> print("0x%.8x" % v.as_long())
3956 0x0badc0de
3957 """
3958 return int(self.as_string())
3959
3961 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3962 The most significant bit is assumed to be the sign.
3963
3964 >>> BitVecVal(4, 3).as_signed_long()
3965 -4
3966 >>> BitVecVal(7, 3).as_signed_long()
3967 -1
3968 >>> BitVecVal(3, 3).as_signed_long()
3969 3
3970 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
3971 -1
3972 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
3973 -1
3974 """
3975 sz = self.size()
3976 val = self.as_long()
3977 if val >= 2**(sz - 1):
3978 val = val - 2**sz
3979 if val < -2**(sz - 1):
3980 val = val + 2**sz
3981 return int(val)
3982
3983 def as_string(self):
3984 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3985
3988
3989
3990def is_bv(a):
3991 """Return `True` if `a` is a Z3 bit-vector expression.
3992
3993 >>> b = BitVec('b', 32)
3994 >>> is_bv(b)
3995 True
3996 >>> is_bv(b + 10)
3997 True
3998 >>> is_bv(Int('x'))
3999 False
4000 """
4001 return isinstance(a, BitVecRef)
4002
4003
4005 """Return `True` if `a` is a Z3 bit-vector numeral value.
4006
4007 >>> b = BitVec('b', 32)
4008 >>> is_bv_value(b)
4009 False
4010 >>> b = BitVecVal(10, 32)
4011 >>> b
4012 10
4013 >>> is_bv_value(b)
4014 True
4015 """
4016 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4017
4018
4019def BV2Int(a, is_signed=False):
4020 """Return the Z3 expression BV2Int(a).
4021
4022 >>> b = BitVec('b', 3)
4023 >>> BV2Int(b).sort()
4024 Int
4025 >>> x = Int('x')
4026 >>> x > BV2Int(b)
4027 x > BV2Int(b)
4028 >>> x > BV2Int(b, is_signed=False)
4029 x > BV2Int(b)
4030 >>> x > BV2Int(b, is_signed=True)
4031 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4032 >>> solve(x > BV2Int(b), b == 1, x < 3)
4033 [x = 2, b = 1]
4034 """
4035 if z3_debug():
4036 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4037 ctx = a.ctx
4038 # investigate problem with bv2int
4039 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4040
4041
4042def Int2BV(a, num_bits):
4043 """Return the z3 expression Int2BV(a, num_bits).
4044 It is a bit-vector of width num_bits and represents the
4045 modulo of a by 2^num_bits
4046 """
4047 ctx = a.ctx
4048 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4049
4050
4051def BitVecSort(sz, ctx=None):
4052 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4053
4054 >>> Byte = BitVecSort(8)
4055 >>> Word = BitVecSort(16)
4056 >>> Byte
4057 BitVec(8)
4058 >>> x = Const('x', Byte)
4059 >>> eq(x, BitVec('x', 8))
4060 True
4061 """
4062 ctx = _get_ctx(ctx)
4063 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4064
4065
4066def BitVecVal(val, bv, ctx=None):
4067 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4068
4069 >>> v = BitVecVal(10, 32)
4070 >>> v
4071 10
4072 >>> print("0x%.8x" % v.as_long())
4073 0x0000000a
4074 """
4075 if is_bv_sort(bv):
4076 ctx = bv.ctx
4077 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4078 else:
4079 ctx = _get_ctx(ctx)
4080 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4081
4082
4083def BitVec(name, bv, ctx=None):
4084 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4085 If `ctx=None`, then the global context is used.
4086
4087 >>> x = BitVec('x', 16)
4088 >>> is_bv(x)
4089 True
4090 >>> x.size()
4091 16
4092 >>> x.sort()
4093 BitVec(16)
4094 >>> word = BitVecSort(16)
4095 >>> x2 = BitVec('x', word)
4096 >>> eq(x, x2)
4097 True
4098 """
4099 if isinstance(bv, BitVecSortRef):
4100 ctx = bv.ctx
4101 else:
4102 ctx = _get_ctx(ctx)
4103 bv = BitVecSort(bv, ctx)
4104 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4105
4106
4107def BitVecs(names, bv, ctx=None):
4108 """Return a tuple of bit-vector constants of size bv.
4109
4110 >>> x, y, z = BitVecs('x y z', 16)
4111 >>> x.size()
4112 16
4113 >>> x.sort()
4114 BitVec(16)
4115 >>> Sum(x, y, z)
4116 0 + x + y + z
4117 >>> Product(x, y, z)
4118 1*x*y*z
4119 >>> simplify(Product(x, y, z))
4120 x*y*z
4121 """
4122 ctx = _get_ctx(ctx)
4123 if isinstance(names, str):
4124 names = names.split(" ")
4125 return [BitVec(name, bv, ctx) for name in names]
4126
4127
4128def Concat(*args):
4129 """Create a Z3 bit-vector concatenation expression.
4130
4131 >>> v = BitVecVal(1, 4)
4132 >>> Concat(v, v+1, v)
4133 Concat(Concat(1, 1 + 1), 1)
4134 >>> simplify(Concat(v, v+1, v))
4135 289
4136 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4137 121
4138 """
4139 args = _get_args(args)
4140 sz = len(args)
4141 if z3_debug():
4142 _z3_assert(sz >= 2, "At least two arguments expected.")
4143
4144 ctx = None
4145 for a in args:
4146 if is_expr(a):
4147 ctx = a.ctx
4148 break
4149 if is_seq(args[0]) or isinstance(args[0], str):
4150 args = [_coerce_seq(s, ctx) for s in args]
4151 if z3_debug():
4152 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4153 v = (Ast * sz)()
4154 for i in range(sz):
4155 v[i] = args[i].as_ast()
4156 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4157
4158 if is_re(args[0]):
4159 if z3_debug():
4160 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4161 v = (Ast * sz)()
4162 for i in range(sz):
4163 v[i] = args[i].as_ast()
4164 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4165
4166 if z3_debug():
4167 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4168 r = args[0]
4169 for i in range(sz - 1):
4170 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4171 return r
4172
4173
4174def Extract(high, low, a):
4175 """Create a Z3 bit-vector extraction expression.
4176 Extract is overloaded to also work on sequence extraction.
4177 The functions SubString and SubSeq are redirected to Extract.
4178 For this case, the arguments are reinterpreted as:
4179 high - is a sequence (string)
4180 low - is an offset
4181 a - is the length to be extracted
4182
4183 >>> x = BitVec('x', 8)
4184 >>> Extract(6, 2, x)
4185 Extract(6, 2, x)
4186 >>> Extract(6, 2, x).sort()
4187 BitVec(5)
4188 >>> simplify(Extract(StringVal("abcd"),2,1))
4189 "c"
4190 """
4191 if isinstance(high, str):
4192 high = StringVal(high)
4193 if is_seq(high):
4194 s = high
4195 offset, length = _coerce_exprs(low, a, s.ctx)
4196 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4197 if z3_debug():
4198 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4199 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4200 "First and second arguments must be non negative integers")
4201 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4202 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4203
4204
4206 if z3_debug():
4207 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4208
4209
4210def ULE(a, b):
4211 """Create the Z3 expression (unsigned) `other <= self`.
4212
4213 Use the operator <= for signed less than or equal to.
4214
4215 >>> x, y = BitVecs('x y', 32)
4216 >>> ULE(x, y)
4217 ULE(x, y)
4218 >>> (x <= y).sexpr()
4219 '(bvsle x y)'
4220 >>> ULE(x, y).sexpr()
4221 '(bvule x y)'
4222 """
4223 _check_bv_args(a, b)
4224 a, b = _coerce_exprs(a, b)
4225 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4226
4227
4228def ULT(a, b):
4229 """Create the Z3 expression (unsigned) `other < self`.
4230
4231 Use the operator < for signed less than.
4232
4233 >>> x, y = BitVecs('x y', 32)
4234 >>> ULT(x, y)
4235 ULT(x, y)
4236 >>> (x < y).sexpr()
4237 '(bvslt x y)'
4238 >>> ULT(x, y).sexpr()
4239 '(bvult x y)'
4240 """
4241 _check_bv_args(a, b)
4242 a, b = _coerce_exprs(a, b)
4243 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4244
4245
4246def UGE(a, b):
4247 """Create the Z3 expression (unsigned) `other >= self`.
4248
4249 Use the operator >= for signed greater than or equal to.
4250
4251 >>> x, y = BitVecs('x y', 32)
4252 >>> UGE(x, y)
4253 UGE(x, y)
4254 >>> (x >= y).sexpr()
4255 '(bvsge x y)'
4256 >>> UGE(x, y).sexpr()
4257 '(bvuge x y)'
4258 """
4259 _check_bv_args(a, b)
4260 a, b = _coerce_exprs(a, b)
4261 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4262
4263
4264def UGT(a, b):
4265 """Create the Z3 expression (unsigned) `other > self`.
4266
4267 Use the operator > for signed greater than.
4268
4269 >>> x, y = BitVecs('x y', 32)
4270 >>> UGT(x, y)
4271 UGT(x, y)
4272 >>> (x > y).sexpr()
4273 '(bvsgt x y)'
4274 >>> UGT(x, y).sexpr()
4275 '(bvugt x y)'
4276 """
4277 _check_bv_args(a, b)
4278 a, b = _coerce_exprs(a, b)
4279 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4280
4281
4282def UDiv(a, b):
4283 """Create the Z3 expression (unsigned) division `self / other`.
4284
4285 Use the operator / for signed division.
4286
4287 >>> x = BitVec('x', 32)
4288 >>> y = BitVec('y', 32)
4289 >>> UDiv(x, y)
4290 UDiv(x, y)
4291 >>> UDiv(x, y).sort()
4292 BitVec(32)
4293 >>> (x / y).sexpr()
4294 '(bvsdiv x y)'
4295 >>> UDiv(x, y).sexpr()
4296 '(bvudiv x y)'
4297 """
4298 _check_bv_args(a, b)
4299 a, b = _coerce_exprs(a, b)
4300 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4301
4302
4303def URem(a, b):
4304 """Create the Z3 expression (unsigned) remainder `self % other`.
4305
4306 Use the operator % for signed modulus, and SRem() for signed remainder.
4307
4308 >>> x = BitVec('x', 32)
4309 >>> y = BitVec('y', 32)
4310 >>> URem(x, y)
4311 URem(x, y)
4312 >>> URem(x, y).sort()
4313 BitVec(32)
4314 >>> (x % y).sexpr()
4315 '(bvsmod x y)'
4316 >>> URem(x, y).sexpr()
4317 '(bvurem x y)'
4318 """
4319 _check_bv_args(a, b)
4320 a, b = _coerce_exprs(a, b)
4321 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4322
4323
4324def SRem(a, b):
4325 """Create the Z3 expression signed remainder.
4326
4327 Use the operator % for signed modulus, and URem() for unsigned remainder.
4328
4329 >>> x = BitVec('x', 32)
4330 >>> y = BitVec('y', 32)
4331 >>> SRem(x, y)
4332 SRem(x, y)
4333 >>> SRem(x, y).sort()
4334 BitVec(32)
4335 >>> (x % y).sexpr()
4336 '(bvsmod x y)'
4337 >>> SRem(x, y).sexpr()
4338 '(bvsrem x y)'
4339 """
4340 _check_bv_args(a, b)
4341 a, b = _coerce_exprs(a, b)
4342 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4343
4344
4345def LShR(a, b):
4346 """Create the Z3 expression logical right shift.
4347
4348 Use the operator >> for the arithmetical right shift.
4349
4350 >>> x, y = BitVecs('x y', 32)
4351 >>> LShR(x, y)
4352 LShR(x, y)
4353 >>> (x >> y).sexpr()
4354 '(bvashr x y)'
4355 >>> LShR(x, y).sexpr()
4356 '(bvlshr x y)'
4357 >>> BitVecVal(4, 3)
4358 4
4359 >>> BitVecVal(4, 3).as_signed_long()
4360 -4
4361 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4362 -2
4363 >>> simplify(BitVecVal(4, 3) >> 1)
4364 6
4365 >>> simplify(LShR(BitVecVal(4, 3), 1))
4366 2
4367 >>> simplify(BitVecVal(2, 3) >> 1)
4368 1
4369 >>> simplify(LShR(BitVecVal(2, 3), 1))
4370 1
4371 """
4372 _check_bv_args(a, b)
4373 a, b = _coerce_exprs(a, b)
4374 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4375
4376
4377def RotateLeft(a, b):
4378 """Return an expression representing `a` rotated to the left `b` times.
4379
4380 >>> a, b = BitVecs('a b', 16)
4381 >>> RotateLeft(a, b)
4382 RotateLeft(a, b)
4383 >>> simplify(RotateLeft(a, 0))
4384 a
4385 >>> simplify(RotateLeft(a, 16))
4386 a
4387 """
4388 _check_bv_args(a, b)
4389 a, b = _coerce_exprs(a, b)
4390 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4391
4392
4393def RotateRight(a, b):
4394 """Return an expression representing `a` rotated to the right `b` times.
4395
4396 >>> a, b = BitVecs('a b', 16)
4397 >>> RotateRight(a, b)
4398 RotateRight(a, b)
4399 >>> simplify(RotateRight(a, 0))
4400 a
4401 >>> simplify(RotateRight(a, 16))
4402 a
4403 """
4404 _check_bv_args(a, b)
4405 a, b = _coerce_exprs(a, b)
4406 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4407
4408
4409def SignExt(n, a):
4410 """Return a bit-vector expression with `n` extra sign-bits.
4411
4412 >>> x = BitVec('x', 16)
4413 >>> n = SignExt(8, x)
4414 >>> n.size()
4415 24
4416 >>> n
4417 SignExt(8, x)
4418 >>> n.sort()
4419 BitVec(24)
4420 >>> v0 = BitVecVal(2, 2)
4421 >>> v0
4422 2
4423 >>> v0.size()
4424 2
4425 >>> v = simplify(SignExt(6, v0))
4426 >>> v
4427 254
4428 >>> v.size()
4429 8
4430 >>> print("%.x" % v.as_long())
4431 fe
4432 """
4433 if z3_debug():
4434 _z3_assert(_is_int(n), "First argument must be an integer")
4435 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4436 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4437
4438
4439def ZeroExt(n, a):
4440 """Return a bit-vector expression with `n` extra zero-bits.
4441
4442 >>> x = BitVec('x', 16)
4443 >>> n = ZeroExt(8, x)
4444 >>> n.size()
4445 24
4446 >>> n
4447 ZeroExt(8, x)
4448 >>> n.sort()
4449 BitVec(24)
4450 >>> v0 = BitVecVal(2, 2)
4451 >>> v0
4452 2
4453 >>> v0.size()
4454 2
4455 >>> v = simplify(ZeroExt(6, v0))
4456 >>> v
4457 2
4458 >>> v.size()
4459 8
4460 """
4461 if z3_debug():
4462 _z3_assert(_is_int(n), "First argument must be an integer")
4463 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4464 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4465
4466
4468 """Return an expression representing `n` copies of `a`.
4469
4470 >>> x = BitVec('x', 8)
4471 >>> n = RepeatBitVec(4, x)
4472 >>> n
4473 RepeatBitVec(4, x)
4474 >>> n.size()
4475 32
4476 >>> v0 = BitVecVal(10, 4)
4477 >>> print("%.x" % v0.as_long())
4478 a
4479 >>> v = simplify(RepeatBitVec(4, v0))
4480 >>> v.size()
4481 16
4482 >>> print("%.x" % v.as_long())
4483 aaaa
4484 """
4485 if z3_debug():
4486 _z3_assert(_is_int(n), "First argument must be an integer")
4487 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4488 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4489
4490
4492 """Return the reduction-and expression of `a`."""
4493 if z3_debug():
4494 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4495 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4496
4497
4498def BVRedOr(a):
4499 """Return the reduction-or expression of `a`."""
4500 if z3_debug():
4501 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4502 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4503
4504
4505def BVAddNoOverflow(a, b, signed):
4506 """A predicate the determines that bit-vector addition does not overflow"""
4507 _check_bv_args(a, b)
4508 a, b = _coerce_exprs(a, b)
4509 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4510
4511
4513 """A predicate the determines that signed bit-vector addition does not underflow"""
4514 _check_bv_args(a, b)
4515 a, b = _coerce_exprs(a, b)
4516 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4517
4518
4520 """A predicate the determines that bit-vector subtraction does not overflow"""
4521 _check_bv_args(a, b)
4522 a, b = _coerce_exprs(a, b)
4523 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4524
4525
4526def BVSubNoUnderflow(a, b, signed):
4527 """A predicate the determines that bit-vector subtraction does not underflow"""
4528 _check_bv_args(a, b)
4529 a, b = _coerce_exprs(a, b)
4530 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4531
4532
4534 """A predicate the determines that bit-vector signed division does not overflow"""
4535 _check_bv_args(a, b)
4536 a, b = _coerce_exprs(a, b)
4537 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4538
4539
4541 """A predicate the determines that bit-vector unary negation does not overflow"""
4542 if z3_debug():
4543 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4544 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4545
4546
4547def BVMulNoOverflow(a, b, signed):
4548 """A predicate the determines that bit-vector multiplication does not overflow"""
4549 _check_bv_args(a, b)
4550 a, b = _coerce_exprs(a, b)
4551 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4552
4553
4555 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4556 _check_bv_args(a, b)
4557 a, b = _coerce_exprs(a, b)
4558 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4559
4560
4561
4566
4568 """Array sorts."""
4569
4570 def domain(self):
4571 """Return the domain of the array sort `self`.
4572
4573 >>> A = ArraySort(IntSort(), BoolSort())
4574 >>> A.domain()
4575 Int
4576 """
4578
4579 def domain_n(self, i):
4580 """Return the domain of the array sort `self`.
4581 """
4583
4584 def range(self):
4585 """Return the range of the array sort `self`.
4586
4587 >>> A = ArraySort(IntSort(), BoolSort())
4588 >>> A.range()
4589 Bool
4590 """
4592
4593
4595 """Array expressions. """
4596
4597 def sort(self):
4598 """Return the array sort of the array expression `self`.
4599
4600 >>> a = Array('a', IntSort(), BoolSort())
4601 >>> a.sort()
4602 Array(Int, Bool)
4603 """
4605
4606 def domain(self):
4607 """Shorthand for `self.sort().domain()`.
4608
4609 >>> a = Array('a', IntSort(), BoolSort())
4610 >>> a.domain()
4611 Int
4612 """
4613 return self.sortsort().domain()
4614
4615 def domain_n(self, i):
4616 """Shorthand for self.sort().domain_n(i)`."""
4617 return self.sortsort().domain_n(i)
4618
4619 def range(self):
4620 """Shorthand for `self.sort().range()`.
4621
4622 >>> a = Array('a', IntSort(), BoolSort())
4623 >>> a.range()
4624 Bool
4625 """
4626 return self.sortsort().range()
4627
4628 def __getitem__(self, arg):
4629 """Return the Z3 expression `self[arg]`.
4630
4631 >>> a = Array('a', IntSort(), BoolSort())
4632 >>> i = Int('i')
4633 >>> a[i]
4634 a[i]
4635 >>> a[i].sexpr()
4636 '(select a i)'
4637 """
4638 return _array_select(self, arg)
4639
4640 def default(self):
4641 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
4642
4643
4644def _array_select(ar, arg):
4645 if isinstance(arg, tuple):
4646 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4647 _args, sz = _to_ast_array(args)
4648 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4649 arg = ar.sort().domain().cast(arg)
4650 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4651
4652
4654 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4655
4656
4658 """Return `True` if `a` is a Z3 array expression.
4659
4660 >>> a = Array('a', IntSort(), IntSort())
4661 >>> is_array(a)
4662 True
4663 >>> is_array(Store(a, 0, 1))
4664 True
4665 >>> is_array(a[0])
4666 False
4667 """
4668 return isinstance(a, ArrayRef)
4669
4670
4672 """Return `True` if `a` is a Z3 constant array.
4673
4674 >>> a = K(IntSort(), 10)
4675 >>> is_const_array(a)
4676 True
4677 >>> a = Array('a', IntSort(), IntSort())
4678 >>> is_const_array(a)
4679 False
4680 """
4681 return is_app_of(a, Z3_OP_CONST_ARRAY)
4682
4683
4684def is_K(a):
4685 """Return `True` if `a` is a Z3 constant array.
4686
4687 >>> a = K(IntSort(), 10)
4688 >>> is_K(a)
4689 True
4690 >>> a = Array('a', IntSort(), IntSort())
4691 >>> is_K(a)
4692 False
4693 """
4694 return is_app_of(a, Z3_OP_CONST_ARRAY)
4695
4696
4697def is_map(a):
4698 """Return `True` if `a` is a Z3 map array expression.
4699
4700 >>> f = Function('f', IntSort(), IntSort())
4701 >>> b = Array('b', IntSort(), IntSort())
4702 >>> a = Map(f, b)
4703 >>> a
4704 Map(f, b)
4705 >>> is_map(a)
4706 True
4707 >>> is_map(b)
4708 False
4709 """
4710 return is_app_of(a, Z3_OP_ARRAY_MAP)
4711
4712
4714 """Return `True` if `a` is a Z3 default array expression.
4715 >>> d = Default(K(IntSort(), 10))
4716 >>> is_default(d)
4717 True
4718 """
4719 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4720
4721
4723 """Return the function declaration associated with a Z3 map array expression.
4724
4725 >>> f = Function('f', IntSort(), IntSort())
4726 >>> b = Array('b', IntSort(), IntSort())
4727 >>> a = Map(f, b)
4728 >>> eq(f, get_map_func(a))
4729 True
4730 >>> get_map_func(a)
4731 f
4732 >>> get_map_func(a)(0)
4733 f(0)
4734 """
4735 if z3_debug():
4736 _z3_assert(is_map(a), "Z3 array map expression expected.")
4737 return FuncDeclRef(
4739 a.ctx_ref(),
4740 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4741 ),
4742 ctx=a.ctx,
4743 )
4744
4745
4746def ArraySort(*sig):
4747 """Return the Z3 array sort with the given domain and range sorts.
4748
4749 >>> A = ArraySort(IntSort(), BoolSort())
4750 >>> A
4751 Array(Int, Bool)
4752 >>> A.domain()
4753 Int
4754 >>> A.range()
4755 Bool
4756 >>> AA = ArraySort(IntSort(), A)
4757 >>> AA
4758 Array(Int, Array(Int, Bool))
4759 """
4760 sig = _get_args(sig)
4761 if z3_debug():
4762 _z3_assert(len(sig) > 1, "At least two arguments expected")
4763 arity = len(sig) - 1
4764 r = sig[arity]
4765 d = sig[0]
4766 if z3_debug():
4767 for s in sig:
4768 _z3_assert(is_sort(s), "Z3 sort expected")
4769 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4770 ctx = d.ctx
4771 if len(sig) == 2:
4772 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4773 dom = (Sort * arity)()
4774 for i in range(arity):
4775 dom[i] = sig[i].ast
4776 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4777
4778
4779def Array(name, *sorts):
4780 """Return an array constant named `name` with the given domain and range sorts.
4781
4782 >>> a = Array('a', IntSort(), IntSort())
4783 >>> a.sort()
4784 Array(Int, Int)
4785 >>> a[0]
4786 a[0]
4787 """
4788 s = ArraySort(sorts)
4789 ctx = s.ctx
4790 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4791
4792
4793def Update(a, *args):
4794 """Return a Z3 store array expression.
4795
4796 >>> a = Array('a', IntSort(), IntSort())
4797 >>> i, v = Ints('i v')
4798 >>> s = Update(a, i, v)
4799 >>> s.sort()
4800 Array(Int, Int)
4801 >>> prove(s[i] == v)
4802 proved
4803 >>> j = Int('j')
4804 >>> prove(Implies(i != j, s[j] == a[j]))
4805 proved
4806 """
4807 if z3_debug():
4808 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4809 args = _get_args(args)
4810 ctx = a.ctx
4811 if len(args) <= 1:
4812 raise Z3Exception("array update requires index and value arguments")
4813 if len(args) == 2:
4814 i = args[0]
4815 v = args[1]
4816 i = a.sort().domain().cast(i)
4817 v = a.sort().range().cast(v)
4818 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4819 v = a.sort().range().cast(args[-1])
4820 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4821 _args, sz = _to_ast_array(idxs)
4822 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4823
4824
4825def Default(a):
4826 """ Return a default value for array expression.
4827 >>> b = K(IntSort(), 1)
4828 >>> prove(Default(b) == 1)
4829 proved
4830 """
4831 if z3_debug():
4832 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4833 return a.default()
4834
4835
4836def Store(a, *args):
4837 """Return a Z3 store array expression.
4838
4839 >>> a = Array('a', IntSort(), IntSort())
4840 >>> i, v = Ints('i v')
4841 >>> s = Store(a, i, v)
4842 >>> s.sort()
4843 Array(Int, Int)
4844 >>> prove(s[i] == v)
4845 proved
4846 >>> j = Int('j')
4847 >>> prove(Implies(i != j, s[j] == a[j]))
4848 proved
4849 """
4850 return Update(a, args)
4851
4852
4853def Select(a, *args):
4854 """Return a Z3 select array expression.
4855
4856 >>> a = Array('a', IntSort(), IntSort())
4857 >>> i = Int('i')
4858 >>> Select(a, i)
4859 a[i]
4860 >>> eq(Select(a, i), a[i])
4861 True
4862 """
4863 args = _get_args(args)
4864 if z3_debug():
4865 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4866 return a[args]
4867
4868
4869def Map(f, *args):
4870 """Return a Z3 map array expression.
4871
4872 >>> f = Function('f', IntSort(), IntSort(), IntSort())
4873 >>> a1 = Array('a1', IntSort(), IntSort())
4874 >>> a2 = Array('a2', IntSort(), IntSort())
4875 >>> b = Map(f, a1, a2)
4876 >>> b
4877 Map(f, a1, a2)
4878 >>> prove(b[0] == f(a1[0], a2[0]))
4879 proved
4880 """
4881 args = _get_args(args)
4882 if z3_debug():
4883 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
4884 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
4885 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
4886 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
4887 _args, sz = _to_ast_array(args)
4888 ctx = f.ctx
4889 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
4890
4891
4892def K(dom, v):
4893 """Return a Z3 constant array expression.
4894
4895 >>> a = K(IntSort(), 10)
4896 >>> a
4897 K(Int, 10)
4898 >>> a.sort()
4899 Array(Int, Int)
4900 >>> i = Int('i')
4901 >>> a[i]
4902 K(Int, 10)[i]
4903 >>> simplify(a[i])
4904 10
4905 """
4906 if z3_debug():
4907 _z3_assert(is_sort(dom), "Z3 sort expected")
4908 ctx = dom.ctx
4909 if not is_expr(v):
4910 v = _py2expr(v, ctx)
4911 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
4912
4913
4914def Ext(a, b):
4915 """Return extensionality index for one-dimensional arrays.
4916 >> a, b = Consts('a b', SetSort(IntSort()))
4917 >> Ext(a, b)
4918 Ext(a, b)
4919 """
4920 ctx = a.ctx
4921 if z3_debug():
4922 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
4923 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4924
4925
4926def SetHasSize(a, k):
4927 ctx = a.ctx
4928 k = _py2expr(k, ctx)
4929 return _to_expr_ref(Z3_mk_set_has_size(ctx.ref(), a.as_ast(), k.as_ast()), ctx)
4930
4931
4933 """Return `True` if `a` is a Z3 array select application.
4934
4935 >>> a = Array('a', IntSort(), IntSort())
4936 >>> is_select(a)
4937 False
4938 >>> i = Int('i')
4939 >>> is_select(a[i])
4940 True
4941 """
4942 return is_app_of(a, Z3_OP_SELECT)
4943
4944
4946 """Return `True` if `a` is a Z3 array store application.
4947
4948 >>> a = Array('a', IntSort(), IntSort())
4949 >>> is_store(a)
4950 False
4951 >>> is_store(Store(a, 0, 1))
4952 True
4953 """
4954 return is_app_of(a, Z3_OP_STORE)
4955
4956
4961
4962
4963def SetSort(s):
4964 """ Create a set sort over element sort s"""
4965 return ArraySort(s, BoolSort())
4966
4967
4969 """Create the empty set
4970 >>> EmptySet(IntSort())
4971 K(Int, False)
4972 """
4973 ctx = s.ctx
4974 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
4975
4976
4977def FullSet(s):
4978 """Create the full set
4979 >>> FullSet(IntSort())
4980 K(Int, True)
4981 """
4982 ctx = s.ctx
4983 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
4984
4985
4986def SetUnion(*args):
4987 """ Take the union of sets
4988 >>> a = Const('a', SetSort(IntSort()))
4989 >>> b = Const('b', SetSort(IntSort()))
4990 >>> SetUnion(a, b)
4991 union(a, b)
4992 """
4993 args = _get_args(args)
4994 ctx = _ctx_from_ast_arg_list(args)
4995 _args, sz = _to_ast_array(args)
4996 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
4997
4998
4999def SetIntersect(*args):
5000 """ Take the union of sets
5001 >>> a = Const('a', SetSort(IntSort()))
5002 >>> b = Const('b', SetSort(IntSort()))
5003 >>> SetIntersect(a, b)
5004 intersection(a, b)
5005 """
5006 args = _get_args(args)
5007 ctx = _ctx_from_ast_arg_list(args)
5008 _args, sz = _to_ast_array(args)
5009 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5010
5011
5012def SetAdd(s, e):
5013 """ Add element e to set s
5014 >>> a = Const('a', SetSort(IntSort()))
5015 >>> SetAdd(a, 1)
5016 Store(a, 1, True)
5017 """
5018 ctx = _ctx_from_ast_arg_list([s, e])
5019 e = _py2expr(e, ctx)
5020 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5021
5022
5023def SetDel(s, e):
5024 """ Remove element e to set s
5025 >>> a = Const('a', SetSort(IntSort()))
5026 >>> SetDel(a, 1)
5027 Store(a, 1, False)
5028 """
5029 ctx = _ctx_from_ast_arg_list([s, e])
5030 e = _py2expr(e, ctx)
5031 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5032
5033
5035 """ The complement of set s
5036 >>> a = Const('a', SetSort(IntSort()))
5037 >>> SetComplement(a)
5038 complement(a)
5039 """
5040 ctx = s.ctx
5041 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5042
5043
5045 """ The set difference of a and b
5046 >>> a = Const('a', SetSort(IntSort()))
5047 >>> b = Const('b', SetSort(IntSort()))
5048 >>> SetDifference(a, b)
5049 setminus(a, b)
5050 """
5051 ctx = _ctx_from_ast_arg_list([a, b])
5052 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5053
5054
5055def IsMember(e, s):
5056 """ Check if e is a member of set s
5057 >>> a = Const('a', SetSort(IntSort()))
5058 >>> IsMember(1, a)
5059 a[1]
5060 """
5061 ctx = _ctx_from_ast_arg_list([s, e])
5062 e = _py2expr(e, ctx)
5063 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5064
5065
5066def IsSubset(a, b):
5067 """ Check if a is a subset of b
5068 >>> a = Const('a', SetSort(IntSort()))
5069 >>> b = Const('b', SetSort(IntSort()))
5070 >>> IsSubset(a, b)
5071 subset(a, b)
5072 """
5073 ctx = _ctx_from_ast_arg_list([a, b])
5074 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5075
5076
5077
5082
5084 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5085 if not isinstance(acc, tuple):
5086 return False
5087 if len(acc) != 2:
5088 return False
5089 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5090
5091
5093 """Helper class for declaring Z3 datatypes.
5094
5095 >>> List = Datatype('List')
5096 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5097 >>> List.declare('nil')
5098 >>> List = List.create()
5099 >>> # List is now a Z3 declaration
5100 >>> List.nil
5101 nil
5102 >>> List.cons(10, List.nil)
5103 cons(10, nil)
5104 >>> List.cons(10, List.nil).sort()
5105 List
5106 >>> cons = List.cons
5107 >>> nil = List.nil
5108 >>> car = List.car
5109 >>> cdr = List.cdr
5110 >>> n = cons(1, cons(0, nil))
5111 >>> n
5112 cons(1, cons(0, nil))
5113 >>> simplify(cdr(n))
5114 cons(0, nil)
5115 >>> simplify(car(n))
5116 1
5117 """
5118
5119 def __init__(self, name, ctx=None):
5120 self.ctx = _get_ctx(ctx)
5121 self.name = name
5123
5124 def __deepcopy__(self, memo={}):
5125 r = Datatype(self.name, self.ctx)
5126 r.constructors = copy.deepcopy(self.constructors)
5127 return r
5128
5129 def declare_core(self, name, rec_name, *args):
5130 if z3_debug():
5131 _z3_assert(isinstance(name, str), "String expected")
5132 _z3_assert(isinstance(rec_name, str), "String expected")
5133 _z3_assert(
5134 all([_valid_accessor(a) for a in args]),
5135 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5136 )
5137 self.constructors.append((name, rec_name, args))
5138
5139 def declare(self, name, *args):
5140 """Declare constructor named `name` with the given accessors `args`.
5141 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5142 or a reference to the datatypes being declared.
5143
5144 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5145 declares the constructor named `cons` that builds a new List using an integer and a List.
5146 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5147 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5148 we use the method create() to create the actual datatype in Z3.
5149
5150 >>> List = Datatype('List')
5151 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5152 >>> List.declare('nil')
5153 >>> List = List.create()
5154 """
5155 if z3_debug():
5156 _z3_assert(isinstance(name, str), "String expected")
5157 _z3_assert(name != "", "Constructor name cannot be empty")
5158 return self.declare_core(name, "is-" + name, *args)
5159
5160 def __repr__(self):
5161 return "Datatype(%s, %s)" % (self.name, self.constructors)
5162
5163 def create(self):
5164 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5165
5166 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5167
5168 >>> List = Datatype('List')
5169 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5170 >>> List.declare('nil')
5171 >>> List = List.create()
5172 >>> List.nil
5173 nil
5174 >>> List.cons(10, List.nil)
5175 cons(10, nil)
5176 """
5177 return CreateDatatypes([self])[0]
5178
5179
5181 """Auxiliary object used to create Z3 datatypes."""
5182
5183 def __init__(self, c, ctx):
5184 self.c = c
5185 self.ctx = ctx
5186
5187 def __del__(self):
5188 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5189 Z3_del_constructor(self.ctx.ref(), self.c)
5190
5191
5193 """Auxiliary object used to create Z3 datatypes."""
5194
5195 def __init__(self, c, ctx):
5196 self.c = c
5197 self.ctx = ctx
5198
5199 def __del__(self):
5200 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5201 Z3_del_constructor_list(self.ctx.ref(), self.c)
5202
5203
5205 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5206
5207 In the following example we define a Tree-List using two mutually recursive datatypes.
5208
5209 >>> TreeList = Datatype('TreeList')
5210 >>> Tree = Datatype('Tree')
5211 >>> # Tree has two constructors: leaf and node
5212 >>> Tree.declare('leaf', ('val', IntSort()))
5213 >>> # a node contains a list of trees
5214 >>> Tree.declare('node', ('children', TreeList))
5215 >>> TreeList.declare('nil')
5216 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5217 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5218 >>> Tree.val(Tree.leaf(10))
5219 val(leaf(10))
5220 >>> simplify(Tree.val(Tree.leaf(10)))
5221 10
5222 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5223 >>> n1
5224 node(cons(leaf(10), cons(leaf(20), nil)))
5225 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5226 >>> simplify(n2 == n1)
5227 False
5228 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5229 True
5230 """
5231 ds = _get_args(ds)
5232 if z3_debug():
5233 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5234 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5235 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5236 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5237 ctx = ds[0].ctx
5238 num = len(ds)
5239 names = (Symbol * num)()
5240 out = (Sort * num)()
5241 clists = (ConstructorList * num)()
5242 to_delete = []
5243 for i in range(num):
5244 d = ds[i]
5245 names[i] = to_symbol(d.name, ctx)
5246 num_cs = len(d.constructors)
5247 cs = (Constructor * num_cs)()
5248 for j in range(num_cs):
5249 c = d.constructors[j]
5250 cname = to_symbol(c[0], ctx)
5251 rname = to_symbol(c[1], ctx)
5252 fs = c[2]
5253 num_fs = len(fs)
5254 fnames = (Symbol * num_fs)()
5255 sorts = (Sort * num_fs)()
5256 refs = (ctypes.c_uint * num_fs)()
5257 for k in range(num_fs):
5258 fname = fs[k][0]
5259 ftype = fs[k][1]
5260 fnames[k] = to_symbol(fname, ctx)
5261 if isinstance(ftype, Datatype):
5262 if z3_debug():
5263 _z3_assert(
5264 ds.count(ftype) == 1,
5265 "One and only one occurrence of each datatype is expected",
5266 )
5267 sorts[k] = None
5268 refs[k] = ds.index(ftype)
5269 else:
5270 if z3_debug():
5271 _z3_assert(is_sort(ftype), "Z3 sort expected")
5272 sorts[k] = ftype.ast
5273 refs[k] = 0
5274 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5275 to_delete.append(ScopedConstructor(cs[j], ctx))
5276 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5277 to_delete.append(ScopedConstructorList(clists[i], ctx))
5278 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5279 result = []
5280 # Create a field for every constructor, recognizer and accessor
5281 for i in range(num):
5282 dref = DatatypeSortRef(out[i], ctx)
5283 num_cs = dref.num_constructors()
5284 for j in range(num_cs):
5285 cref = dref.constructor(j)
5286 cref_name = cref.name()
5287 cref_arity = cref.arity()
5288 if cref.arity() == 0:
5289 cref = cref()
5290 setattr(dref, cref_name, cref)
5291 rref = dref.recognizer(j)
5292 setattr(dref, "is_" + cref_name, rref)
5293 for k in range(cref_arity):
5294 aref = dref.accessor(j, k)
5295 setattr(dref, aref.name(), aref)
5296 result.append(dref)
5297 return tuple(result)
5298
5299
5301 """Datatype sorts."""
5302
5304 """Return the number of constructors in the given Z3 datatype.
5305
5306 >>> List = Datatype('List')
5307 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5308 >>> List.declare('nil')
5309 >>> List = List.create()
5310 >>> # List is now a Z3 declaration
5311 >>> List.num_constructors()
5312 2
5313 """
5315
5316 def constructor(self, idx):
5317 """Return a constructor of the datatype `self`.
5318
5319 >>> List = Datatype('List')
5320 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5321 >>> List.declare('nil')
5322 >>> List = List.create()
5323 >>> # List is now a Z3 declaration
5324 >>> List.num_constructors()
5325 2
5326 >>> List.constructor(0)
5327 cons
5328 >>> List.constructor(1)
5329 nil
5330 """
5331 if z3_debug():
5332 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5334
5335 def recognizer(self, idx):
5336 """In Z3, each constructor has an associated recognizer predicate.
5337
5338 If the constructor is named `name`, then the recognizer `is_name`.
5339
5340 >>> List = Datatype('List')
5341 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5342 >>> List.declare('nil')
5343 >>> List = List.create()
5344 >>> # List is now a Z3 declaration
5345 >>> List.num_constructors()
5346 2
5347 >>> List.recognizer(0)
5348 is(cons)
5349 >>> List.recognizer(1)
5350 is(nil)
5351 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5352 False
5353 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5354 True
5355 >>> l = Const('l', List)
5356 >>> simplify(List.is_cons(l))
5357 is(cons, l)
5358 """
5359 if z3_debug():
5360 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5362
5363 def accessor(self, i, j):
5364 """In Z3, each constructor has 0 or more accessor.
5365 The number of accessors is equal to the arity of the constructor.
5366
5367 >>> List = Datatype('List')
5368 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5369 >>> List.declare('nil')
5370 >>> List = List.create()
5371 >>> List.num_constructors()
5372 2
5373 >>> List.constructor(0)
5374 cons
5375 >>> num_accs = List.constructor(0).arity()
5376 >>> num_accs
5377 2
5378 >>> List.accessor(0, 0)
5379 car
5380 >>> List.accessor(0, 1)
5381 cdr
5382 >>> List.constructor(1)
5383 nil
5384 >>> num_accs = List.constructor(1).arity()
5385 >>> num_accs
5386 0
5387 """
5388 if z3_debug():
5389 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5390 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5391 return FuncDeclRef(
5393 ctx=self.ctxctxctx,
5394 )
5395
5396
5398 """Datatype expressions."""
5399
5400 def sort(self):
5401 """Return the datatype sort of the datatype expression `self`."""
5403
5404def DatatypeSort(name, ctx = None):
5405 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype"""
5406 ctx = _get_ctx(ctx)
5407 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
5408
5409def TupleSort(name, sorts, ctx=None):
5410 """Create a named tuple sort base on a set of underlying sorts
5411 Example:
5412 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5413 """
5414 tuple = Datatype(name, ctx)
5415 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5416 tuple.declare(name, *projects)
5417 tuple = tuple.create()
5418 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5419
5420
5421def DisjointSum(name, sorts, ctx=None):
5422 """Create a named tagged union sort base on a set of underlying sorts
5423 Example:
5424 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5425 """
5426 sum = Datatype(name, ctx)
5427 for i in range(len(sorts)):
5428 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5429 sum = sum.create()
5430 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5431
5432
5433def EnumSort(name, values, ctx=None):
5434 """Return a new enumeration sort named `name` containing the given values.
5435
5436 The result is a pair (sort, list of constants).
5437 Example:
5438 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5439 """
5440 if z3_debug():
5441 _z3_assert(isinstance(name, str), "Name must be a string")
5442 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5443 _z3_assert(len(values) > 0, "At least one value expected")
5444 ctx = _get_ctx(ctx)
5445 num = len(values)
5446 _val_names = (Symbol * num)()
5447 for i in range(num):
5448 _val_names[i] = to_symbol(values[i], ctx)
5449 _values = (FuncDecl * num)()
5450 _testers = (FuncDecl * num)()
5451 name = to_symbol(name, ctx)
5452 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5453 V = []
5454 for i in range(num):
5455 V.append(FuncDeclRef(_values[i], ctx))
5456 V = [a() for a in V]
5457 return S, V
5458
5459
5464
5465
5467 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5468
5469 Consider using the function `args2params` to create instances of this object.
5470 """
5471
5472 def __init__(self, ctx=None, params=None):
5473 self.ctx = _get_ctx(ctx)
5474 if params is None:
5475 self.params = Z3_mk_params(self.ctx.ref())
5476 else:
5477 self.params = params
5478 Z3_params_inc_ref(self.ctx.ref(), self.params)
5479
5480 def __deepcopy__(self, memo={}):
5481 return ParamsRef(self.ctx, self.params)
5482
5483 def __del__(self):
5484 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5485 Z3_params_dec_ref(self.ctx.ref(), self.params)
5486
5487 def set(self, name, val):
5488 """Set parameter name with value val."""
5489 if z3_debug():
5490 _z3_assert(isinstance(name, str), "parameter name must be a string")
5491 name_sym = to_symbol(name, self.ctx)
5492 if isinstance(val, bool):
5493 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5494 elif _is_int(val):
5495 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5496 elif isinstance(val, float):
5497 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5498 elif isinstance(val, str):
5499 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5500 else:
5501 if z3_debug():
5502 _z3_assert(False, "invalid parameter value")
5503
5504 def __repr__(self):
5505 return Z3_params_to_string(self.ctx.ref(), self.params)
5506
5507 def validate(self, ds):
5508 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5509 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5510
5511
5512def args2params(arguments, keywords, ctx=None):
5513 """Convert python arguments into a Z3_params object.
5514 A ':' is added to the keywords, and '_' is replaced with '-'
5515
5516 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5517 (params model true relevancy 2 elim_and true)
5518 """
5519 if z3_debug():
5520 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5521 prev = None
5522 r = ParamsRef(ctx)
5523 for a in arguments:
5524 if prev is None:
5525 prev = a
5526 else:
5527 r.set(prev, a)
5528 prev = None
5529 for k in keywords:
5530 v = keywords[k]
5531 r.set(k, v)
5532 return r
5533
5534
5536 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5537 """
5538
5539 def __init__(self, descr, ctx=None):
5540 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5541 self.ctx = _get_ctx(ctx)
5542 self.descr = descr
5543 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5544
5545 def __deepcopy__(self, memo={}):
5546 return ParamsDescrsRef(self.descr, self.ctx)
5547
5548 def __del__(self):
5549 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5550 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5551
5552 def size(self):
5553 """Return the size of in the parameter description `self`.
5554 """
5555 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5556
5557 def __len__(self):
5558 """Return the size of in the parameter description `self`.
5559 """
5560 return self.size()
5561
5562 def get_name(self, i):
5563 """Return the i-th parameter name in the parameter description `self`.
5564 """
5565 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5566
5567 def get_kind(self, n):
5568 """Return the kind of the parameter named `n`.
5569 """
5570 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5571
5572 def get_documentation(self, n):
5573 """Return the documentation string of the parameter named `n`.
5574 """
5575 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5576
5577 def __getitem__(self, arg):
5578 if _is_int(arg):
5579 return self.get_name(arg)
5580 else:
5581 return self.get_kind(arg)
5582
5583 def __repr__(self):
5584 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5585
5586
5591
5592
5594 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5595
5596 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5597 A goal has a solution if one of its subgoals has a solution.
5598 A goal is unsatisfiable if all subgoals are unsatisfiable.
5599 """
5600
5601 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5602 if z3_debug():
5603 _z3_assert(goal is None or ctx is not None,
5604 "If goal is different from None, then ctx must be also different from None")
5605 self.ctx = _get_ctx(ctx)
5606 self.goal = goal
5607 if self.goal is None:
5608 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5609 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5610
5611 def __del__(self):
5612 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5613 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5614
5615 def depth(self):
5616 """Return the depth of the goal `self`.
5617 The depth corresponds to the number of tactics applied to `self`.
5618
5619 >>> x, y = Ints('x y')
5620 >>> g = Goal()
5621 >>> g.add(x == 0, y >= x + 1)
5622 >>> g.depth()
5623 0
5624 >>> r = Then('simplify', 'solve-eqs')(g)
5625 >>> # r has 1 subgoal
5626 >>> len(r)
5627 1
5628 >>> r[0].depth()
5629 2
5630 """
5631 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5632
5633 def inconsistent(self):
5634 """Return `True` if `self` contains the `False` constraints.
5635
5636 >>> x, y = Ints('x y')
5637 >>> g = Goal()
5638 >>> g.inconsistent()
5639 False
5640 >>> g.add(x == 0, x == 1)
5641 >>> g
5642 [x == 0, x == 1]
5643 >>> g.inconsistent()
5644 False
5645 >>> g2 = Tactic('propagate-values')(g)[0]
5646 >>> g2.inconsistent()
5647 True
5648 """
5649 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5650
5651 def prec(self):
5652 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5653
5654 >>> g = Goal()
5655 >>> g.prec() == Z3_GOAL_PRECISE
5656 True
5657 >>> x, y = Ints('x y')
5658 >>> g.add(x == y + 1)
5659 >>> g.prec() == Z3_GOAL_PRECISE
5660 True
5661 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5662 >>> g2 = t(g)[0]
5663 >>> g2
5664 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5665 >>> g2.prec() == Z3_GOAL_PRECISE
5666 False
5667 >>> g2.prec() == Z3_GOAL_UNDER
5668 True
5669 """
5670 return Z3_goal_precision(self.ctx.ref(), self.goal)
5671
5672 def precision(self):
5673 """Alias for `prec()`.
5674
5675 >>> g = Goal()
5676 >>> g.precision() == Z3_GOAL_PRECISE
5677 True
5678 """
5679 return self.prec()
5680
5681 def size(self):
5682 """Return the number of constraints in the goal `self`.
5683
5684 >>> g = Goal()
5685 >>> g.size()
5686 0
5687 >>> x, y = Ints('x y')
5688 >>> g.add(x == 0, y > x)
5689 >>> g.size()
5690 2
5691 """
5692 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5693
5694 def __len__(self):
5695 """Return the number of constraints in the goal `self`.
5696
5697 >>> g = Goal()
5698 >>> len(g)
5699 0
5700 >>> x, y = Ints('x y')
5701 >>> g.add(x == 0, y > x)
5702 >>> len(g)
5703 2
5704 """
5705 return self.size()
5706
5707 def get(self, i):
5708 """Return a constraint in the goal `self`.
5709
5710 >>> g = Goal()
5711 >>> x, y = Ints('x y')
5712 >>> g.add(x == 0, y > x)
5713 >>> g.get(0)
5714 x == 0
5715 >>> g.get(1)
5716 y > x
5717 """
5718 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5719
5720 def __getitem__(self, arg):
5721 """Return a constraint in the goal `self`.
5722
5723 >>> g = Goal()
5724 >>> x, y = Ints('x y')
5725 >>> g.add(x == 0, y > x)
5726 >>> g[0]
5727 x == 0
5728 >>> g[1]
5729 y > x
5730 """
5731 if arg >= len(self):
5732 raise IndexError
5733 return self.get(arg)
5734
5735 def assert_exprs(self, *args):
5736 """Assert constraints into the goal.
5737
5738 >>> x = Int('x')
5739 >>> g = Goal()
5740 >>> g.assert_exprs(x > 0, x < 2)
5741 >>> g
5742 [x > 0, x < 2]
5743 """
5744 args = _get_args(args)
5745 s = BoolSort(self.ctx)
5746 for arg in args:
5747 arg = s.cast(arg)
5748 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5749
5750 def append(self, *args):
5751 """Add constraints.
5752
5753 >>> x = Int('x')
5754 >>> g = Goal()
5755 >>> g.append(x > 0, x < 2)
5756 >>> g
5757 [x > 0, x < 2]
5758 """
5759 self.assert_exprs(*args)
5760
5761 def insert(self, *args):
5762 """Add constraints.
5763
5764 >>> x = Int('x')
5765 >>> g = Goal()
5766 >>> g.insert(x > 0, x < 2)
5767 >>> g
5768 [x > 0, x < 2]
5769 """
5770 self.assert_exprs(*args)
5771
5772 def add(self, *args):
5773 """Add constraints.
5774
5775 >>> x = Int('x')
5776 >>> g = Goal()
5777 >>> g.add(x > 0, x < 2)
5778 >>> g
5779 [x > 0, x < 2]
5780 """
5781 self.assert_exprs(*args)
5782
5783 def convert_model(self, model):
5784 """Retrieve model from a satisfiable goal
5785 >>> a, b = Ints('a b')
5786 >>> g = Goal()
5787 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5788 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5789 >>> r = t(g)
5790 >>> r[0]
5791 [Or(b == 0, b == 1), Not(0 <= b)]
5792 >>> r[1]
5793 [Or(b == 0, b == 1), Not(1 <= b)]
5794 >>> # Remark: the subgoal r[0] is unsatisfiable
5795 >>> # Creating a solver for solving the second subgoal
5796 >>> s = Solver()
5797 >>> s.add(r[1])
5798 >>> s.check()
5799 sat
5800 >>> s.model()
5801 [b = 0]
5802 >>> # Model s.model() does not assign a value to `a`
5803 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5804 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5805 >>> r[1].convert_model(s.model())
5806 [b = 0, a = 1]
5807 """
5808 if z3_debug():
5809 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5810 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5811
5812 def __repr__(self):
5813 return obj_to_string(self)
5814
5815 def sexpr(self):
5816 """Return a textual representation of the s-expression representing the goal."""
5817 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5818
5819 def dimacs(self, include_names=True):
5820 """Return a textual representation of the goal in DIMACS format."""
5821 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5822
5823 def translate(self, target):
5824 """Copy goal `self` to context `target`.
5825
5826 >>> x = Int('x')
5827 >>> g = Goal()
5828 >>> g.add(x > 10)
5829 >>> g
5830 [x > 10]
5831 >>> c2 = Context()
5832 >>> g2 = g.translate(c2)
5833 >>> g2
5834 [x > 10]
5835 >>> g.ctx == main_ctx()
5836 True
5837 >>> g2.ctx == c2
5838 True
5839 >>> g2.ctx == main_ctx()
5840 False
5841 """
5842 if z3_debug():
5843 _z3_assert(isinstance(target, Context), "target must be a context")
5844 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5845
5846 def __copy__(self):
5847 return self.translate(self.ctx)
5848
5849 def __deepcopy__(self, memo={}):
5850 return self.translate(self.ctx)
5851
5852 def simplify(self, *arguments, **keywords):
5853 """Return a new simplified goal.
5854
5855 This method is essentially invoking the simplify tactic.
5856
5857 >>> g = Goal()
5858 >>> x = Int('x')
5859 >>> g.add(x + 1 >= 2)
5860 >>> g
5861 [x + 1 >= 2]
5862 >>> g2 = g.simplify()
5863 >>> g2
5864 [x >= 1]
5865 >>> # g was not modified
5866 >>> g
5867 [x + 1 >= 2]
5868 """
5869 t = Tactic("simplify")
5870 return t.apply(self, *arguments, **keywords)[0]
5871
5872 def as_expr(self):
5873 """Return goal `self` as a single Z3 expression.
5874
5875 >>> x = Int('x')
5876 >>> g = Goal()
5877 >>> g.as_expr()
5878 True
5879 >>> g.add(x > 1)
5880 >>> g.as_expr()
5881 x > 1
5882 >>> g.add(x < 10)
5883 >>> g.as_expr()
5884 And(x > 1, x < 10)
5885 """
5886 sz = len(self)
5887 if sz == 0:
5888 return BoolVal(True, self.ctx)
5889 elif sz == 1:
5890 return self.get(0)
5891 else:
5892 return And([self.get(i) for i in range(len(self))], self.ctx)
5893
5894
5899
5900
5902 """A collection (vector) of ASTs."""
5903
5904 def __init__(self, v=None, ctx=None):
5905 self.vector = None
5906 if v is None:
5907 self.ctx = _get_ctx(ctx)
5908 self.vector = Z3_mk_ast_vector(self.ctx.ref())
5909 else:
5910 self.vector = v
5911 assert ctx is not None
5912 self.ctx = ctx
5913 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
5914
5915 def __del__(self):
5916 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
5917 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
5918
5919 def __len__(self):
5920 """Return the size of the vector `self`.
5921
5922 >>> A = AstVector()
5923 >>> len(A)
5924 0
5925 >>> A.push(Int('x'))
5926 >>> A.push(Int('x'))
5927 >>> len(A)
5928 2
5929 """
5930 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
5931
5932 def __getitem__(self, i):
5933 """Return the AST at position `i`.
5934
5935 >>> A = AstVector()
5936 >>> A.push(Int('x') + 1)
5937 >>> A.push(Int('y'))
5938 >>> A[0]
5939 x + 1
5940 >>> A[1]
5941 y
5942 """
5943
5944 if isinstance(i, int):
5945 if i < 0:
5946 i += self.__len__()
5947
5948 if i >= self.__len__():
5949 raise IndexError
5950 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
5951
5952 elif isinstance(i, slice):
5953 result = []
5954 for ii in range(*i.indices(self.__len__())):
5955 result.append(_to_ast_ref(
5956 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
5957 self.ctx,
5958 ))
5959 return result
5960
5961 def __setitem__(self, i, v):
5962 """Update AST at position `i`.
5963
5964 >>> A = AstVector()
5965 >>> A.push(Int('x') + 1)
5966 >>> A.push(Int('y'))
5967 >>> A[0]
5968 x + 1
5969 >>> A[0] = Int('x')
5970 >>> A[0]
5971 x
5972 """
5973 if i >= self.__len__():
5974 raise IndexError
5975 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
5976
5977 def push(self, v):
5978 """Add `v` in the end of the vector.
5979
5980 >>> A = AstVector()
5981 >>> len(A)
5982 0
5983 >>> A.push(Int('x'))
5984 >>> len(A)
5985 1
5986 """
5987 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
5988
5989 def resize(self, sz):
5990 """Resize the vector to `sz` elements.
5991
5992 >>> A = AstVector()
5993 >>> A.resize(10)
5994 >>> len(A)
5995 10
5996 >>> for i in range(10): A[i] = Int('x')
5997 >>> A[5]
5998 x
5999 """
6000 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6001
6002 def __contains__(self, item):
6003 """Return `True` if the vector contains `item`.
6004
6005 >>> x = Int('x')
6006 >>> A = AstVector()
6007 >>> x in A
6008 False
6009 >>> A.push(x)
6010 >>> x in A
6011 True
6012 >>> (x+1) in A
6013 False
6014 >>> A.push(x+1)
6015 >>> (x+1) in A
6016 True
6017 >>> A
6018 [x, x + 1]
6019 """
6020 for elem in self:
6021 if elem.eq(item):
6022 return True
6023 return False
6024
6025 def translate(self, other_ctx):
6026 """Copy vector `self` to context `other_ctx`.
6027
6028 >>> x = Int('x')
6029 >>> A = AstVector()
6030 >>> A.push(x)
6031 >>> c2 = Context()
6032 >>> B = A.translate(c2)
6033 >>> B
6034 [x]
6035 """
6036 return AstVector(
6037 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6038 ctx=other_ctx,
6039 )
6040
6041 def __copy__(self):
6042 return self.translate(self.ctx)
6043
6044 def __deepcopy__(self, memo={}):
6045 return self.translate(self.ctx)
6046
6047 def __repr__(self):
6048 return obj_to_string(self)
6049
6050 def sexpr(self):
6051 """Return a textual representation of the s-expression representing the vector."""
6052 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6053
6054
6059
6060
6062 """A mapping from ASTs to ASTs."""
6063
6064 def __init__(self, m=None, ctx=None):
6065 self.map = None
6066 if m is None:
6067 self.ctx = _get_ctx(ctx)
6068 self.map = Z3_mk_ast_map(self.ctx.ref())
6069 else:
6070 self.map = m
6071 assert ctx is not None
6072 self.ctx = ctx
6073 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6074
6075 def __deepcopy__(self, memo={}):
6076 return AstMap(self.map, self.ctx)
6077
6078 def __del__(self):
6079 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6080 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6081
6082 def __len__(self):
6083 """Return the size of the map.
6084
6085 >>> M = AstMap()
6086 >>> len(M)
6087 0
6088 >>> x = Int('x')
6089 >>> M[x] = IntVal(1)
6090 >>> len(M)
6091 1
6092 """
6093 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6094
6095 def __contains__(self, key):
6096 """Return `True` if the map contains key `key`.
6097
6098 >>> M = AstMap()
6099 >>> x = Int('x')
6100 >>> M[x] = x + 1
6101 >>> x in M
6102 True
6103 >>> x+1 in M
6104 False
6105 """
6106 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6107
6108 def __getitem__(self, key):
6109 """Retrieve the value associated with key `key`.
6110
6111 >>> M = AstMap()
6112 >>> x = Int('x')
6113 >>> M[x] = x + 1
6114 >>> M[x]
6115 x + 1
6116 """
6117 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6118
6119 def __setitem__(self, k, v):
6120 """Add/Update key `k` with value `v`.
6121
6122 >>> M = AstMap()
6123 >>> x = Int('x')
6124 >>> M[x] = x + 1
6125 >>> len(M)
6126 1
6127 >>> M[x]
6128 x + 1
6129 >>> M[x] = IntVal(1)
6130 >>> M[x]
6131 1
6132 """
6133 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6134
6135 def __repr__(self):
6136 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6137
6138 def erase(self, k):
6139 """Remove the entry associated with key `k`.
6140
6141 >>> M = AstMap()
6142 >>> x = Int('x')
6143 >>> M[x] = x + 1
6144 >>> len(M)
6145 1
6146 >>> M.erase(x)
6147 >>> len(M)
6148 0
6149 """
6150 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6151
6152 def reset(self):
6153 """Remove all entries from the map.
6154
6155 >>> M = AstMap()
6156 >>> x = Int('x')
6157 >>> M[x] = x + 1
6158 >>> M[x+x] = IntVal(1)
6159 >>> len(M)
6160 2
6161 >>> M.reset()
6162 >>> len(M)
6163 0
6164 """
6165 Z3_ast_map_reset(self.ctx.ref(), self.map)
6166
6167 def keys(self):
6168 """Return an AstVector containing all keys in the map.
6169
6170 >>> M = AstMap()
6171 >>> x = Int('x')
6172 >>> M[x] = x + 1
6173 >>> M[x+x] = IntVal(1)
6174 >>> M.keys()
6175 [x, x + x]
6176 """
6177 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6178
6179
6184
6185
6187 """Store the value of the interpretation of a function in a particular point."""
6188
6189 def __init__(self, entry, ctx):
6190 self.entry = entry
6191 self.ctx = ctx
6192 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6193
6194 def __deepcopy__(self, memo={}):
6195 return FuncEntry(self.entry, self.ctx)
6196
6197 def __del__(self):
6198 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6199 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6200
6201 def num_args(self):
6202 """Return the number of arguments in the given entry.
6203
6204 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6205 >>> s = Solver()
6206 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6207 >>> s.check()
6208 sat
6209 >>> m = s.model()
6210 >>> f_i = m[f]
6211 >>> f_i.num_entries()
6212 1
6213 >>> e = f_i.entry(0)
6214 >>> e.num_args()
6215 2
6216 """
6217 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6218
6219 def arg_value(self, idx):
6220 """Return the value of argument `idx`.
6221
6222 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6223 >>> s = Solver()
6224 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6225 >>> s.check()
6226 sat
6227 >>> m = s.model()
6228 >>> f_i = m[f]
6229 >>> f_i.num_entries()
6230 1
6231 >>> e = f_i.entry(0)
6232 >>> e
6233 [1, 2, 20]
6234 >>> e.num_args()
6235 2
6236 >>> e.arg_value(0)
6237 1
6238 >>> e.arg_value(1)
6239 2
6240 >>> try:
6241 ... e.arg_value(2)
6242 ... except IndexError:
6243 ... print("index error")
6244 index error
6245 """
6246 if idx >= self.num_args():
6247 raise IndexError
6248 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6249
6250 def value(self):
6251 """Return the value of the function at point `self`.
6252
6253 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6254 >>> s = Solver()
6255 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6256 >>> s.check()
6257 sat
6258 >>> m = s.model()
6259 >>> f_i = m[f]
6260 >>> f_i.num_entries()
6261 1
6262 >>> e = f_i.entry(0)
6263 >>> e
6264 [1, 2, 20]
6265 >>> e.num_args()
6266 2
6267 >>> e.value()
6268 20
6269 """
6270 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6271
6272 def as_list(self):
6273 """Return entry `self` as a Python list.
6274 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6275 >>> s = Solver()
6276 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6277 >>> s.check()
6278 sat
6279 >>> m = s.model()
6280 >>> f_i = m[f]
6281 >>> f_i.num_entries()
6282 1
6283 >>> e = f_i.entry(0)
6284 >>> e.as_list()
6285 [1, 2, 20]
6286 """
6287 args = [self.arg_value(i) for i in range(self.num_args())]
6288 args.append(self.value())
6289 return args
6290
6291 def __repr__(self):
6292 return repr(self.as_list())
6293
6294
6296 """Stores the interpretation of a function in a Z3 model."""
6297
6298 def __init__(self, f, ctx):
6299 self.f = f
6300 self.ctx = ctx
6301 if self.f is not None:
6302 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6303
6304 def __del__(self):
6305 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6306 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6307
6308 def else_value(self):
6309 """
6310 Return the `else` value for a function interpretation.
6311 Return None if Z3 did not specify the `else` value for
6312 this object.
6313
6314 >>> f = Function('f', IntSort(), IntSort())
6315 >>> s = Solver()
6316 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6317 >>> s.check()
6318 sat
6319 >>> m = s.model()
6320 >>> m[f]
6321 [2 -> 0, else -> 1]
6322 >>> m[f].else_value()
6323 1
6324 """
6325 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6326 if r:
6327 return _to_expr_ref(r, self.ctx)
6328 else:
6329 return None
6330
6331 def num_entries(self):
6332 """Return the number of entries/points in the function interpretation `self`.
6333
6334 >>> f = Function('f', IntSort(), IntSort())
6335 >>> s = Solver()
6336 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6337 >>> s.check()
6338 sat
6339 >>> m = s.model()
6340 >>> m[f]
6341 [2 -> 0, else -> 1]
6342 >>> m[f].num_entries()
6343 1
6344 """
6345 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6346
6347 def arity(self):
6348 """Return the number of arguments for each entry in the function interpretation `self`.
6349
6350 >>> f = Function('f', IntSort(), IntSort())
6351 >>> s = Solver()
6352 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6353 >>> s.check()
6354 sat
6355 >>> m = s.model()
6356 >>> m[f].arity()
6357 1
6358 """
6359 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6360
6361 def entry(self, idx):
6362 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6363
6364 >>> f = Function('f', IntSort(), IntSort())
6365 >>> s = Solver()
6366 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6367 >>> s.check()
6368 sat
6369 >>> m = s.model()
6370 >>> m[f]
6371 [2 -> 0, else -> 1]
6372 >>> m[f].num_entries()
6373 1
6374 >>> m[f].entry(0)
6375 [2, 0]
6376 """
6377 if idx >= self.num_entries():
6378 raise IndexError
6379 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6380
6381 def translate(self, other_ctx):
6382 """Copy model 'self' to context 'other_ctx'.
6383 """
6384 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6385
6386 def __copy__(self):
6387 return self.translate(self.ctx)
6388
6389 def __deepcopy__(self, memo={}):
6390 return self.translate(self.ctx)
6391
6392 def as_list(self):
6393 """Return the function interpretation as a Python list.
6394 >>> f = Function('f', IntSort(), IntSort())
6395 >>> s = Solver()
6396 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6397 >>> s.check()
6398 sat
6399 >>> m = s.model()
6400 >>> m[f]
6401 [2 -> 0, else -> 1]
6402 >>> m[f].as_list()
6403 [[2, 0], 1]
6404 """
6405 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6406 r.append(self.else_value())
6407 return r
6408
6409 def __repr__(self):
6410 return obj_to_string(self)
6411
6412
6414 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6415
6416 def __init__(self, m, ctx):
6417 assert ctx is not None
6418 self.model = m
6419 self.ctx = ctx
6420 Z3_model_inc_ref(self.ctx.ref(), self.model)
6421
6422 def __del__(self):
6423 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6424 Z3_model_dec_ref(self.ctx.ref(), self.model)
6425
6426 def __repr__(self):
6427 return obj_to_string(self)
6428
6429 def sexpr(self):
6430 """Return a textual representation of the s-expression representing the model."""
6431 return Z3_model_to_string(self.ctx.ref(), self.model)
6432
6433 def eval(self, t, model_completion=False):
6434 """Evaluate the expression `t` in the model `self`.
6435 If `model_completion` is enabled, then a default interpretation is automatically added
6436 for symbols that do not have an interpretation in the model `self`.
6437
6438 >>> x = Int('x')
6439 >>> s = Solver()
6440 >>> s.add(x > 0, x < 2)
6441 >>> s.check()
6442 sat
6443 >>> m = s.model()
6444 >>> m.eval(x + 1)
6445 2
6446 >>> m.eval(x == 1)
6447 True
6448 >>> y = Int('y')
6449 >>> m.eval(y + x)
6450 1 + y
6451 >>> m.eval(y)
6452 y
6453 >>> m.eval(y, model_completion=True)
6454 0
6455 >>> # Now, m contains an interpretation for y
6456 >>> m.eval(y + x)
6457 1
6458 """
6459 r = (Ast * 1)()
6460 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6461 return _to_expr_ref(r[0], self.ctx)
6462 raise Z3Exception("failed to evaluate expression in the model")
6463
6464 def evaluate(self, t, model_completion=False):
6465 """Alias for `eval`.
6466
6467 >>> x = Int('x')
6468 >>> s = Solver()
6469 >>> s.add(x > 0, x < 2)
6470 >>> s.check()
6471 sat
6472 >>> m = s.model()
6473 >>> m.evaluate(x + 1)
6474 2
6475 >>> m.evaluate(x == 1)
6476 True
6477 >>> y = Int('y')
6478 >>> m.evaluate(y + x)
6479 1 + y
6480 >>> m.evaluate(y)
6481 y
6482 >>> m.evaluate(y, model_completion=True)
6483 0
6484 >>> # Now, m contains an interpretation for y
6485 >>> m.evaluate(y + x)
6486 1
6487 """
6488 return self.eval(t, model_completion)
6489
6490 def __len__(self):
6491 """Return the number of constant and function declarations in the model `self`.
6492
6493 >>> f = Function('f', IntSort(), IntSort())
6494 >>> x = Int('x')
6495 >>> s = Solver()
6496 >>> s.add(x > 0, f(x) != x)
6497 >>> s.check()
6498 sat
6499 >>> m = s.model()
6500 >>> len(m)
6501 2
6502 """
6503 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6504 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6505 return num_consts + num_funcs
6506
6507 def get_interp(self, decl):
6508 """Return the interpretation for a given declaration or constant.
6509
6510 >>> f = Function('f', IntSort(), IntSort())
6511 >>> x = Int('x')
6512 >>> s = Solver()
6513 >>> s.add(x > 0, x < 2, f(x) == 0)
6514 >>> s.check()
6515 sat
6516 >>> m = s.model()
6517 >>> m[x]
6518 1
6519 >>> m[f]
6520 [else -> 0]
6521 """
6522 if z3_debug():
6523 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6524 if is_const(decl):
6525 decl = decl.decl()
6526 try:
6527 if decl.arity() == 0:
6528 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6529 if _r.value is None:
6530 return None
6531 r = _to_expr_ref(_r, self.ctx)
6532 if is_as_array(r):
6533 fi = self.get_interp(get_as_array_func(r))
6534 if fi is None:
6535 return fi
6536 e = fi.else_value()
6537 if e is None:
6538 return fi
6539 if fi.arity() != 1:
6540 return fi
6541 srt = decl.range()
6542 dom = srt.domain()
6543 e = K(dom, e)
6544 i = 0
6545 sz = fi.num_entries()
6546 n = fi.arity()
6547 while i < sz:
6548 fe = fi.entry(i)
6549 e = Store(e, fe.arg_value(0), fe.value())
6550 i += 1
6551 return e
6552 else:
6553 return r
6554 else:
6555 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6556 except Z3Exception:
6557 return None
6558
6559 def num_sorts(self):
6560 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6561
6562 >>> A = DeclareSort('A')
6563 >>> a, b = Consts('a b', A)
6564 >>> s = Solver()
6565 >>> s.add(a != b)
6566 >>> s.check()
6567 sat
6568 >>> m = s.model()
6569 >>> m.num_sorts()
6570 1
6571 """
6572 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6573
6574 def get_sort(self, idx):
6575 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6576
6577 >>> A = DeclareSort('A')
6578 >>> B = DeclareSort('B')
6579 >>> a1, a2 = Consts('a1 a2', A)
6580 >>> b1, b2 = Consts('b1 b2', B)
6581 >>> s = Solver()
6582 >>> s.add(a1 != a2, b1 != b2)
6583 >>> s.check()
6584 sat
6585 >>> m = s.model()
6586 >>> m.num_sorts()
6587 2
6588 >>> m.get_sort(0)
6589 A
6590 >>> m.get_sort(1)
6591 B
6592 """
6593 if idx >= self.num_sorts():
6594 raise IndexError
6595 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6596
6597 def sorts(self):
6598 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6599
6600 >>> A = DeclareSort('A')
6601 >>> B = DeclareSort('B')
6602 >>> a1, a2 = Consts('a1 a2', A)
6603 >>> b1, b2 = Consts('b1 b2', B)
6604 >>> s = Solver()
6605 >>> s.add(a1 != a2, b1 != b2)
6606 >>> s.check()
6607 sat
6608 >>> m = s.model()
6609 >>> m.sorts()
6610 [A, B]
6611 """
6612 return [self.get_sort(i) for i in range(self.num_sorts())]
6613
6614 def get_universe(self, s):
6615 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6616
6617 >>> A = DeclareSort('A')
6618 >>> a, b = Consts('a b', A)
6619 >>> s = Solver()
6620 >>> s.add(a != b)
6621 >>> s.check()
6622 sat
6623 >>> m = s.model()
6624 >>> m.get_universe(A)
6625 [A!val!1, A!val!0]
6626 """
6627 if z3_debug():
6628 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6629 try:
6630 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6631 except Z3Exception:
6632 return None
6633
6634 def __getitem__(self, idx):
6635 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6636 If `idx` is a declaration, then the actual interpretation is returned.
6637
6638 The elements can be retrieved using position or the actual declaration.
6639
6640 >>> f = Function('f', IntSort(), IntSort())
6641 >>> x = Int('x')
6642 >>> s = Solver()
6643 >>> s.add(x > 0, x < 2, f(x) == 0)
6644 >>> s.check()
6645 sat
6646 >>> m = s.model()
6647 >>> len(m)
6648 2
6649 >>> m[0]
6650 x
6651 >>> m[1]
6652 f
6653 >>> m[x]
6654 1
6655 >>> m[f]
6656 [else -> 0]
6657 >>> for d in m: print("%s -> %s" % (d, m[d]))
6658 x -> 1
6659 f -> [else -> 0]
6660 """
6661 if _is_int(idx):
6662 if idx >= len(self):
6663 raise IndexError
6664 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6665 if (idx < num_consts):
6666 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6667 else:
6668 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6669 if isinstance(idx, FuncDeclRef):
6670 return self.get_interp(idx)
6671 if is_const(idx):
6672 return self.get_interp(idx.decl())
6673 if isinstance(idx, SortRef):
6674 return self.get_universe(idx)
6675 if z3_debug():
6676 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6677 return None
6678
6679 def decls(self):
6680 """Return a list with all symbols that have an interpretation in the model `self`.
6681 >>> f = Function('f', IntSort(), IntSort())
6682 >>> x = Int('x')
6683 >>> s = Solver()
6684 >>> s.add(x > 0, x < 2, f(x) == 0)
6685 >>> s.check()
6686 sat
6687 >>> m = s.model()
6688 >>> m.decls()
6689 [x, f]
6690 """
6691 r = []
6692 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6693 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6694 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6695 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6696 return r
6697
6698 def update_value(self, x, value):
6699 """Update the interpretation of a constant"""
6700 if is_expr(x):
6701 x = x.decl()
6702 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6703 fi1 = value.f
6704 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6705 fi2 = FuncInterp(fi2, x.ctx)
6706 for i in range(value.num_entries()):
6707 e = value.entry(i)
6708 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6709 v = AstVector()
6710 for j in range(n):
6711 v.push(e.arg_value(j))
6712 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6713 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6714 return
6715 if not is_func_decl(x) or x.arity() != 0:
6716 raise Z3Exception("Expecting 0-ary function or constant expression")
6717 value = _py2expr(value)
6718 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6719
6720 def translate(self, target):
6721 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6722 """
6723 if z3_debug():
6724 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6725 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6726 return ModelRef(model, target)
6727
6728 def __copy__(self):
6729 return self.translate(self.ctx)
6730
6731 def __deepcopy__(self, memo={}):
6732 return self.translate(self.ctx)
6733
6734
6735def Model(ctx=None):
6736 ctx = _get_ctx(ctx)
6737 return ModelRef(Z3_mk_model(ctx.ref()), ctx)
6738
6739
6741 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6742 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6743
6744
6746 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6747 if z3_debug():
6748 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6749 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6750
6751
6756
6757
6759 """Statistics for `Solver.check()`."""
6760
6761 def __init__(self, stats, ctx):
6762 self.stats = stats
6763 self.ctx = ctx
6764 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6765
6766 def __deepcopy__(self, memo={}):
6767 return Statistics(self.stats, self.ctx)
6768
6769 def __del__(self):
6770 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6771 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6772
6773 def __repr__(self):
6774 if in_html_mode():
6775 out = io.StringIO()
6776 even = True
6777 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6778 for k, v in self:
6779 if even:
6780 out.write(u('<tr style="background-color:#CFCFCF">'))
6781 even = False
6782 else:
6783 out.write(u("<tr>"))
6784 even = True
6785 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6786 out.write(u("</table>"))
6787 return out.getvalue()
6788 else:
6789 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6790
6791 def __len__(self):
6792 """Return the number of statistical counters.
6793
6794 >>> x = Int('x')
6795 >>> s = Then('simplify', 'nlsat').solver()
6796 >>> s.add(x > 0)
6797 >>> s.check()
6798 sat
6799 >>> st = s.statistics()
6800 >>> len(st)
6801 7
6802 """
6803 return int(Z3_stats_size(self.ctx.ref(), self.stats))
6804
6805 def __getitem__(self, idx):
6806 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6807
6808 >>> x = Int('x')
6809 >>> s = Then('simplify', 'nlsat').solver()
6810 >>> s.add(x > 0)
6811 >>> s.check()
6812 sat
6813 >>> st = s.statistics()
6814 >>> len(st)
6815 7
6816 >>> st[0]
6817 ('nlsat propagations', 2)
6818 >>> st[1]
6819 ('nlsat restarts', 1)
6820 """
6821 if idx >= len(self):
6822 raise IndexError
6823 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6824 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6825 else:
6826 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6827 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
6828
6829 def keys(self):
6830 """Return the list of statistical counters.
6831
6832 >>> x = Int('x')
6833 >>> s = Then('simplify', 'nlsat').solver()
6834 >>> s.add(x > 0)
6835 >>> s.check()
6836 sat
6837 >>> st = s.statistics()
6838 """
6839 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
6840
6841 def get_key_value(self, key):
6842 """Return the value of a particular statistical counter.
6843
6844 >>> x = Int('x')
6845 >>> s = Then('simplify', 'nlsat').solver()
6846 >>> s.add(x > 0)
6847 >>> s.check()
6848 sat
6849 >>> st = s.statistics()
6850 >>> st.get_key_value('nlsat propagations')
6851 2
6852 """
6853 for idx in range(len(self)):
6854 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
6855 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6856 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6857 else:
6858 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6859 raise Z3Exception("unknown key")
6860
6861 def __getattr__(self, name):
6862 """Access the value of statistical using attributes.
6863
6864 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
6865 we should use '_' (e.g., 'nlsat_propagations').
6866
6867 >>> x = Int('x')
6868 >>> s = Then('simplify', 'nlsat').solver()
6869 >>> s.add(x > 0)
6870 >>> s.check()
6871 sat
6872 >>> st = s.statistics()
6873 >>> st.nlsat_propagations
6874 2
6875 >>> st.nlsat_stages
6876 2
6877 """
6878 key = name.replace("_", " ")
6879 try:
6880 return self.get_key_value(key)
6881 except Z3Exception:
6882 raise AttributeError
6883
6884
6889
6890
6892 """Represents the result of a satisfiability check: sat, unsat, unknown.
6893
6894 >>> s = Solver()
6895 >>> s.check()
6896 sat
6897 >>> r = s.check()
6898 >>> isinstance(r, CheckSatResult)
6899 True
6900 """
6901
6902 def __init__(self, r):
6903 self.r = r
6904
6905 def __deepcopy__(self, memo={}):
6906 return CheckSatResult(self.r)
6907
6908 def __eq__(self, other):
6909 return isinstance(other, CheckSatResult) and self.r == other.r
6910
6911 def __ne__(self, other):
6912 return not self.__eq__(other)
6913
6914 def __repr__(self):
6915 if in_html_mode():
6916 if self.r == Z3_L_TRUE:
6917 return "<b>sat</b>"
6918 elif self.r == Z3_L_FALSE:
6919 return "<b>unsat</b>"
6920 else:
6921 return "<b>unknown</b>"
6922 else:
6923 if self.r == Z3_L_TRUE:
6924 return "sat"
6925 elif self.r == Z3_L_FALSE:
6926 return "unsat"
6927 else:
6928 return "unknown"
6929
6930 def _repr_html_(self):
6931 in_html = in_html_mode()
6932 set_html_mode(True)
6933 res = repr(self)
6934 set_html_mode(in_html)
6935 return res
6936
6937
6938sat = CheckSatResult(Z3_L_TRUE)
6939unsat = CheckSatResult(Z3_L_FALSE)
6940unknown = CheckSatResult(Z3_L_UNDEF)
6941
6942
6944 """
6945 Solver API provides methods for implementing the main SMT 2.0 commands:
6946 push, pop, check, get-model, etc.
6947 """
6948
6949 def __init__(self, solver=None, ctx=None, logFile=None):
6950 assert solver is None or ctx is not None
6951 self.ctx = _get_ctx(ctx)
6952 self.backtrack_level = 4000000000
6953 self.solver = None
6954 if solver is None:
6955 self.solver = Z3_mk_solver(self.ctx.ref())
6956 else:
6957 self.solver = solver
6958 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
6959 if logFile is not None:
6960 self.set("smtlib2_log", logFile)
6961
6962 def __del__(self):
6963 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
6964 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
6965
6966 def __enter__(self):
6967 self.push()
6968 return self
6969
6970 def __exit__(self, *exc_info):
6971 self.pop()
6972
6973 def set(self, *args, **keys):
6974 """Set a configuration option.
6975 The method `help()` return a string containing all available options.
6976
6977 >>> s = Solver()
6978 >>> # The option MBQI can be set using three different approaches.
6979 >>> s.set(mbqi=True)
6980 >>> s.set('MBQI', True)
6981 >>> s.set(':mbqi', True)
6982 """
6983 p = args2params(args, keys, self.ctx)
6984 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
6985
6986 def push(self):
6987 """Create a backtracking point.
6988
6989 >>> x = Int('x')
6990 >>> s = Solver()
6991 >>> s.add(x > 0)
6992 >>> s
6993 [x > 0]
6994 >>> s.push()
6995 >>> s.add(x < 1)
6996 >>> s
6997 [x > 0, x < 1]
6998 >>> s.check()
6999 unsat
7000 >>> s.pop()
7001 >>> s.check()
7002 sat
7003 >>> s
7004 [x > 0]
7005 """
7006 Z3_solver_push(self.ctx.ref(), self.solver)
7007
7008 def pop(self, num=1):
7009 """Backtrack \\c num backtracking points.
7010
7011 >>> x = Int('x')
7012 >>> s = Solver()
7013 >>> s.add(x > 0)
7014 >>> s
7015 [x > 0]
7016 >>> s.push()
7017 >>> s.add(x < 1)
7018 >>> s
7019 [x > 0, x < 1]
7020 >>> s.check()
7021 unsat
7022 >>> s.pop()
7023 >>> s.check()
7024 sat
7025 >>> s
7026 [x > 0]
7027 """
7028 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7029
7030 def num_scopes(self):
7031 """Return the current number of backtracking points.
7032
7033 >>> s = Solver()
7034 >>> s.num_scopes()
7035 0
7036 >>> s.push()
7037 >>> s.num_scopes()
7038 1
7039 >>> s.push()
7040 >>> s.num_scopes()
7041 2
7042 >>> s.pop()
7043 >>> s.num_scopes()
7044 1
7045 """
7046 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7047
7048 def reset(self):
7049 """Remove all asserted constraints and backtracking points created using `push()`.
7050
7051 >>> x = Int('x')
7052 >>> s = Solver()
7053 >>> s.add(x > 0)
7054 >>> s
7055 [x > 0]
7056 >>> s.reset()
7057 >>> s
7058 []
7059 """
7060 Z3_solver_reset(self.ctx.ref(), self.solver)
7061
7062 def assert_exprs(self, *args):
7063 """Assert constraints into the solver.
7064
7065 >>> x = Int('x')
7066 >>> s = Solver()
7067 >>> s.assert_exprs(x > 0, x < 2)
7068 >>> s
7069 [x > 0, x < 2]
7070 """
7071 args = _get_args(args)
7072 s = BoolSort(self.ctx)
7073 for arg in args:
7074 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7075 for f in arg:
7076 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7077 else:
7078 arg = s.cast(arg)
7079 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7080
7081 def add(self, *args):
7082 """Assert constraints into the solver.
7083
7084 >>> x = Int('x')
7085 >>> s = Solver()
7086 >>> s.add(x > 0, x < 2)
7087 >>> s
7088 [x > 0, x < 2]
7089 """
7090 self.assert_exprs(*args)
7091
7092 def __iadd__(self, fml):
7093 self.add(fml)
7094 return self
7095
7096 def append(self, *args):
7097 """Assert constraints into the solver.
7098
7099 >>> x = Int('x')
7100 >>> s = Solver()
7101 >>> s.append(x > 0, x < 2)
7102 >>> s
7103 [x > 0, x < 2]
7104 """
7105 self.assert_exprs(*args)
7106
7107 def insert(self, *args):
7108 """Assert constraints into the solver.
7109
7110 >>> x = Int('x')
7111 >>> s = Solver()
7112 >>> s.insert(x > 0, x < 2)
7113 >>> s
7114 [x > 0, x < 2]
7115 """
7116 self.assert_exprs(*args)
7117
7118 def assert_and_track(self, a, p):
7119 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7120
7121 If `p` is a string, it will be automatically converted into a Boolean constant.
7122
7123 >>> x = Int('x')
7124 >>> p3 = Bool('p3')
7125 >>> s = Solver()
7126 >>> s.set(unsat_core=True)
7127 >>> s.assert_and_track(x > 0, 'p1')
7128 >>> s.assert_and_track(x != 1, 'p2')
7129 >>> s.assert_and_track(x < 0, p3)
7130 >>> print(s.check())
7131 unsat
7132 >>> c = s.unsat_core()
7133 >>> len(c)
7134 2
7135 >>> Bool('p1') in c
7136 True
7137 >>> Bool('p2') in c
7138 False
7139 >>> p3 in c
7140 True
7141 """
7142 if isinstance(p, str):
7143 p = Bool(p, self.ctx)
7144 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7145 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7146 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7147
7148 def check(self, *assumptions):
7149 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7150
7151 >>> x = Int('x')
7152 >>> s = Solver()
7153 >>> s.check()
7154 sat
7155 >>> s.add(x > 0, x < 2)
7156 >>> s.check()
7157 sat
7158 >>> s.model().eval(x)
7159 1
7160 >>> s.add(x < 1)
7161 >>> s.check()
7162 unsat
7163 >>> s.reset()
7164 >>> s.add(2**x == 4)
7165 >>> s.check()
7166 unknown
7167 """
7168 s = BoolSort(self.ctx)
7169 assumptions = _get_args(assumptions)
7170 num = len(assumptions)
7171 _assumptions = (Ast * num)()
7172 for i in range(num):
7173 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7174 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7175 return CheckSatResult(r)
7176
7177 def model(self):
7178 """Return a model for the last `check()`.
7179
7180 This function raises an exception if
7181 a model is not available (e.g., last `check()` returned unsat).
7182
7183 >>> s = Solver()
7184 >>> a = Int('a')
7185 >>> s.add(a + 2 == 0)
7186 >>> s.check()
7187 sat
7188 >>> s.model()
7189 [a = -2]
7190 """
7191 try:
7192 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7193 except Z3Exception:
7194 raise Z3Exception("model is not available")
7195
7196 def import_model_converter(self, other):
7197 """Import model converter from other into the current solver"""
7198 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7199
7200 def interrupt(self):
7201 """Interrupt the execution of the solver object.
7202 Remarks: This ensures that the interrupt applies only
7203 to the given solver object and it applies only if it is running.
7204 """
7205 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7206
7207 def unsat_core(self):
7208 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7209
7210 These are the assumptions Z3 used in the unsatisfiability proof.
7211 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7212 They may be also used to "retract" assumptions. Note that, assumptions are not really
7213 "soft constraints", but they can be used to implement them.
7214
7215 >>> p1, p2, p3 = Bools('p1 p2 p3')
7216 >>> x, y = Ints('x y')
7217 >>> s = Solver()
7218 >>> s.add(Implies(p1, x > 0))
7219 >>> s.add(Implies(p2, y > x))
7220 >>> s.add(Implies(p2, y < 1))
7221 >>> s.add(Implies(p3, y > -3))
7222 >>> s.check(p1, p2, p3)
7223 unsat
7224 >>> core = s.unsat_core()
7225 >>> len(core)
7226 2
7227 >>> p1 in core
7228 True
7229 >>> p2 in core
7230 True
7231 >>> p3 in core
7232 False
7233 >>> # "Retracting" p2
7234 >>> s.check(p1, p3)
7235 sat
7236 """
7237 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7238
7239 def consequences(self, assumptions, variables):
7240 """Determine fixed values for the variables based on the solver state and assumptions.
7241 >>> s = Solver()
7242 >>> a, b, c, d = Bools('a b c d')
7243 >>> s.add(Implies(a,b), Implies(b, c))
7244 >>> s.consequences([a],[b,c,d])
7245 (sat, [Implies(a, b), Implies(a, c)])
7246 >>> s.consequences([Not(c),d],[a,b,c,d])
7247 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7248 """
7249 if isinstance(assumptions, list):
7250 _asms = AstVector(None, self.ctx)
7251 for a in assumptions:
7252 _asms.push(a)
7253 assumptions = _asms
7254 if isinstance(variables, list):
7255 _vars = AstVector(None, self.ctx)
7256 for a in variables:
7257 _vars.push(a)
7258 variables = _vars
7259 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7260 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7261 consequences = AstVector(None, self.ctx)
7262 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7263 variables.vector, consequences.vector)
7264 sz = len(consequences)
7265 consequences = [consequences[i] for i in range(sz)]
7266 return CheckSatResult(r), consequences
7267
7268 def from_file(self, filename):
7269 """Parse assertions from a file"""
7270 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7271
7272 def from_string(self, s):
7273 """Parse assertions from a string"""
7274 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7275
7276 def cube(self, vars=None):
7277 """Get set of cubes
7278 The method takes an optional set of variables that restrict which
7279 variables may be used as a starting point for cubing.
7280 If vars is not None, then the first case split is based on a variable in
7281 this set.
7282 """
7283 self.cube_vs = AstVector(None, self.ctx)
7284 if vars is not None:
7285 for v in vars:
7286 self.cube_vs.push(v)
7287 while True:
7288 lvl = self.backtrack_level
7289 self.backtrack_level = 4000000000
7290 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7291 if (len(r) == 1 and is_false(r[0])):
7292 return
7293 yield r
7294 if (len(r) == 0):
7295 return
7296
7297 def cube_vars(self):
7298 """Access the set of variables that were touched by the most recently generated cube.
7299 This set of variables can be used as a starting point for additional cubes.
7300 The idea is that variables that appear in clauses that are reduced by the most recent
7301 cube are likely more useful to cube on."""
7302 return self.cube_vs
7303
7304 def root(self, t):
7305 t = _py2expr(t, self.ctx)
7306 """Retrieve congruence closure root of the term t relative to the current search state
7307 The function primarily works for SimpleSolver. Terms and variables that are
7308 eliminated during pre-processing are not visible to the congruence closure.
7309 """
7310 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7311
7312 def next(self, t):
7313 t = _py2expr(t, self.ctx)
7314 """Retrieve congruence closure sibling of the term t relative to the current search state
7315 The function primarily works for SimpleSolver. Terms and variables that are
7316 eliminated during pre-processing are not visible to the congruence closure.
7317 """
7318 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7319
7320 def proof(self):
7321 """Return a proof for the last `check()`. Proof construction must be enabled."""
7322 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7323
7324 def assertions(self):
7325 """Return an AST vector containing all added constraints.
7326
7327 >>> s = Solver()
7328 >>> s.assertions()
7329 []
7330 >>> a = Int('a')
7331 >>> s.add(a > 0)
7332 >>> s.add(a < 10)
7333 >>> s.assertions()
7334 [a > 0, a < 10]
7335 """
7336 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7337
7338 def units(self):
7339 """Return an AST vector containing all currently inferred units.
7340 """
7341 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7342
7343 def non_units(self):
7344 """Return an AST vector containing all atomic formulas in solver state that are not units.
7345 """
7346 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7347
7348 def trail_levels(self):
7349 """Return trail and decision levels of the solver state after a check() call.
7350 """
7351 trail = self.trail()
7352 levels = (ctypes.c_uint * len(trail))()
7353 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7354 return trail, levels
7355
7356 def set_initial_value(self, var, value):
7357 """initialize the solver's state by setting the initial value of var to value
7358 """
7359 s = var.sort()
7360 value = s.cast(value)
7361 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7362
7363 def trail(self):
7364 """Return trail of the solver state after a check() call.
7365 """
7366 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7367
7368 def statistics(self):
7369 """Return statistics for the last `check()`.
7370
7371 >>> s = SimpleSolver()
7372 >>> x = Int('x')
7373 >>> s.add(x > 0)
7374 >>> s.check()
7375 sat
7376 >>> st = s.statistics()
7377 >>> st.get_key_value('final checks')
7378 1
7379 >>> len(st) > 0
7380 True
7381 >>> st[0] != 0
7382 True
7383 """
7384 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7385
7386 def reason_unknown(self):
7387 """Return a string describing why the last `check()` returned `unknown`.
7388
7389 >>> x = Int('x')
7390 >>> s = SimpleSolver()
7391 >>> s.add(2**x == 4)
7392 >>> s.check()
7393 unknown
7394 >>> s.reason_unknown()
7395 '(incomplete (theory arithmetic))'
7396 """
7397 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7398
7399 def help(self):
7400 """Display a string describing all available options."""
7401 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7402
7403 def param_descrs(self):
7404 """Return the parameter description set."""
7405 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7406
7407 def __repr__(self):
7408 """Return a formatted string with all added constraints."""
7409 return obj_to_string(self)
7410
7411 def translate(self, target):
7412 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7413
7414 >>> c1 = Context()
7415 >>> c2 = Context()
7416 >>> s1 = Solver(ctx=c1)
7417 >>> s2 = s1.translate(c2)
7418 """
7419 if z3_debug():
7420 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7421 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7422 return Solver(solver, target)
7423
7424 def __copy__(self):
7425 return self.translate(self.ctx)
7426
7427 def __deepcopy__(self, memo={}):
7428 return self.translate(self.ctx)
7429
7430 def sexpr(self):
7431 """Return a formatted string (in Lisp-like format) with all added constraints.
7432 We say the string is in s-expression format.
7433
7434 >>> x = Int('x')
7435 >>> s = Solver()
7436 >>> s.add(x > 0)
7437 >>> s.add(x < 2)
7438 >>> r = s.sexpr()
7439 """
7440 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7441
7442 def dimacs(self, include_names=True):
7443 """Return a textual representation of the solver in DIMACS format."""
7444 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7445
7446 def to_smt2(self):
7447 """return SMTLIB2 formatted benchmark for solver's assertions"""
7448 es = self.assertions()
7449 sz = len(es)
7450 sz1 = sz
7451 if sz1 > 0:
7452 sz1 -= 1
7453 v = (Ast * sz1)()
7454 for i in range(sz1):
7455 v[i] = es[i].as_ast()
7456 if sz > 0:
7457 e = es[sz1].as_ast()
7458 else:
7459 e = BoolVal(True, self.ctx).as_ast()
7460 return Z3_benchmark_to_smtlib_string(
7461 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7462 )
7463
7464
7465def SolverFor(logic, ctx=None, logFile=None):
7466 """Create a solver customized for the given logic.
7467
7468 The parameter `logic` is a string. It should be contains
7469 the name of a SMT-LIB logic.
7470 See http://www.smtlib.org/ for the name of all available logics.
7471
7472 >>> s = SolverFor("QF_LIA")
7473 >>> x = Int('x')
7474 >>> s.add(x > 0)
7475 >>> s.add(x < 2)
7476 >>> s.check()
7477 sat
7478 >>> s.model()
7479 [x = 1]
7480 """
7481 ctx = _get_ctx(ctx)
7482 logic = to_symbol(logic)
7483 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7484
7485
7486def SimpleSolver(ctx=None, logFile=None):
7487 """Return a simple general purpose solver with limited amount of preprocessing.
7488
7489 >>> s = SimpleSolver()
7490 >>> x = Int('x')
7491 >>> s.add(x > 0)
7492 >>> s.check()
7493 sat
7494 """
7495 ctx = _get_ctx(ctx)
7496 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7497
7498#########################################
7499#
7500# Fixedpoint
7501#
7502#########################################
7503
7504
7505class Fixedpoint(Z3PPObject):
7506 """Fixedpoint API provides methods for solving with recursive predicates"""
7507
7508 def __init__(self, fixedpoint=None, ctx=None):
7509 assert fixedpoint is None or ctx is not None
7510 self.ctx = _get_ctx(ctx)
7511 self.fixedpoint = None
7512 if fixedpoint is None:
7513 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7514 else:
7515 self.fixedpoint = fixedpoint
7516 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7517 self.vars = []
7518
7519 def __deepcopy__(self, memo={}):
7520 return FixedPoint(self.fixedpoint, self.ctx)
7521
7522 def __del__(self):
7523 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7524 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7525
7526 def set(self, *args, **keys):
7527 """Set a configuration option. The method `help()` return a string containing all available options.
7528 """
7529 p = args2params(args, keys, self.ctx)
7530 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7531
7532 def help(self):
7533 """Display a string describing all available options."""
7534 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7535
7536 def param_descrs(self):
7537 """Return the parameter description set."""
7538 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7539
7540 def assert_exprs(self, *args):
7541 """Assert constraints as background axioms for the fixedpoint solver."""
7542 args = _get_args(args)
7543 s = BoolSort(self.ctx)
7544 for arg in args:
7545 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7546 for f in arg:
7547 f = self.abstract(f)
7548 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7549 else:
7550 arg = s.cast(arg)
7551 arg = self.abstract(arg)
7552 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7553
7554 def add(self, *args):
7555 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7556 self.assert_exprs(*args)
7557
7558 def __iadd__(self, fml):
7559 self.add(fml)
7560 return self
7561
7562 def append(self, *args):
7563 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7564 self.assert_exprs(*args)
7565
7566 def insert(self, *args):
7567 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7568 self.assert_exprs(*args)
7569
7570 def add_rule(self, head, body=None, name=None):
7571 """Assert rules defining recursive predicates to the fixedpoint solver.
7572 >>> a = Bool('a')
7573 >>> b = Bool('b')
7574 >>> s = Fixedpoint()
7575 >>> s.register_relation(a.decl())
7576 >>> s.register_relation(b.decl())
7577 >>> s.fact(a)
7578 >>> s.rule(b, a)
7579 >>> s.query(b)
7580 sat
7581 """
7582 if name is None:
7583 name = ""
7584 name = to_symbol(name, self.ctx)
7585 if body is None:
7586 head = self.abstract(head)
7587 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7588 else:
7589 body = _get_args(body)
7590 f = self.abstract(Implies(And(body, self.ctx), head))
7591 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7592
7593 def rule(self, head, body=None, name=None):
7594 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7595 self.add_rule(head, body, name)
7596
7597 def fact(self, head, name=None):
7598 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7599 self.add_rule(head, None, name)
7600
7601 def query(self, *query):
7602 """Query the fixedpoint engine whether formula is derivable.
7603 You can also pass an tuple or list of recursive predicates.
7604 """
7605 query = _get_args(query)
7606 sz = len(query)
7607 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7608 _decls = (FuncDecl * sz)()
7609 i = 0
7610 for q in query:
7611 _decls[i] = q.ast
7612 i = i + 1
7613 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7614 else:
7615 if sz == 1:
7616 query = query[0]
7617 else:
7618 query = And(query, self.ctx)
7619 query = self.abstract(query, False)
7620 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7621 return CheckSatResult(r)
7622
7623 def query_from_lvl(self, lvl, *query):
7624 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7625 """
7626 query = _get_args(query)
7627 sz = len(query)
7628 if sz >= 1 and isinstance(query[0], FuncDecl):
7629 _z3_assert(False, "unsupported")
7630 else:
7631 if sz == 1:
7632 query = query[0]
7633 else:
7634 query = And(query)
7635 query = self.abstract(query, False)
7636 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7637 return CheckSatResult(r)
7638
7639 def update_rule(self, head, body, name):
7640 """update rule"""
7641 if name is None:
7642 name = ""
7643 name = to_symbol(name, self.ctx)
7644 body = _get_args(body)
7645 f = self.abstract(Implies(And(body, self.ctx), head))
7646 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7647
7648 def get_answer(self):
7649 """Retrieve answer from last query call."""
7650 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7651 return _to_expr_ref(r, self.ctx)
7652
7653 def get_ground_sat_answer(self):
7654 """Retrieve a ground cex from last query call."""
7655 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7656 return _to_expr_ref(r, self.ctx)
7657
7658 def get_rules_along_trace(self):
7659 """retrieve rules along the counterexample trace"""
7660 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7661
7662 def get_rule_names_along_trace(self):
7663 """retrieve rule names along the counterexample trace"""
7664 # this is a hack as I don't know how to return a list of symbols from C++;
7665 # obtain names as a single string separated by semicolons
7666 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7667 # split into individual names
7668 return names.split(";")
7669
7670 def get_num_levels(self, predicate):
7671 """Retrieve number of levels used for predicate in PDR engine"""
7672 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7673
7674 def get_cover_delta(self, level, predicate):
7675 """Retrieve properties known about predicate for the level'th unfolding.
7676 -1 is treated as the limit (infinity)
7677 """
7678 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7679 return _to_expr_ref(r, self.ctx)
7680
7681 def add_cover(self, level, predicate, property):
7682 """Add property to predicate for the level'th unfolding.
7683 -1 is treated as infinity (infinity)
7684 """
7685 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7686
7687 def register_relation(self, *relations):
7688 """Register relation as recursive"""
7689 relations = _get_args(relations)
7690 for f in relations:
7691 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7692
7693 def set_predicate_representation(self, f, *representations):
7694 """Control how relation is represented"""
7695 representations = _get_args(representations)
7696 representations = [to_symbol(s) for s in representations]
7697 sz = len(representations)
7698 args = (Symbol * sz)()
7699 for i in range(sz):
7700 args[i] = representations[i]
7701 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7702
7703 def parse_string(self, s):
7704 """Parse rules and queries from a string"""
7705 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7706
7707 def parse_file(self, f):
7708 """Parse rules and queries from a file"""
7709 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7710
7711 def get_rules(self):
7712 """retrieve rules that have been added to fixedpoint context"""
7713 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7714
7715 def get_assertions(self):
7716 """retrieve assertions that have been added to fixedpoint context"""
7717 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7718
7719 def __repr__(self):
7720 """Return a formatted string with all added rules and constraints."""
7721 return self.sexpr()
7722
7723 def sexpr(self):
7724 """Return a formatted string (in Lisp-like format) with all added constraints.
7725 We say the string is in s-expression format.
7726 """
7727 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7728
7729 def to_string(self, queries):
7730 """Return a formatted string (in Lisp-like format) with all added constraints.
7731 We say the string is in s-expression format.
7732 Include also queries.
7733 """
7734 args, len = _to_ast_array(queries)
7735 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7736
7737 def statistics(self):
7738 """Return statistics for the last `query()`.
7739 """
7740 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7741
7742 def reason_unknown(self):
7743 """Return a string describing why the last `query()` returned `unknown`.
7744 """
7745 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7746
7747 def declare_var(self, *vars):
7748 """Add variable or several variables.
7749 The added variable or variables will be bound in the rules
7750 and queries
7751 """
7752 vars = _get_args(vars)
7753 for v in vars:
7754 self.vars += [v]
7755
7756 def abstract(self, fml, is_forall=True):
7757 if self.vars == []:
7758 return fml
7759 if is_forall:
7760 return ForAll(self.vars, fml)
7761 else:
7762 return Exists(self.vars, fml)
7763
7764
7765#########################################
7766#
7767# Finite domains
7768#
7769#########################################
7770
7771class FiniteDomainSortRef(SortRef):
7772 """Finite domain sort."""
7773
7774 def size(self):
7775 """Return the size of the finite domain sort"""
7776 r = (ctypes.c_ulonglong * 1)()
7777 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7778 return r[0]
7779 else:
7780 raise Z3Exception("Failed to retrieve finite domain sort size")
7781
7782
7783def FiniteDomainSort(name, sz, ctx=None):
7784 """Create a named finite domain sort of a given size sz"""
7785 if not isinstance(name, Symbol):
7786 name = to_symbol(name)
7787 ctx = _get_ctx(ctx)
7788 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7789
7790
7791def is_finite_domain_sort(s):
7792 """Return True if `s` is a Z3 finite-domain sort.
7793
7794 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7795 True
7796 >>> is_finite_domain_sort(IntSort())
7797 False
7798 """
7799 return isinstance(s, FiniteDomainSortRef)
7800
7801
7802class FiniteDomainRef(ExprRef):
7803 """Finite-domain expressions."""
7804
7805 def sort(self):
7806 """Return the sort of the finite-domain expression `self`."""
7807 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7808
7809 def as_string(self):
7810 """Return a Z3 floating point expression as a Python string."""
7811 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7812
7813
7814def is_finite_domain(a):
7815 """Return `True` if `a` is a Z3 finite-domain expression.
7816
7817 >>> s = FiniteDomainSort('S', 100)
7818 >>> b = Const('b', s)
7819 >>> is_finite_domain(b)
7820 True
7821 >>> is_finite_domain(Int('x'))
7822 False
7823 """
7824 return isinstance(a, FiniteDomainRef)
7825
7826
7827class FiniteDomainNumRef(FiniteDomainRef):
7828 """Integer values."""
7829
7830 def as_long(self):
7831 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7832
7833 >>> s = FiniteDomainSort('S', 100)
7834 >>> v = FiniteDomainVal(3, s)
7835 >>> v
7836 3
7837 >>> v.as_long() + 1
7838 4
7839 """
7840 return int(self.as_string())
7841
7842 def as_string(self):
7843 """Return a Z3 finite-domain numeral as a Python string.
7844
7845 >>> s = FiniteDomainSort('S', 100)
7846 >>> v = FiniteDomainVal(42, s)
7847 >>> v.as_string()
7848 '42'
7849 """
7850 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
7851
7852
7853def FiniteDomainVal(val, sort, ctx=None):
7854 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
7855
7856 >>> s = FiniteDomainSort('S', 256)
7857 >>> FiniteDomainVal(255, s)
7858 255
7859 >>> FiniteDomainVal('100', s)
7860 100
7861 """
7862 if z3_debug():
7863 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
7864 ctx = sort.ctx
7865 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
7866
7867
7868def is_finite_domain_value(a):
7869 """Return `True` if `a` is a Z3 finite-domain value.
7870
7871 >>> s = FiniteDomainSort('S', 100)
7872 >>> b = Const('b', s)
7873 >>> is_finite_domain_value(b)
7874 False
7875 >>> b = FiniteDomainVal(10, s)
7876 >>> b
7877 10
7878 >>> is_finite_domain_value(b)
7879 True
7880 """
7881 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
7882
7883
7884#########################################
7885#
7886# Optimize
7887#
7888#########################################
7889
7890class OptimizeObjective:
7891 def __init__(self, opt, value, is_max):
7892 self._opt = opt
7893 self._value = value
7894 self._is_max = is_max
7895
7896 def lower(self):
7897 opt = self._opt
7898 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7899
7900 def upper(self):
7901 opt = self._opt
7902 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7903
7904 def lower_values(self):
7905 opt = self._opt
7906 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7907
7908 def upper_values(self):
7909 opt = self._opt
7910 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7911
7912 def value(self):
7913 if self._is_max:
7914 return self.upper()
7915 else:
7916 return self.lower()
7917
7918 def __str__(self):
7919 return "%s:%s" % (self._value, self._is_max)
7920
7921
7922_on_models = {}
7923
7924
7925def _global_on_model(ctx):
7926 (fn, mdl) = _on_models[ctx]
7927 fn(mdl)
7928
7929
7930_on_model_eh = on_model_eh_type(_global_on_model)
7931
7932
7933class Optimize(Z3PPObject):
7934 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
7935
7936 def __init__(self, optimize=None, ctx=None):
7937 self.ctx = _get_ctx(ctx)
7938 if optimize is None:
7939 self.optimize = Z3_mk_optimize(self.ctx.ref())
7940 else:
7941 self.optimize = optimize
7942 self._on_models_id = None
7943 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
7944
7945 def __deepcopy__(self, memo={}):
7946 return Optimize(self.optimize, self.ctx)
7947
7948 def __del__(self):
7949 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
7950 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
7951 if self._on_models_id is not None:
7952 del _on_models[self._on_models_id]
7953
7954 def set(self, *args, **keys):
7955 """Set a configuration option.
7956 The method `help()` return a string containing all available options.
7957 """
7958 p = args2params(args, keys, self.ctx)
7959 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
7960
7961 def help(self):
7962 """Display a string describing all available options."""
7963 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
7964
7965 def param_descrs(self):
7966 """Return the parameter description set."""
7967 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
7968
7969 def assert_exprs(self, *args):
7970 """Assert constraints as background axioms for the optimize solver."""
7971 args = _get_args(args)
7972 s = BoolSort(self.ctx)
7973 for arg in args:
7974 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7975 for f in arg:
7976 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
7977 else:
7978 arg = s.cast(arg)
7979 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
7980
7981 def add(self, *args):
7982 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
7983 self.assert_exprs(*args)
7984
7985 def __iadd__(self, fml):
7986 self.add(fml)
7987 return self
7988
7989 def assert_and_track(self, a, p):
7990 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7991
7992 If `p` is a string, it will be automatically converted into a Boolean constant.
7993
7994 >>> x = Int('x')
7995 >>> p3 = Bool('p3')
7996 >>> s = Optimize()
7997 >>> s.assert_and_track(x > 0, 'p1')
7998 >>> s.assert_and_track(x != 1, 'p2')
7999 >>> s.assert_and_track(x < 0, p3)
8000 >>> print(s.check())
8001 unsat
8002 >>> c = s.unsat_core()
8003 >>> len(c)
8004 2
8005 >>> Bool('p1') in c
8006 True
8007 >>> Bool('p2') in c
8008 False
8009 >>> p3 in c
8010 True
8011 """
8012 if isinstance(p, str):
8013 p = Bool(p, self.ctx)
8014 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8015 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8016 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8017
8018 def add_soft(self, arg, weight="1", id=None):
8019 """Add soft constraint with optional weight and optional identifier.
8020 If no weight is supplied, then the penalty for violating the soft constraint
8021 is 1.
8022 Soft constraints are grouped by identifiers. Soft constraints that are
8023 added without identifiers are grouped by default.
8024 """
8025 if _is_int(weight):
8026 weight = "%d" % weight
8027 elif isinstance(weight, float):
8028 weight = "%f" % weight
8029 if not isinstance(weight, str):
8030 raise Z3Exception("weight should be a string or an integer")
8031 if id is None:
8032 id = ""
8033 id = to_symbol(id, self.ctx)
8034
8035 def asoft(a):
8036 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8037 return OptimizeObjective(self, v, False)
8038 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8039 return [asoft(a) for a in arg]
8040 return asoft(arg)
8041
8042 def set_initial_value(self, var, value):
8043 """initialize the solver's state by setting the initial value of var to value
8044 """
8045 s = var.sort()
8046 value = s.cast(value)
8047 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8048
8049 def maximize(self, arg):
8050 """Add objective function to maximize."""
8051 return OptimizeObjective(
8052 self,
8053 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8054 is_max=True,
8055 )
8056
8057 def minimize(self, arg):
8058 """Add objective function to minimize."""
8059 return OptimizeObjective(
8060 self,
8061 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8062 is_max=False,
8063 )
8064
8065 def push(self):
8066 """create a backtracking point for added rules, facts and assertions"""
8067 Z3_optimize_push(self.ctx.ref(), self.optimize)
8068
8069 def pop(self):
8070 """restore to previously created backtracking point"""
8071 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8072
8073 def check(self, *assumptions):
8074 """Check consistency and produce optimal values."""
8075 assumptions = _get_args(assumptions)
8076 num = len(assumptions)
8077 _assumptions = (Ast * num)()
8078 for i in range(num):
8079 _assumptions[i] = assumptions[i].as_ast()
8080 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8081
8082 def reason_unknown(self):
8083 """Return a string that describes why the last `check()` returned `unknown`."""
8084 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8085
8086 def model(self):
8087 """Return a model for the last check()."""
8088 try:
8089 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8090 except Z3Exception:
8091 raise Z3Exception("model is not available")
8092
8093 def unsat_core(self):
8094 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8095
8096 def lower(self, obj):
8097 if not isinstance(obj, OptimizeObjective):
8098 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8099 return obj.lower()
8100
8101 def upper(self, obj):
8102 if not isinstance(obj, OptimizeObjective):
8103 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8104 return obj.upper()
8105
8106 def lower_values(self, obj):
8107 if not isinstance(obj, OptimizeObjective):
8108 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8109 return obj.lower_values()
8110
8111 def upper_values(self, obj):
8112 if not isinstance(obj, OptimizeObjective):
8113 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8114 return obj.upper_values()
8115
8116 def from_file(self, filename):
8117 """Parse assertions and objectives from a file"""
8118 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8119
8120 def from_string(self, s):
8121 """Parse assertions and objectives from a string"""
8122 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8123
8124 def assertions(self):
8125 """Return an AST vector containing all added constraints."""
8126 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8127
8128 def objectives(self):
8129 """returns set of objective functions"""
8130 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8131
8132 def __repr__(self):
8133 """Return a formatted string with all added rules and constraints."""
8134 return self.sexpr()
8135
8136 def sexpr(self):
8137 """Return a formatted string (in Lisp-like format) with all added constraints.
8138 We say the string is in s-expression format.
8139 """
8140 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8141
8142 def statistics(self):
8143 """Return statistics for the last check`.
8144 """
8145 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8146
8147 def set_on_model(self, on_model):
8148 """Register a callback that is invoked with every incremental improvement to
8149 objective values. The callback takes a model as argument.
8150 The life-time of the model is limited to the callback so the
8151 model has to be (deep) copied if it is to be used after the callback
8152 """
8153 id = len(_on_models) + 41
8154 mdl = Model(self.ctx)
8155 _on_models[id] = (on_model, mdl)
8156 self._on_models_id = id
8157 Z3_optimize_register_model_eh(
8158 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8159 )
8160
8161
8162#########################################
8163#
8164# ApplyResult
8165#
8166#########################################
8167class ApplyResult(Z3PPObject):
8168 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8169 It also contains model and proof converters.
8170 """
8171
8172 def __init__(self, result, ctx):
8173 self.result = result
8174 self.ctx = ctx
8175 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8176
8177 def __deepcopy__(self, memo={}):
8178 return ApplyResult(self.result, self.ctx)
8179
8180 def __del__(self):
8181 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8182 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8183
8184 def __len__(self):
8185 """Return the number of subgoals in `self`.
8186
8187 >>> a, b = Ints('a b')
8188 >>> g = Goal()
8189 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8190 >>> t = Tactic('split-clause')
8191 >>> r = t(g)
8192 >>> len(r)
8193 2
8194 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8195 >>> len(t(g))
8196 4
8197 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8198 >>> len(t(g))
8199 1
8200 """
8201 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8202
8203 def __getitem__(self, idx):
8204 """Return one of the subgoals stored in ApplyResult object `self`.
8205
8206 >>> a, b = Ints('a b')
8207 >>> g = Goal()
8208 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8209 >>> t = Tactic('split-clause')
8210 >>> r = t(g)
8211 >>> r[0]
8212 [a == 0, Or(b == 0, b == 1), a > b]
8213 >>> r[1]
8214 [a == 1, Or(b == 0, b == 1), a > b]
8215 """
8216 if idx >= len(self):
8217 raise IndexError
8218 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8219
8220 def __repr__(self):
8221 return obj_to_string(self)
8222
8223 def sexpr(self):
8224 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8225 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8226
8227 def as_expr(self):
8228 """Return a Z3 expression consisting of all subgoals.
8229
8230 >>> x = Int('x')
8231 >>> g = Goal()
8232 >>> g.add(x > 1)
8233 >>> g.add(Or(x == 2, x == 3))
8234 >>> r = Tactic('simplify')(g)
8235 >>> r
8236 [[Not(x <= 1), Or(x == 2, x == 3)]]
8237 >>> r.as_expr()
8238 And(Not(x <= 1), Or(x == 2, x == 3))
8239 >>> r = Tactic('split-clause')(g)
8240 >>> r
8241 [[x > 1, x == 2], [x > 1, x == 3]]
8242 >>> r.as_expr()
8243 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8244 """
8245 sz = len(self)
8246 if sz == 0:
8247 return BoolVal(False, self.ctx)
8248 elif sz == 1:
8249 return self[0].as_expr()
8250 else:
8251 return Or([self[i].as_expr() for i in range(len(self))])
8252
8253#########################################
8254#
8255# Simplifiers
8256#
8257#########################################
8258
8259class Simplifier:
8260 """Simplifiers act as pre-processing utilities for solvers.
8261 Build a custom simplifier and add it to a solver"""
8262
8263 def __init__(self, simplifier, ctx=None):
8264 self.ctx = _get_ctx(ctx)
8265 self.simplifier = None
8266 if isinstance(simplifier, SimplifierObj):
8267 self.simplifier = simplifier
8268 elif isinstance(simplifier, list):
8269 simps = [Simplifier(s, ctx) for s in simplifier]
8270 self.simplifier = simps[0].simplifier
8271 for i in range(1, len(simps)):
8272 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8273 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8274 return
8275 else:
8276 if z3_debug():
8277 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8278 try:
8279 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8280 except Z3Exception:
8281 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8282 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8283
8284 def __deepcopy__(self, memo={}):
8285 return Simplifier(self.simplifier, self.ctx)
8286
8287 def __del__(self):
8288 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8289 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8290
8291 def using_params(self, *args, **keys):
8292 """Return a simplifier that uses the given configuration options"""
8293 p = args2params(args, keys, self.ctx)
8294 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8295
8296 def add(self, solver):
8297 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8298 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8299
8300 def help(self):
8301 """Display a string containing a description of the available options for the `self` simplifier."""
8302 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8303
8304 def param_descrs(self):
8305 """Return the parameter description set."""
8306 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8307
8308
8309#########################################
8310#
8311# Tactics
8312#
8313#########################################
8314
8315
8316class Tactic:
8317 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8318 A Tactic can be converted into a Solver using the method solver().
8319
8320 Several combinators are available for creating new tactics using the built-in ones:
8321 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8322 """
8323
8324 def __init__(self, tactic, ctx=None):
8325 self.ctx = _get_ctx(ctx)
8326 self.tactic = None
8327 if isinstance(tactic, TacticObj):
8328 self.tactic = tactic
8329 else:
8330 if z3_debug():
8331 _z3_assert(isinstance(tactic, str), "tactic name expected")
8332 try:
8333 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8334 except Z3Exception:
8335 raise Z3Exception("unknown tactic '%s'" % tactic)
8336 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8337
8338 def __deepcopy__(self, memo={}):
8339 return Tactic(self.tactic, self.ctx)
8340
8341 def __del__(self):
8342 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8343 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8344
8345 def solver(self, logFile=None):
8346 """Create a solver using the tactic `self`.
8347
8348 The solver supports the methods `push()` and `pop()`, but it
8349 will always solve each `check()` from scratch.
8350
8351 >>> t = Then('simplify', 'nlsat')
8352 >>> s = t.solver()
8353 >>> x = Real('x')
8354 >>> s.add(x**2 == 2, x > 0)
8355 >>> s.check()
8356 sat
8357 >>> s.model()
8358 [x = 1.4142135623?]
8359 """
8360 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8361
8362 def apply(self, goal, *arguments, **keywords):
8363 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8364
8365 >>> x, y = Ints('x y')
8366 >>> t = Tactic('solve-eqs')
8367 >>> t.apply(And(x == 0, y >= x + 1))
8368 [[y >= 1]]
8369 """
8370 if z3_debug():
8371 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8372 goal = _to_goal(goal)
8373 if len(arguments) > 0 or len(keywords) > 0:
8374 p = args2params(arguments, keywords, self.ctx)
8375 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8376 else:
8377 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8378
8379 def __call__(self, goal, *arguments, **keywords):
8380 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8381
8382 >>> x, y = Ints('x y')
8383 >>> t = Tactic('solve-eqs')
8384 >>> t(And(x == 0, y >= x + 1))
8385 [[y >= 1]]
8386 """
8387 return self.apply(goal, *arguments, **keywords)
8388
8389 def help(self):
8390 """Display a string containing a description of the available options for the `self` tactic."""
8391 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8392
8393 def param_descrs(self):
8394 """Return the parameter description set."""
8395 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8396
8397
8398def _to_goal(a):
8399 if isinstance(a, BoolRef):
8400 goal = Goal(ctx=a.ctx)
8401 goal.add(a)
8402 return goal
8403 else:
8404 return a
8405
8406
8407def _to_tactic(t, ctx=None):
8408 if isinstance(t, Tactic):
8409 return t
8410 else:
8411 return Tactic(t, ctx)
8412
8413
8414def _and_then(t1, t2, ctx=None):
8415 t1 = _to_tactic(t1, ctx)
8416 t2 = _to_tactic(t2, ctx)
8417 if z3_debug():
8418 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8419 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8420
8421
8422def _or_else(t1, t2, ctx=None):
8423 t1 = _to_tactic(t1, ctx)
8424 t2 = _to_tactic(t2, ctx)
8425 if z3_debug():
8426 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8427 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8428
8429
8430def AndThen(*ts, **ks):
8431 """Return a tactic that applies the tactics in `*ts` in sequence.
8432
8433 >>> x, y = Ints('x y')
8434 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8435 >>> t(And(x == 0, y > x + 1))
8436 [[Not(y <= 1)]]
8437 >>> t(And(x == 0, y > x + 1)).as_expr()
8438 Not(y <= 1)
8439 """
8440 if z3_debug():
8441 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8442 ctx = ks.get("ctx", None)
8443 num = len(ts)
8444 r = ts[0]
8445 for i in range(num - 1):
8446 r = _and_then(r, ts[i + 1], ctx)
8447 return r
8448
8449
8450def Then(*ts, **ks):
8451 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8452
8453 >>> x, y = Ints('x y')
8454 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8455 >>> t(And(x == 0, y > x + 1))
8456 [[Not(y <= 1)]]
8457 >>> t(And(x == 0, y > x + 1)).as_expr()
8458 Not(y <= 1)
8459 """
8460 return AndThen(*ts, **ks)
8461
8462
8463def OrElse(*ts, **ks):
8464 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8465
8466 >>> x = Int('x')
8467 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8468 >>> # Tactic split-clause fails if there is no clause in the given goal.
8469 >>> t(x == 0)
8470 [[x == 0]]
8471 >>> t(Or(x == 0, x == 1))
8472 [[x == 0], [x == 1]]
8473 """
8474 if z3_debug():
8475 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8476 ctx = ks.get("ctx", None)
8477 num = len(ts)
8478 r = ts[0]
8479 for i in range(num - 1):
8480 r = _or_else(r, ts[i + 1], ctx)
8481 return r
8482
8483
8484def ParOr(*ts, **ks):
8485 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8486
8487 >>> x = Int('x')
8488 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8489 >>> t(x + 1 == 2)
8490 [[x == 1]]
8491 """
8492 if z3_debug():
8493 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8494 ctx = _get_ctx(ks.get("ctx", None))
8495 ts = [_to_tactic(t, ctx) for t in ts]
8496 sz = len(ts)
8497 _args = (TacticObj * sz)()
8498 for i in range(sz):
8499 _args[i] = ts[i].tactic
8500 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8501
8502
8503def ParThen(t1, t2, ctx=None):
8504 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8505 The subgoals are processed in parallel.
8506
8507 >>> x, y = Ints('x y')
8508 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8509 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8510 [[x == 1, y == 2], [x == 2, y == 3]]
8511 """
8512 t1 = _to_tactic(t1, ctx)
8513 t2 = _to_tactic(t2, ctx)
8514 if z3_debug():
8515 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8516 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8517
8518
8519def ParAndThen(t1, t2, ctx=None):
8520 """Alias for ParThen(t1, t2, ctx)."""
8521 return ParThen(t1, t2, ctx)
8522
8523
8524def With(t, *args, **keys):
8525 """Return a tactic that applies tactic `t` using the given configuration options.
8526
8527 >>> x, y = Ints('x y')
8528 >>> t = With(Tactic('simplify'), som=True)
8529 >>> t((x + 1)*(y + 2) == 0)
8530 [[2*x + y + x*y == -2]]
8531 """
8532 ctx = keys.pop("ctx", None)
8533 t = _to_tactic(t, ctx)
8534 p = args2params(args, keys, t.ctx)
8535 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8536
8537
8538def WithParams(t, p):
8539 """Return a tactic that applies tactic `t` using the given configuration options.
8540
8541 >>> x, y = Ints('x y')
8542 >>> p = ParamsRef()
8543 >>> p.set("som", True)
8544 >>> t = WithParams(Tactic('simplify'), p)
8545 >>> t((x + 1)*(y + 2) == 0)
8546 [[2*x + y + x*y == -2]]
8547 """
8548 t = _to_tactic(t, None)
8549 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8550
8551
8552def Repeat(t, max=4294967295, ctx=None):
8553 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8554 or the maximum number of iterations `max` is reached.
8555
8556 >>> x, y = Ints('x y')
8557 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8558 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8559 >>> r = t(c)
8560 >>> for subgoal in r: print(subgoal)
8561 [x == 0, y == 0, x > y]
8562 [x == 0, y == 1, x > y]
8563 [x == 1, y == 0, x > y]
8564 [x == 1, y == 1, x > y]
8565 >>> t = Then(t, Tactic('propagate-values'))
8566 >>> t(c)
8567 [[x == 1, y == 0]]
8568 """
8569 t = _to_tactic(t, ctx)
8570 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8571
8572
8573def TryFor(t, ms, ctx=None):
8574 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8575
8576 If `t` does not terminate in `ms` milliseconds, then it fails.
8577 """
8578 t = _to_tactic(t, ctx)
8579 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8580
8581
8582def tactics(ctx=None):
8583 """Return a list of all available tactics in Z3.
8584
8585 >>> l = tactics()
8586 >>> l.count('simplify') == 1
8587 True
8588 """
8589 ctx = _get_ctx(ctx)
8590 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8591
8592
8593def tactic_description(name, ctx=None):
8594 """Return a short description for the tactic named `name`.
8595
8596 >>> d = tactic_description('simplify')
8597 """
8598 ctx = _get_ctx(ctx)
8599 return Z3_tactic_get_descr(ctx.ref(), name)
8600
8601
8602def describe_tactics():
8603 """Display a (tabular) description of all available tactics in Z3."""
8604 if in_html_mode():
8605 even = True
8606 print('<table border="1" cellpadding="2" cellspacing="0">')
8607 for t in tactics():
8608 if even:
8609 print('<tr style="background-color:#CFCFCF">')
8610 even = False
8611 else:
8612 print("<tr>")
8613 even = True
8614 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8615 print("</table>")
8616 else:
8617 for t in tactics():
8618 print("%s : %s" % (t, tactic_description(t)))
8619
8620
8621class Probe:
8622 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8623 to decide which solver and/or preprocessing step will be used.
8624 """
8625
8626 def __init__(self, probe, ctx=None):
8627 self.ctx = _get_ctx(ctx)
8628 self.probe = None
8629 if isinstance(probe, ProbeObj):
8630 self.probe = probe
8631 elif isinstance(probe, float):
8632 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8633 elif _is_int(probe):
8634 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8635 elif isinstance(probe, bool):
8636 if probe:
8637 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8638 else:
8639 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8640 else:
8641 if z3_debug():
8642 _z3_assert(isinstance(probe, str), "probe name expected")
8643 try:
8644 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8645 except Z3Exception:
8646 raise Z3Exception("unknown probe '%s'" % probe)
8647 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8648
8649 def __deepcopy__(self, memo={}):
8650 return Probe(self.probe, self.ctx)
8651
8652 def __del__(self):
8653 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8654 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8655
8656 def __lt__(self, other):
8657 """Return a probe that evaluates to "true" when the value returned by `self`
8658 is less than the value returned by `other`.
8659
8660 >>> p = Probe('size') < 10
8661 >>> x = Int('x')
8662 >>> g = Goal()
8663 >>> g.add(x > 0)
8664 >>> g.add(x < 10)
8665 >>> p(g)
8666 1.0
8667 """
8668 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8669
8670 def __gt__(self, other):
8671 """Return a probe that evaluates to "true" when the value returned by `self`
8672 is greater than the value returned by `other`.
8673
8674 >>> p = Probe('size') > 10
8675 >>> x = Int('x')
8676 >>> g = Goal()
8677 >>> g.add(x > 0)
8678 >>> g.add(x < 10)
8679 >>> p(g)
8680 0.0
8681 """
8682 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8683
8684 def __le__(self, other):
8685 """Return a probe that evaluates to "true" when the value returned by `self`
8686 is less than or equal to the value returned by `other`.
8687
8688 >>> p = Probe('size') <= 2
8689 >>> x = Int('x')
8690 >>> g = Goal()
8691 >>> g.add(x > 0)
8692 >>> g.add(x < 10)
8693 >>> p(g)
8694 1.0
8695 """
8696 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8697
8698 def __ge__(self, other):
8699 """Return a probe that evaluates to "true" when the value returned by `self`
8700 is greater than or equal to the value returned by `other`.
8701
8702 >>> p = Probe('size') >= 2
8703 >>> x = Int('x')
8704 >>> g = Goal()
8705 >>> g.add(x > 0)
8706 >>> g.add(x < 10)
8707 >>> p(g)
8708 1.0
8709 """
8710 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8711
8712 def __eq__(self, other):
8713 """Return a probe that evaluates to "true" when the value returned by `self`
8714 is equal to the value returned by `other`.
8715
8716 >>> p = Probe('size') == 2
8717 >>> x = Int('x')
8718 >>> g = Goal()
8719 >>> g.add(x > 0)
8720 >>> g.add(x < 10)
8721 >>> p(g)
8722 1.0
8723 """
8724 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8725
8726 def __ne__(self, other):
8727 """Return a probe that evaluates to "true" when the value returned by `self`
8728 is not equal to the value returned by `other`.
8729
8730 >>> p = Probe('size') != 2
8731 >>> x = Int('x')
8732 >>> g = Goal()
8733 >>> g.add(x > 0)
8734 >>> g.add(x < 10)
8735 >>> p(g)
8736 0.0
8737 """
8738 p = self.__eq__(other)
8739 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8740
8741 def __call__(self, goal):
8742 """Evaluate the probe `self` in the given goal.
8743
8744 >>> p = Probe('size')
8745 >>> x = Int('x')
8746 >>> g = Goal()
8747 >>> g.add(x > 0)
8748 >>> g.add(x < 10)
8749 >>> p(g)
8750 2.0
8751 >>> g.add(x < 20)
8752 >>> p(g)
8753 3.0
8754 >>> p = Probe('num-consts')
8755 >>> p(g)
8756 1.0
8757 >>> p = Probe('is-propositional')
8758 >>> p(g)
8759 0.0
8760 >>> p = Probe('is-qflia')
8761 >>> p(g)
8762 1.0
8763 """
8764 if z3_debug():
8765 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8766 goal = _to_goal(goal)
8767 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8768
8769
8770def is_probe(p):
8771 """Return `True` if `p` is a Z3 probe.
8772
8773 >>> is_probe(Int('x'))
8774 False
8775 >>> is_probe(Probe('memory'))
8776 True
8777 """
8778 return isinstance(p, Probe)
8779
8780
8781def _to_probe(p, ctx=None):
8782 if is_probe(p):
8783 return p
8784 else:
8785 return Probe(p, ctx)
8786
8787
8788def probes(ctx=None):
8789 """Return a list of all available probes in Z3.
8790
8791 >>> l = probes()
8792 >>> l.count('memory') == 1
8793 True
8794 """
8795 ctx = _get_ctx(ctx)
8796 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8797
8798
8799def probe_description(name, ctx=None):
8800 """Return a short description for the probe named `name`.
8801
8802 >>> d = probe_description('memory')
8803 """
8804 ctx = _get_ctx(ctx)
8805 return Z3_probe_get_descr(ctx.ref(), name)
8806
8807
8808def describe_probes():
8809 """Display a (tabular) description of all available probes in Z3."""
8810 if in_html_mode():
8811 even = True
8812 print('<table border="1" cellpadding="2" cellspacing="0">')
8813 for p in probes():
8814 if even:
8815 print('<tr style="background-color:#CFCFCF">')
8816 even = False
8817 else:
8818 print("<tr>")
8819 even = True
8820 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
8821 print("</table>")
8822 else:
8823 for p in probes():
8824 print("%s : %s" % (p, probe_description(p)))
8825
8826
8827def _probe_nary(f, args, ctx):
8828 if z3_debug():
8829 _z3_assert(len(args) > 0, "At least one argument expected")
8830 num = len(args)
8831 r = _to_probe(args[0], ctx)
8832 for i in range(num - 1):
8833 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
8834 return r
8835
8836
8837def _probe_and(args, ctx):
8838 return _probe_nary(Z3_probe_and, args, ctx)
8839
8840
8841def _probe_or(args, ctx):
8842 return _probe_nary(Z3_probe_or, args, ctx)
8843
8844
8845def FailIf(p, ctx=None):
8846 """Return a tactic that fails if the probe `p` evaluates to true.
8847 Otherwise, it returns the input goal unmodified.
8848
8849 In the following example, the tactic applies 'simplify' if and only if there are
8850 more than 2 constraints in the goal.
8851
8852 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
8853 >>> x, y = Ints('x y')
8854 >>> g = Goal()
8855 >>> g.add(x > 0)
8856 >>> g.add(y > 0)
8857 >>> t(g)
8858 [[x > 0, y > 0]]
8859 >>> g.add(x == y + 1)
8860 >>> t(g)
8861 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8862 """
8863 p = _to_probe(p, ctx)
8864 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
8865
8866
8867def When(p, t, ctx=None):
8868 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
8869 Otherwise, it returns the input goal unmodified.
8870
8871 >>> t = When(Probe('size') > 2, Tactic('simplify'))
8872 >>> x, y = Ints('x y')
8873 >>> g = Goal()
8874 >>> g.add(x > 0)
8875 >>> g.add(y > 0)
8876 >>> t(g)
8877 [[x > 0, y > 0]]
8878 >>> g.add(x == y + 1)
8879 >>> t(g)
8880 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8881 """
8882 p = _to_probe(p, ctx)
8883 t = _to_tactic(t, ctx)
8884 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
8885
8886
8887def Cond(p, t1, t2, ctx=None):
8888 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
8889
8890 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
8891 """
8892 p = _to_probe(p, ctx)
8893 t1 = _to_tactic(t1, ctx)
8894 t2 = _to_tactic(t2, ctx)
8895 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
8896
8897#########################################
8898#
8899# Utils
8900#
8901#########################################
8902
8903
8904def simplify(a, *arguments, **keywords):
8905 """Simplify the expression `a` using the given options.
8906
8907 This function has many options. Use `help_simplify` to obtain the complete list.
8908
8909 >>> x = Int('x')
8910 >>> y = Int('y')
8911 >>> simplify(x + 1 + y + x + 1)
8912 2 + 2*x + y
8913 >>> simplify((x + 1)*(y + 1), som=True)
8914 1 + x + y + x*y
8915 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
8916 And(Not(x == y), Not(x == 1), Not(y == 1))
8917 >>> simplify(And(x == 0, y == 1), elim_and=True)
8918 Not(Or(Not(x == 0), Not(y == 1)))
8919 """
8920 if z3_debug():
8921 _z3_assert(is_expr(a), "Z3 expression expected")
8922 if len(arguments) > 0 or len(keywords) > 0:
8923 p = args2params(arguments, keywords, a.ctx)
8924 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
8925 else:
8926 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
8927
8928
8929def help_simplify():
8930 """Return a string describing all options available for Z3 `simplify` procedure."""
8931 print(Z3_simplify_get_help(main_ctx().ref()))
8932
8933
8934def simplify_param_descrs():
8935 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
8936 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
8937
8938
8939def substitute(t, *m):
8940 """Apply substitution m on t, m is a list of pairs of the form (from, to).
8941 Every occurrence in t of from is replaced with to.
8942
8943 >>> x = Int('x')
8944 >>> y = Int('y')
8945 >>> substitute(x + 1, (x, y + 1))
8946 y + 1 + 1
8947 >>> f = Function('f', IntSort(), IntSort())
8948 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
8949 1 + 1
8950 """
8951 if isinstance(m, tuple):
8952 m1 = _get_args(m)
8953 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
8954 m = m1
8955 if z3_debug():
8956 _z3_assert(is_expr(t), "Z3 expression expected")
8957 _z3_assert(
8958 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
8959 "Z3 invalid substitution, expression pairs expected.")
8960 _z3_assert(
8961 all([p[0].sort().eq(p[1].sort()) for p in m]),
8962 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
8963 num = len(m)
8964 _from = (Ast * num)()
8965 _to = (Ast * num)()
8966 for i in range(num):
8967 _from[i] = m[i][0].as_ast()
8968 _to[i] = m[i][1].as_ast()
8969 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
8970
8971
8972def substitute_vars(t, *m):
8973 """Substitute the free variables in t with the expression in m.
8974
8975 >>> v0 = Var(0, IntSort())
8976 >>> v1 = Var(1, IntSort())
8977 >>> x = Int('x')
8978 >>> f = Function('f', IntSort(), IntSort(), IntSort())
8979 >>> # replace v0 with x+1 and v1 with x
8980 >>> substitute_vars(f(v0, v1), x + 1, x)
8981 f(x + 1, x)
8982 """
8983 if z3_debug():
8984 _z3_assert(is_expr(t), "Z3 expression expected")
8985 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
8986 num = len(m)
8987 _to = (Ast * num)()
8988 for i in range(num):
8989 _to[i] = m[i].as_ast()
8990 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
8991
8992def substitute_funs(t, *m):
8993 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
8994 Every occurrence in to of the function from is replaced with the expression to.
8995 The expression to can have free variables, that refer to the arguments of from.
8996 For examples, see
8997 """
8998 if isinstance(m, tuple):
8999 m1 = _get_args(m)
9000 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9001 m = m1
9002 if z3_debug():
9003 _z3_assert(is_expr(t), "Z3 expression expected")
9004 _z3_assert(all([isinstance(p, tuple) and is_func_decl(p[0]) and is_expr(p[1]) for p in m]), "Z3 invalid substitution, function pairs expected.")
9005 num = len(m)
9006 _from = (FuncDecl * num)()
9007 _to = (Ast * num)()
9008 for i in range(num):
9009 _from[i] = m[i][0].as_func_decl()
9010 _to[i] = m[i][1].as_ast()
9011 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9012
9013
9014def Sum(*args):
9015 """Create the sum of the Z3 expressions.
9016
9017 >>> a, b, c = Ints('a b c')
9018 >>> Sum(a, b, c)
9019 a + b + c
9020 >>> Sum([a, b, c])
9021 a + b + c
9022 >>> A = IntVector('a', 5)
9023 >>> Sum(A)
9024 a__0 + a__1 + a__2 + a__3 + a__4
9025 """
9026 args = _get_args(args)
9027 if len(args) == 0:
9028 return 0
9029 ctx = _ctx_from_ast_arg_list(args)
9030 if ctx is None:
9031 return _reduce(lambda a, b: a + b, args, 0)
9032 args = _coerce_expr_list(args, ctx)
9033 if is_bv(args[0]):
9034 return _reduce(lambda a, b: a + b, args, 0)
9035 else:
9036 _args, sz = _to_ast_array(args)
9037 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9038
9039
9040def Product(*args):
9041 """Create the product of the Z3 expressions.
9042
9043 >>> a, b, c = Ints('a b c')
9044 >>> Product(a, b, c)
9045 a*b*c
9046 >>> Product([a, b, c])
9047 a*b*c
9048 >>> A = IntVector('a', 5)
9049 >>> Product(A)
9050 a__0*a__1*a__2*a__3*a__4
9051 """
9052 args = _get_args(args)
9053 if len(args) == 0:
9054 return 1
9055 ctx = _ctx_from_ast_arg_list(args)
9056 if ctx is None:
9057 return _reduce(lambda a, b: a * b, args, 1)
9058 args = _coerce_expr_list(args, ctx)
9059 if is_bv(args[0]):
9060 return _reduce(lambda a, b: a * b, args, 1)
9061 else:
9062 _args, sz = _to_ast_array(args)
9063 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9064
9065def Abs(arg):
9066 """Create the absolute value of an arithmetic expression"""
9067 return If(arg > 0, arg, -arg)
9068
9069
9070def AtMost(*args):
9071 """Create an at-most Pseudo-Boolean k constraint.
9072
9073 >>> a, b, c = Bools('a b c')
9074 >>> f = AtMost(a, b, c, 2)
9075 """
9076 args = _get_args(args)
9077 if z3_debug():
9078 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9079 ctx = _ctx_from_ast_arg_list(args)
9080 if z3_debug():
9081 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9082 args1 = _coerce_expr_list(args[:-1], ctx)
9083 k = args[-1]
9084 _args, sz = _to_ast_array(args1)
9085 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9086
9087
9088def AtLeast(*args):
9089 """Create an at-least Pseudo-Boolean k constraint.
9090
9091 >>> a, b, c = Bools('a b c')
9092 >>> f = AtLeast(a, b, c, 2)
9093 """
9094 args = _get_args(args)
9095 if z3_debug():
9096 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9097 ctx = _ctx_from_ast_arg_list(args)
9098 if z3_debug():
9099 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9100 args1 = _coerce_expr_list(args[:-1], ctx)
9101 k = args[-1]
9102 _args, sz = _to_ast_array(args1)
9103 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9104
9105
9106def _reorder_pb_arg(arg):
9107 a, b = arg
9108 if not _is_int(b) and _is_int(a):
9109 return b, a
9110 return arg
9111
9112
9113def _pb_args_coeffs(args, default_ctx=None):
9114 args = _get_args_ast_list(args)
9115 if len(args) == 0:
9116 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9117 args = [_reorder_pb_arg(arg) for arg in args]
9118 args, coeffs = zip(*args)
9119 if z3_debug():
9120 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9121 ctx = _ctx_from_ast_arg_list(args)
9122 if z3_debug():
9123 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9124 args = _coerce_expr_list(args, ctx)
9125 _args, sz = _to_ast_array(args)
9126 _coeffs = (ctypes.c_int * len(coeffs))()
9127 for i in range(len(coeffs)):
9128 _z3_check_cint_overflow(coeffs[i], "coefficient")
9129 _coeffs[i] = coeffs[i]
9130 return ctx, sz, _args, _coeffs, args
9131
9132
9133def PbLe(args, k):
9134 """Create a Pseudo-Boolean inequality k constraint.
9135
9136 >>> a, b, c = Bools('a b c')
9137 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9138 """
9139 _z3_check_cint_overflow(k, "k")
9140 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9141 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9142
9143
9144def PbGe(args, k):
9145 """Create a Pseudo-Boolean inequality k constraint.
9146
9147 >>> a, b, c = Bools('a b c')
9148 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9149 """
9150 _z3_check_cint_overflow(k, "k")
9151 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9152 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9153
9154
9155def PbEq(args, k, ctx=None):
9156 """Create a Pseudo-Boolean equality k constraint.
9157
9158 >>> a, b, c = Bools('a b c')
9159 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9160 """
9161 _z3_check_cint_overflow(k, "k")
9162 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9163 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9164
9165
9166def solve(*args, **keywords):
9167 """Solve the constraints `*args`.
9168
9169 This is a simple function for creating demonstrations. It creates a solver,
9170 configure it using the options in `keywords`, adds the constraints
9171 in `args`, and invokes check.
9172
9173 >>> a = Int('a')
9174 >>> solve(a > 0, a < 2)
9175 [a = 1]
9176 """
9177 show = keywords.pop("show", False)
9178 s = Solver()
9179 s.set(**keywords)
9180 s.add(*args)
9181 if show:
9182 print(s)
9183 r = s.check()
9184 if r == unsat:
9185 print("no solution")
9186 elif r == unknown:
9187 print("failed to solve")
9188 try:
9189 print(s.model())
9190 except Z3Exception:
9191 return
9192 else:
9193 print(s.model())
9194
9195
9196def solve_using(s, *args, **keywords):
9197 """Solve the constraints `*args` using solver `s`.
9198
9199 This is a simple function for creating demonstrations. It is similar to `solve`,
9200 but it uses the given solver `s`.
9201 It configures solver `s` using the options in `keywords`, adds the constraints
9202 in `args`, and invokes check.
9203 """
9204 show = keywords.pop("show", False)
9205 if z3_debug():
9206 _z3_assert(isinstance(s, Solver), "Solver object expected")
9207 s.set(**keywords)
9208 s.add(*args)
9209 if show:
9210 print("Problem:")
9211 print(s)
9212 r = s.check()
9213 if r == unsat:
9214 print("no solution")
9215 elif r == unknown:
9216 print("failed to solve")
9217 try:
9218 print(s.model())
9219 except Z3Exception:
9220 return
9221 else:
9222 if show:
9223 print("Solution:")
9224 print(s.model())
9225
9226
9227def prove(claim, show=False, **keywords):
9228 """Try to prove the given claim.
9229
9230 This is a simple function for creating demonstrations. It tries to prove
9231 `claim` by showing the negation is unsatisfiable.
9232
9233 >>> p, q = Bools('p q')
9234 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9235 proved
9236 """
9237 if z3_debug():
9238 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9239 s = Solver()
9240 s.set(**keywords)
9241 s.add(Not(claim))
9242 if show:
9243 print(s)
9244 r = s.check()
9245 if r == unsat:
9246 print("proved")
9247 elif r == unknown:
9248 print("failed to prove")
9249 print(s.model())
9250 else:
9251 print("counterexample")
9252 print(s.model())
9253
9254
9255def _solve_html(*args, **keywords):
9256 """Version of function `solve` that renders HTML output."""
9257 show = keywords.pop("show", False)
9258 s = Solver()
9259 s.set(**keywords)
9260 s.add(*args)
9261 if show:
9262 print("<b>Problem:</b>")
9263 print(s)
9264 r = s.check()
9265 if r == unsat:
9266 print("<b>no solution</b>")
9267 elif r == unknown:
9268 print("<b>failed to solve</b>")
9269 try:
9270 print(s.model())
9271 except Z3Exception:
9272 return
9273 else:
9274 if show:
9275 print("<b>Solution:</b>")
9276 print(s.model())
9277
9278
9279def _solve_using_html(s, *args, **keywords):
9280 """Version of function `solve_using` that renders HTML."""
9281 show = keywords.pop("show", False)
9282 if z3_debug():
9283 _z3_assert(isinstance(s, Solver), "Solver object expected")
9284 s.set(**keywords)
9285 s.add(*args)
9286 if show:
9287 print("<b>Problem:</b>")
9288 print(s)
9289 r = s.check()
9290 if r == unsat:
9291 print("<b>no solution</b>")
9292 elif r == unknown:
9293 print("<b>failed to solve</b>")
9294 try:
9295 print(s.model())
9296 except Z3Exception:
9297 return
9298 else:
9299 if show:
9300 print("<b>Solution:</b>")
9301 print(s.model())
9302
9303
9304def _prove_html(claim, show=False, **keywords):
9305 """Version of function `prove` that renders HTML."""
9306 if z3_debug():
9307 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9308 s = Solver()
9309 s.set(**keywords)
9310 s.add(Not(claim))
9311 if show:
9312 print(s)
9313 r = s.check()
9314 if r == unsat:
9315 print("<b>proved</b>")
9316 elif r == unknown:
9317 print("<b>failed to prove</b>")
9318 print(s.model())
9319 else:
9320 print("<b>counterexample</b>")
9321 print(s.model())
9322
9323
9324def _dict2sarray(sorts, ctx):
9325 sz = len(sorts)
9326 _names = (Symbol * sz)()
9327 _sorts = (Sort * sz)()
9328 i = 0
9329 for k in sorts:
9330 v = sorts[k]
9331 if z3_debug():
9332 _z3_assert(isinstance(k, str), "String expected")
9333 _z3_assert(is_sort(v), "Z3 sort expected")
9334 _names[i] = to_symbol(k, ctx)
9335 _sorts[i] = v.ast
9336 i = i + 1
9337 return sz, _names, _sorts
9338
9339
9340def _dict2darray(decls, ctx):
9341 sz = len(decls)
9342 _names = (Symbol * sz)()
9343 _decls = (FuncDecl * sz)()
9344 i = 0
9345 for k in decls:
9346 v = decls[k]
9347 if z3_debug():
9348 _z3_assert(isinstance(k, str), "String expected")
9349 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9350 _names[i] = to_symbol(k, ctx)
9351 if is_const(v):
9352 _decls[i] = v.decl().ast
9353 else:
9354 _decls[i] = v.ast
9355 i = i + 1
9356 return sz, _names, _decls
9357
9358class ParserContext:
9359 def __init__(self, ctx= None):
9360 self.ctx = _get_ctx(ctx)
9361 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9362 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9363
9364 def __del__(self):
9365 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9366 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9367 self.pctx = None
9368
9369 def add_sort(self, sort):
9370 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9371
9372 def add_decl(self, decl):
9373 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9374
9375 def from_string(self, s):
9376 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9377
9378def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9379 """Parse a string in SMT 2.0 format using the given sorts and decls.
9380
9381 The arguments sorts and decls are Python dictionaries used to initialize
9382 the symbol table used for the SMT 2.0 parser.
9383
9384 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9385 [x > 0, x < 10]
9386 >>> x, y = Ints('x y')
9387 >>> f = Function('f', IntSort(), IntSort())
9388 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9389 [x + f(y) > 0]
9390 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9391 [a > 0]
9392 """
9393 ctx = _get_ctx(ctx)
9394 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9395 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9396 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9397
9398
9399def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9400 """Parse a file in SMT 2.0 format using the given sorts and decls.
9401
9402 This function is similar to parse_smt2_string().
9403 """
9404 ctx = _get_ctx(ctx)
9405 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9406 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9407 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9408
9409
9410#########################################
9411#
9412# Floating-Point Arithmetic
9413#
9414#########################################
9415
9416
9417# Global default rounding mode
9418_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9419_dflt_fpsort_ebits = 11
9420_dflt_fpsort_sbits = 53
9421
9422
9423def get_default_rounding_mode(ctx=None):
9424 """Retrieves the global default rounding mode."""
9425 global _dflt_rounding_mode
9426 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9427 return RTZ(ctx)
9428 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9429 return RTN(ctx)
9430 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9431 return RTP(ctx)
9432 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9433 return RNE(ctx)
9434 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9435 return RNA(ctx)
9436
9437
9438_ROUNDING_MODES = frozenset({
9439 Z3_OP_FPA_RM_TOWARD_ZERO,
9440 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9441 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9442 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9443 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9444})
9445
9446
9447def set_default_rounding_mode(rm, ctx=None):
9448 global _dflt_rounding_mode
9449 if is_fprm_value(rm):
9450 _dflt_rounding_mode = rm.decl().kind()
9451 else:
9452 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9453 _dflt_rounding_mode = rm
9454
9455
9456def get_default_fp_sort(ctx=None):
9457 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9458
9459
9460def set_default_fp_sort(ebits, sbits, ctx=None):
9461 global _dflt_fpsort_ebits
9462 global _dflt_fpsort_sbits
9463 _dflt_fpsort_ebits = ebits
9464 _dflt_fpsort_sbits = sbits
9465
9466
9467def _dflt_rm(ctx=None):
9468 return get_default_rounding_mode(ctx)
9469
9470
9471def _dflt_fps(ctx=None):
9472 return get_default_fp_sort(ctx)
9473
9474
9475def _coerce_fp_expr_list(alist, ctx):
9476 first_fp_sort = None
9477 for a in alist:
9478 if is_fp(a):
9479 if first_fp_sort is None:
9480 first_fp_sort = a.sort()
9481 elif first_fp_sort == a.sort():
9482 pass # OK, same as before
9483 else:
9484 # we saw at least 2 different float sorts; something will
9485 # throw a sort mismatch later, for now assume None.
9486 first_fp_sort = None
9487 break
9488
9489 r = []
9490 for i in range(len(alist)):
9491 a = alist[i]
9492 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9493 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9494 r.append(FPVal(a, None, first_fp_sort, ctx))
9495 else:
9496 r.append(a)
9497 return _coerce_expr_list(r, ctx)
9498
9499
9500# FP Sorts
9501
9502class FPSortRef(SortRef):
9503 """Floating-point sort."""
9504
9505 def ebits(self):
9506 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9507 >>> b = FPSort(8, 24)
9508 >>> b.ebits()
9509 8
9510 """
9511 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9512
9513 def sbits(self):
9514 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9515 >>> b = FPSort(8, 24)
9516 >>> b.sbits()
9517 24
9518 """
9519 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9520
9521 def cast(self, val):
9522 """Try to cast `val` as a floating-point expression.
9523 >>> b = FPSort(8, 24)
9524 >>> b.cast(1.0)
9525 1
9526 >>> b.cast(1.0).sexpr()
9527 '(fp #b0 #x7f #b00000000000000000000000)'
9528 """
9529 if is_expr(val):
9530 if z3_debug():
9531 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9532 return val
9533 else:
9534 return FPVal(val, None, self, self.ctx)
9535
9536
9537def Float16(ctx=None):
9538 """Floating-point 16-bit (half) sort."""
9539 ctx = _get_ctx(ctx)
9540 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9541
9542
9543def FloatHalf(ctx=None):
9544 """Floating-point 16-bit (half) sort."""
9545 ctx = _get_ctx(ctx)
9546 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9547
9548
9549def Float32(ctx=None):
9550 """Floating-point 32-bit (single) sort."""
9551 ctx = _get_ctx(ctx)
9552 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9553
9554
9555def FloatSingle(ctx=None):
9556 """Floating-point 32-bit (single) sort."""
9557 ctx = _get_ctx(ctx)
9558 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9559
9560
9561def Float64(ctx=None):
9562 """Floating-point 64-bit (double) sort."""
9563 ctx = _get_ctx(ctx)
9564 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9565
9566
9567def FloatDouble(ctx=None):
9568 """Floating-point 64-bit (double) sort."""
9569 ctx = _get_ctx(ctx)
9570 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9571
9572
9573def Float128(ctx=None):
9574 """Floating-point 128-bit (quadruple) sort."""
9575 ctx = _get_ctx(ctx)
9576 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9577
9578
9579def FloatQuadruple(ctx=None):
9580 """Floating-point 128-bit (quadruple) sort."""
9581 ctx = _get_ctx(ctx)
9582 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9583
9584
9585class FPRMSortRef(SortRef):
9586 """"Floating-point rounding mode sort."""
9587
9588
9589def is_fp_sort(s):
9590 """Return True if `s` is a Z3 floating-point sort.
9591
9592 >>> is_fp_sort(FPSort(8, 24))
9593 True
9594 >>> is_fp_sort(IntSort())
9595 False
9596 """
9597 return isinstance(s, FPSortRef)
9598
9599
9600def is_fprm_sort(s):
9601 """Return True if `s` is a Z3 floating-point rounding mode sort.
9602
9603 >>> is_fprm_sort(FPSort(8, 24))
9604 False
9605 >>> is_fprm_sort(RNE().sort())
9606 True
9607 """
9608 return isinstance(s, FPRMSortRef)
9609
9610# FP Expressions
9611
9612
9613class FPRef(ExprRef):
9614 """Floating-point expressions."""
9615
9616 def sort(self):
9617 """Return the sort of the floating-point expression `self`.
9618
9619 >>> x = FP('1.0', FPSort(8, 24))
9620 >>> x.sort()
9621 FPSort(8, 24)
9622 >>> x.sort() == FPSort(8, 24)
9623 True
9624 """
9625 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9626
9627 def ebits(self):
9628 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9629 >>> b = FPSort(8, 24)
9630 >>> b.ebits()
9631 8
9632 """
9633 return self.sort().ebits()
9634
9635 def sbits(self):
9636 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9637 >>> b = FPSort(8, 24)
9638 >>> b.sbits()
9639 24
9640 """
9641 return self.sort().sbits()
9642
9643 def as_string(self):
9644 """Return a Z3 floating point expression as a Python string."""
9645 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9646
9647 def __le__(self, other):
9648 return fpLEQ(self, other, self.ctx)
9649
9650 def __lt__(self, other):
9651 return fpLT(self, other, self.ctx)
9652
9653 def __ge__(self, other):
9654 return fpGEQ(self, other, self.ctx)
9655
9656 def __gt__(self, other):
9657 return fpGT(self, other, self.ctx)
9658
9659 def __add__(self, other):
9660 """Create the Z3 expression `self + other`.
9661
9662 >>> x = FP('x', FPSort(8, 24))
9663 >>> y = FP('y', FPSort(8, 24))
9664 >>> x + y
9665 x + y
9666 >>> (x + y).sort()
9667 FPSort(8, 24)
9668 """
9669 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9670 return fpAdd(_dflt_rm(), a, b, self.ctx)
9671
9672 def __radd__(self, other):
9673 """Create the Z3 expression `other + self`.
9674
9675 >>> x = FP('x', FPSort(8, 24))
9676 >>> 10 + x
9677 1.25*(2**3) + x
9678 """
9679 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9680 return fpAdd(_dflt_rm(), a, b, self.ctx)
9681
9682 def __sub__(self, other):
9683 """Create the Z3 expression `self - other`.
9684
9685 >>> x = FP('x', FPSort(8, 24))
9686 >>> y = FP('y', FPSort(8, 24))
9687 >>> x - y
9688 x - y
9689 >>> (x - y).sort()
9690 FPSort(8, 24)
9691 """
9692 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9693 return fpSub(_dflt_rm(), a, b, self.ctx)
9694
9695 def __rsub__(self, other):
9696 """Create the Z3 expression `other - self`.
9697
9698 >>> x = FP('x', FPSort(8, 24))
9699 >>> 10 - x
9700 1.25*(2**3) - x
9701 """
9702 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9703 return fpSub(_dflt_rm(), a, b, self.ctx)
9704
9705 def __mul__(self, other):
9706 """Create the Z3 expression `self * other`.
9707
9708 >>> x = FP('x', FPSort(8, 24))
9709 >>> y = FP('y', FPSort(8, 24))
9710 >>> x * y
9711 x * y
9712 >>> (x * y).sort()
9713 FPSort(8, 24)
9714 >>> 10 * y
9715 1.25*(2**3) * y
9716 """
9717 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9718 return fpMul(_dflt_rm(), a, b, self.ctx)
9719
9720 def __rmul__(self, other):
9721 """Create the Z3 expression `other * self`.
9722
9723 >>> x = FP('x', FPSort(8, 24))
9724 >>> y = FP('y', FPSort(8, 24))
9725 >>> x * y
9726 x * y
9727 >>> x * 10
9728 x * 1.25*(2**3)
9729 """
9730 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9731 return fpMul(_dflt_rm(), a, b, self.ctx)
9732
9733 def __pos__(self):
9734 """Create the Z3 expression `+self`."""
9735 return self
9736
9737 def __neg__(self):
9738 """Create the Z3 expression `-self`.
9739
9740 >>> x = FP('x', Float32())
9741 >>> -x
9742 -x
9743 """
9744 return fpNeg(self)
9745
9746 def __div__(self, other):
9747 """Create the Z3 expression `self / other`.
9748
9749 >>> x = FP('x', FPSort(8, 24))
9750 >>> y = FP('y', FPSort(8, 24))
9751 >>> x / y
9752 x / y
9753 >>> (x / y).sort()
9754 FPSort(8, 24)
9755 >>> 10 / y
9756 1.25*(2**3) / y
9757 """
9758 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9759 return fpDiv(_dflt_rm(), a, b, self.ctx)
9760
9761 def __rdiv__(self, other):
9762 """Create the Z3 expression `other / self`.
9763
9764 >>> x = FP('x', FPSort(8, 24))
9765 >>> y = FP('y', FPSort(8, 24))
9766 >>> x / y
9767 x / y
9768 >>> x / 10
9769 x / 1.25*(2**3)
9770 """
9771 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9772 return fpDiv(_dflt_rm(), a, b, self.ctx)
9773
9774 def __truediv__(self, other):
9775 """Create the Z3 expression division `self / other`."""
9776 return self.__div__(other)
9777
9778 def __rtruediv__(self, other):
9779 """Create the Z3 expression division `other / self`."""
9780 return self.__rdiv__(other)
9781
9782 def __mod__(self, other):
9783 """Create the Z3 expression mod `self % other`."""
9784 return fpRem(self, other)
9785
9786 def __rmod__(self, other):
9787 """Create the Z3 expression mod `other % self`."""
9788 return fpRem(other, self)
9789
9790
9791class FPRMRef(ExprRef):
9792 """Floating-point rounding mode expressions"""
9793
9794 def as_string(self):
9795 """Return a Z3 floating point expression as a Python string."""
9796 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9797
9798
9799def RoundNearestTiesToEven(ctx=None):
9800 ctx = _get_ctx(ctx)
9801 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9802
9803
9804def RNE(ctx=None):
9805 ctx = _get_ctx(ctx)
9806 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9807
9808
9809def RoundNearestTiesToAway(ctx=None):
9810 ctx = _get_ctx(ctx)
9811 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9812
9813
9814def RNA(ctx=None):
9815 ctx = _get_ctx(ctx)
9816 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9817
9818
9819def RoundTowardPositive(ctx=None):
9820 ctx = _get_ctx(ctx)
9821 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9822
9823
9824def RTP(ctx=None):
9825 ctx = _get_ctx(ctx)
9826 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9827
9828
9829def RoundTowardNegative(ctx=None):
9830 ctx = _get_ctx(ctx)
9831 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9832
9833
9834def RTN(ctx=None):
9835 ctx = _get_ctx(ctx)
9836 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9837
9838
9839def RoundTowardZero(ctx=None):
9840 ctx = _get_ctx(ctx)
9841 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9842
9843
9844def RTZ(ctx=None):
9845 ctx = _get_ctx(ctx)
9846 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9847
9848
9849def is_fprm(a):
9850 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
9851
9852 >>> rm = RNE()
9853 >>> is_fprm(rm)
9854 True
9855 >>> rm = 1.0
9856 >>> is_fprm(rm)
9857 False
9858 """
9859 return isinstance(a, FPRMRef)
9860
9861
9862def is_fprm_value(a):
9863 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
9864 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
9865
9866# FP Numerals
9867
9868
9869class FPNumRef(FPRef):
9870 """The sign of the numeral.
9871
9872 >>> x = FPVal(+1.0, FPSort(8, 24))
9873 >>> x.sign()
9874 False
9875 >>> x = FPVal(-1.0, FPSort(8, 24))
9876 >>> x.sign()
9877 True
9878 """
9879
9880 def sign(self):
9881 num = (ctypes.c_int)()
9882 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
9883 if nsign is False:
9884 raise Z3Exception("error retrieving the sign of a numeral.")
9885 return num.value != 0
9886
9887 """The sign of a floating-point numeral as a bit-vector expression.
9888
9889 Remark: NaN's are invalid arguments.
9890 """
9891
9892 def sign_as_bv(self):
9893 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9894
9895 """The significand of the numeral.
9896
9897 >>> x = FPVal(2.5, FPSort(8, 24))
9898 >>> x.significand()
9899 1.25
9900 """
9901
9902 def significand(self):
9903 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
9904
9905 """The significand of the numeral as a long.
9906
9907 >>> x = FPVal(2.5, FPSort(8, 24))
9908 >>> x.significand_as_long()
9909 1.25
9910 """
9911
9912 def significand_as_long(self):
9913 ptr = (ctypes.c_ulonglong * 1)()
9914 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
9915 raise Z3Exception("error retrieving the significand of a numeral.")
9916 return ptr[0]
9917
9918 """The significand of the numeral as a bit-vector expression.
9919
9920 Remark: NaN are invalid arguments.
9921 """
9922
9923 def significand_as_bv(self):
9924 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9925
9926 """The exponent of the numeral.
9927
9928 >>> x = FPVal(2.5, FPSort(8, 24))
9929 >>> x.exponent()
9930 1
9931 """
9932
9933 def exponent(self, biased=True):
9934 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
9935
9936 """The exponent of the numeral as a long.
9937
9938 >>> x = FPVal(2.5, FPSort(8, 24))
9939 >>> x.exponent_as_long()
9940 1
9941 """
9942
9943 def exponent_as_long(self, biased=True):
9944 ptr = (ctypes.c_longlong * 1)()
9945 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
9946 raise Z3Exception("error retrieving the exponent of a numeral.")
9947 return ptr[0]
9948
9949 """The exponent of the numeral as a bit-vector expression.
9950
9951 Remark: NaNs are invalid arguments.
9952 """
9953
9954 def exponent_as_bv(self, biased=True):
9955 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
9956
9957 """Indicates whether the numeral is a NaN."""
9958
9959 def isNaN(self):
9960 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
9961
9962 """Indicates whether the numeral is +oo or -oo."""
9963
9964 def isInf(self):
9965 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
9966
9967 """Indicates whether the numeral is +zero or -zero."""
9968
9969 def isZero(self):
9970 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
9971
9972 """Indicates whether the numeral is normal."""
9973
9974 def isNormal(self):
9975 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
9976
9977 """Indicates whether the numeral is subnormal."""
9978
9979 def isSubnormal(self):
9980 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
9981
9982 """Indicates whether the numeral is positive."""
9983
9984 def isPositive(self):
9985 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
9986
9987 """Indicates whether the numeral is negative."""
9988
9989 def isNegative(self):
9990 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
9991
9992 """
9993 The string representation of the numeral.
9994
9995 >>> x = FPVal(20, FPSort(8, 24))
9996 >>> x.as_string()
9997 1.25*(2**4)
9998 """
9999
10000 def as_string(self):
10001 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10002 return ("FPVal(%s, %s)" % (s, self.sort()))
10003
10004
10005def is_fp(a):
10006 """Return `True` if `a` is a Z3 floating-point expression.
10007
10008 >>> b = FP('b', FPSort(8, 24))
10009 >>> is_fp(b)
10010 True
10011 >>> is_fp(b + 1.0)
10012 True
10013 >>> is_fp(Int('x'))
10014 False
10015 """
10016 return isinstance(a, FPRef)
10017
10018
10019def is_fp_value(a):
10020 """Return `True` if `a` is a Z3 floating-point numeral value.
10021
10022 >>> b = FP('b', FPSort(8, 24))
10023 >>> is_fp_value(b)
10024 False
10025 >>> b = FPVal(1.0, FPSort(8, 24))
10026 >>> b
10027 1
10028 >>> is_fp_value(b)
10029 True
10030 """
10031 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10032
10033
10034def FPSort(ebits, sbits, ctx=None):
10035 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10036
10037 >>> Single = FPSort(8, 24)
10038 >>> Double = FPSort(11, 53)
10039 >>> Single
10040 FPSort(8, 24)
10041 >>> x = Const('x', Single)
10042 >>> eq(x, FP('x', FPSort(8, 24)))
10043 True
10044 """
10045 ctx = _get_ctx(ctx)
10046 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10047
10048
10049def _to_float_str(val, exp=0):
10050 if isinstance(val, float):
10051 if math.isnan(val):
10052 res = "NaN"
10053 elif val == 0.0:
10054 sone = math.copysign(1.0, val)
10055 if sone < 0.0:
10056 return "-0.0"
10057 else:
10058 return "+0.0"
10059 elif val == float("+inf"):
10060 res = "+oo"
10061 elif val == float("-inf"):
10062 res = "-oo"
10063 else:
10064 v = val.as_integer_ratio()
10065 num = v[0]
10066 den = v[1]
10067 rvs = str(num) + "/" + str(den)
10068 res = rvs + "p" + _to_int_str(exp)
10069 elif isinstance(val, bool):
10070 if val:
10071 res = "1.0"
10072 else:
10073 res = "0.0"
10074 elif _is_int(val):
10075 res = str(val)
10076 elif isinstance(val, str):
10077 inx = val.find("*(2**")
10078 if inx == -1:
10079 res = val
10080 elif val[-1] == ")":
10081 res = val[0:inx]
10082 exp = str(int(val[inx + 5:-1]) + int(exp))
10083 else:
10084 _z3_assert(False, "String does not have floating-point numeral form.")
10085 elif z3_debug():
10086 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10087 if exp == 0:
10088 return res
10089 else:
10090 return res + "p" + exp
10091
10092
10093def fpNaN(s):
10094 """Create a Z3 floating-point NaN term.
10095
10096 >>> s = FPSort(8, 24)
10097 >>> set_fpa_pretty(True)
10098 >>> fpNaN(s)
10099 NaN
10100 >>> pb = get_fpa_pretty()
10101 >>> set_fpa_pretty(False)
10102 >>> fpNaN(s)
10103 fpNaN(FPSort(8, 24))
10104 >>> set_fpa_pretty(pb)
10105 """
10106 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10107 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10108
10109
10110def fpPlusInfinity(s):
10111 """Create a Z3 floating-point +oo term.
10112
10113 >>> s = FPSort(8, 24)
10114 >>> pb = get_fpa_pretty()
10115 >>> set_fpa_pretty(True)
10116 >>> fpPlusInfinity(s)
10117 +oo
10118 >>> set_fpa_pretty(False)
10119 >>> fpPlusInfinity(s)
10120 fpPlusInfinity(FPSort(8, 24))
10121 >>> set_fpa_pretty(pb)
10122 """
10123 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10124 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10125
10126
10127def fpMinusInfinity(s):
10128 """Create a Z3 floating-point -oo term."""
10129 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10130 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10131
10132
10133def fpInfinity(s, negative):
10134 """Create a Z3 floating-point +oo or -oo term."""
10135 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10136 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10137 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10138
10139
10140def fpPlusZero(s):
10141 """Create a Z3 floating-point +0.0 term."""
10142 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10143 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10144
10145
10146def fpMinusZero(s):
10147 """Create a Z3 floating-point -0.0 term."""
10148 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10149 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10150
10151
10152def fpZero(s, negative):
10153 """Create a Z3 floating-point +0.0 or -0.0 term."""
10154 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10155 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10156 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10157
10158
10159def FPVal(sig, exp=None, fps=None, ctx=None):
10160 """Return a floating-point value of value `val` and sort `fps`.
10161 If `ctx=None`, then the global context is used.
10162
10163 >>> v = FPVal(20.0, FPSort(8, 24))
10164 >>> v
10165 1.25*(2**4)
10166 >>> print("0x%.8x" % v.exponent_as_long(False))
10167 0x00000004
10168 >>> v = FPVal(2.25, FPSort(8, 24))
10169 >>> v
10170 1.125*(2**1)
10171 >>> v = FPVal(-2.25, FPSort(8, 24))
10172 >>> v
10173 -1.125*(2**1)
10174 >>> FPVal(-0.0, FPSort(8, 24))
10175 -0.0
10176 >>> FPVal(0.0, FPSort(8, 24))
10177 +0.0
10178 >>> FPVal(+0.0, FPSort(8, 24))
10179 +0.0
10180 """
10181 ctx = _get_ctx(ctx)
10182 if is_fp_sort(exp):
10183 fps = exp
10184 exp = None
10185 elif fps is None:
10186 fps = _dflt_fps(ctx)
10187 _z3_assert(is_fp_sort(fps), "sort mismatch")
10188 if exp is None:
10189 exp = 0
10190 val = _to_float_str(sig)
10191 if val == "NaN" or val == "nan":
10192 return fpNaN(fps)
10193 elif val == "-0.0":
10194 return fpMinusZero(fps)
10195 elif val == "0.0" or val == "+0.0":
10196 return fpPlusZero(fps)
10197 elif val == "+oo" or val == "+inf" or val == "+Inf":
10198 return fpPlusInfinity(fps)
10199 elif val == "-oo" or val == "-inf" or val == "-Inf":
10200 return fpMinusInfinity(fps)
10201 else:
10202 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10203
10204
10205def FP(name, fpsort, ctx=None):
10206 """Return a floating-point constant named `name`.
10207 `fpsort` is the floating-point sort.
10208 If `ctx=None`, then the global context is used.
10209
10210 >>> x = FP('x', FPSort(8, 24))
10211 >>> is_fp(x)
10212 True
10213 >>> x.ebits()
10214 8
10215 >>> x.sort()
10216 FPSort(8, 24)
10217 >>> word = FPSort(8, 24)
10218 >>> x2 = FP('x', word)
10219 >>> eq(x, x2)
10220 True
10221 """
10222 if isinstance(fpsort, FPSortRef) and ctx is None:
10223 ctx = fpsort.ctx
10224 else:
10225 ctx = _get_ctx(ctx)
10226 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10227
10228
10229def FPs(names, fpsort, ctx=None):
10230 """Return an array of floating-point constants.
10231
10232 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10233 >>> x.sort()
10234 FPSort(8, 24)
10235 >>> x.sbits()
10236 24
10237 >>> x.ebits()
10238 8
10239 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10240 (x + y) * z
10241 """
10242 ctx = _get_ctx(ctx)
10243 if isinstance(names, str):
10244 names = names.split(" ")
10245 return [FP(name, fpsort, ctx) for name in names]
10246
10247
10248def fpAbs(a, ctx=None):
10249 """Create a Z3 floating-point absolute value expression.
10250
10251 >>> s = FPSort(8, 24)
10252 >>> rm = RNE()
10253 >>> x = FPVal(1.0, s)
10254 >>> fpAbs(x)
10255 fpAbs(1)
10256 >>> y = FPVal(-20.0, s)
10257 >>> y
10258 -1.25*(2**4)
10259 >>> fpAbs(y)
10260 fpAbs(-1.25*(2**4))
10261 >>> fpAbs(-1.25*(2**4))
10262 fpAbs(-1.25*(2**4))
10263 >>> fpAbs(x).sort()
10264 FPSort(8, 24)
10265 """
10266 ctx = _get_ctx(ctx)
10267 [a] = _coerce_fp_expr_list([a], ctx)
10268 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10269
10270
10271def fpNeg(a, ctx=None):
10272 """Create a Z3 floating-point addition expression.
10273
10274 >>> s = FPSort(8, 24)
10275 >>> rm = RNE()
10276 >>> x = FP('x', s)
10277 >>> fpNeg(x)
10278 -x
10279 >>> fpNeg(x).sort()
10280 FPSort(8, 24)
10281 """
10282 ctx = _get_ctx(ctx)
10283 [a] = _coerce_fp_expr_list([a], ctx)
10284 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10285
10286
10287def _mk_fp_unary(f, rm, a, ctx):
10288 ctx = _get_ctx(ctx)
10289 [a] = _coerce_fp_expr_list([a], ctx)
10290 if z3_debug():
10291 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10292 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10293 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10294
10295
10296def _mk_fp_unary_pred(f, a, ctx):
10297 ctx = _get_ctx(ctx)
10298 [a] = _coerce_fp_expr_list([a], ctx)
10299 if z3_debug():
10300 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10301 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10302
10303
10304def _mk_fp_bin(f, rm, a, b, ctx):
10305 ctx = _get_ctx(ctx)
10306 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10307 if z3_debug():
10308 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10309 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10310 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10311
10312
10313def _mk_fp_bin_norm(f, a, b, ctx):
10314 ctx = _get_ctx(ctx)
10315 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10316 if z3_debug():
10317 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10318 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10319
10320
10321def _mk_fp_bin_pred(f, a, b, ctx):
10322 ctx = _get_ctx(ctx)
10323 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10324 if z3_debug():
10325 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10326 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10327
10328
10329def _mk_fp_tern(f, rm, a, b, c, ctx):
10330 ctx = _get_ctx(ctx)
10331 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10332 if z3_debug():
10333 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10334 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10335 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10336 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10337
10338
10339def fpAdd(rm, a, b, ctx=None):
10340 """Create a Z3 floating-point addition expression.
10341
10342 >>> s = FPSort(8, 24)
10343 >>> rm = RNE()
10344 >>> x = FP('x', s)
10345 >>> y = FP('y', s)
10346 >>> fpAdd(rm, x, y)
10347 x + y
10348 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10349 fpAdd(RTZ(), x, y)
10350 >>> fpAdd(rm, x, y).sort()
10351 FPSort(8, 24)
10352 """
10353 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10354
10355
10356def fpSub(rm, a, b, ctx=None):
10357 """Create a Z3 floating-point subtraction expression.
10358
10359 >>> s = FPSort(8, 24)
10360 >>> rm = RNE()
10361 >>> x = FP('x', s)
10362 >>> y = FP('y', s)
10363 >>> fpSub(rm, x, y)
10364 x - y
10365 >>> fpSub(rm, x, y).sort()
10366 FPSort(8, 24)
10367 """
10368 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10369
10370
10371def fpMul(rm, a, b, ctx=None):
10372 """Create a Z3 floating-point multiplication expression.
10373
10374 >>> s = FPSort(8, 24)
10375 >>> rm = RNE()
10376 >>> x = FP('x', s)
10377 >>> y = FP('y', s)
10378 >>> fpMul(rm, x, y)
10379 x * y
10380 >>> fpMul(rm, x, y).sort()
10381 FPSort(8, 24)
10382 """
10383 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10384
10385
10386def fpDiv(rm, a, b, ctx=None):
10387 """Create a Z3 floating-point division expression.
10388
10389 >>> s = FPSort(8, 24)
10390 >>> rm = RNE()
10391 >>> x = FP('x', s)
10392 >>> y = FP('y', s)
10393 >>> fpDiv(rm, x, y)
10394 x / y
10395 >>> fpDiv(rm, x, y).sort()
10396 FPSort(8, 24)
10397 """
10398 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10399
10400
10401def fpRem(a, b, ctx=None):
10402 """Create a Z3 floating-point remainder expression.
10403
10404 >>> s = FPSort(8, 24)
10405 >>> x = FP('x', s)
10406 >>> y = FP('y', s)
10407 >>> fpRem(x, y)
10408 fpRem(x, y)
10409 >>> fpRem(x, y).sort()
10410 FPSort(8, 24)
10411 """
10412 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10413
10414
10415def fpMin(a, b, ctx=None):
10416 """Create a Z3 floating-point minimum expression.
10417
10418 >>> s = FPSort(8, 24)
10419 >>> rm = RNE()
10420 >>> x = FP('x', s)
10421 >>> y = FP('y', s)
10422 >>> fpMin(x, y)
10423 fpMin(x, y)
10424 >>> fpMin(x, y).sort()
10425 FPSort(8, 24)
10426 """
10427 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10428
10429
10430def fpMax(a, b, ctx=None):
10431 """Create a Z3 floating-point maximum expression.
10432
10433 >>> s = FPSort(8, 24)
10434 >>> rm = RNE()
10435 >>> x = FP('x', s)
10436 >>> y = FP('y', s)
10437 >>> fpMax(x, y)
10438 fpMax(x, y)
10439 >>> fpMax(x, y).sort()
10440 FPSort(8, 24)
10441 """
10442 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10443
10444
10445def fpFMA(rm, a, b, c, ctx=None):
10446 """Create a Z3 floating-point fused multiply-add expression.
10447 """
10448 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10449
10450
10451def fpSqrt(rm, a, ctx=None):
10452 """Create a Z3 floating-point square root expression.
10453 """
10454 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10455
10456
10457def fpRoundToIntegral(rm, a, ctx=None):
10458 """Create a Z3 floating-point roundToIntegral expression.
10459 """
10460 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10461
10462
10463def fpIsNaN(a, ctx=None):
10464 """Create a Z3 floating-point isNaN expression.
10465
10466 >>> s = FPSort(8, 24)
10467 >>> x = FP('x', s)
10468 >>> y = FP('y', s)
10469 >>> fpIsNaN(x)
10470 fpIsNaN(x)
10471 """
10472 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10473
10474
10475def fpIsInf(a, ctx=None):
10476 """Create a Z3 floating-point isInfinite expression.
10477
10478 >>> s = FPSort(8, 24)
10479 >>> x = FP('x', s)
10480 >>> fpIsInf(x)
10481 fpIsInf(x)
10482 """
10483 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10484
10485
10486def fpIsZero(a, ctx=None):
10487 """Create a Z3 floating-point isZero expression.
10488 """
10489 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10490
10491
10492def fpIsNormal(a, ctx=None):
10493 """Create a Z3 floating-point isNormal expression.
10494 """
10495 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10496
10497
10498def fpIsSubnormal(a, ctx=None):
10499 """Create a Z3 floating-point isSubnormal expression.
10500 """
10501 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10502
10503
10504def fpIsNegative(a, ctx=None):
10505 """Create a Z3 floating-point isNegative expression.
10506 """
10507 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10508
10509
10510def fpIsPositive(a, ctx=None):
10511 """Create a Z3 floating-point isPositive expression.
10512 """
10513 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10514
10515
10516def _check_fp_args(a, b):
10517 if z3_debug():
10518 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10519
10520
10521def fpLT(a, b, ctx=None):
10522 """Create the Z3 floating-point expression `other < self`.
10523
10524 >>> x, y = FPs('x y', FPSort(8, 24))
10525 >>> fpLT(x, y)
10526 x < y
10527 >>> (x < y).sexpr()
10528 '(fp.lt x y)'
10529 """
10530 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10531
10532
10533def fpLEQ(a, b, ctx=None):
10534 """Create the Z3 floating-point expression `other <= self`.
10535
10536 >>> x, y = FPs('x y', FPSort(8, 24))
10537 >>> fpLEQ(x, y)
10538 x <= y
10539 >>> (x <= y).sexpr()
10540 '(fp.leq x y)'
10541 """
10542 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10543
10544
10545def fpGT(a, b, ctx=None):
10546 """Create the Z3 floating-point expression `other > self`.
10547
10548 >>> x, y = FPs('x y', FPSort(8, 24))
10549 >>> fpGT(x, y)
10550 x > y
10551 >>> (x > y).sexpr()
10552 '(fp.gt x y)'
10553 """
10554 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10555
10556
10557def fpGEQ(a, b, ctx=None):
10558 """Create the Z3 floating-point expression `other >= self`.
10559
10560 >>> x, y = FPs('x y', FPSort(8, 24))
10561 >>> fpGEQ(x, y)
10562 x >= y
10563 >>> (x >= y).sexpr()
10564 '(fp.geq x y)'
10565 """
10566 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10567
10568
10569def fpEQ(a, b, ctx=None):
10570 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10571
10572 >>> x, y = FPs('x y', FPSort(8, 24))
10573 >>> fpEQ(x, y)
10574 fpEQ(x, y)
10575 >>> fpEQ(x, y).sexpr()
10576 '(fp.eq x y)'
10577 """
10578 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10579
10580
10581def fpNEQ(a, b, ctx=None):
10582 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10583
10584 >>> x, y = FPs('x y', FPSort(8, 24))
10585 >>> fpNEQ(x, y)
10586 Not(fpEQ(x, y))
10587 >>> (x != y).sexpr()
10588 '(distinct x y)'
10589 """
10590 return Not(fpEQ(a, b, ctx))
10591
10592
10593def fpFP(sgn, exp, sig, ctx=None):
10594 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10595
10596 >>> s = FPSort(8, 24)
10597 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10598 >>> print(x)
10599 fpFP(1, 127, 4194304)
10600 >>> xv = FPVal(-1.5, s)
10601 >>> print(xv)
10602 -1.5
10603 >>> slvr = Solver()
10604 >>> slvr.add(fpEQ(x, xv))
10605 >>> slvr.check()
10606 sat
10607 >>> xv = FPVal(+1.5, s)
10608 >>> print(xv)
10609 1.5
10610 >>> slvr = Solver()
10611 >>> slvr.add(fpEQ(x, xv))
10612 >>> slvr.check()
10613 unsat
10614 """
10615 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10616 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10617 ctx = _get_ctx(ctx)
10618 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10619 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10620
10621
10622def fpToFP(a1, a2=None, a3=None, ctx=None):
10623 """Create a Z3 floating-point conversion expression from other term sorts
10624 to floating-point.
10625
10626 From a bit-vector term in IEEE 754-2008 format:
10627 >>> x = FPVal(1.0, Float32())
10628 >>> x_bv = fpToIEEEBV(x)
10629 >>> simplify(fpToFP(x_bv, Float32()))
10630 1
10631
10632 From a floating-point term with different precision:
10633 >>> x = FPVal(1.0, Float32())
10634 >>> x_db = fpToFP(RNE(), x, Float64())
10635 >>> x_db.sort()
10636 FPSort(11, 53)
10637
10638 From a real term:
10639 >>> x_r = RealVal(1.5)
10640 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10641 1.5
10642
10643 From a signed bit-vector term:
10644 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10645 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10646 -1.25*(2**2)
10647 """
10648 ctx = _get_ctx(ctx)
10649 if is_bv(a1) and is_fp_sort(a2):
10650 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10651 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10652 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10653 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10654 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10655 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10656 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10657 else:
10658 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10659
10660
10661def fpBVToFP(v, sort, ctx=None):
10662 """Create a Z3 floating-point conversion expression that represents the
10663 conversion from a bit-vector term to a floating-point term.
10664
10665 >>> x_bv = BitVecVal(0x3F800000, 32)
10666 >>> x_fp = fpBVToFP(x_bv, Float32())
10667 >>> x_fp
10668 fpToFP(1065353216)
10669 >>> simplify(x_fp)
10670 1
10671 """
10672 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10673 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10674 ctx = _get_ctx(ctx)
10675 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10676
10677
10678def fpFPToFP(rm, v, sort, ctx=None):
10679 """Create a Z3 floating-point conversion expression that represents the
10680 conversion from a floating-point term to a floating-point term of different precision.
10681
10682 >>> x_sgl = FPVal(1.0, Float32())
10683 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10684 >>> x_dbl
10685 fpToFP(RNE(), 1)
10686 >>> simplify(x_dbl)
10687 1
10688 >>> x_dbl.sort()
10689 FPSort(11, 53)
10690 """
10691 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10692 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10693 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10694 ctx = _get_ctx(ctx)
10695 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10696
10697
10698def fpRealToFP(rm, v, sort, ctx=None):
10699 """Create a Z3 floating-point conversion expression that represents the
10700 conversion from a real term to a floating-point term.
10701
10702 >>> x_r = RealVal(1.5)
10703 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10704 >>> x_fp
10705 fpToFP(RNE(), 3/2)
10706 >>> simplify(x_fp)
10707 1.5
10708 """
10709 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10710 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10711 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10712 ctx = _get_ctx(ctx)
10713 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10714
10715
10716def fpSignedToFP(rm, v, sort, ctx=None):
10717 """Create a Z3 floating-point conversion expression that represents the
10718 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10719
10720 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10721 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10722 >>> x_fp
10723 fpToFP(RNE(), 4294967291)
10724 >>> simplify(x_fp)
10725 -1.25*(2**2)
10726 """
10727 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10728 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10729 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10730 ctx = _get_ctx(ctx)
10731 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10732
10733
10734def fpUnsignedToFP(rm, v, sort, ctx=None):
10735 """Create a Z3 floating-point conversion expression that represents the
10736 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10737
10738 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10739 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10740 >>> x_fp
10741 fpToFPUnsigned(RNE(), 4294967291)
10742 >>> simplify(x_fp)
10743 1*(2**32)
10744 """
10745 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10746 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10747 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10748 ctx = _get_ctx(ctx)
10749 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10750
10751
10752def fpToFPUnsigned(rm, x, s, ctx=None):
10753 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10754 if z3_debug():
10755 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10756 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10757 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10758 ctx = _get_ctx(ctx)
10759 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10760
10761
10762def fpToSBV(rm, x, s, ctx=None):
10763 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10764
10765 >>> x = FP('x', FPSort(8, 24))
10766 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10767 >>> print(is_fp(x))
10768 True
10769 >>> print(is_bv(y))
10770 True
10771 >>> print(is_fp(y))
10772 False
10773 >>> print(is_bv(x))
10774 False
10775 """
10776 if z3_debug():
10777 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10778 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10779 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10780 ctx = _get_ctx(ctx)
10781 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10782
10783
10784def fpToUBV(rm, x, s, ctx=None):
10785 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10786
10787 >>> x = FP('x', FPSort(8, 24))
10788 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10789 >>> print(is_fp(x))
10790 True
10791 >>> print(is_bv(y))
10792 True
10793 >>> print(is_fp(y))
10794 False
10795 >>> print(is_bv(x))
10796 False
10797 """
10798 if z3_debug():
10799 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10800 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10801 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10802 ctx = _get_ctx(ctx)
10803 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10804
10805
10806def fpToReal(x, ctx=None):
10807 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
10808
10809 >>> x = FP('x', FPSort(8, 24))
10810 >>> y = fpToReal(x)
10811 >>> print(is_fp(x))
10812 True
10813 >>> print(is_real(y))
10814 True
10815 >>> print(is_fp(y))
10816 False
10817 >>> print(is_real(x))
10818 False
10819 """
10820 if z3_debug():
10821 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10822 ctx = _get_ctx(ctx)
10823 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
10824
10825
10826def fpToIEEEBV(x, ctx=None):
10827 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
10828
10829 The size of the resulting bit-vector is automatically determined.
10830
10831 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
10832 knows only one NaN and it will always produce the same bit-vector representation of
10833 that NaN.
10834
10835 >>> x = FP('x', FPSort(8, 24))
10836 >>> y = fpToIEEEBV(x)
10837 >>> print(is_fp(x))
10838 True
10839 >>> print(is_bv(y))
10840 True
10841 >>> print(is_fp(y))
10842 False
10843 >>> print(is_bv(x))
10844 False
10845 """
10846 if z3_debug():
10847 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10848 ctx = _get_ctx(ctx)
10849 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
10850
10851
10852#########################################
10853#
10854# Strings, Sequences and Regular expressions
10855#
10856#########################################
10857
10858class SeqSortRef(SortRef):
10859 """Sequence sort."""
10860
10861 def is_string(self):
10862 """Determine if sort is a string
10863 >>> s = StringSort()
10864 >>> s.is_string()
10865 True
10866 >>> s = SeqSort(IntSort())
10867 >>> s.is_string()
10868 False
10869 """
10870 return Z3_is_string_sort(self.ctx_ref(), self.ast)
10871
10872 def basis(self):
10873 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10874
10875class CharSortRef(SortRef):
10876 """Character sort."""
10877
10878
10879def StringSort(ctx=None):
10880 """Create a string sort
10881 >>> s = StringSort()
10882 >>> print(s)
10883 String
10884 """
10885 ctx = _get_ctx(ctx)
10886 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
10887
10888def CharSort(ctx=None):
10889 """Create a character sort
10890 >>> ch = CharSort()
10891 >>> print(ch)
10892 Char
10893 """
10894 ctx = _get_ctx(ctx)
10895 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
10896
10897
10898def SeqSort(s):
10899 """Create a sequence sort over elements provided in the argument
10900 >>> s = SeqSort(IntSort())
10901 >>> s == Unit(IntVal(1)).sort()
10902 True
10903 """
10904 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
10905
10906
10907class SeqRef(ExprRef):
10908 """Sequence expression."""
10909
10910 def sort(self):
10911 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
10912
10913 def __add__(self, other):
10914 return Concat(self, other)
10915
10916 def __radd__(self, other):
10917 return Concat(other, self)
10918
10919 def __getitem__(self, i):
10920 if _is_int(i):
10921 i = IntVal(i, self.ctx)
10922 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
10923
10924 def at(self, i):
10925 if _is_int(i):
10926 i = IntVal(i, self.ctx)
10927 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
10928
10929 def is_string(self):
10930 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
10931
10932 def is_string_value(self):
10933 return Z3_is_string(self.ctx_ref(), self.as_ast())
10934
10935 def as_string(self):
10936 """Return a string representation of sequence expression."""
10937 if self.is_string_value():
10938 string_length = ctypes.c_uint()
10939 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
10940 return string_at(chars, size=string_length.value).decode("latin-1")
10941 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10942
10943 def __le__(self, other):
10944 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10945
10946 def __lt__(self, other):
10947 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10948
10949 def __ge__(self, other):
10950 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
10951
10952 def __gt__(self, other):
10953 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
10954
10955
10956def _coerce_char(ch, ctx=None):
10957 if isinstance(ch, str):
10958 ctx = _get_ctx(ctx)
10959 ch = CharVal(ch, ctx)
10960 if not is_expr(ch):
10961 raise Z3Exception("Character expression expected")
10962 return ch
10963
10964class CharRef(ExprRef):
10965 """Character expression."""
10966
10967 def __le__(self, other):
10968 other = _coerce_char(other, self.ctx)
10969 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10970
10971 def to_int(self):
10972 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
10973
10974 def to_bv(self):
10975 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
10976
10977 def is_digit(self):
10978 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
10979
10980
10981def CharVal(ch, ctx=None):
10982 ctx = _get_ctx(ctx)
10983 if isinstance(ch, str):
10984 ch = ord(ch)
10985 if not isinstance(ch, int):
10986 raise Z3Exception("character value should be an ordinal")
10987 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
10988
10989def CharFromBv(bv):
10990 if not is_expr(bv):
10991 raise Z3Exception("Bit-vector expression needed")
10992 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
10993
10994def CharToBv(ch, ctx=None):
10995 ch = _coerce_char(ch, ctx)
10996 return ch.to_bv()
10997
10998def CharToInt(ch, ctx=None):
10999 ch = _coerce_char(ch, ctx)
11000 return ch.to_int()
11001
11002def CharIsDigit(ch, ctx=None):
11003 ch = _coerce_char(ch, ctx)
11004 return ch.is_digit()
11005
11006def _coerce_seq(s, ctx=None):
11007 if isinstance(s, str):
11008 ctx = _get_ctx(ctx)
11009 s = StringVal(s, ctx)
11010 if not is_expr(s):
11011 raise Z3Exception("Non-expression passed as a sequence")
11012 if not is_seq(s):
11013 raise Z3Exception("Non-sequence passed as a sequence")
11014 return s
11015
11016
11017def _get_ctx2(a, b, ctx=None):
11018 if is_expr(a):
11019 return a.ctx
11020 if is_expr(b):
11021 return b.ctx
11022 if ctx is None:
11023 ctx = main_ctx()
11024 return ctx
11025
11026
11027def is_seq(a):
11028 """Return `True` if `a` is a Z3 sequence expression.
11029 >>> print (is_seq(Unit(IntVal(0))))
11030 True
11031 >>> print (is_seq(StringVal("abc")))
11032 True
11033 """
11034 return isinstance(a, SeqRef)
11035
11036
11037def is_string(a):
11038 """Return `True` if `a` is a Z3 string expression.
11039 >>> print (is_string(StringVal("ab")))
11040 True
11041 """
11042 return isinstance(a, SeqRef) and a.is_string()
11043
11044
11045def is_string_value(a):
11046 """return 'True' if 'a' is a Z3 string constant expression.
11047 >>> print (is_string_value(StringVal("a")))
11048 True
11049 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11050 False
11051 """
11052 return isinstance(a, SeqRef) and a.is_string_value()
11053
11054def StringVal(s, ctx=None):
11055 """create a string expression"""
11056 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11057 ctx = _get_ctx(ctx)
11058 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11059
11060
11061def String(name, ctx=None):
11062 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11063
11064 >>> x = String('x')
11065 """
11066 ctx = _get_ctx(ctx)
11067 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11068
11069
11070def Strings(names, ctx=None):
11071 """Return a tuple of String constants. """
11072 ctx = _get_ctx(ctx)
11073 if isinstance(names, str):
11074 names = names.split(" ")
11075 return [String(name, ctx) for name in names]
11076
11077
11078def SubString(s, offset, length):
11079 """Extract substring or subsequence starting at offset"""
11080 return Extract(s, offset, length)
11081
11082
11083def SubSeq(s, offset, length):
11084 """Extract substring or subsequence starting at offset"""
11085 return Extract(s, offset, length)
11086
11087
11088def Empty(s):
11089 """Create the empty sequence of the given sort
11090 >>> e = Empty(StringSort())
11091 >>> e2 = StringVal("")
11092 >>> print(e.eq(e2))
11093 True
11094 >>> e3 = Empty(SeqSort(IntSort()))
11095 >>> print(e3)
11096 Empty(Seq(Int))
11097 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11098 >>> print(e4)
11099 Empty(ReSort(Seq(Int)))
11100 """
11101 if isinstance(s, SeqSortRef):
11102 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11103 if isinstance(s, ReSortRef):
11104 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11105 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11106
11107
11108def Full(s):
11109 """Create the regular expression that accepts the universal language
11110 >>> e = Full(ReSort(SeqSort(IntSort())))
11111 >>> print(e)
11112 Full(ReSort(Seq(Int)))
11113 >>> e1 = Full(ReSort(StringSort()))
11114 >>> print(e1)
11115 Full(ReSort(String))
11116 """
11117 if isinstance(s, ReSortRef):
11118 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11119 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11120
11121
11122
11123def Unit(a):
11124 """Create a singleton sequence"""
11125 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11126
11127
11128def PrefixOf(a, b):
11129 """Check if 'a' is a prefix of 'b'
11130 >>> s1 = PrefixOf("ab", "abc")
11131 >>> simplify(s1)
11132 True
11133 >>> s2 = PrefixOf("bc", "abc")
11134 >>> simplify(s2)
11135 False
11136 """
11137 ctx = _get_ctx2(a, b)
11138 a = _coerce_seq(a, ctx)
11139 b = _coerce_seq(b, ctx)
11140 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11141
11142
11143def SuffixOf(a, b):
11144 """Check if 'a' is a suffix of 'b'
11145 >>> s1 = SuffixOf("ab", "abc")
11146 >>> simplify(s1)
11147 False
11148 >>> s2 = SuffixOf("bc", "abc")
11149 >>> simplify(s2)
11150 True
11151 """
11152 ctx = _get_ctx2(a, b)
11153 a = _coerce_seq(a, ctx)
11154 b = _coerce_seq(b, ctx)
11155 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11156
11157
11158def Contains(a, b):
11159 """Check if 'a' contains 'b'
11160 >>> s1 = Contains("abc", "ab")
11161 >>> simplify(s1)
11162 True
11163 >>> s2 = Contains("abc", "bc")
11164 >>> simplify(s2)
11165 True
11166 >>> x, y, z = Strings('x y z')
11167 >>> s3 = Contains(Concat(x,y,z), y)
11168 >>> simplify(s3)
11169 True
11170 """
11171 ctx = _get_ctx2(a, b)
11172 a = _coerce_seq(a, ctx)
11173 b = _coerce_seq(b, ctx)
11174 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11175
11176
11177def Replace(s, src, dst):
11178 """Replace the first occurrence of 'src' by 'dst' in 's'
11179 >>> r = Replace("aaa", "a", "b")
11180 >>> simplify(r)
11181 "baa"
11182 """
11183 ctx = _get_ctx2(dst, s)
11184 if ctx is None and is_expr(src):
11185 ctx = src.ctx
11186 src = _coerce_seq(src, ctx)
11187 dst = _coerce_seq(dst, ctx)
11188 s = _coerce_seq(s, ctx)
11189 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11190
11191
11192def IndexOf(s, substr, offset=None):
11193 """Retrieve the index of substring within a string starting at a specified offset.
11194 >>> simplify(IndexOf("abcabc", "bc", 0))
11195 1
11196 >>> simplify(IndexOf("abcabc", "bc", 2))
11197 4
11198 """
11199 if offset is None:
11200 offset = IntVal(0)
11201 ctx = None
11202 if is_expr(offset):
11203 ctx = offset.ctx
11204 ctx = _get_ctx2(s, substr, ctx)
11205 s = _coerce_seq(s, ctx)
11206 substr = _coerce_seq(substr, ctx)
11207 if _is_int(offset):
11208 offset = IntVal(offset, ctx)
11209 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11210
11211
11212def LastIndexOf(s, substr):
11213 """Retrieve the last index of substring within a string"""
11214 ctx = None
11215 ctx = _get_ctx2(s, substr, ctx)
11216 s = _coerce_seq(s, ctx)
11217 substr = _coerce_seq(substr, ctx)
11218 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11219
11220
11221def Length(s):
11222 """Obtain the length of a sequence 's'
11223 >>> l = Length(StringVal("abc"))
11224 >>> simplify(l)
11225 3
11226 """
11227 s = _coerce_seq(s)
11228 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11229
11230def SeqMap(f, s):
11231 """Map function 'f' over sequence 's'"""
11232 ctx = _get_ctx2(f, s)
11233 s = _coerce_seq(s, ctx)
11234 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11235
11236def SeqMapI(f, i, s):
11237 """Map function 'f' over sequence 's' at index 'i'"""
11238 ctx = _get_ctx(f, s)
11239 s = _coerce_seq(s, ctx)
11240 if not is_expr(i):
11241 i = _py2expr(i)
11242 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11243
11244def SeqFoldLeft(f, a, s):
11245 ctx = _get_ctx2(f, s)
11246 s = _coerce_seq(s, ctx)
11247 a = _py2expr(a)
11248 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11249
11250def SeqFoldLeftI(f, i, a, s):
11251 ctx = _get_ctx2(f, s)
11252 s = _coerce_seq(s, ctx)
11253 a = _py2expr(a)
11254 i = _py2epxr(i)
11255 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11256
11257def StrToInt(s):
11258 """Convert string expression to integer
11259 >>> a = StrToInt("1")
11260 >>> simplify(1 == a)
11261 True
11262 >>> b = StrToInt("2")
11263 >>> simplify(1 == b)
11264 False
11265 >>> c = StrToInt(IntToStr(2))
11266 >>> simplify(1 == c)
11267 False
11268 """
11269 s = _coerce_seq(s)
11270 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11271
11272
11273def IntToStr(s):
11274 """Convert integer expression to string"""
11275 if not is_expr(s):
11276 s = _py2expr(s)
11277 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11278
11279
11280def StrToCode(s):
11281 """Convert a unit length string to integer code"""
11282 if not is_expr(s):
11283 s = _py2expr(s)
11284 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11285
11286def StrFromCode(c):
11287 """Convert code to a string"""
11288 if not is_expr(c):
11289 c = _py2expr(c)
11290 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11291
11292def Re(s, ctx=None):
11293 """The regular expression that accepts sequence 's'
11294 >>> s1 = Re("ab")
11295 >>> s2 = Re(StringVal("ab"))
11296 >>> s3 = Re(Unit(BoolVal(True)))
11297 """
11298 s = _coerce_seq(s, ctx)
11299 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11300
11301
11302# Regular expressions
11303
11304class ReSortRef(SortRef):
11305 """Regular expression sort."""
11306
11307 def basis(self):
11308 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11309
11310
11311def ReSort(s):
11312 if is_ast(s):
11313 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11314 if s is None or isinstance(s, Context):
11315 ctx = _get_ctx(s)
11316 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11317 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11318
11319
11320class ReRef(ExprRef):
11321 """Regular expressions."""
11322
11323 def __add__(self, other):
11324 return Union(self, other)
11325
11326
11327def is_re(s):
11328 return isinstance(s, ReRef)
11329
11330
11331def InRe(s, re):
11332 """Create regular expression membership test
11333 >>> re = Union(Re("a"),Re("b"))
11334 >>> print (simplify(InRe("a", re)))
11335 True
11336 >>> print (simplify(InRe("b", re)))
11337 True
11338 >>> print (simplify(InRe("c", re)))
11339 False
11340 """
11341 s = _coerce_seq(s, re.ctx)
11342 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11343
11344
11345def Union(*args):
11346 """Create union of regular expressions.
11347 >>> re = Union(Re("a"), Re("b"), Re("c"))
11348 >>> print (simplify(InRe("d", re)))
11349 False
11350 """
11351 args = _get_args(args)
11352 sz = len(args)
11353 if z3_debug():
11354 _z3_assert(sz > 0, "At least one argument expected.")
11355 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11356 if sz == 1:
11357 return args[0]
11358 ctx = args[0].ctx
11359 v = (Ast * sz)()
11360 for i in range(sz):
11361 v[i] = args[i].as_ast()
11362 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11363
11364
11365def Intersect(*args):
11366 """Create intersection of regular expressions.
11367 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11368 """
11369 args = _get_args(args)
11370 sz = len(args)
11371 if z3_debug():
11372 _z3_assert(sz > 0, "At least one argument expected.")
11373 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11374 if sz == 1:
11375 return args[0]
11376 ctx = args[0].ctx
11377 v = (Ast * sz)()
11378 for i in range(sz):
11379 v[i] = args[i].as_ast()
11380 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11381
11382
11383def Plus(re):
11384 """Create the regular expression accepting one or more repetitions of argument.
11385 >>> re = Plus(Re("a"))
11386 >>> print(simplify(InRe("aa", re)))
11387 True
11388 >>> print(simplify(InRe("ab", re)))
11389 False
11390 >>> print(simplify(InRe("", re)))
11391 False
11392 """
11393 if z3_debug():
11394 _z3_assert(is_expr(re), "expression expected")
11395 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11396
11397
11398def Option(re):
11399 """Create the regular expression that optionally accepts the argument.
11400 >>> re = Option(Re("a"))
11401 >>> print(simplify(InRe("a", re)))
11402 True
11403 >>> print(simplify(InRe("", re)))
11404 True
11405 >>> print(simplify(InRe("aa", re)))
11406 False
11407 """
11408 if z3_debug():
11409 _z3_assert(is_expr(re), "expression expected")
11410 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11411
11412
11413def Complement(re):
11414 """Create the complement regular expression."""
11415 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11416
11417
11418def Star(re):
11419 """Create the regular expression accepting zero or more repetitions of argument.
11420 >>> re = Star(Re("a"))
11421 >>> print(simplify(InRe("aa", re)))
11422 True
11423 >>> print(simplify(InRe("ab", re)))
11424 False
11425 >>> print(simplify(InRe("", re)))
11426 True
11427 """
11428 if z3_debug():
11429 _z3_assert(is_expr(re), "expression expected")
11430 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11431
11432
11433def Loop(re, lo, hi=0):
11434 """Create the regular expression accepting between a lower and upper bound repetitions
11435 >>> re = Loop(Re("a"), 1, 3)
11436 >>> print(simplify(InRe("aa", re)))
11437 True
11438 >>> print(simplify(InRe("aaaa", re)))
11439 False
11440 >>> print(simplify(InRe("", re)))
11441 False
11442 """
11443 if z3_debug():
11444 _z3_assert(is_expr(re), "expression expected")
11445 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11446
11447
11448def Range(lo, hi, ctx=None):
11449 """Create the range regular expression over two sequences of length 1
11450 >>> range = Range("a","z")
11451 >>> print(simplify(InRe("b", range)))
11452 True
11453 >>> print(simplify(InRe("bb", range)))
11454 False
11455 """
11456 lo = _coerce_seq(lo, ctx)
11457 hi = _coerce_seq(hi, ctx)
11458 if z3_debug():
11459 _z3_assert(is_expr(lo), "expression expected")
11460 _z3_assert(is_expr(hi), "expression expected")
11461 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11462
11463def Diff(a, b, ctx=None):
11464 """Create the difference regular expression
11465 """
11466 if z3_debug():
11467 _z3_assert(is_expr(a), "expression expected")
11468 _z3_assert(is_expr(b), "expression expected")
11469 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11470
11471def AllChar(regex_sort, ctx=None):
11472 """Create a regular expression that accepts all single character strings
11473 """
11474 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11475
11476# Special Relations
11477
11478
11479def PartialOrder(a, index):
11480 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11481
11482
11483def LinearOrder(a, index):
11484 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11485
11486
11487def TreeOrder(a, index):
11488 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11489
11490
11491def PiecewiseLinearOrder(a, index):
11492 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11493
11494
11495def TransitiveClosure(f):
11496 """Given a binary relation R, such that the two arguments have the same sort
11497 create the transitive closure relation R+.
11498 The transitive closure R+ is a new relation.
11499 """
11500 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11501
11502def to_Ast(ptr,):
11503 ast = Ast(ptr)
11504 super(ctypes.c_void_p, ast).__init__(ptr)
11505 return ast
11506
11507def to_ContextObj(ptr,):
11508 ctx = ContextObj(ptr)
11509 super(ctypes.c_void_p, ctx).__init__(ptr)
11510 return ctx
11511
11512def to_AstVectorObj(ptr,):
11513 v = AstVectorObj(ptr)
11514 super(ctypes.c_void_p, v).__init__(ptr)
11515 return v
11516
11517# NB. my-hacky-class only works for a single instance of OnClause
11518# it should be replaced with a proper correlation between OnClause
11519# and object references that can be passed over the FFI.
11520# for UserPropagator we use a global dictionary, which isn't great code.
11521
11522_my_hacky_class = None
11523def on_clause_eh(ctx, p, n, dep, clause):
11524 onc = _my_hacky_class
11525 p = _to_expr_ref(to_Ast(p), onc.ctx)
11526 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11527 deps = [dep[i] for i in range(n)]
11528 onc.on_clause(p, deps, clause)
11529
11530_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11531
11532class OnClause:
11533 def __init__(self, s, on_clause):
11534 self.s = s
11535 self.ctx = s.ctx
11536 self.on_clause = on_clause
11537 self.idx = 22
11538 global _my_hacky_class
11539 _my_hacky_class = self
11540 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11541
11542
11543class PropClosures:
11544 def __init__(self):
11545 self.bases = {}
11546 self.lock = None
11547
11548 def set_threaded(self):
11549 if self.lock is None:
11550 import threading
11551 self.lock = threading.Lock()
11552
11553 def get(self, ctx):
11554 if self.lock:
11555 with self.lock:
11556 r = self.bases[ctx]
11557 else:
11558 r = self.bases[ctx]
11559 return r
11560
11561 def set(self, ctx, r):
11562 if self.lock:
11563 with self.lock:
11564 self.bases[ctx] = r
11565 else:
11566 self.bases[ctx] = r
11567
11568 def insert(self, r):
11569 if self.lock:
11570 with self.lock:
11571 id = len(self.bases) + 3
11572 self.bases[id] = r
11573 else:
11574 id = len(self.bases) + 3
11575 self.bases[id] = r
11576 return id
11577
11578
11579_prop_closures = None
11580
11581
11582def ensure_prop_closures():
11583 global _prop_closures
11584 if _prop_closures is None:
11585 _prop_closures = PropClosures()
11586
11587
11588def user_prop_push(ctx, cb):
11589 prop = _prop_closures.get(ctx)
11590 prop.cb = cb
11591 prop.push()
11592
11593
11594def user_prop_pop(ctx, cb, num_scopes):
11595 prop = _prop_closures.get(ctx)
11596 prop.cb = cb
11597 prop.pop(num_scopes)
11598
11599
11600def user_prop_fresh(ctx, _new_ctx):
11601 _prop_closures.set_threaded()
11602 prop = _prop_closures.get(ctx)
11603 nctx = Context()
11604 Z3_del_context(nctx.ctx)
11605 new_ctx = to_ContextObj(_new_ctx)
11606 nctx.ctx = new_ctx
11607 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11608 nctx.owner = False
11609 new_prop = prop.fresh(nctx)
11610 _prop_closures.set(new_prop.id, new_prop)
11611 return new_prop.id
11612
11613
11614def user_prop_fixed(ctx, cb, id, value):
11615 prop = _prop_closures.get(ctx)
11616 old_cb = prop.cb
11617 prop.cb = cb
11618 id = _to_expr_ref(to_Ast(id), prop.ctx())
11619 value = _to_expr_ref(to_Ast(value), prop.ctx())
11620 prop.fixed(id, value)
11621 prop.cb = old_cb
11622
11623def user_prop_created(ctx, cb, id):
11624 prop = _prop_closures.get(ctx)
11625 old_cb = prop.cb
11626 prop.cb = cb
11627 id = _to_expr_ref(to_Ast(id), prop.ctx())
11628 prop.created(id)
11629 prop.cb = old_cb
11630
11631
11632def user_prop_final(ctx, cb):
11633 prop = _prop_closures.get(ctx)
11634 old_cb = prop.cb
11635 prop.cb = cb
11636 prop.final()
11637 prop.cb = old_cb
11638
11639def user_prop_eq(ctx, cb, x, y):
11640 prop = _prop_closures.get(ctx)
11641 old_cb = prop.cb
11642 prop.cb = cb
11643 x = _to_expr_ref(to_Ast(x), prop.ctx())
11644 y = _to_expr_ref(to_Ast(y), prop.ctx())
11645 prop.eq(x, y)
11646 prop.cb = old_cb
11647
11648def user_prop_diseq(ctx, cb, x, y):
11649 prop = _prop_closures.get(ctx)
11650 old_cb = prop.cb
11651 prop.cb = cb
11652 x = _to_expr_ref(to_Ast(x), prop.ctx())
11653 y = _to_expr_ref(to_Ast(y), prop.ctx())
11654 prop.diseq(x, y)
11655 prop.cb = old_cb
11656
11657def user_prop_decide(ctx, cb, t, idx, phase):
11658 prop = _prop_closures.get(ctx)
11659 old_cb = prop.cb
11660 prop.cb = cb
11661 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11662 prop.decide(t, idx, phase)
11663 prop.cb = old_cb
11664
11665
11666_user_prop_push = Z3_push_eh(user_prop_push)
11667_user_prop_pop = Z3_pop_eh(user_prop_pop)
11668_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11669_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11670_user_prop_created = Z3_created_eh(user_prop_created)
11671_user_prop_final = Z3_final_eh(user_prop_final)
11672_user_prop_eq = Z3_eq_eh(user_prop_eq)
11673_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11674_user_prop_decide = Z3_decide_eh(user_prop_decide)
11675
11676
11677def PropagateFunction(name, *sig):
11678 """Create a function that gets tracked by user propagator.
11679 Every term headed by this function symbol is tracked.
11680 If a term is fixed and the fixed callback is registered a
11681 callback is invoked that the term headed by this function is fixed.
11682 """
11683 sig = _get_args(sig)
11684 if z3_debug():
11685 _z3_assert(len(sig) > 0, "At least two arguments expected")
11686 arity = len(sig) - 1
11687 rng = sig[arity]
11688 if z3_debug():
11689 _z3_assert(is_sort(rng), "Z3 sort expected")
11690 dom = (Sort * arity)()
11691 for i in range(arity):
11692 if z3_debug():
11693 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11694 dom[i] = sig[i].ast
11695 ctx = rng.ctx
11696 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11697
11698
11699
11700class UserPropagateBase:
11701
11702 #
11703 # Either solver is set or ctx is set.
11704 # Propagators that are created through callbacks
11705 # to "fresh" inherit the context of that is supplied
11706 # as argument to the callback.
11707 # This context should not be deleted. It is owned by the solver.
11708 #
11709 def __init__(self, s, ctx=None):
11710 assert s is None or ctx is None
11711 ensure_prop_closures()
11712 self.solver = s
11713 self._ctx = None
11714 self.fresh_ctx = None
11715 self.cb = None
11716 self.id = _prop_closures.insert(self)
11717 self.fixed = None
11718 self.final = None
11719 self.eq = None
11720 self.diseq = None
11721 self.created = None
11722 if ctx:
11723 self.fresh_ctx = ctx
11724 if s:
11725 Z3_solver_propagate_init(self.ctx_ref(),
11726 s.solver,
11727 ctypes.c_void_p(self.id),
11728 _user_prop_push,
11729 _user_prop_pop,
11730 _user_prop_fresh)
11731
11732 def __del__(self):
11733 if self._ctx:
11734 self._ctx.ctx = None
11735
11736 def ctx(self):
11737 if self.fresh_ctx:
11738 return self.fresh_ctx
11739 else:
11740 return self.solver.ctx
11741
11742 def ctx_ref(self):
11743 return self.ctx().ref()
11744
11745 def add_fixed(self, fixed):
11746 assert not self.fixed
11747 assert not self._ctx
11748 if self.solver:
11749 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11750 self.fixed = fixed
11751
11752 def add_created(self, created):
11753 assert not self.created
11754 assert not self._ctx
11755 if self.solver:
11756 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
11757 self.created = created
11758
11759 def add_final(self, final):
11760 assert not self.final
11761 assert not self._ctx
11762 if self.solver:
11763 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
11764 self.final = final
11765
11766 def add_eq(self, eq):
11767 assert not self.eq
11768 assert not self._ctx
11769 if self.solver:
11770 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
11771 self.eq = eq
11772
11773 def add_diseq(self, diseq):
11774 assert not self.diseq
11775 assert not self._ctx
11776 if self.solver:
11777 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
11778 self.diseq = diseq
11779
11780 def add_decide(self, decide):
11781 assert not self.decide
11782 assert not self._ctx
11783 if self.solver:
11784 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
11785 self.decide = decide
11786
11787 def push(self):
11788 raise Z3Exception("push needs to be overwritten")
11789
11790 def pop(self, num_scopes):
11791 raise Z3Exception("pop needs to be overwritten")
11792
11793 def fresh(self, new_ctx):
11794 raise Z3Exception("fresh needs to be overwritten")
11795
11796 def add(self, e):
11797 assert not self._ctx
11798 if self.solver:
11799 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
11800 else:
11801 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
11802
11803 #
11804 # Tell the solver to perform the next split on a given term
11805 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
11806 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
11807 #
11808 def next_split(self, t, idx, phase):
11809 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
11810
11811 #
11812 # Propagation can only be invoked as during a fixed or final callback.
11813 #
11814 def propagate(self, e, ids, eqs=[]):
11815 _ids, num_fixed = _to_ast_array(ids)
11816 num_eqs = len(eqs)
11817 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
11818 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
11819 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
11820 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
11821
11822 def conflict(self, deps = [], eqs = []):
11823 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3142
as_decimal(self, prec)
Definition z3py.py:3154
__rmod__(self, other)
Definition z3py.py:2630
__mod__(self, other)
Definition z3py.py:2615
__pow__(self, other)
Definition z3py.py:2539
__gt__(self, other)
Definition z3py.py:2688
__lt__(self, other)
Definition z3py.py:2675
__rtruediv__(self, other)
Definition z3py.py:2611
__rmul__(self, other)
Definition z3py.py:2506
__rsub__(self, other)
Definition z3py.py:2529
__add__(self, other)
Definition z3py.py:2468
__sub__(self, other)
Definition z3py.py:2516
is_real(self)
Definition z3py.py:2457
is_int(self)
Definition z3py.py:2443
__radd__(self, other)
Definition z3py.py:2481
__truediv__(self, other)
Definition z3py.py:2590
__le__(self, other)
Definition z3py.py:2662
__rpow__(self, other)
Definition z3py.py:2553
__pos__(self)
Definition z3py.py:2653
sort(self)
Definition z3py.py:2433
__mul__(self, other)
Definition z3py.py:2491
__rdiv__(self, other)
Definition z3py.py:2594
__ge__(self, other)
Definition z3py.py:2701
__neg__(self)
Definition z3py.py:2642
__div__(self, other)
Definition z3py.py:2567
Arithmetic.
Definition z3py.py:2338
subsort(self, other)
Definition z3py.py:2372
cast(self, val)
Definition z3py.py:2376
domain(self)
Definition z3py.py:4606
domain_n(self, i)
Definition z3py.py:4615
__getitem__(self, arg)
Definition z3py.py:4628
range(self)
Definition z3py.py:4619
sort(self)
Definition z3py.py:4597
default(self)
Definition z3py.py:4640
domain_n(self, i)
Definition z3py.py:4579
erase(self, k)
Definition z3py.py:6138
__deepcopy__(self, memo={})
Definition z3py.py:6075
__init__(self, m=None, ctx=None)
Definition z3py.py:6064
__repr__(self)
Definition z3py.py:6135
__len__(self)
Definition z3py.py:6082
keys(self)
Definition z3py.py:6167
__setitem__(self, k, v)
Definition z3py.py:6119
__contains__(self, key)
Definition z3py.py:6095
__del__(self)
Definition z3py.py:6078
__getitem__(self, key)
Definition z3py.py:6108
reset(self)
Definition z3py.py:6152
__deepcopy__(self, memo={})
Definition z3py.py:355
__nonzero__(self)
Definition z3py.py:370
as_ast(self)
Definition z3py.py:392
translate(self, target)
Definition z3py.py:421
__hash__(self)
Definition z3py.py:367
__init__(self, ast, ctx=None)
Definition z3py.py:345
__str__(self)
Definition z3py.py:358
ctx_ref(self)
Definition z3py.py:400
__repr__(self)
Definition z3py.py:361
get_id(self)
Definition z3py.py:396
hash(self)
Definition z3py.py:440
__eq__(self, other)
Definition z3py.py:364
eq(self, other)
Definition z3py.py:404
sexpr(self)
Definition z3py.py:383
__del__(self)
Definition z3py.py:350
__bool__(self)
Definition z3py.py:373
__copy__(self)
Definition z3py.py:437
__deepcopy__(self, memo={})
Definition z3py.py:6044
translate(self, other_ctx)
Definition z3py.py:6025
__repr__(self)
Definition z3py.py:6047
__len__(self)
Definition z3py.py:5919
__init__(self, v=None, ctx=None)
Definition z3py.py:5904
push(self, v)
Definition z3py.py:5977
__getitem__(self, i)
Definition z3py.py:5932
sexpr(self)
Definition z3py.py:6050
__del__(self)
Definition z3py.py:5915
__setitem__(self, i, v)
Definition z3py.py:5961
__contains__(self, item)
Definition z3py.py:6002
__copy__(self)
Definition z3py.py:6041
resize(self, sz)
Definition z3py.py:5989
as_binary_string(self)
Definition z3py.py:3986
as_signed_long(self)
Definition z3py.py:3960
as_string(self)
Definition z3py.py:3983
__and__(self, other)
Definition z3py.py:3650
__rmod__(self, other)
Definition z3py.py:3791
__rrshift__(self, other)
Definition z3py.py:3917
__mod__(self, other)
Definition z3py.py:3770
__or__(self, other)
Definition z3py.py:3627
__rlshift__(self, other)
Definition z3py.py:3931
__gt__(self, other)
Definition z3py.py:3841
__lt__(self, other)
Definition z3py.py:3825
__invert__(self)
Definition z3py.py:3716
__rtruediv__(self, other)
Definition z3py.py:3766
__rmul__(self, other)
Definition z3py.py:3594
__rxor__(self, other)
Definition z3py.py:3686
__ror__(self, other)
Definition z3py.py:3640
__rsub__(self, other)
Definition z3py.py:3617
__add__(self, other)
Definition z3py.py:3558
__sub__(self, other)
Definition z3py.py:3604
__radd__(self, other)
Definition z3py.py:3571
size(self)
Definition z3py.py:3547
__rand__(self, other)
Definition z3py.py:3663
__truediv__(self, other)
Definition z3py.py:3746
__le__(self, other)
Definition z3py.py:3809
__xor__(self, other)
Definition z3py.py:3673
__lshift__(self, other)
Definition z3py.py:3903
__pos__(self)
Definition z3py.py:3696
sort(self)
Definition z3py.py:3536
__mul__(self, other)
Definition z3py.py:3581
__rdiv__(self, other)
Definition z3py.py:3750
__ge__(self, other)
Definition z3py.py:3857
__neg__(self)
Definition z3py.py:3705
__rshift__(self, other)
Definition z3py.py:3873
__div__(self, other)
Definition z3py.py:3727
Bit-Vectors.
Definition z3py.py:3489
subsort(self, other)
Definition z3py.py:3501
cast(self, val)
Definition z3py.py:3504
__and__(self, other)
Definition z3py.py:1596
__or__(self, other)
Definition z3py.py:1599
__invert__(self)
Definition z3py.py:1605
__rmul__(self, other)
Definition z3py.py:1582
__add__(self, other)
Definition z3py.py:1574
__radd__(self, other)
Definition z3py.py:1579
__xor__(self, other)
Definition z3py.py:1602
sort(self)
Definition z3py.py:1571
__mul__(self, other)
Definition z3py.py:1585
Booleans.
Definition z3py.py:1532
subsort(self, other)
Definition z3py.py:1558
is_bool(self)
Definition z3py.py:1564
cast(self, val)
Definition z3py.py:1535
__deepcopy__(self, memo={})
Definition z3py.py:6905
__eq__(self, other)
Definition z3py.py:6908
__ne__(self, other)
Definition z3py.py:6911
__init__(self, r)
Definition z3py.py:6902
param_descrs(self)
Definition z3py.py:230
__init__(self, *args, **kws)
Definition z3py.py:192
interrupt(self)
Definition z3py.py:222
__del__(self)
Definition z3py.py:212
ref(self)
Definition z3py.py:218
bool owner
Definition z3py.py:207
__deepcopy__(self, memo={})
Definition z3py.py:5124
create(self)
Definition z3py.py:5163
__init__(self, name, ctx=None)
Definition z3py.py:5119
__repr__(self)
Definition z3py.py:5160
list constructors
Definition z3py.py:5122
declare(self, name, *args)
Definition z3py.py:5139
declare_core(self, name, rec_name, *args)
Definition z3py.py:5129
constructor(self, idx)
Definition z3py.py:5316
accessor(self, i, j)
Definition z3py.py:5363
num_constructors(self)
Definition z3py.py:5303
recognizer(self, idx)
Definition z3py.py:5335
Expressions.
Definition z3py.py:979
as_ast(self)
Definition z3py.py:990
__hash__(self)
Definition z3py.py:1036
children(self)
Definition z3py.py:1113
serialize(self)
Definition z3py.py:1131
get_id(self)
Definition z3py.py:993
num_args(self)
Definition z3py.py:1076
__eq__(self, other)
Definition z3py.py:1019
__ne__(self, other)
Definition z3py.py:1040
from_string(self, s)
Definition z3py.py:1128
sort_kind(self)
Definition z3py.py:1008
arg(self, idx)
Definition z3py.py:1092
sort(self)
Definition z3py.py:996
params(self)
Definition z3py.py:1058
decl(self)
Definition z3py.py:1061
Function Declarations.
Definition z3py.py:740
as_func_decl(self)
Definition z3py.py:754
domain(self, i)
Definition z3py.py:778
as_ast(self)
Definition z3py.py:748
__call__(self, *args)
Definition z3py.py:837
arity(self)
Definition z3py.py:768
get_id(self)
Definition z3py.py:751
range(self)
Definition z3py.py:790
params(self)
Definition z3py.py:813
Definition z3py.py:6186
__deepcopy__(self, memo={})
Definition z3py.py:6194
ctx
Definition z3py.py:6191
__repr__(self)
Definition z3py.py:6291
num_args(self)
Definition z3py.py:6201
entry
Definition z3py.py:6190
value(self)
Definition z3py.py:6250
__init__(self, entry, ctx)
Definition z3py.py:6189
__del__(self)
Definition z3py.py:6197
as_list(self)
Definition z3py.py:6272
arg_value(self, idx)
Definition z3py.py:6219
__deepcopy__(self, memo={})
Definition z3py.py:6389
translate(self, other_ctx)
Definition z3py.py:6381
arity(self)
Definition z3py.py:6347
__repr__(self)
Definition z3py.py:6409
num_entries(self)
Definition z3py.py:6331
__init__(self, f, ctx)
Definition z3py.py:6298
__del__(self)
Definition z3py.py:6304
as_list(self)
Definition z3py.py:6392
else_value(self)
Definition z3py.py:6308
entry(self, idx)
Definition z3py.py:6361
__copy__(self)
Definition z3py.py:6386
__deepcopy__(self, memo={})
Definition z3py.py:5849
get(self, i)
Definition z3py.py:5707
prec(self)
Definition z3py.py:5651
translate(self, target)
Definition z3py.py:5823
append(self, *args)
Definition z3py.py:5750
as_expr(self)
Definition z3py.py:5872
assert_exprs(self, *args)
Definition z3py.py:5735
__repr__(self)
Definition z3py.py:5812
__len__(self)
Definition z3py.py:5694
inconsistent(self)
Definition z3py.py:5633
dimacs(self, include_names=True)
Definition z3py.py:5819
__getitem__(self, arg)
Definition z3py.py:5720
size(self)
Definition z3py.py:5681
precision(self)
Definition z3py.py:5672
simplify(self, *arguments, **keywords)
Definition z3py.py:5852
sexpr(self)
Definition z3py.py:5815
add(self, *args)
Definition z3py.py:5772
__del__(self)
Definition z3py.py:5611
convert_model(self, model)
Definition z3py.py:5783
insert(self, *args)
Definition z3py.py:5761
depth(self)
Definition z3py.py:5615
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5601
__copy__(self)
Definition z3py.py:5846
as_binary_string(self)
Definition z3py.py:3033
as_long(self)
Definition z3py.py:3012
as_string(self)
Definition z3py.py:3025
__deepcopy__(self, memo={})
Definition z3py.py:6731
eval(self, t, model_completion=False)
Definition z3py.py:6433
translate(self, target)
Definition z3py.py:6720
__getitem__(self, idx)
Definition z3py.py:6634
num_sorts(self)
Definition z3py.py:6559
get_universe(self, s)
Definition z3py.py:6614
get_sort(self, idx)
Definition z3py.py:6574
__repr__(self)
Definition z3py.py:6426
__len__(self)
Definition z3py.py:6490
get_interp(self, decl)
Definition z3py.py:6507
__init__(self, m, ctx)
Definition z3py.py:6416
sexpr(self)
Definition z3py.py:6429
sorts(self)
Definition z3py.py:6597
__del__(self)
Definition z3py.py:6422
decls(self)
Definition z3py.py:6679
update_value(self, x, value)
Definition z3py.py:6698
evaluate(self, t, model_completion=False)
Definition z3py.py:6464
__copy__(self)
Definition z3py.py:6728
__deepcopy__(self, memo={})
Definition z3py.py:5545
__init__(self, descr, ctx=None)
Definition z3py.py:5539
get_kind(self, n)
Definition z3py.py:5567
get_documentation(self, n)
Definition z3py.py:5572
__getitem__(self, arg)
Definition z3py.py:5577
get_name(self, i)
Definition z3py.py:5562
Parameter Sets.
Definition z3py.py:5466
__deepcopy__(self, memo={})
Definition z3py.py:5480
validate(self, ds)
Definition z3py.py:5507
__repr__(self)
Definition z3py.py:5504
__init__(self, ctx=None, params=None)
Definition z3py.py:5472
set(self, name, val)
Definition z3py.py:5487
__del__(self)
Definition z3py.py:5483
Patterns.
Definition z3py.py:1961
as_ast(self)
Definition z3py.py:1966
get_id(self)
Definition z3py.py:1969
Quantifiers.
Definition z3py.py:2028
num_no_patterns(self)
Definition z3py.py:2146
no_pattern(self, idx)
Definition z3py.py:2150
num_patterns(self)
Definition z3py.py:2116
var_name(self, idx)
Definition z3py.py:2179
__getitem__(self, arg)
Definition z3py.py:2085
var_sort(self, idx)
Definition z3py.py:2195
pattern(self, idx)
Definition z3py.py:2128
numerator_as_long(self)
Definition z3py.py:3071
is_int_value(self)
Definition z3py.py:3101
as_fraction(self)
Definition z3py.py:3129
numerator(self)
Definition z3py.py:3045
is_real(self)
Definition z3py.py:3098
as_long(self)
Definition z3py.py:3104
is_int(self)
Definition z3py.py:3095
denominator_as_long(self)
Definition z3py.py:3084
as_string(self)
Definition z3py.py:3120
denominator(self)
Definition z3py.py:3060
as_decimal(self, prec)
Definition z3py.py:3108
__init__(self, c, ctx)
Definition z3py.py:5183
__init__(self, c, ctx)
Definition z3py.py:5195
Strings, Sequences and Regular expressions.
Definition z3py.py:10858
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:6949
assert_and_track(self, a, p)
Definition z3py.py:7118
num_scopes(self)
Definition z3py.py:7030
append(self, *args)
Definition z3py.py:7096
__iadd__(self, fml)
Definition z3py.py:7092
pop(self, num=1)
Definition z3py.py:7008
import_model_converter(self, other)
Definition z3py.py:7196
assert_exprs(self, *args)
Definition z3py.py:7062
model(self)
Definition z3py.py:7177
set(self, *args, **keys)
Definition z3py.py:6973
__enter__(self)
Definition z3py.py:6966
add(self, *args)
Definition z3py.py:7081
__del__(self)
Definition z3py.py:6962
int backtrack_level
Definition z3py.py:6952
insert(self, *args)
Definition z3py.py:7107
check(self, *assumptions)
Definition z3py.py:7148
push(self)
Definition z3py.py:6986
__exit__(self, *exc_info)
Definition z3py.py:6970
reset(self)
Definition z3py.py:7048
subsort(self, other)
Definition z3py.py:585
as_ast(self)
Definition z3py.py:562
__hash__(self)
Definition z3py.py:642
kind(self)
Definition z3py.py:568
get_id(self)
Definition z3py.py:565
__eq__(self, other)
Definition z3py.py:618
__ne__(self, other)
Definition z3py.py:631
cast(self, val)
Definition z3py.py:593
name(self)
Definition z3py.py:608
Statistics.
Definition z3py.py:6758
__deepcopy__(self, memo={})
Definition z3py.py:6766
__getattr__(self, name)
Definition z3py.py:6861
__getitem__(self, idx)
Definition z3py.py:6805
__init__(self, stats, ctx)
Definition z3py.py:6761
__repr__(self)
Definition z3py.py:6773
__len__(self)
Definition z3py.py:6791
__del__(self)
Definition z3py.py:6769
get_key_value(self, key)
Definition z3py.py:6841
subsort(self, other)
Definition z3py.py:716
cast(self, val)
Definition z3py.py:719
ASTs base class.
Definition z3py.py:328
_repr_html_(self)
Definition z3py.py:334
use_pp(self)
Definition z3py.py:331
Z3_ast Z3_API Z3_model_get_const_interp(Z3_context c, Z3_model m, Z3_func_decl a)
Return the interpretation (i.e., assignment) of constant a in the model m. Return NULL,...
Z3_sort Z3_API Z3_mk_int_sort(Z3_context c)
Create the integer type.
Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const *domain, Z3_sort range)
Create an array type with N arguments.
bool Z3_API Z3_open_log(Z3_string filename)
Log interaction to a file.
Z3_parameter_kind Z3_API Z3_get_decl_parameter_kind(Z3_context c, Z3_func_decl d, unsigned idx)
Return the parameter type associated with a declaration.
Z3_ast Z3_API Z3_get_denominator(Z3_context c, Z3_ast a)
Return the denominator (as a numeral AST) of a numeral AST of sort Real.
Z3_probe Z3_API Z3_probe_not(Z3_context x, Z3_probe p)
Return a probe that evaluates to "true" when p does not evaluate to true.
Z3_decl_kind Z3_API Z3_get_decl_kind(Z3_context c, Z3_func_decl d)
Return declaration kind corresponding to declaration.
void Z3_API Z3_solver_assert_and_track(Z3_context c, Z3_solver s, Z3_ast a, Z3_ast p)
Assert a constraint a into the solver, and track it (in the unsat) core using the Boolean constant p.
Z3_ast Z3_API Z3_func_interp_get_else(Z3_context c, Z3_func_interp f)
Return the 'else' value of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsge(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than or equal to.
void Z3_API Z3_ast_map_inc_ref(Z3_context c, Z3_ast_map m)
Increment the reference counter of the given AST map.
Z3_ast Z3_API Z3_mk_const_array(Z3_context c, Z3_sort domain, Z3_ast v)
Create the constant array.
Z3_ast Z3_API Z3_mk_bvsle(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than or equal to.
Z3_func_decl Z3_API Z3_get_app_decl(Z3_context c, Z3_app a)
Return the declaration of a constant or function application.
void Z3_API Z3_del_context(Z3_context c)
Delete the given logical context.
Z3_func_decl Z3_API Z3_get_decl_func_decl_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_ast Z3_API Z3_ast_map_find(Z3_context c, Z3_ast_map m, Z3_ast k)
Return the value associated with the key k.
Z3_string Z3_API Z3_ast_map_to_string(Z3_context c, Z3_ast_map m)
Convert the given map into a string.
Z3_string Z3_API Z3_param_descrs_to_string(Z3_context c, Z3_param_descrs p)
Convert a parameter description set into a string. This function is mainly used for printing the cont...
Z3_ast Z3_API Z3_mk_zero_ext(Z3_context c, unsigned i, Z3_ast t1)
Extend the given bit-vector with zeros to the (unsigned) equivalent bit-vector of size m+i,...
void Z3_API Z3_solver_set_params(Z3_context c, Z3_solver s, Z3_params p)
Set the given solver using the given parameters.
Z3_ast Z3_API Z3_mk_set_intersect(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the intersection of a list of sets.
Z3_params Z3_API Z3_mk_params(Z3_context c)
Create a Z3 (empty) parameter set. Starting at Z3 4.0, parameter sets are used to configure many comp...
unsigned Z3_API Z3_get_decl_num_parameters(Z3_context c, Z3_func_decl d)
Return the number of parameters associated with a declaration.
Z3_ast Z3_API Z3_mk_set_subset(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Check for subsetness of sets.
Z3_ast Z3_API Z3_mk_bvule(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than or equal to.
Z3_ast Z3_API Z3_mk_full_set(Z3_context c, Z3_sort domain)
Create the full set.
Z3_param_kind Z3_API Z3_param_descrs_get_kind(Z3_context c, Z3_param_descrs p, Z3_symbol n)
Return the kind associated with the given parameter name n.
void Z3_API Z3_add_rec_def(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast args[], Z3_ast body)
Define the body of a recursive function.
Z3_ast Z3_API Z3_mk_true(Z3_context c)
Create an AST node representing true.
Z3_ast Z3_API Z3_mk_set_union(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the union of a list of sets.
Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast default_value)
Create a fresh func_interp object, add it to a model for a specified function. It has reference count...
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed division of t1 and t2 does not overflow.
unsigned Z3_API Z3_get_arity(Z3_context c, Z3_func_decl d)
Alias for Z3_get_domain_size.
void Z3_API Z3_ast_vector_set(Z3_context c, Z3_ast_vector v, unsigned i, Z3_ast a)
Update position i of the AST vector v with the AST a.
Z3_ast Z3_API Z3_mk_bvxor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise exclusive-or.
Z3_string Z3_API Z3_stats_to_string(Z3_context c, Z3_stats s)
Convert a statistics into a string.
Z3_sort Z3_API Z3_mk_real_sort(Z3_context c)
Create the real type.
Z3_ast Z3_API Z3_mk_le(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than or equal to.
bool Z3_API Z3_global_param_get(Z3_string param_id, Z3_string_ptr param_value)
Get a global (or module) parameter.
bool Z3_API Z3_goal_inconsistent(Z3_context c, Z3_goal g)
Return true if the given goal contains the formula false.
Z3_ast Z3_API Z3_mk_lambda_const(Z3_context c, unsigned num_bound, Z3_app const bound[], Z3_ast body)
Create a lambda expression using a list of constants that form the set of bound variables.
void Z3_API Z3_solver_dec_ref(Z3_context c, Z3_solver s)
Decrement the reference counter of the given solver.
Z3_ast Z3_API Z3_mk_bvslt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than.
Z3_func_decl Z3_API Z3_model_get_func_decl(Z3_context c, Z3_model m, unsigned i)
Return the declaration of the i-th function in the given model.
bool Z3_API Z3_ast_map_contains(Z3_context c, Z3_ast_map m, Z3_ast k)
Return true if the map m contains the AST key k.
Z3_ast Z3_API Z3_mk_numeral(Z3_context c, Z3_string numeral, Z3_sort ty)
Create a numeral of a given sort.
unsigned Z3_API Z3_func_entry_get_num_args(Z3_context c, Z3_func_entry e)
Return the number of arguments in a Z3_func_entry object.
Z3_symbol Z3_API Z3_get_decl_symbol_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the double value associated with an double parameter.
Z3_symbol Z3_API Z3_get_quantifier_skolem_id(Z3_context c, Z3_ast a)
Obtain skolem id of quantifier.
Z3_ast Z3_API Z3_get_numerator(Z3_context c, Z3_ast a)
Return the numerator (as a numeral AST) of a numeral AST of sort Real.
Z3_ast Z3_API Z3_mk_unary_minus(Z3_context c, Z3_ast arg)
Create an AST node representing - arg.
Z3_ast Z3_API Z3_mk_and(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] and ... and args[num_args-1].
void Z3_API Z3_interrupt(Z3_context c)
Interrupt the execution of a Z3 procedure. This procedure can be used to interrupt: solvers,...
void Z3_API Z3_goal_assert(Z3_context c, Z3_goal g, Z3_ast a)
Add a new formula a to the given goal. The formula is split according to the following procedure that...
Z3_symbol Z3_API Z3_param_descrs_get_name(Z3_context c, Z3_param_descrs p, unsigned i)
Return the name of the parameter at given index i.
Z3_ast Z3_API Z3_func_entry_get_value(Z3_context c, Z3_func_entry e)
Return the value of this point.
bool Z3_API Z3_is_quantifier_exists(Z3_context c, Z3_ast a)
Determine if ast is an existential quantifier.
Z3_sort Z3_API Z3_mk_uninterpreted_sort(Z3_context c, Z3_symbol s)
Create a free (uninterpreted) type using the given name (symbol).
Z3_ast Z3_API Z3_mk_false(Z3_context c)
Create an AST node representing false.
Z3_ast_vector Z3_API Z3_ast_map_keys(Z3_context c, Z3_ast_map m)
Return the keys stored in the given map.
Z3_ast Z3_API Z3_mk_bvmul(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement multiplication.
Z3_model Z3_API Z3_goal_convert_model(Z3_context c, Z3_goal g, Z3_model m)
Convert a model of the formulas of a goal to a model of an original goal. The model may be null,...
void Z3_API Z3_del_constructor(Z3_context c, Z3_constructor constr)
Reclaim memory allocated to constructor.
Z3_ast Z3_API Z3_mk_bvsgt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than.
Z3_string Z3_API Z3_ast_to_string(Z3_context c, Z3_ast a)
Convert the given AST node into a string.
Z3_context Z3_API Z3_mk_context_rc(Z3_config c)
Create a context using the given configuration. This function is similar to Z3_mk_context....
Z3_string Z3_API Z3_get_full_version(void)
Return a string that fully describes the version of Z3 in use.
void Z3_API Z3_enable_trace(Z3_string tag)
Enable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_mk_set_complement(Z3_context c, Z3_ast arg)
Take the complement of a set.
unsigned Z3_API Z3_get_quantifier_num_patterns(Z3_context c, Z3_ast a)
Return number of patterns used in quantifier.
Z3_symbol Z3_API Z3_get_quantifier_bound_name(Z3_context c, Z3_ast a, unsigned i)
Return symbol of the i'th bound variable.
bool Z3_API Z3_stats_is_uint(Z3_context c, Z3_stats s, unsigned idx)
Return true if the given statistical data is a unsigned integer.
unsigned Z3_API Z3_model_get_num_consts(Z3_context c, Z3_model m)
Return the number of constants assigned by the given model.
Z3_ast Z3_API Z3_mk_extract(Z3_context c, unsigned high, unsigned low, Z3_ast t1)
Extract the bits high down to low from a bit-vector of size m to yield a new bit-vector of size n,...
Z3_ast Z3_API Z3_mk_mod(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 mod arg2.
Z3_ast Z3_API Z3_mk_bvredand(Z3_context c, Z3_ast t1)
Take conjunction of bits in vector, return vector of length 1.
Z3_ast Z3_API Z3_mk_set_add(Z3_context c, Z3_ast set, Z3_ast elem)
Add an element to a set.
Z3_ast Z3_API Z3_mk_ge(Z3_context c, Z3_ast t1, Z3_ast t2)
Create greater than or equal to.
Z3_ast Z3_API Z3_mk_bvadd_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed addition of t1 and t2 does not underflow.
Z3_ast Z3_API Z3_mk_bvadd_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise addition of t1 and t2 does not overflow.
void Z3_API Z3_set_ast_print_mode(Z3_context c, Z3_ast_print_mode mode)
Select mode for the format used for pretty-printing AST nodes.
Z3_ast Z3_API Z3_mk_array_default(Z3_context c, Z3_ast array)
Access the array default value. Produces the default range value, for arrays that can be represented ...
unsigned Z3_API Z3_model_get_num_sorts(Z3_context c, Z3_model m)
Return the number of uninterpreted sorts that m assigns an interpretation to.
Z3_constructor Z3_API Z3_mk_constructor(Z3_context c, Z3_symbol name, Z3_symbol recognizer, unsigned num_fields, Z3_symbol const field_names[], Z3_sort_opt const sorts[], unsigned sort_refs[])
Create a constructor.
Z3_ast_vector Z3_API Z3_ast_vector_translate(Z3_context s, Z3_ast_vector v, Z3_context t)
Translate the AST vector v from context s into an AST vector in context t.
void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e)
Increment the reference counter of the given Z3_func_entry object.
Z3_ast Z3_API Z3_mk_fresh_const(Z3_context c, Z3_string prefix, Z3_sort ty)
Declare and create a fresh constant.
Z3_ast Z3_API Z3_mk_bvsub_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed subtraction of t1 and t2 does not overflow.
void Z3_API Z3_solver_push(Z3_context c, Z3_solver s)
Create a backtracking point.
Z3_ast Z3_API Z3_mk_bvsub_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise subtraction of t1 and t2 does not underflow.
Z3_goal Z3_API Z3_goal_translate(Z3_context source, Z3_goal g, Z3_context target)
Copy a goal g from the context source to the context target.
Z3_ast Z3_API Z3_mk_bvudiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned division.
Z3_string Z3_API Z3_ast_vector_to_string(Z3_context c, Z3_ast_vector v)
Convert AST vector into a string.
Z3_ast Z3_API Z3_mk_bvshl(Z3_context c, Z3_ast t1, Z3_ast t2)
Shift left.
bool Z3_API Z3_is_numeral_ast(Z3_context c, Z3_ast a)
Z3_ast Z3_API Z3_mk_bvsrem(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed remainder (sign follows dividend).
bool Z3_API Z3_is_as_array(Z3_context c, Z3_ast a)
The (_ as-array f) AST node is a construct for assigning interpretations for arrays in Z3....
Z3_func_decl Z3_API Z3_mk_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a constant or function.
Z3_ast Z3_API Z3_mk_is_int(Z3_context c, Z3_ast t1)
Check if a real number is an integer.
void Z3_API Z3_params_set_bool(Z3_context c, Z3_params p, Z3_symbol k, bool v)
Add a Boolean parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_mk_ite(Z3_context c, Z3_ast t1, Z3_ast t2, Z3_ast t3)
Create an AST node representing an if-then-else: ite(t1, t2, t3).
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i)
Array read. The argument a is the array and i is the index of the array that gets read.
Z3_ast Z3_API Z3_mk_sign_ext(Z3_context c, unsigned i, Z3_ast t1)
Sign-extend of the given bit-vector to the (signed) equivalent bit-vector of size m+i,...
unsigned Z3_API Z3_goal_size(Z3_context c, Z3_goal g)
Return the number of formulas in the given goal.
void Z3_API Z3_stats_inc_ref(Z3_context c, Z3_stats s)
Increment the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs)
n-ary Array read. The argument a is the array and idxs are the indices of the array that gets read.
Z3_ast_vector Z3_API Z3_algebraic_get_poly(Z3_context c, Z3_ast a)
Return the coefficients of the defining polynomial.
Z3_ast Z3_API Z3_mk_div(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 div arg2.
void Z3_API Z3_model_dec_ref(Z3_context c, Z3_model m)
Decrement the reference counter of the given model.
void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f)
Increment the reference counter of the given Z3_func_interp object.
void Z3_API Z3_params_set_double(Z3_context c, Z3_params p, Z3_symbol k, double v)
Add a double parameter k with value v to the parameter set p.
Z3_string Z3_API Z3_param_descrs_get_documentation(Z3_context c, Z3_param_descrs p, Z3_symbol s)
Retrieve documentation string corresponding to parameter name s.
Z3_sort Z3_API Z3_mk_datatype_sort(Z3_context c, Z3_symbol name)
create a forward reference to a recursive datatype being declared. The forward reference can be used ...
Z3_solver Z3_API Z3_mk_solver(Z3_context c)
Create a new solver. This solver is a "combined solver" (see combined_solver module) that internally ...
Z3_model Z3_API Z3_solver_get_model(Z3_context c, Z3_solver s)
Retrieve the model for the last Z3_solver_check or Z3_solver_check_assumptions.
int Z3_API Z3_get_symbol_int(Z3_context c, Z3_symbol s)
Return the symbol int value.
Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a)
Return the function declaration f associated with a (_ as_array f) node.
Z3_ast Z3_API Z3_mk_ext_rotate_left(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the left t2 times.
void Z3_API Z3_goal_inc_ref(Z3_context c, Z3_goal g)
Increment the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_implies(Z3_context c, Z3_ast t1, Z3_ast t2)
Create an AST node representing t1 implies t2.
unsigned Z3_API Z3_get_datatype_sort_num_constructors(Z3_context c, Z3_sort t)
Return number of constructors for datatype.
void Z3_API Z3_params_set_uint(Z3_context c, Z3_params p, Z3_symbol k, unsigned v)
Add a unsigned parameter k with value v to the parameter set p.
Z3_lbool Z3_API Z3_solver_check_assumptions(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[])
Check whether the assertions in the given solver and optional assumptions are consistent or not.
Z3_sort Z3_API Z3_model_get_sort(Z3_context c, Z3_model m, unsigned i)
Return a uninterpreted sort that m assigns an interpretation.
Z3_ast Z3_API Z3_mk_bvashr(Z3_context c, Z3_ast t1, Z3_ast t2)
Arithmetic shift right.
Z3_ast Z3_API Z3_mk_bv2int(Z3_context c, Z3_ast t1, bool is_signed)
Create an integer from the bit-vector argument t1. If is_signed is false, then the bit-vector t1 is t...
Z3_sort Z3_API Z3_get_array_sort_domain_n(Z3_context c, Z3_sort t, unsigned idx)
Return the i'th domain sort of an n-dimensional array.
Z3_ast Z3_API Z3_mk_set_del(Z3_context c, Z3_ast set, Z3_ast elem)
Remove an element to a set.
Z3_ast Z3_API Z3_mk_bvmul_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise multiplication of t1 and t2 does not overflow.
Z3_ast Z3_API Z3_mk_bvor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise or.
int Z3_API Z3_get_decl_int_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the integer value associated with an integer parameter.
unsigned Z3_API Z3_get_quantifier_num_no_patterns(Z3_context c, Z3_ast a)
Return number of no_patterns used in quantifier.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor(Z3_context c, Z3_sort t, unsigned idx)
Return idx'th constructor.
void Z3_API Z3_ast_vector_resize(Z3_context c, Z3_ast_vector v, unsigned n)
Resize the AST vector v.
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c, bool is_forall, unsigned weight, Z3_symbol quantifier_id, Z3_symbol skolem_id, unsigned num_bound, Z3_app const bound[], unsigned num_patterns, Z3_pattern const patterns[], unsigned num_no_patterns, Z3_ast const no_patterns[], Z3_ast body)
Create a universal or existential quantifier using a list of constants that will form the set of boun...
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[])
Create a pattern for quantifier instantiation.
Z3_symbol_kind Z3_API Z3_get_symbol_kind(Z3_context c, Z3_symbol s)
Return Z3_INT_SYMBOL if the symbol was constructed using Z3_mk_int_symbol, and Z3_STRING_SYMBOL if th...
bool Z3_API Z3_is_lambda(Z3_context c, Z3_ast a)
Determine if ast is a lambda expression.
unsigned Z3_API Z3_stats_get_uint_value(Z3_context c, Z3_stats s, unsigned idx)
Return the unsigned value of the given statistical data.
Z3_sort Z3_API Z3_get_array_sort_domain(Z3_context c, Z3_sort t)
Return the domain of the given array sort. In the case of a multi-dimensional array,...
Z3_ast Z3_API Z3_mk_bvmul_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed multiplication of t1 and t2 does not underflo...
Z3_ast Z3_API Z3_func_decl_to_ast(Z3_context c, Z3_func_decl f)
Convert a Z3_func_decl into Z3_ast. This is just type casting.
void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a)
Add a constant interpretation.
Z3_ast Z3_API Z3_mk_bvadd(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement addition.
unsigned Z3_API Z3_algebraic_get_i(Z3_context c, Z3_ast a)
Return which root of the polynomial the algebraic number represents.
void Z3_API Z3_params_dec_ref(Z3_context c, Z3_params p)
Decrement the reference counter of the given parameter set.
Z3_ast Z3_API Z3_get_app_arg(Z3_context c, Z3_app a, unsigned i)
Return the i-th argument of the given application.
Z3_string Z3_API Z3_model_to_string(Z3_context c, Z3_model m)
Convert the given model into a string.
Z3_func_decl Z3_API Z3_mk_fresh_func_decl(Z3_context c, Z3_string prefix, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a fresh constant or function.
unsigned Z3_API Z3_ast_map_size(Z3_context c, Z3_ast_map m)
Return the size of the given map.
unsigned Z3_API Z3_param_descrs_size(Z3_context c, Z3_param_descrs p)
Return the number of parameters in the given parameter description set.
Z3_string Z3_API Z3_goal_to_dimacs_string(Z3_context c, Z3_goal g, bool include_names)
Convert a goal into a DIMACS formatted string. The goal must be in CNF. You can convert a goal to CNF...
Z3_ast Z3_API Z3_mk_lt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than.
Z3_ast Z3_API Z3_get_quantifier_no_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th no_pattern.
double Z3_API Z3_stats_get_double_value(Z3_context c, Z3_stats s, unsigned idx)
Return the double value of the given statistical data.
Z3_ast Z3_API Z3_mk_bvugt(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than.
unsigned Z3_API Z3_goal_depth(Z3_context c, Z3_goal g)
Return the depth of the given goal. It tracks how many transformations were applied to it.
Z3_string Z3_API Z3_get_symbol_string(Z3_context c, Z3_symbol s)
Return the symbol name.
Z3_ast Z3_API Z3_pattern_to_ast(Z3_context c, Z3_pattern p)
Convert a Z3_pattern into Z3_ast. This is just type casting.
Z3_ast Z3_API Z3_mk_bvnot(Z3_context c, Z3_ast t1)
Bitwise negation.
Z3_ast Z3_API Z3_mk_bvurem(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned remainder.
void Z3_API Z3_mk_datatypes(Z3_context c, unsigned num_sorts, Z3_symbol const sort_names[], Z3_sort sorts[], Z3_constructor_list constructor_lists[])
Create mutually recursive datatypes.
unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f)
Return the arity (number of arguments) of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsub(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement subtraction.
Z3_ast Z3_API Z3_get_algebraic_number_upper(Z3_context c, Z3_ast a, unsigned precision)
Return a upper bound for the given real algebraic number. The interval isolating the number is smalle...
Z3_ast Z3_API Z3_mk_power(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 ^ arg2.
Z3_ast Z3_API Z3_mk_seq_concat(Z3_context c, unsigned n, Z3_ast const args[])
Concatenate sequences.
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c, Z3_symbol name, unsigned n, Z3_symbol const enum_names[], Z3_func_decl enum_consts[], Z3_func_decl enum_testers[])
Create a enumeration sort.
unsigned Z3_API Z3_get_bv_sort_size(Z3_context c, Z3_sort t)
Return the size of the given bit-vector sort.
Z3_ast Z3_API Z3_mk_set_member(Z3_context c, Z3_ast elem, Z3_ast set)
Check for set membership.
void Z3_API Z3_ast_vector_dec_ref(Z3_context c, Z3_ast_vector v)
Decrement the reference counter of the given AST vector.
void Z3_API Z3_func_interp_dec_ref(Z3_context c, Z3_func_interp f)
Decrement the reference counter of the given Z3_func_interp object.
void Z3_API Z3_params_inc_ref(Z3_context c, Z3_params p)
Increment the reference counter of the given parameter set.
void Z3_API Z3_set_error_handler(Z3_context c, Z3_error_handler h)
Register a Z3 error handler.
Z3_ast Z3_API Z3_mk_distinct(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing distinct(args[0], ..., args[num_args-1]).
Z3_config Z3_API Z3_mk_config(void)
Create a configuration object for the Z3 context object.
void Z3_API Z3_set_param_value(Z3_config c, Z3_string param_id, Z3_string param_value)
Set a configuration parameter.
Z3_sort Z3_API Z3_mk_bv_sort(Z3_context c, unsigned sz)
Create a bit-vector type of the given size.
Z3_ast Z3_API Z3_mk_bvult(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than.
void Z3_API Z3_ast_map_dec_ref(Z3_context c, Z3_ast_map m)
Decrement the reference counter of the given AST map.
Z3_string Z3_API Z3_params_to_string(Z3_context c, Z3_params p)
Convert a parameter set into a string. This function is mainly used for printing the contents of a pa...
Z3_param_descrs Z3_API Z3_get_global_param_descrs(Z3_context c)
Retrieve description of global parameters.
Z3_func_decl Z3_API Z3_model_get_const_decl(Z3_context c, Z3_model m, unsigned i)
Return the i-th constant in the given model.
Z3_ast Z3_API Z3_translate(Z3_context source, Z3_ast a, Z3_context target)
Translate/Copy the AST a from context source to context target. AST a must have been created using co...
Z3_sort Z3_API Z3_get_range(Z3_context c, Z3_func_decl d)
Return the range of the given declaration.
void Z3_API Z3_global_param_set(Z3_string param_id, Z3_string param_value)
Set a global (or module) parameter. This setting is shared by all Z3 contexts.
Z3_ast_vector Z3_API Z3_model_get_sort_universe(Z3_context c, Z3_model m, Z3_sort s)
Return the finite set of distinct values that represent the interpretation for sort s.
void Z3_API Z3_func_entry_dec_ref(Z3_context c, Z3_func_entry e)
Decrement the reference counter of the given Z3_func_entry object.
unsigned Z3_API Z3_stats_size(Z3_context c, Z3_stats s)
Return the number of statistical data in s.
void Z3_API Z3_append_log(Z3_string string)
Append user-defined string to interaction log.
Z3_ast Z3_API Z3_get_quantifier_body(Z3_context c, Z3_ast a)
Return body of quantifier.
void Z3_API Z3_param_descrs_dec_ref(Z3_context c, Z3_param_descrs p)
Decrement the reference counter of the given parameter description set.
Z3_model Z3_API Z3_mk_model(Z3_context c)
Create a fresh model object. It has reference count 0.
Z3_symbol Z3_API Z3_get_decl_name(Z3_context c, Z3_func_decl d)
Return the constant declaration name as a symbol.
Z3_ast Z3_API Z3_mk_bvneg_no_overflow(Z3_context c, Z3_ast t1)
Check that bit-wise negation does not overflow when t1 is interpreted as a signed bit-vector.
Z3_string Z3_API Z3_stats_get_key(Z3_context c, Z3_stats s, unsigned idx)
Return the key (a string) for a particular statistical data.
Z3_ast Z3_API Z3_mk_bvand(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise and.
Z3_ast_kind Z3_API Z3_get_ast_kind(Z3_context c, Z3_ast a)
Return the kind of the given AST.
Z3_ast Z3_API Z3_mk_bvsmod(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed remainder (sign follows divisor).
Z3_model Z3_API Z3_model_translate(Z3_context c, Z3_model m, Z3_context dst)
translate model from context c to context dst.
void Z3_API Z3_get_version(unsigned *major, unsigned *minor, unsigned *build_number, unsigned *revision_number)
Return Z3 version number information.
Z3_ast Z3_API Z3_mk_int2bv(Z3_context c, unsigned n, Z3_ast t1)
Create an n bit bit-vector from the integer argument t1.
void Z3_API Z3_solver_assert(Z3_context c, Z3_solver s, Z3_ast a)
Assert a constraint into the solver.
unsigned Z3_API Z3_ast_vector_size(Z3_context c, Z3_ast_vector v)
Return the size of the given AST vector.
unsigned Z3_API Z3_get_quantifier_weight(Z3_context c, Z3_ast a)
Obtain weight of quantifier.
bool Z3_API Z3_model_eval(Z3_context c, Z3_model m, Z3_ast t, bool model_completion, Z3_ast *v)
Evaluate the AST node t in the given model. Return true if succeeded, and store the result in v.
unsigned Z3_API Z3_solver_get_num_scopes(Z3_context c, Z3_solver s)
Return the number of backtracking points.
Z3_sort Z3_API Z3_get_array_sort_range(Z3_context c, Z3_sort t)
Return the range of the given array sort.
void Z3_API Z3_del_constructor_list(Z3_context c, Z3_constructor_list clist)
Reclaim memory allocated for constructor list.
Z3_ast Z3_API Z3_mk_bound(Z3_context c, unsigned index, Z3_sort ty)
Create a variable.
unsigned Z3_API Z3_get_app_num_args(Z3_context c, Z3_app a)
Return the number of argument of an application. If t is an constant, then the number of arguments is...
Z3_ast Z3_API Z3_func_entry_get_arg(Z3_context c, Z3_func_entry e, unsigned i)
Return an argument of a Z3_func_entry object.
Z3_ast Z3_API Z3_mk_eq(Z3_context c, Z3_ast l, Z3_ast r)
Create an AST node representing l = r.
void Z3_API Z3_ast_vector_inc_ref(Z3_context c, Z3_ast_vector v)
Increment the reference counter of the given AST vector.
unsigned Z3_API Z3_model_get_num_funcs(Z3_context c, Z3_model m)
Return the number of function interpretations in the given model.
void Z3_API Z3_dec_ref(Z3_context c, Z3_ast a)
Decrement the reference counter of the given AST. The context c should have been created using Z3_mk_...
Z3_ast_vector Z3_API Z3_mk_ast_vector(Z3_context c)
Return an empty AST vector.
Z3_ast Z3_API Z3_mk_empty_set(Z3_context c, Z3_sort domain)
Create the empty set.
Z3_ast Z3_API Z3_mk_set_has_size(Z3_context c, Z3_ast set, Z3_ast k)
Create predicate that holds if Boolean array set has k elements set to true.
Z3_ast Z3_API Z3_mk_repeat(Z3_context c, unsigned i, Z3_ast t1)
Repeat the given bit-vector up length i.
Z3_goal_prec Z3_API Z3_goal_precision(Z3_context c, Z3_goal g)
Return the "precision" of the given goal. Goals can be transformed using over and under approximation...
void Z3_API Z3_solver_pop(Z3_context c, Z3_solver s, unsigned n)
Backtrack n backtracking points.
void Z3_API Z3_ast_map_erase(Z3_context c, Z3_ast_map m, Z3_ast k)
Erase a key from the map.
Z3_ast Z3_API Z3_mk_int2real(Z3_context c, Z3_ast t1)
Coerce an integer to a real.
unsigned Z3_API Z3_get_index_value(Z3_context c, Z3_ast a)
Return index of de-Bruijn bound variable.
Z3_goal Z3_API Z3_mk_goal(Z3_context c, bool models, bool unsat_cores, bool proofs)
Create a goal (aka problem). A goal is essentially a set of formulas, that can be solved and/or trans...
double Z3_API Z3_get_decl_double_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the double value associated with an double parameter.
unsigned Z3_API Z3_get_ast_hash(Z3_context c, Z3_ast a)
Return a hash code for the given AST. The hash code is structural but two different AST objects can m...
Z3_symbol Z3_API Z3_get_sort_name(Z3_context c, Z3_sort d)
Return the sort name as a symbol.
void Z3_API Z3_params_validate(Z3_context c, Z3_params p, Z3_param_descrs d)
Validate the parameter set p against the parameter description set d.
Z3_func_decl Z3_API Z3_get_datatype_sort_recognizer(Z3_context c, Z3_sort t, unsigned idx)
Return idx'th recognizer.
void Z3_API Z3_global_param_reset_all(void)
Restore the value of all global (and module) parameters. This command will not affect already created...
Z3_ast Z3_API Z3_mk_gt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create greater than.
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v)
Array update.
Z3_string Z3_API Z3_get_decl_rational_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the rational value, as a string, associated with a rational parameter.
void Z3_API Z3_ast_vector_push(Z3_context c, Z3_ast_vector v, Z3_ast a)
Add the AST a in the end of the AST vector v. The size of v is increased by one.
bool Z3_API Z3_is_eq_ast(Z3_context c, Z3_ast t1, Z3_ast t2)
Compare terms.
bool Z3_API Z3_is_quantifier_forall(Z3_context c, Z3_ast a)
Determine if an ast is a universal quantifier.
Z3_ast_map Z3_API Z3_mk_ast_map(Z3_context c)
Return an empty mapping from AST to AST.
Z3_ast Z3_API Z3_mk_xor(Z3_context c, Z3_ast t1, Z3_ast t2)
Create an AST node representing t1 xor t2.
Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const *args)
Map f on the argument arrays.
Z3_ast Z3_API Z3_mk_const(Z3_context c, Z3_symbol s, Z3_sort ty)
Declare and create a constant.
Z3_symbol Z3_API Z3_mk_string_symbol(Z3_context c, Z3_string s)
Create a Z3 symbol using a C string.
void Z3_API Z3_param_descrs_inc_ref(Z3_context c, Z3_param_descrs p)
Increment the reference counter of the given parameter description set.
void Z3_API Z3_stats_dec_ref(Z3_context c, Z3_stats s)
Decrement the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_array_ext(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create array extensionality index given two arrays with the same sort. The meaning is given by the ax...
Z3_ast Z3_API Z3_mk_re_concat(Z3_context c, unsigned n, Z3_ast const args[])
Create the concatenation of the regular languages.
Z3_ast Z3_API Z3_sort_to_ast(Z3_context c, Z3_sort s)
Convert a Z3_sort into Z3_ast. This is just type casting.
Z3_func_entry Z3_API Z3_func_interp_get_entry(Z3_context c, Z3_func_interp f, unsigned i)
Return a "point" of the given function interpretation. It represents the value of f in a particular p...
Z3_func_decl Z3_API Z3_mk_rec_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a recursive function.
unsigned Z3_API Z3_get_ast_id(Z3_context c, Z3_ast t)
Return a unique identifier for t. The identifier is unique up to structural equality....
Z3_ast Z3_API Z3_mk_concat(Z3_context c, Z3_ast t1, Z3_ast t2)
Concatenate the given bit-vectors.
unsigned Z3_API Z3_get_quantifier_num_bound(Z3_context c, Z3_ast a)
Return number of bound variables of quantifier.
Z3_sort Z3_API Z3_get_decl_sort_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the sort value associated with a sort parameter.
Z3_constructor_list Z3_API Z3_mk_constructor_list(Z3_context c, unsigned num_constructors, Z3_constructor const constructors[])
Create list of constructors.
Z3_ast Z3_API Z3_mk_app(Z3_context c, Z3_func_decl d, unsigned num_args, Z3_ast const args[])
Create a constant or function application.
Z3_sort_kind Z3_API Z3_get_sort_kind(Z3_context c, Z3_sort t)
Return the sort kind (e.g., array, tuple, int, bool, etc).
Z3_ast Z3_API Z3_mk_bvneg(Z3_context c, Z3_ast t1)
Standard two's complement unary minus.
Z3_ast Z3_API Z3_mk_store_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs, Z3_ast v)
n-ary Array update.
Z3_sort Z3_API Z3_get_domain(Z3_context c, Z3_func_decl d, unsigned i)
Return the sort of the i-th parameter of the given function declaration.
Z3_sort Z3_API Z3_mk_bool_sort(Z3_context c)
Create the Boolean type.
void Z3_API Z3_params_set_symbol(Z3_context c, Z3_params p, Z3_symbol k, Z3_symbol v)
Add a symbol parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_ast_vector_get(Z3_context c, Z3_ast_vector v, unsigned i)
Return the AST at position i in the AST vector v.
Z3_func_decl Z3_API Z3_to_func_decl(Z3_context c, Z3_ast a)
Convert an AST into a FUNC_DECL_AST. This is just type casting.
Z3_ast Z3_API Z3_mk_set_difference(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Take the set difference between two sets.
Z3_ast Z3_API Z3_mk_bvsdiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed division.
Z3_ast Z3_API Z3_mk_bvlshr(Z3_context c, Z3_ast t1, Z3_ast t2)
Logical shift right.
Z3_ast Z3_API Z3_get_decl_ast_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_pattern Z3_API Z3_get_quantifier_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th pattern.
void Z3_API Z3_goal_dec_ref(Z3_context c, Z3_goal g)
Decrement the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_not(Z3_context c, Z3_ast a)
Create an AST node representing not(a).
Z3_ast Z3_API Z3_mk_or(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] or ... or args[num_args-1].
Z3_sort Z3_API Z3_mk_array_sort(Z3_context c, Z3_sort domain, Z3_sort range)
Create an array type.
void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m)
Increment the reference counter of the given model.
Z3_ast Z3_API Z3_mk_seq_extract(Z3_context c, Z3_ast s, Z3_ast offset, Z3_ast length)
Extract subsequence starting at offset of length.
Z3_sort Z3_API Z3_mk_type_variable(Z3_context c, Z3_symbol s)
Create a type variable.
Z3_string Z3_API Z3_get_numeral_string(Z3_context c, Z3_ast a)
Return numeral value, as a decimal string of a numeric constant term.
void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value)
add a function entry to a function interpretation.
Z3_ast Z3_API Z3_mk_bvuge(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than or equal to.
Z3_string Z3_API Z3_get_numeral_binary_string(Z3_context c, Z3_ast a)
Return numeral value, as a binary string of a numeric constant term.
Z3_sort Z3_API Z3_get_quantifier_bound_sort(Z3_context c, Z3_ast a, unsigned i)
Return sort of the i'th bound variable.
void Z3_API Z3_disable_trace(Z3_string tag)
Disable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_goal_formula(Z3_context c, Z3_goal g, unsigned idx)
Return a formula from the given goal.
Z3_symbol Z3_API Z3_mk_int_symbol(Z3_context c, int i)
Create a Z3 symbol using an integer.
unsigned Z3_API Z3_func_interp_get_num_entries(Z3_context c, Z3_func_interp f)
Return the number of entries in the given function interpretation.
void Z3_API Z3_ast_map_insert(Z3_context c, Z3_ast_map m, Z3_ast k, Z3_ast v)
Store/Replace a new key, value pair in the given map.
Z3_string Z3_API Z3_goal_to_string(Z3_context c, Z3_goal g)
Convert a goal into a string.
bool Z3_API Z3_is_eq_sort(Z3_context c, Z3_sort s1, Z3_sort s2)
compare sorts.
void Z3_API Z3_del_config(Z3_config c)
Delete the given configuration object.
void Z3_API Z3_inc_ref(Z3_context c, Z3_ast a)
Increment the reference counter of the given AST. The context c should have been created using Z3_mk_...
Z3_ast Z3_API Z3_mk_real2int(Z3_context c, Z3_ast t1)
Coerce a real to an integer.
Z3_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f)
Return the interpretation of the function f in the model m. Return NULL, if the model does not assign...
void Z3_API Z3_solver_inc_ref(Z3_context c, Z3_solver s)
Increment the reference counter of the given solver.
Z3_symbol Z3_API Z3_get_quantifier_id(Z3_context c, Z3_ast a)
Obtain id of quantifier.
Z3_ast Z3_API Z3_mk_ext_rotate_right(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the right t2 times.
Z3_string Z3_API Z3_get_numeral_decimal_string(Z3_context c, Z3_ast a, unsigned precision)
Return numeral as a string in decimal notation. The result has at most precision decimal places.
Z3_sort Z3_API Z3_get_sort(Z3_context c, Z3_ast a)
Return the sort of an AST node.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(Z3_context c, Z3_sort t, unsigned idx_c, unsigned idx_a)
Return idx_a'th accessor for the idx_c'th constructor.
Z3_ast Z3_API Z3_mk_bvredor(Z3_context c, Z3_ast t1)
Take disjunction of bits in vector, return vector of length 1.
void Z3_API Z3_ast_map_reset(Z3_context c, Z3_ast_map m)
Remove all keys from the given map.
void Z3_API Z3_solver_reset(Z3_context c, Z3_solver s)
Remove all assertions from the solver.
bool Z3_API Z3_is_algebraic_number(Z3_context c, Z3_ast a)
Return true if the given AST is a real algebraic number.
_py2expr(a, ctx=None)
Definition z3py.py:3173
RotateRight(a, b)
Definition z3py.py:4393
_symbol2py(ctx, s)
Definition z3py.py:132
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4066
BVSNegNoOverflow(a)
Definition z3py.py:4540
SetAdd(s, e)
Definition z3py.py:5012
SetSort(s)
Sets.
Definition z3py.py:4963
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1220
UGT(a, b)
Definition z3py.py:4264
is_probe(p)
Definition z3py.py:8770
is_lt(a)
Definition z3py.py:2931
Var(idx, s)
Definition z3py.py:1488
SetDel(s, e)
Definition z3py.py:5023
BoolSort(ctx=None)
Definition z3py.py:1731
is_bv_sort(s)
Definition z3py.py:3522
_ctx_from_ast_args(*args)
Definition z3py.py:511
RatVal(a, b, ctx=None)
Definition z3py.py:3265
_to_func_decl_ref(a, ctx)
Definition z3py.py:923
SetUnion(*args)
Definition z3py.py:4986
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5083
BitVec(name, bv, ctx=None)
Definition z3py.py:4083
DeclareSort(name, ctx=None)
Definition z3py.py:695
EmptySet(s)
Definition z3py.py:4968
BVMulNoUnderflow(a, b)
Definition z3py.py:4554
CreateDatatypes(*ds)
Definition z3py.py:5204
is_func_decl(a)
Definition z3py.py:868
get_as_array_func(n)
Definition z3py.py:6745
Distinct(*args)
Definition z3py.py:1422
is_distinct(a)
Definition z3py.py:1719
RecAddDefinition(f, args, body)
Definition z3py.py:945
ToInt(a)
Definition z3py.py:3422
Implies(a, b, ctx=None)
Definition z3py.py:1825
UGE(a, b)
Definition z3py.py:4246
Model(ctx=None)
Definition z3py.py:6735
Ext(a, b)
Definition z3py.py:4914
_to_ast_array(args)
Definition z3py.py:523
_check_bv_args(a, b)
Definition z3py.py:4205
RealSort(ctx=None)
Definition z3py.py:3205
IsSubset(a, b)
Definition z3py.py:5066
DeclareTypeVar(name, ctx=None)
Definition z3py.py:723
_get_args_ast_list(args)
Definition z3py.py:158
_to_ref_array(ref, args)
Definition z3py.py:531
get_map_func(a)
Definition z3py.py:4722
_z3_check_cint_overflow(n, name)
Definition z3py.py:110
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5409
is_sort(s)
Definition z3py.py:647
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1248
is_select(a)
Definition z3py.py:4932
SignExt(n, a)
Definition z3py.py:4409
Int(name, ctx=None)
Definition z3py.py:3294
Bools(names, ctx=None)
Definition z3py.py:1780
_probe_and(args, ctx)
Definition z3py.py:8837
Int2BV(a, num_bits)
Definition z3py.py:4042
Lambda(vs, body)
Definition z3py.py:2311
_to_param_value(val)
Definition z3py.py:168
FreshFunction(*sig)
Definition z3py.py:904
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3375
BVRedOr(a)
Definition z3py.py:4498
is_true(a)
Definition z3py.py:1629
SRem(a, b)
Definition z3py.py:4324
is_le(a)
Definition z3py.py:2919
is_idiv(a)
Definition z3py.py:2895
set_option(*args, **kws)
Definition z3py.py:301
_ast_kind(ctx, a)
Definition z3py.py:491
is_bv(a)
Definition z3py.py:3990
SetDifference(a, b)
Definition z3py.py:5044
_get_ctx(ctx)
Definition z3py.py:260
BitVecs(names, bv, ctx=None)
Definition z3py.py:4107
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1796
is_mul(a)
Definition z3py.py:2854
_has_probe(args)
Definition z3py.py:1881
IsMember(e, s)
Definition z3py.py:5055
get_param(name)
Definition z3py.py:307
BVAddNoUnderflow(a, b)
Definition z3py.py:4512
deserialize(st)
Definition z3py.py:1137
Extract(high, low, a)
Definition z3py.py:4174
Function(name, *sig)
Definition z3py.py:881
get_version()
Definition z3py.py:92
FreshConst(sort, prefix="c")
Definition z3py.py:1482
ULT(a, b)
Definition z3py.py:4228
EnumSort(name, values, ctx=None)
Definition z3py.py:5433
_to_int_str(val)
Definition z3py.py:3222
is_algebraic_value(a)
Definition z3py.py:2828
is_bv_value(a)
Definition z3py.py:4004
BVSDivNoOverflow(a, b)
Definition z3py.py:4533
SetIntersect(*args)
Definition z3py.py:4999
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:8904
BV2Int(a, is_signed=False)
Definition z3py.py:4019
RealVar(idx, ctx=None)
Definition z3py.py:1503
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3333
is_div(a)
Definition z3py.py:2878
_to_ast_ref(a, ctx)
Definition z3py.py:539
_to_func_decl_array(args)
Definition z3py.py:515
disable_trace(msg)
Definition z3py.py:79
is_map(a)
Definition z3py.py:4697
is_not(a)
Definition z3py.py:1697
Or(*args)
Definition z3py.py:1922
is_re(s)
Definition z3py.py:11327
is_bool(a)
Definition z3py.py:1611
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5512
Consts(names, sort)
Definition z3py.py:1467
Cond(p, t1, t2, ctx=None)
Definition z3py.py:8887
is_mod(a)
Definition z3py.py:2907
_to_pattern(arg)
Definition z3py.py:2015
is_arith(a)
Definition z3py.py:2715
If(a, b, c, ctx=None)
Definition z3py.py:1399
is_app_of(a, k)
Definition z3py.py:1386
is_app(a)
Definition z3py.py:1283
_sort(ctx, a)
Definition z3py.py:691
z3_error_handler(c, e)
Definition z3py.py:174
Reals(names, ctx=None)
Definition z3py.py:3360
is_int_value(a)
Definition z3py.py:2782
set_param(*args, **kws)
Definition z3py.py:271
is_pattern(a)
Definition z3py.py:1973
is_add(a)
Definition z3py.py:2842
is_to_int(a)
Definition z3py.py:2994
_coerce_seq(s, ctx=None)
Definition z3py.py:11006
is_ge(a)
Definition z3py.py:2943
is_sub(a)
Definition z3py.py:2866
is_implies(a)
Definition z3py.py:1685
ULE(a, b)
Definition z3py.py:4210
is_real(a)
Definition z3py.py:2755
is_arith_sort(s)
Definition z3py.py:2414
FullSet(s)
Definition z3py.py:4977
to_symbol(s, ctx=None)
Definition z3py.py:124
is_array(a)
Definition z3py.py:4657
_get_args(args)
Definition z3py.py:144
And(*args)
Definition z3py.py:1889
RepeatBitVec(n, a)
Definition z3py.py:4467
SetHasSize(a, k)
Definition z3py.py:4926
is_to_real(a)
Definition z3py.py:2979
get_version_string()
Definition z3py.py:83
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3390
Array(name, *sorts)
Definition z3py.py:4779
Concat(*args)
Definition z3py.py:4128
_reduce(func, sequence, initial)
Definition z3py.py:1241
is_false(a)
Definition z3py.py:1647
_is_algebraic(ctx, a)
Definition z3py.py:2778
Ints(names, ctx=None)
Definition z3py.py:3307
Select(a, *args)
Definition z3py.py:4853
Const(name, sort)
Definition z3py.py:1455
is_array_sort(a)
Definition z3py.py:4653
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4505
is_int(a)
Definition z3py.py:2736
Real(name, ctx=None)
Definition z3py.py:3347
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1811
BitVecSort(sz, ctx=None)
Definition z3py.py:4051
open_log(fname)
Definition z3py.py:114
is_and(a)
Definition z3py.py:1661
RecFunction(name, *sig)
Definition z3py.py:927
get_ctx(ctx)
Definition z3py.py:267
BVSubNoOverflow(a, b)
Definition z3py.py:4519
is_default(a)
Definition z3py.py:4713
is_K(a)
Definition z3py.py:4684
Bool(name, ctx=None)
Definition z3py.py:1768
_is_int(v)
Definition z3py.py:68
is_const_array(a)
Definition z3py.py:4671
Sqrt(a, ctx=None)
Definition z3py.py:3457
main_ctx()
Definition z3py.py:239
Default(a)
Definition z3py.py:4825
is_is_int(a)
Definition z3py.py:2967
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:497
SetComplement(s)
Definition z3py.py:5034
is_as_array(n)
Definition z3py.py:6740
is_store(a)
Definition z3py.py:4945
eq(a, b)
Definition z3py.py:472
is_quantifier(a)
Definition z3py.py:2223
is_eq(a)
Definition z3py.py:1709
reset_params()
Definition z3py.py:295
_mk_bin(f, a, b)
Definition z3py.py:1446
K(dom, v)
Definition z3py.py:4892
Xor(a, b, ctx=None)
Definition z3py.py:1839
Store(a, *args)
Definition z3py.py:4836
mk_not(a)
Definition z3py.py:1874
is_expr(a)
Definition z3py.py:1260
_array_select(ar, arg)
Definition z3py.py:4644
is_or(a)
Definition z3py.py:1673
is_const(a)
Definition z3py.py:1309
BoolVal(val, ctx=None)
Definition z3py.py:1749
RealVal(val, ctx=None)
Definition z3py.py:3246
z3_debug()
Definition z3py.py:62
get_full_version()
Definition z3py.py:101
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3320
_coerce_expr_merge(s, a)
Definition z3py.py:1201
LShR(a, b)
Definition z3py.py:4345
RealVarVector(n, ctx=None)
Definition z3py.py:1514
ArraySort(*sig)
Definition z3py.py:4746
Map(f, *args)
Definition z3py.py:4869
is_rational_value(a)
Definition z3py.py:2806
_probe_or(args, ctx)
Definition z3py.py:8841
is_gt(a)
Definition z3py.py:2955
BVRedAnd(a)
Definition z3py.py:4491
Cbrt(a, ctx=None)
Definition z3py.py:3470
_to_expr_ref(a, ctx)
Definition z3py.py:1151
is_ast(a)
Definition z3py.py:451
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5421
IntSort(ctx=None)
Definition z3py.py:3188
is_seq(a)
Definition z3py.py:11027
Not(a, ctx=None)
Definition z3py.py:1855
_to_sort_ref(s, ctx)
Definition z3py.py:660
enable_trace(msg)
Definition z3py.py:75
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2290
ToReal(a)
Definition z3py.py:3404
URem(a, b)
Definition z3py.py:4303
StringVal(s, ctx=None)
Definition z3py.py:11054
IsInt(a)
Definition z3py.py:3440
_is_numeral(ctx, a)
Definition z3py.py:2774
MultiPattern(*args)
Definition z3py.py:1991
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2272
ZeroExt(n, a)
Definition z3py.py:4439
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:555
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4526
UDiv(a, b)
Definition z3py.py:4282
DatatypeSort(name, ctx=None)
Definition z3py.py:5404
Q(a, b, ctx=None)
Definition z3py.py:3281
Update(a, *args)
Definition z3py.py:4793
get_var_index(a)
Definition z3py.py:1353
append_log(s)
Definition z3py.py:119
is_var(a)
Definition z3py.py:1328
IntVal(val, ctx=None)
Definition z3py.py:3234
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4547
RotateLeft(a, b)
Definition z3py.py:4377
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2237
_z3_assert(cond, msg)
Definition z3py.py:105