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 def py_value(self):
451 """Return a Python value that is equivalent to `self`."""
452 return None
453
454
455def is_ast(a):
456 """Return `True` if `a` is an AST node.
457
458 >>> is_ast(10)
459 False
460 >>> is_ast(IntVal(10))
461 True
462 >>> is_ast(Int('x'))
463 True
464 >>> is_ast(BoolSort())
465 True
466 >>> is_ast(Function('f', IntSort(), IntSort()))
467 True
468 >>> is_ast("x")
469 False
470 >>> is_ast(Solver())
471 False
472 """
473 return isinstance(a, AstRef)
474
475
476def eq(a, b):
477 """Return `True` if `a` and `b` are structurally identical AST nodes.
478
479 >>> x = Int('x')
480 >>> y = Int('y')
481 >>> eq(x, y)
482 False
483 >>> eq(x + 1, x + 1)
484 True
485 >>> eq(x + 1, 1 + x)
486 False
487 >>> eq(simplify(x + 1), simplify(1 + x))
488 True
489 """
490 if z3_debug():
491 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
492 return a.eq(b)
493
494
495def _ast_kind(ctx, a):
496 if is_ast(a):
497 a = a.as_ast()
498 return Z3_get_ast_kind(ctx.ref(), a)
499
500
501def _ctx_from_ast_arg_list(args, default_ctx=None):
502 ctx = None
503 for a in args:
504 if is_ast(a) or is_probe(a):
505 if ctx is None:
506 ctx = a.ctx
507 else:
508 if z3_debug():
509 _z3_assert(ctx == a.ctx, "Context mismatch")
510 if ctx is None:
511 ctx = default_ctx
512 return ctx
513
514
516 return _ctx_from_ast_arg_list(args)
517
518
520 sz = len(args)
521 _args = (FuncDecl * sz)()
522 for i in range(sz):
523 _args[i] = args[i].as_func_decl()
524 return _args, sz
525
526
528 sz = len(args)
529 _args = (Ast * sz)()
530 for i in range(sz):
531 _args[i] = args[i].as_ast()
532 return _args, sz
533
534
535def _to_ref_array(ref, args):
536 sz = len(args)
537 _args = (ref * sz)()
538 for i in range(sz):
539 _args[i] = args[i].as_ast()
540 return _args, sz
541
542
543def _to_ast_ref(a, ctx):
544 k = _ast_kind(ctx, a)
545 if k == Z3_SORT_AST:
546 return _to_sort_ref(a, ctx)
547 elif k == Z3_FUNC_DECL_AST:
548 return _to_func_decl_ref(a, ctx)
549 else:
550 return _to_expr_ref(a, ctx)
551
552
553
558
559def _sort_kind(ctx, s):
560 return Z3_get_sort_kind(ctx.ref(), s)
561
562
564 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
565
566 def as_ast(self):
567 return Z3_sort_to_ast(self.ctx_ref(), self.ast)
568
569 def get_id(self):
570 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
571
572 def kind(self):
573 """Return the Z3 internal kind of a sort.
574 This method can be used to test if `self` is one of the Z3 builtin sorts.
575
576 >>> b = BoolSort()
577 >>> b.kind() == Z3_BOOL_SORT
578 True
579 >>> b.kind() == Z3_INT_SORT
580 False
581 >>> A = ArraySort(IntSort(), IntSort())
582 >>> A.kind() == Z3_ARRAY_SORT
583 True
584 >>> A.kind() == Z3_INT_SORT
585 False
586 """
587 return _sort_kind(self.ctx, self.ast)
588
589 def subsort(self, other):
590 """Return `True` if `self` is a subsort of `other`.
591
592 >>> IntSort().subsort(RealSort())
593 True
594 """
595 return False
596
597 def cast(self, val):
598 """Try to cast `val` as an element of sort `self`.
599
600 This method is used in Z3Py to convert Python objects such as integers,
601 floats, longs and strings into Z3 expressions.
602
603 >>> x = Int('x')
604 >>> RealSort().cast(x)
605 ToReal(x)
606 """
607 if z3_debug():
608 _z3_assert(is_expr(val), "Z3 expression expected")
609 _z3_assert(self.eq(val.sort()), "Sort mismatch")
610 return val
611
612 def name(self):
613 """Return the name (string) of sort `self`.
614
615 >>> BoolSort().name()
616 'Bool'
617 >>> ArraySort(IntSort(), IntSort()).name()
618 'Array'
619 """
620 return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
621
622 def __eq__(self, other):
623 """Return `True` if `self` and `other` are the same Z3 sort.
624
625 >>> p = Bool('p')
626 >>> p.sort() == BoolSort()
627 True
628 >>> p.sort() == IntSort()
629 False
630 """
631 if other is None:
632 return False
633 return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
634
635 def __ne__(self, other):
636 """Return `True` if `self` and `other` are not the same Z3 sort.
637
638 >>> p = Bool('p')
639 >>> p.sort() != BoolSort()
640 False
641 >>> p.sort() != IntSort()
642 True
643 """
644 return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
645
646 def __hash__(self):
647 """ Hash code. """
648 return AstRef.__hash__(self)
649
650
651def is_sort(s):
652 """Return `True` if `s` is a Z3 sort.
653
654 >>> is_sort(IntSort())
655 True
656 >>> is_sort(Int('x'))
657 False
658 >>> is_expr(Int('x'))
659 True
660 """
661 return isinstance(s, SortRef)
662
663
664def _to_sort_ref(s, ctx):
665 if z3_debug():
666 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
667 k = _sort_kind(ctx, s)
668 if k == Z3_BOOL_SORT:
669 return BoolSortRef(s, ctx)
670 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
671 return ArithSortRef(s, ctx)
672 elif k == Z3_BV_SORT:
673 return BitVecSortRef(s, ctx)
674 elif k == Z3_ARRAY_SORT:
675 return ArraySortRef(s, ctx)
676 elif k == Z3_DATATYPE_SORT:
677 return DatatypeSortRef(s, ctx)
678 elif k == Z3_FINITE_DOMAIN_SORT:
679 return FiniteDomainSortRef(s, ctx)
680 elif k == Z3_FLOATING_POINT_SORT:
681 return FPSortRef(s, ctx)
682 elif k == Z3_ROUNDING_MODE_SORT:
683 return FPRMSortRef(s, ctx)
684 elif k == Z3_RE_SORT:
685 return ReSortRef(s, ctx)
686 elif k == Z3_SEQ_SORT:
687 return SeqSortRef(s, ctx)
688 elif k == Z3_CHAR_SORT:
689 return CharSortRef(s, ctx)
690 elif k == Z3_TYPE_VAR:
691 return TypeVarRef(s, ctx)
692 return SortRef(s, ctx)
693
694
695def _sort(ctx, a):
696 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
697
698
699def DeclareSort(name, ctx=None):
700 """Create a new uninterpreted sort named `name`.
701
702 If `ctx=None`, then the new sort is declared in the global Z3Py context.
703
704 >>> A = DeclareSort('A')
705 >>> a = Const('a', A)
706 >>> b = Const('b', A)
707 >>> a.sort() == A
708 True
709 >>> b.sort() == A
710 True
711 >>> a == b
712 a == b
713 """
714 ctx = _get_ctx(ctx)
715 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
716
718 """Type variable reference"""
719
720 def subsort(self, other):
721 return True
722
723 def cast(self, val):
724 return val
725
726
727def DeclareTypeVar(name, ctx=None):
728 """Create a new type variable named `name`.
729
730 If `ctx=None`, then the new sort is declared in the global Z3Py context.
731
732 """
733 ctx = _get_ctx(ctx)
734 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
735
736
737
742
743
745 """Function declaration. Every constant and function have an associated declaration.
746
747 The declaration assigns a name, a sort (i.e., type), and for function
748 the sort (i.e., type) of each of its arguments. Note that, in Z3,
749 a constant is a function with 0 arguments.
750 """
751
752 def as_ast(self):
753 return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
754
755 def get_id(self):
756 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
757
758 def as_func_decl(self):
759 return self.ast
760
761 def name(self):
762 """Return the name of the function declaration `self`.
763
764 >>> f = Function('f', IntSort(), IntSort())
765 >>> f.name()
766 'f'
767 >>> isinstance(f.name(), str)
768 True
769 """
770 return _symbol2py(self.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
771
772 def arity(self):
773 """Return the number of arguments of a function declaration.
774 If `self` is a constant, then `self.arity()` is 0.
775
776 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
777 >>> f.arity()
778 2
779 """
780 return int(Z3_get_arity(self.ctx_ref(), self.ast))
781
782 def domain(self, i):
783 """Return the sort of the argument `i` of a function declaration.
784 This method assumes that `0 <= i < self.arity()`.
785
786 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
787 >>> f.domain(0)
788 Int
789 >>> f.domain(1)
790 Real
791 """
792 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
793
794 def range(self):
795 """Return the sort of the range of a function declaration.
796 For constants, this is the sort of the constant.
797
798 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
799 >>> f.range()
800 Bool
801 """
802 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.ast), self.ctx)
803
804 def kind(self):
805 """Return the internal kind of a function declaration.
806 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
807
808 >>> x = Int('x')
809 >>> d = (x + 1).decl()
810 >>> d.kind() == Z3_OP_ADD
811 True
812 >>> d.kind() == Z3_OP_MUL
813 False
814 """
815 return Z3_get_decl_kind(self.ctx_ref(), self.ast)
816
817 def params(self):
818 ctx = self.ctx
819 n = Z3_get_decl_num_parameters(self.ctx_ref(), self.ast)
820 result = [None for i in range(n)]
821 for i in range(n):
822 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.ast, i)
823 if k == Z3_PARAMETER_INT:
824 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.ast, i)
825 elif k == Z3_PARAMETER_DOUBLE:
826 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.ast, i)
827 elif k == Z3_PARAMETER_RATIONAL:
828 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.ast, i)
829 elif k == Z3_PARAMETER_SYMBOL:
830 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.ast, i)
831 elif k == Z3_PARAMETER_SORT:
832 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.ast, i), ctx)
833 elif k == Z3_PARAMETER_AST:
834 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.ast, i), ctx)
835 elif k == Z3_PARAMETER_FUNC_DECL:
836 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.ast, i), ctx)
837 elif k == Z3_PARAMETER_INTERNAL:
838 result[i] = "internal parameter"
839 elif k == Z3_PARAMETER_ZSTRING:
840 result[i] = "internal string"
841 else:
842 assert(False)
843 return result
844
845 def __call__(self, *args):
846 """Create a Z3 application expression using the function `self`, and the given arguments.
847
848 The arguments must be Z3 expressions. This method assumes that
849 the sorts of the elements in `args` match the sorts of the
850 domain. Limited coercion is supported. For example, if
851 args[0] is a Python integer, and the function expects a Z3
852 integer, then the argument is automatically converted into a
853 Z3 integer.
854
855 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
856 >>> x = Int('x')
857 >>> y = Real('y')
858 >>> f(x, y)
859 f(x, y)
860 >>> f(x, x)
861 f(x, ToReal(x))
862 """
863 args = _get_args(args)
864 num = len(args)
865 _args = (Ast * num)()
866 saved = []
867 for i in range(num):
868 # self.domain(i).cast(args[i]) may create a new Z3 expression,
869 # then we must save in 'saved' to prevent it from being garbage collected.
870 tmp = self.domain(i).cast(args[i])
871 saved.append(tmp)
872 _args[i] = tmp.as_ast()
873 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
874
875
877 """Return `True` if `a` is a Z3 function declaration.
878
879 >>> f = Function('f', IntSort(), IntSort())
880 >>> is_func_decl(f)
881 True
882 >>> x = Real('x')
883 >>> is_func_decl(x)
884 False
885 """
886 return isinstance(a, FuncDeclRef)
887
888
889def Function(name, *sig):
890 """Create a new Z3 uninterpreted function with the given sorts.
891
892 >>> f = Function('f', IntSort(), IntSort())
893 >>> f(f(0))
894 f(f(0))
895 """
896 sig = _get_args(sig)
897 if z3_debug():
898 _z3_assert(len(sig) > 0, "At least two arguments expected")
899 arity = len(sig) - 1
900 rng = sig[arity]
901 if z3_debug():
902 _z3_assert(is_sort(rng), "Z3 sort expected")
903 dom = (Sort * arity)()
904 for i in range(arity):
905 if z3_debug():
906 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
907 dom[i] = sig[i].ast
908 ctx = rng.ctx
909 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
910
911
913 """Create a new fresh Z3 uninterpreted function with the given sorts.
914 """
915 sig = _get_args(sig)
916 if z3_debug():
917 _z3_assert(len(sig) > 0, "At least two arguments expected")
918 arity = len(sig) - 1
919 rng = sig[arity]
920 if z3_debug():
921 _z3_assert(is_sort(rng), "Z3 sort expected")
922 dom = (z3.Sort * arity)()
923 for i in range(arity):
924 if z3_debug():
925 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
926 dom[i] = sig[i].ast
927 ctx = rng.ctx
928 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
929
930
932 return FuncDeclRef(a, ctx)
933
934
935def RecFunction(name, *sig):
936 """Create a new Z3 recursive with the given sorts."""
937 sig = _get_args(sig)
938 if z3_debug():
939 _z3_assert(len(sig) > 0, "At least two arguments expected")
940 arity = len(sig) - 1
941 rng = sig[arity]
942 if z3_debug():
943 _z3_assert(is_sort(rng), "Z3 sort expected")
944 dom = (Sort * arity)()
945 for i in range(arity):
946 if z3_debug():
947 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
948 dom[i] = sig[i].ast
949 ctx = rng.ctx
950 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
951
952
953def RecAddDefinition(f, args, body):
954 """Set the body of a recursive function.
955 Recursive definitions can be simplified if they are applied to ground
956 arguments.
957 >>> ctx = Context()
958 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
959 >>> n = Int('n', ctx)
960 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
961 >>> simplify(fac(5))
962 120
963 >>> s = Solver(ctx=ctx)
964 >>> s.add(fac(n) < 3)
965 >>> s.check()
966 sat
967 >>> s.model().eval(fac(5))
968 120
969 """
970 if is_app(args):
971 args = [args]
972 ctx = body.ctx
973 args = _get_args(args)
974 n = len(args)
975 _args = (Ast * n)()
976 for i in range(n):
977 _args[i] = args[i].ast
978 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
979
980
985
986
988 """Constraints, formulas and terms are expressions in Z3.
989
990 Expressions are ASTs. Every expression has a sort.
991 There are three main kinds of expressions:
992 function applications, quantifiers and bounded variables.
993 A constant is a function application with 0 arguments.
994 For quantifier free problems, all expressions are
995 function applications.
996 """
997
998 def as_ast(self):
999 return self.ast
1000
1001 def get_id(self):
1002 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1003
1004 def sort(self):
1005 """Return the sort of expression `self`.
1006
1007 >>> x = Int('x')
1008 >>> (x + 1).sort()
1009 Int
1010 >>> y = Real('y')
1011 >>> (x + y).sort()
1012 Real
1013 """
1014 return _sort(self.ctx, self.as_ast())
1015
1016 def sort_kind(self):
1017 """Shorthand for `self.sort().kind()`.
1018
1019 >>> a = Array('a', IntSort(), IntSort())
1020 >>> a.sort_kind() == Z3_ARRAY_SORT
1021 True
1022 >>> a.sort_kind() == Z3_INT_SORT
1023 False
1024 """
1025 return self.sort().kind()
1026
1027 def __eq__(self, other):
1028 """Return a Z3 expression that represents the constraint `self == other`.
1029
1030 If `other` is `None`, then this method simply returns `False`.
1031
1032 >>> a = Int('a')
1033 >>> b = Int('b')
1034 >>> a == b
1035 a == b
1036 >>> a is None
1037 False
1038 """
1039 if other is None:
1040 return False
1041 a, b = _coerce_exprs(self, other)
1042 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
1043
1044 def __hash__(self):
1045 """ Hash code. """
1046 return AstRef.__hash__(self)
1047
1048 def __ne__(self, other):
1049 """Return a Z3 expression that represents the constraint `self != other`.
1050
1051 If `other` is `None`, then this method simply returns `True`.
1052
1053 >>> a = Int('a')
1054 >>> b = Int('b')
1055 >>> a != b
1056 a != b
1057 >>> a is not None
1058 True
1059 """
1060 if other is None:
1061 return True
1062 a, b = _coerce_exprs(self, other)
1063 _args, sz = _to_ast_array((a, b))
1064 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
1065
1066 def params(self):
1067 return self.decl().params()
1068
1069 def decl(self):
1070 """Return the Z3 function declaration associated with a Z3 application.
1071
1072 >>> f = Function('f', IntSort(), IntSort())
1073 >>> a = Int('a')
1074 >>> t = f(a)
1075 >>> eq(t.decl(), f)
1076 True
1077 >>> (a + 1).decl()
1078 +
1079 """
1080 if z3_debug():
1081 _z3_assert(is_app(self), "Z3 application expected")
1082 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_ast()), self.ctx)
1083
1084 def kind(self):
1085 """Return the Z3 internal kind of a function application."""
1086 if z3_debug():
1087 _z3_assert(is_app(self), "Z3 application expected")
1089
1090
1091 def num_args(self):
1092 """Return the number of arguments of a Z3 application.
1093
1094 >>> a = Int('a')
1095 >>> b = Int('b')
1096 >>> (a + b).num_args()
1097 2
1098 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1099 >>> t = f(a, b, 0)
1100 >>> t.num_args()
1101 3
1102 """
1103 if z3_debug():
1104 _z3_assert(is_app(self), "Z3 application expected")
1105 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_ast()))
1106
1107 def arg(self, idx):
1108 """Return argument `idx` of the application `self`.
1109
1110 This method assumes that `self` is a function application with at least `idx+1` arguments.
1111
1112 >>> a = Int('a')
1113 >>> b = Int('b')
1114 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1115 >>> t = f(a, b, 0)
1116 >>> t.arg(0)
1117 a
1118 >>> t.arg(1)
1119 b
1120 >>> t.arg(2)
1121 0
1122 """
1123 if z3_debug():
1124 _z3_assert(is_app(self), "Z3 application expected")
1125 _z3_assert(idx < self.num_args(), "Invalid argument index")
1126 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_ast(), idx), self.ctx)
1127
1128 def children(self):
1129 """Return a list containing the children of the given expression
1130
1131 >>> a = Int('a')
1132 >>> b = Int('b')
1133 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1134 >>> t = f(a, b, 0)
1135 >>> t.children()
1136 [a, b, 0]
1137 """
1138 if is_app(self):
1139 return [self.arg(i) for i in range(self.num_args())]
1140 else:
1141 return []
1142
1143 def from_string(self, s):
1144 pass
1145
1146 def serialize(self):
1147 s = Solver()
1148 f = Function('F', self.sort(), BoolSort(self.ctx))
1149 s.add(f(self))
1150 return s.sexpr()
1151
1153 """inverse function to the serialize method on ExprRef.
1154 It is made available to make it easier for users to serialize expressions back and forth between
1155 strings. Solvers can be serialized using the 'sexpr()' method.
1156 """
1157 s = Solver()
1158 s.from_string(st)
1159 if len(s.assertions()) != 1:
1160 raise Z3Exception("single assertion expected")
1161 fml = s.assertions()[0]
1162 if fml.num_args() != 1:
1163 raise Z3Exception("dummy function 'F' expected")
1164 return fml.arg(0)
1165
1166def _to_expr_ref(a, ctx):
1167 if isinstance(a, Pattern):
1168 return PatternRef(a, ctx)
1169 ctx_ref = ctx.ref()
1170 k = Z3_get_ast_kind(ctx_ref, a)
1171 if k == Z3_QUANTIFIER_AST:
1172 return QuantifierRef(a, ctx)
1173 sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1174 if sk == Z3_BOOL_SORT:
1175 return BoolRef(a, ctx)
1176 if sk == Z3_INT_SORT:
1177 if k == Z3_NUMERAL_AST:
1178 return IntNumRef(a, ctx)
1179 return ArithRef(a, ctx)
1180 if sk == Z3_REAL_SORT:
1181 if k == Z3_NUMERAL_AST:
1182 return RatNumRef(a, ctx)
1183 if _is_algebraic(ctx, a):
1184 return AlgebraicNumRef(a, ctx)
1185 return ArithRef(a, ctx)
1186 if sk == Z3_BV_SORT:
1187 if k == Z3_NUMERAL_AST:
1188 return BitVecNumRef(a, ctx)
1189 else:
1190 return BitVecRef(a, ctx)
1191 if sk == Z3_ARRAY_SORT:
1192 return ArrayRef(a, ctx)
1193 if sk == Z3_DATATYPE_SORT:
1194 return DatatypeRef(a, ctx)
1195 if sk == Z3_FLOATING_POINT_SORT:
1196 if k == Z3_APP_AST and _is_numeral(ctx, a):
1197 return FPNumRef(a, ctx)
1198 else:
1199 return FPRef(a, ctx)
1200 if sk == Z3_FINITE_DOMAIN_SORT:
1201 if k == Z3_NUMERAL_AST:
1202 return FiniteDomainNumRef(a, ctx)
1203 else:
1204 return FiniteDomainRef(a, ctx)
1205 if sk == Z3_ROUNDING_MODE_SORT:
1206 return FPRMRef(a, ctx)
1207 if sk == Z3_SEQ_SORT:
1208 return SeqRef(a, ctx)
1209 if sk == Z3_CHAR_SORT:
1210 return CharRef(a, ctx)
1211 if sk == Z3_RE_SORT:
1212 return ReRef(a, ctx)
1213 return ExprRef(a, ctx)
1214
1215
1217 if is_expr(a):
1218 s1 = a.sort()
1219 if s is None:
1220 return s1
1221 if s1.eq(s):
1222 return s
1223 elif s.subsort(s1):
1224 return s1
1225 elif s1.subsort(s):
1226 return s
1227 else:
1228 if z3_debug():
1229 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1230 _z3_assert(False, "sort mismatch")
1231 else:
1232 return s
1233
1234
1235def _coerce_exprs(a, b, ctx=None):
1236 if not is_expr(a) and not is_expr(b):
1237 a = _py2expr(a, ctx)
1238 b = _py2expr(b, ctx)
1239 if isinstance(a, str) and isinstance(b, SeqRef):
1240 a = StringVal(a, b.ctx)
1241 if isinstance(b, str) and isinstance(a, SeqRef):
1242 b = StringVal(b, a.ctx)
1243 if isinstance(a, float) and isinstance(b, ArithRef):
1244 a = RealVal(a, b.ctx)
1245 if isinstance(b, float) and isinstance(a, ArithRef):
1246 b = RealVal(b, a.ctx)
1247
1248 s = None
1249 s = _coerce_expr_merge(s, a)
1250 s = _coerce_expr_merge(s, b)
1251 a = s.cast(a)
1252 b = s.cast(b)
1253 return (a, b)
1254
1255
1256def _reduce(func, sequence, initial):
1257 result = initial
1258 for element in sequence:
1259 result = func(result, element)
1260 return result
1261
1262
1263def _coerce_expr_list(alist, ctx=None):
1264 has_expr = False
1265 for a in alist:
1266 if is_expr(a):
1267 has_expr = True
1268 break
1269 if not has_expr:
1270 alist = [_py2expr(a, ctx) for a in alist]
1271 s = _reduce(_coerce_expr_merge, alist, None)
1272 return [s.cast(a) for a in alist]
1273
1274
1275def is_expr(a):
1276 """Return `True` if `a` is a Z3 expression.
1277
1278 >>> a = Int('a')
1279 >>> is_expr(a)
1280 True
1281 >>> is_expr(a + 1)
1282 True
1283 >>> is_expr(IntSort())
1284 False
1285 >>> is_expr(1)
1286 False
1287 >>> is_expr(IntVal(1))
1288 True
1289 >>> x = Int('x')
1290 >>> is_expr(ForAll(x, x >= 0))
1291 True
1292 >>> is_expr(FPVal(1.0))
1293 True
1294 """
1295 return isinstance(a, ExprRef)
1296
1297
1298def is_app(a):
1299 """Return `True` if `a` is a Z3 function application.
1300
1301 Note that, constants are function applications with 0 arguments.
1302
1303 >>> a = Int('a')
1304 >>> is_app(a)
1305 True
1306 >>> is_app(a + 1)
1307 True
1308 >>> is_app(IntSort())
1309 False
1310 >>> is_app(1)
1311 False
1312 >>> is_app(IntVal(1))
1313 True
1314 >>> x = Int('x')
1315 >>> is_app(ForAll(x, x >= 0))
1316 False
1317 """
1318 if not isinstance(a, ExprRef):
1319 return False
1320 k = _ast_kind(a.ctx, a)
1321 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1322
1323
1325 """Return `True` if `a` is Z3 constant/variable expression.
1326
1327 >>> a = Int('a')
1328 >>> is_const(a)
1329 True
1330 >>> is_const(a + 1)
1331 False
1332 >>> is_const(1)
1333 False
1334 >>> is_const(IntVal(1))
1335 True
1336 >>> x = Int('x')
1337 >>> is_const(ForAll(x, x >= 0))
1338 False
1339 """
1340 return is_app(a) and a.num_args() == 0
1341
1342
1343def is_var(a):
1344 """Return `True` if `a` is variable.
1345
1346 Z3 uses de-Bruijn indices for representing bound variables in
1347 quantifiers.
1348
1349 >>> x = Int('x')
1350 >>> is_var(x)
1351 False
1352 >>> is_const(x)
1353 True
1354 >>> f = Function('f', IntSort(), IntSort())
1355 >>> # Z3 replaces x with bound variables when ForAll is executed.
1356 >>> q = ForAll(x, f(x) == x)
1357 >>> b = q.body()
1358 >>> b
1359 f(Var(0)) == Var(0)
1360 >>> b.arg(1)
1361 Var(0)
1362 >>> is_var(b.arg(1))
1363 True
1364 """
1365 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1366
1367
1369 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1370
1371 >>> x = Int('x')
1372 >>> y = Int('y')
1373 >>> is_var(x)
1374 False
1375 >>> is_const(x)
1376 True
1377 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1378 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1379 >>> q = ForAll([x, y], f(x, y) == x + y)
1380 >>> q.body()
1381 f(Var(1), Var(0)) == Var(1) + Var(0)
1382 >>> b = q.body()
1383 >>> b.arg(0)
1384 f(Var(1), Var(0))
1385 >>> v1 = b.arg(0).arg(0)
1386 >>> v2 = b.arg(0).arg(1)
1387 >>> v1
1388 Var(1)
1389 >>> v2
1390 Var(0)
1391 >>> get_var_index(v1)
1392 1
1393 >>> get_var_index(v2)
1394 0
1395 """
1396 if z3_debug():
1397 _z3_assert(is_var(a), "Z3 bound variable expected")
1398 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1399
1400
1401def is_app_of(a, k):
1402 """Return `True` if `a` is an application of the given kind `k`.
1403
1404 >>> x = Int('x')
1405 >>> n = x + 1
1406 >>> is_app_of(n, Z3_OP_ADD)
1407 True
1408 >>> is_app_of(n, Z3_OP_MUL)
1409 False
1410 """
1411 return is_app(a) and a.kind() == k
1412
1413
1414def If(a, b, c, ctx=None):
1415 """Create a Z3 if-then-else expression.
1416
1417 >>> x = Int('x')
1418 >>> y = Int('y')
1419 >>> max = If(x > y, x, y)
1420 >>> max
1421 If(x > y, x, y)
1422 >>> simplify(max)
1423 If(x <= y, y, x)
1424 """
1425 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1426 return Cond(a, b, c, ctx)
1427 else:
1428 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1429 s = BoolSort(ctx)
1430 a = s.cast(a)
1431 b, c = _coerce_exprs(b, c, ctx)
1432 if z3_debug():
1433 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1434 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1435
1436
1437def Distinct(*args):
1438 """Create a Z3 distinct expression.
1439
1440 >>> x = Int('x')
1441 >>> y = Int('y')
1442 >>> Distinct(x, y)
1443 x != y
1444 >>> z = Int('z')
1445 >>> Distinct(x, y, z)
1446 Distinct(x, y, z)
1447 >>> simplify(Distinct(x, y, z))
1448 Distinct(x, y, z)
1449 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1450 And(Not(x == y), Not(x == z), Not(y == z))
1451 """
1452 args = _get_args(args)
1453 ctx = _ctx_from_ast_arg_list(args)
1454 if z3_debug():
1455 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1456 args = _coerce_expr_list(args, ctx)
1457 _args, sz = _to_ast_array(args)
1458 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1459
1460
1461def _mk_bin(f, a, b):
1462 args = (Ast * 2)()
1463 if z3_debug():
1464 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1465 args[0] = a.as_ast()
1466 args[1] = b.as_ast()
1467 return f(a.ctx.ref(), 2, args)
1468
1469
1470def Const(name, sort):
1471 """Create a constant of the given sort.
1472
1473 >>> Const('x', IntSort())
1474 x
1475 """
1476 if z3_debug():
1477 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1478 ctx = sort.ctx
1479 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1480
1481
1482def Consts(names, sort):
1483 """Create several constants of the given sort.
1484
1485 `names` is a string containing the names of all constants to be created.
1486 Blank spaces separate the names of different constants.
1487
1488 >>> x, y, z = Consts('x y z', IntSort())
1489 >>> x + y + z
1490 x + y + z
1491 """
1492 if isinstance(names, str):
1493 names = names.split(" ")
1494 return [Const(name, sort) for name in names]
1495
1496
1497def FreshConst(sort, prefix="c"):
1498 """Create a fresh constant of a specified sort"""
1499 ctx = _get_ctx(sort.ctx)
1500 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1501
1502
1503def Var(idx, s):
1504 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1505 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1506 declarations.
1507
1508 >>> Var(0, IntSort())
1509 Var(0)
1510 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1511 False
1512 """
1513 if z3_debug():
1514 _z3_assert(is_sort(s), "Z3 sort expected")
1515 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1516
1517
1518def RealVar(idx, ctx=None):
1519 """
1520 Create a real free variable. Free variables are used to create quantified formulas.
1521 They are also used to create polynomials.
1522
1523 >>> RealVar(0)
1524 Var(0)
1525 """
1526 return Var(idx, RealSort(ctx))
1527
1528
1529def RealVarVector(n, ctx=None):
1530 """
1531 Create a list of Real free variables.
1532 The variables have ids: 0, 1, ..., n-1
1533
1534 >>> x0, x1, x2, x3 = RealVarVector(4)
1535 >>> x2
1536 Var(2)
1537 """
1538 return [RealVar(i, ctx) for i in range(n)]
1539
1540
1545
1546
1548 """Boolean sort."""
1549
1550 def cast(self, val):
1551 """Try to cast `val` as a Boolean.
1552
1553 >>> x = BoolSort().cast(True)
1554 >>> x
1555 True
1556 >>> is_expr(x)
1557 True
1558 >>> is_expr(True)
1559 False
1560 >>> x.sort()
1561 Bool
1562 """
1563 if isinstance(val, bool):
1564 return BoolVal(val, self.ctx)
1565 if z3_debug():
1566 if not is_expr(val):
1567 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1568 _z3_assert(is_expr(val), msg % (val, type(val)))
1569 if not self.eq(val.sort()):
1570 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1571 return val
1572
1573 def subsort(self, other):
1574 return isinstance(other, ArithSortRef)
1575
1576 def is_int(self):
1577 return True
1578
1579 def is_bool(self):
1580 return True
1581
1582
1584 """All Boolean expressions are instances of this class."""
1585
1586 def sort(self):
1587 return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
1588
1589 def __add__(self, other):
1590 if isinstance(other, BoolRef):
1591 other = If(other, 1, 0)
1592 return If(self, 1, 0) + other
1593
1594 def __radd__(self, other):
1595 return self + other
1596
1597 def __rmul__(self, other):
1598 return self * other
1599
1600 def __mul__(self, other):
1601 """Create the Z3 expression `self * other`.
1602 """
1603 if isinstance(other, int) and other == 1:
1604 return If(self, 1, 0)
1605 if isinstance(other, int) and other == 0:
1606 return IntVal(0, self.ctx)
1607 if isinstance(other, BoolRef):
1608 other = If(other, 1, 0)
1609 return If(self, other, 0)
1610
1611 def __and__(self, other):
1612 return And(self, other)
1613
1614 def __or__(self, other):
1615 return Or(self, other)
1616
1617 def __xor__(self, other):
1618 return Xor(self, other)
1619
1620 def __invert__(self):
1621 return Not(self)
1622
1623 def py_value(self):
1624 if is_true(self):
1625 return True
1626 if is_false(self):
1627 return False
1628 return None
1629
1630
1631
1632
1633def is_bool(a):
1634 """Return `True` if `a` is a Z3 Boolean expression.
1635
1636 >>> p = Bool('p')
1637 >>> is_bool(p)
1638 True
1639 >>> q = Bool('q')
1640 >>> is_bool(And(p, q))
1641 True
1642 >>> x = Real('x')
1643 >>> is_bool(x)
1644 False
1645 >>> is_bool(x == 0)
1646 True
1647 """
1648 return isinstance(a, BoolRef)
1649
1650
1651def is_true(a):
1652 """Return `True` if `a` is the Z3 true expression.
1653
1654 >>> p = Bool('p')
1655 >>> is_true(p)
1656 False
1657 >>> is_true(simplify(p == p))
1658 True
1659 >>> x = Real('x')
1660 >>> is_true(x == 0)
1661 False
1662 >>> # True is a Python Boolean expression
1663 >>> is_true(True)
1664 False
1665 """
1666 return is_app_of(a, Z3_OP_TRUE)
1667
1668
1670 """Return `True` if `a` is the Z3 false expression.
1671
1672 >>> p = Bool('p')
1673 >>> is_false(p)
1674 False
1675 >>> is_false(False)
1676 False
1677 >>> is_false(BoolVal(False))
1678 True
1679 """
1680 return is_app_of(a, Z3_OP_FALSE)
1681
1682
1683def is_and(a):
1684 """Return `True` if `a` is a Z3 and expression.
1685
1686 >>> p, q = Bools('p q')
1687 >>> is_and(And(p, q))
1688 True
1689 >>> is_and(Or(p, q))
1690 False
1691 """
1692 return is_app_of(a, Z3_OP_AND)
1693
1694
1695def is_or(a):
1696 """Return `True` if `a` is a Z3 or expression.
1697
1698 >>> p, q = Bools('p q')
1699 >>> is_or(Or(p, q))
1700 True
1701 >>> is_or(And(p, q))
1702 False
1703 """
1704 return is_app_of(a, Z3_OP_OR)
1705
1706
1708 """Return `True` if `a` is a Z3 implication expression.
1709
1710 >>> p, q = Bools('p q')
1711 >>> is_implies(Implies(p, q))
1712 True
1713 >>> is_implies(And(p, q))
1714 False
1715 """
1716 return is_app_of(a, Z3_OP_IMPLIES)
1717
1718
1719def is_not(a):
1720 """Return `True` if `a` is a Z3 not expression.
1721
1722 >>> p = Bool('p')
1723 >>> is_not(p)
1724 False
1725 >>> is_not(Not(p))
1726 True
1727 """
1728 return is_app_of(a, Z3_OP_NOT)
1729
1730
1731def is_eq(a):
1732 """Return `True` if `a` is a Z3 equality expression.
1733
1734 >>> x, y = Ints('x y')
1735 >>> is_eq(x == y)
1736 True
1737 """
1738 return is_app_of(a, Z3_OP_EQ)
1739
1740
1742 """Return `True` if `a` is a Z3 distinct expression.
1743
1744 >>> x, y, z = Ints('x y z')
1745 >>> is_distinct(x == y)
1746 False
1747 >>> is_distinct(Distinct(x, y, z))
1748 True
1749 """
1750 return is_app_of(a, Z3_OP_DISTINCT)
1751
1752
1753def BoolSort(ctx=None):
1754 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1755
1756 >>> BoolSort()
1757 Bool
1758 >>> p = Const('p', BoolSort())
1759 >>> is_bool(p)
1760 True
1761 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1762 >>> r(0, 1)
1763 r(0, 1)
1764 >>> is_bool(r(0, 1))
1765 True
1766 """
1767 ctx = _get_ctx(ctx)
1768 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1769
1770
1771def BoolVal(val, ctx=None):
1772 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1773
1774 >>> BoolVal(True)
1775 True
1776 >>> is_true(BoolVal(True))
1777 True
1778 >>> is_true(True)
1779 False
1780 >>> is_false(BoolVal(False))
1781 True
1782 """
1783 ctx = _get_ctx(ctx)
1784 if val:
1785 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1786 else:
1787 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1788
1789
1790def Bool(name, ctx=None):
1791 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1792
1793 >>> p = Bool('p')
1794 >>> q = Bool('q')
1795 >>> And(p, q)
1796 And(p, q)
1797 """
1798 ctx = _get_ctx(ctx)
1799 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1800
1801
1802def Bools(names, ctx=None):
1803 """Return a tuple of Boolean constants.
1804
1805 `names` is a single string containing all names separated by blank spaces.
1806 If `ctx=None`, then the global context is used.
1807
1808 >>> p, q, r = Bools('p q r')
1809 >>> And(p, Or(q, r))
1810 And(p, Or(q, r))
1811 """
1812 ctx = _get_ctx(ctx)
1813 if isinstance(names, str):
1814 names = names.split(" ")
1815 return [Bool(name, ctx) for name in names]
1816
1817
1818def BoolVector(prefix, sz, ctx=None):
1819 """Return a list of Boolean constants of size `sz`.
1820
1821 The constants are named using the given prefix.
1822 If `ctx=None`, then the global context is used.
1823
1824 >>> P = BoolVector('p', 3)
1825 >>> P
1826 [p__0, p__1, p__2]
1827 >>> And(P)
1828 And(p__0, p__1, p__2)
1829 """
1830 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1831
1832
1833def FreshBool(prefix="b", ctx=None):
1834 """Return a fresh Boolean constant in the given context using the given prefix.
1835
1836 If `ctx=None`, then the global context is used.
1837
1838 >>> b1 = FreshBool()
1839 >>> b2 = FreshBool()
1840 >>> eq(b1, b2)
1841 False
1842 """
1843 ctx = _get_ctx(ctx)
1844 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1845
1846
1847def Implies(a, b, ctx=None):
1848 """Create a Z3 implies expression.
1849
1850 >>> p, q = Bools('p q')
1851 >>> Implies(p, q)
1852 Implies(p, q)
1853 """
1854 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1855 s = BoolSort(ctx)
1856 a = s.cast(a)
1857 b = s.cast(b)
1858 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1859
1860
1861def Xor(a, b, ctx=None):
1862 """Create a Z3 Xor expression.
1863
1864 >>> p, q = Bools('p q')
1865 >>> Xor(p, q)
1866 Xor(p, q)
1867 >>> simplify(Xor(p, q))
1868 Not(p == q)
1869 """
1870 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1871 s = BoolSort(ctx)
1872 a = s.cast(a)
1873 b = s.cast(b)
1874 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1875
1876
1877def Not(a, ctx=None):
1878 """Create a Z3 not expression or probe.
1879
1880 >>> p = Bool('p')
1881 >>> Not(Not(p))
1882 Not(Not(p))
1883 >>> simplify(Not(Not(p)))
1884 p
1885 """
1886 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1887 if is_probe(a):
1888 # Not is also used to build probes
1889 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1890 else:
1891 s = BoolSort(ctx)
1892 a = s.cast(a)
1893 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1894
1895
1896def mk_not(a):
1897 if is_not(a):
1898 return a.arg(0)
1899 else:
1900 return Not(a)
1901
1902
1903def _has_probe(args):
1904 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1905 for arg in args:
1906 if is_probe(arg):
1907 return True
1908 return False
1909
1910
1911def And(*args):
1912 """Create a Z3 and-expression or and-probe.
1913
1914 >>> p, q, r = Bools('p q r')
1915 >>> And(p, q, r)
1916 And(p, q, r)
1917 >>> P = BoolVector('p', 5)
1918 >>> And(P)
1919 And(p__0, p__1, p__2, p__3, p__4)
1920 """
1921 last_arg = None
1922 if len(args) > 0:
1923 last_arg = args[len(args) - 1]
1924 if isinstance(last_arg, Context):
1925 ctx = args[len(args) - 1]
1926 args = args[:len(args) - 1]
1927 elif len(args) == 1 and isinstance(args[0], AstVector):
1928 ctx = args[0].ctx
1929 args = [a for a in args[0]]
1930 else:
1931 ctx = None
1932 args = _get_args(args)
1933 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1934 if z3_debug():
1935 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1936 if _has_probe(args):
1937 return _probe_and(args, ctx)
1938 else:
1939 args = _coerce_expr_list(args, ctx)
1940 _args, sz = _to_ast_array(args)
1941 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
1942
1943
1944def Or(*args):
1945 """Create a Z3 or-expression or or-probe.
1946
1947 >>> p, q, r = Bools('p q r')
1948 >>> Or(p, q, r)
1949 Or(p, q, r)
1950 >>> P = BoolVector('p', 5)
1951 >>> Or(P)
1952 Or(p__0, p__1, p__2, p__3, p__4)
1953 """
1954 last_arg = None
1955 if len(args) > 0:
1956 last_arg = args[len(args) - 1]
1957 if isinstance(last_arg, Context):
1958 ctx = args[len(args) - 1]
1959 args = args[:len(args) - 1]
1960 elif len(args) == 1 and isinstance(args[0], AstVector):
1961 ctx = args[0].ctx
1962 args = [a for a in args[0]]
1963 else:
1964 ctx = None
1965 args = _get_args(args)
1966 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1967 if z3_debug():
1968 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1969 if _has_probe(args):
1970 return _probe_or(args, ctx)
1971 else:
1972 args = _coerce_expr_list(args, ctx)
1973 _args, sz = _to_ast_array(args)
1974 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
1975
1976
1981
1982
1984 """Patterns are hints for quantifier instantiation.
1985
1986 """
1987
1988 def as_ast(self):
1989 return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
1990
1991 def get_id(self):
1992 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1993
1994
1996 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
1997
1998 >>> f = Function('f', IntSort(), IntSort())
1999 >>> x = Int('x')
2000 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
2001 >>> q
2002 ForAll(x, f(x) == 0)
2003 >>> q.num_patterns()
2004 1
2005 >>> is_pattern(q.pattern(0))
2006 True
2007 >>> q.pattern(0)
2008 f(Var(0))
2009 """
2010 return isinstance(a, PatternRef)
2011
2012
2013def MultiPattern(*args):
2014 """Create a Z3 multi-pattern using the given expressions `*args`
2015
2016 >>> f = Function('f', IntSort(), IntSort())
2017 >>> g = Function('g', IntSort(), IntSort())
2018 >>> x = Int('x')
2019 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2020 >>> q
2021 ForAll(x, f(x) != g(x))
2022 >>> q.num_patterns()
2023 1
2024 >>> is_pattern(q.pattern(0))
2025 True
2026 >>> q.pattern(0)
2027 MultiPattern(f(Var(0)), g(Var(0)))
2028 """
2029 if z3_debug():
2030 _z3_assert(len(args) > 0, "At least one argument expected")
2031 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2032 ctx = args[0].ctx
2033 args, sz = _to_ast_array(args)
2034 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2035
2036
2038 if is_pattern(arg):
2039 return arg
2040 else:
2041 return MultiPattern(arg)
2042
2043
2048
2049
2051 """Universally and Existentially quantified formulas."""
2052
2053 def as_ast(self):
2054 return self.ast
2055
2056 def get_id(self):
2057 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2058
2059 def sort(self):
2060 """Return the Boolean sort or sort of Lambda."""
2061 if self.is_lambda():
2062 return _sort(self.ctx, self.as_ast())
2063 return BoolSort(self.ctx)
2064
2065 def is_forall(self):
2066 """Return `True` if `self` is a universal quantifier.
2067
2068 >>> f = Function('f', IntSort(), IntSort())
2069 >>> x = Int('x')
2070 >>> q = ForAll(x, f(x) == 0)
2071 >>> q.is_forall()
2072 True
2073 >>> q = Exists(x, f(x) != 0)
2074 >>> q.is_forall()
2075 False
2076 """
2078
2079 def is_exists(self):
2080 """Return `True` if `self` is an existential quantifier.
2081
2082 >>> f = Function('f', IntSort(), IntSort())
2083 >>> x = Int('x')
2084 >>> q = ForAll(x, f(x) == 0)
2085 >>> q.is_exists()
2086 False
2087 >>> q = Exists(x, f(x) != 0)
2088 >>> q.is_exists()
2089 True
2090 """
2091 return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
2092
2093 def is_lambda(self):
2094 """Return `True` if `self` is a lambda expression.
2095
2096 >>> f = Function('f', IntSort(), IntSort())
2097 >>> x = Int('x')
2098 >>> q = Lambda(x, f(x))
2099 >>> q.is_lambda()
2100 True
2101 >>> q = Exists(x, f(x) != 0)
2102 >>> q.is_lambda()
2103 False
2104 """
2105 return Z3_is_lambda(self.ctx_ref(), self.ast)
2106
2107 def __getitem__(self, arg):
2108 """Return the Z3 expression `self[arg]`.
2109 """
2110 if z3_debug():
2111 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2112 return _array_select(self, arg)
2113
2114 def weight(self):
2115 """Return the weight annotation of `self`.
2116
2117 >>> f = Function('f', IntSort(), IntSort())
2118 >>> x = Int('x')
2119 >>> q = ForAll(x, f(x) == 0)
2120 >>> q.weight()
2121 1
2122 >>> q = ForAll(x, f(x) == 0, weight=10)
2123 >>> q.weight()
2124 10
2125 """
2126 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
2127
2128 def skolem_id(self):
2129 """Return the skolem id of `self`.
2130 """
2131 return _symbol2py(self.ctx, Z3_get_quantifier_skolem_id(self.ctx_ref(), self.ast))
2132
2133 def qid(self):
2134 """Return the quantifier id of `self`.
2135 """
2136 return _symbol2py(self.ctx, Z3_get_quantifier_id(self.ctx_ref(), self.ast))
2137
2138 def num_patterns(self):
2139 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2140
2141 >>> f = Function('f', IntSort(), IntSort())
2142 >>> g = Function('g', IntSort(), IntSort())
2143 >>> x = Int('x')
2144 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2145 >>> q.num_patterns()
2146 2
2147 """
2148 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
2149
2150 def pattern(self, idx):
2151 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2152
2153 >>> f = Function('f', IntSort(), IntSort())
2154 >>> g = Function('g', IntSort(), IntSort())
2155 >>> x = Int('x')
2156 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2157 >>> q.num_patterns()
2158 2
2159 >>> q.pattern(0)
2160 f(Var(0))
2161 >>> q.pattern(1)
2162 g(Var(0))
2163 """
2164 if z3_debug():
2165 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2166 return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2167
2169 """Return the number of no-patterns."""
2170 return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
2171
2172 def no_pattern(self, idx):
2173 """Return a no-pattern."""
2174 if z3_debug():
2175 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2176 return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2177
2178 def body(self):
2179 """Return the expression being quantified.
2180
2181 >>> f = Function('f', IntSort(), IntSort())
2182 >>> x = Int('x')
2183 >>> q = ForAll(x, f(x) == 0)
2184 >>> q.body()
2185 f(Var(0)) == 0
2186 """
2187 return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
2188
2189 def num_vars(self):
2190 """Return the number of variables bounded by this quantifier.
2191
2192 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2193 >>> x = Int('x')
2194 >>> y = Int('y')
2195 >>> q = ForAll([x, y], f(x, y) >= x)
2196 >>> q.num_vars()
2197 2
2198 """
2199 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
2200
2201 def var_name(self, idx):
2202 """Return a string representing a name used when displaying the quantifier.
2203
2204 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2205 >>> x = Int('x')
2206 >>> y = Int('y')
2207 >>> q = ForAll([x, y], f(x, y) >= x)
2208 >>> q.var_name(0)
2209 'x'
2210 >>> q.var_name(1)
2211 'y'
2212 """
2213 if z3_debug():
2214 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2215 return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
2216
2217 def var_sort(self, idx):
2218 """Return the sort of a bound variable.
2219
2220 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2221 >>> x = Int('x')
2222 >>> y = Real('y')
2223 >>> q = ForAll([x, y], f(x, y) >= x)
2224 >>> q.var_sort(0)
2225 Int
2226 >>> q.var_sort(1)
2227 Real
2228 """
2229 if z3_debug():
2230 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2231 return _to_sort_ref(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
2232
2233 def children(self):
2234 """Return a list containing a single element self.body()
2235
2236 >>> f = Function('f', IntSort(), IntSort())
2237 >>> x = Int('x')
2238 >>> q = ForAll(x, f(x) == 0)
2239 >>> q.children()
2240 [f(Var(0)) == 0]
2241 """
2242 return [self.body()]
2243
2244
2246 """Return `True` if `a` is a Z3 quantifier.
2247
2248 >>> f = Function('f', IntSort(), IntSort())
2249 >>> x = Int('x')
2250 >>> q = ForAll(x, f(x) == 0)
2251 >>> is_quantifier(q)
2252 True
2253 >>> is_quantifier(f(x))
2254 False
2255 """
2256 return isinstance(a, QuantifierRef)
2257
2258
2259def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2260 if z3_debug():
2261 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2262 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2263 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2264 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2265 if is_app(vs):
2266 ctx = vs.ctx
2267 vs = [vs]
2268 else:
2269 ctx = vs[0].ctx
2270 if not is_expr(body):
2271 body = BoolVal(body, ctx)
2272 num_vars = len(vs)
2273 if num_vars == 0:
2274 return body
2275 _vs = (Ast * num_vars)()
2276 for i in range(num_vars):
2277 # TODO: Check if is constant
2278 _vs[i] = vs[i].as_ast()
2279 patterns = [_to_pattern(p) for p in patterns]
2280 num_pats = len(patterns)
2281 _pats = (Pattern * num_pats)()
2282 for i in range(num_pats):
2283 _pats[i] = patterns[i].ast
2284 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2285 qid = to_symbol(qid, ctx)
2286 skid = to_symbol(skid, ctx)
2287 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2288 num_vars, _vs,
2289 num_pats, _pats,
2290 num_no_pats, _no_pats,
2291 body.as_ast()), ctx)
2292
2293
2294def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2295 """Create a Z3 forall formula.
2296
2297 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2298
2299 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2300 >>> x = Int('x')
2301 >>> y = Int('y')
2302 >>> ForAll([x, y], f(x, y) >= x)
2303 ForAll([x, y], f(x, y) >= x)
2304 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2305 ForAll([x, y], f(x, y) >= x)
2306 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2307 ForAll([x, y], f(x, y) >= x)
2308 """
2309 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2310
2311
2312def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2313 """Create a Z3 exists formula.
2314
2315 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2316
2317
2318 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2319 >>> x = Int('x')
2320 >>> y = Int('y')
2321 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2322 >>> q
2323 Exists([x, y], f(x, y) >= x)
2324 >>> is_quantifier(q)
2325 True
2326 >>> r = Tactic('nnf')(q).as_expr()
2327 >>> is_quantifier(r)
2328 False
2329 """
2330 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2331
2332
2333def Lambda(vs, body):
2334 """Create a Z3 lambda expression.
2335
2336 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2337 >>> mem0 = Array('mem0', IntSort(), IntSort())
2338 >>> lo, hi, e, i = Ints('lo hi e i')
2339 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2340 >>> mem1
2341 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2342 """
2343 ctx = body.ctx
2344 if is_app(vs):
2345 vs = [vs]
2346 num_vars = len(vs)
2347 _vs = (Ast * num_vars)()
2348 for i in range(num_vars):
2349 # TODO: Check if is constant
2350 _vs[i] = vs[i].as_ast()
2351 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2352
2353
2358
2359
2361 """Real and Integer sorts."""
2362
2363 def is_real(self):
2364 """Return `True` if `self` is of the sort Real.
2365
2366 >>> x = Real('x')
2367 >>> x.is_real()
2368 True
2369 >>> (x + 1).is_real()
2370 True
2371 >>> x = Int('x')
2372 >>> x.is_real()
2373 False
2374 """
2375 return self.kind() == Z3_REAL_SORT
2376
2377 def is_int(self):
2378 """Return `True` if `self` is of the sort Integer.
2379
2380 >>> x = Int('x')
2381 >>> x.is_int()
2382 True
2383 >>> (x + 1).is_int()
2384 True
2385 >>> x = Real('x')
2386 >>> x.is_int()
2387 False
2388 """
2389 return self.kind() == Z3_INT_SORT
2390
2391 def is_bool(self):
2392 return False
2393
2394 def subsort(self, other):
2395 """Return `True` if `self` is a subsort of `other`."""
2396 return self.is_int() and is_arith_sort(other) and other.is_real()
2397
2398 def cast(self, val):
2399 """Try to cast `val` as an Integer or Real.
2400
2401 >>> IntSort().cast(10)
2402 10
2403 >>> is_int(IntSort().cast(10))
2404 True
2405 >>> is_int(10)
2406 False
2407 >>> RealSort().cast(10)
2408 10
2409 >>> is_real(RealSort().cast(10))
2410 True
2411 """
2412 if is_expr(val):
2413 if z3_debug():
2414 _z3_assert(self.ctx == val.ctx, "Context mismatch")
2415 val_s = val.sort()
2416 if self.eq(val_s):
2417 return val
2418 if val_s.is_int() and self.is_real():
2419 return ToReal(val)
2420 if val_s.is_bool() and self.is_int():
2421 return If(val, 1, 0)
2422 if val_s.is_bool() and self.is_real():
2423 return ToReal(If(val, 1, 0))
2424 if z3_debug():
2425 _z3_assert(False, "Z3 Integer/Real expression expected")
2426 else:
2427 if self.is_int():
2428 return IntVal(val, self.ctx)
2429 if self.is_real():
2430 return RealVal(val, self.ctx)
2431 if z3_debug():
2432 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2433 _z3_assert(False, msg % self)
2434
2435
2437 """Return `True` if s is an arithmetical sort (type).
2438
2439 >>> is_arith_sort(IntSort())
2440 True
2441 >>> is_arith_sort(RealSort())
2442 True
2443 >>> is_arith_sort(BoolSort())
2444 False
2445 >>> n = Int('x') + 1
2446 >>> is_arith_sort(n.sort())
2447 True
2448 """
2449 return isinstance(s, ArithSortRef)
2450
2451
2453 """Integer and Real expressions."""
2454
2455 def sort(self):
2456 """Return the sort (type) of the arithmetical expression `self`.
2457
2458 >>> Int('x').sort()
2459 Int
2460 >>> (Real('x') + 1).sort()
2461 Real
2462 """
2463 return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
2464
2465 def is_int(self):
2466 """Return `True` if `self` is an integer expression.
2467
2468 >>> x = Int('x')
2469 >>> x.is_int()
2470 True
2471 >>> (x + 1).is_int()
2472 True
2473 >>> y = Real('y')
2474 >>> (x + y).is_int()
2475 False
2476 """
2477 return self.sort().is_int()
2478
2479 def is_real(self):
2480 """Return `True` if `self` is an real expression.
2481
2482 >>> x = Real('x')
2483 >>> x.is_real()
2484 True
2485 >>> (x + 1).is_real()
2486 True
2487 """
2488 return self.sort().is_real()
2489
2490 def __add__(self, other):
2491 """Create the Z3 expression `self + other`.
2492
2493 >>> x = Int('x')
2494 >>> y = Int('y')
2495 >>> x + y
2496 x + y
2497 >>> (x + y).sort()
2498 Int
2499 """
2500 a, b = _coerce_exprs(self, other)
2501 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctx)
2502
2503 def __radd__(self, other):
2504 """Create the Z3 expression `other + self`.
2505
2506 >>> x = Int('x')
2507 >>> 10 + x
2508 10 + x
2509 """
2510 a, b = _coerce_exprs(self, other)
2511 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctx)
2512
2513 def __mul__(self, other):
2514 """Create the Z3 expression `self * other`.
2515
2516 >>> x = Real('x')
2517 >>> y = Real('y')
2518 >>> x * y
2519 x*y
2520 >>> (x * y).sort()
2521 Real
2522 """
2523 if isinstance(other, BoolRef):
2524 return If(other, self, 0)
2525 a, b = _coerce_exprs(self, other)
2526 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
2527
2528 def __rmul__(self, other):
2529 """Create the Z3 expression `other * self`.
2530
2531 >>> x = Real('x')
2532 >>> 10 * x
2533 10*x
2534 """
2535 a, b = _coerce_exprs(self, other)
2536 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctx)
2537
2538 def __sub__(self, other):
2539 """Create the Z3 expression `self - other`.
2540
2541 >>> x = Int('x')
2542 >>> y = Int('y')
2543 >>> x - y
2544 x - y
2545 >>> (x - y).sort()
2546 Int
2547 """
2548 a, b = _coerce_exprs(self, other)
2549 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctx)
2550
2551 def __rsub__(self, other):
2552 """Create the Z3 expression `other - self`.
2553
2554 >>> x = Int('x')
2555 >>> 10 - x
2556 10 - x
2557 """
2558 a, b = _coerce_exprs(self, other)
2559 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctx)
2560
2561 def __pow__(self, other):
2562 """Create the Z3 expression `self**other` (** is the power operator).
2563
2564 >>> x = Real('x')
2565 >>> x**3
2566 x**3
2567 >>> (x**3).sort()
2568 Real
2569 >>> simplify(IntVal(2)**8)
2570 256
2571 """
2572 a, b = _coerce_exprs(self, other)
2573 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2574
2575 def __rpow__(self, other):
2576 """Create the Z3 expression `other**self` (** is the power operator).
2577
2578 >>> x = Real('x')
2579 >>> 2**x
2580 2**x
2581 >>> (2**x).sort()
2582 Real
2583 >>> simplify(2**IntVal(8))
2584 256
2585 """
2586 a, b = _coerce_exprs(self, other)
2587 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2588
2589 def __div__(self, other):
2590 """Create the Z3 expression `other/self`.
2591
2592 >>> x = Int('x')
2593 >>> y = Int('y')
2594 >>> x/y
2595 x/y
2596 >>> (x/y).sort()
2597 Int
2598 >>> (x/y).sexpr()
2599 '(div x y)'
2600 >>> x = Real('x')
2601 >>> y = Real('y')
2602 >>> x/y
2603 x/y
2604 >>> (x/y).sort()
2605 Real
2606 >>> (x/y).sexpr()
2607 '(/ x y)'
2608 """
2609 a, b = _coerce_exprs(self, other)
2610 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2611
2612 def __truediv__(self, other):
2613 """Create the Z3 expression `other/self`."""
2614 return self.__div__(other)
2615
2616 def __rdiv__(self, other):
2617 """Create the Z3 expression `other/self`.
2618
2619 >>> x = Int('x')
2620 >>> 10/x
2621 10/x
2622 >>> (10/x).sexpr()
2623 '(div 10 x)'
2624 >>> x = Real('x')
2625 >>> 10/x
2626 10/x
2627 >>> (10/x).sexpr()
2628 '(/ 10.0 x)'
2629 """
2630 a, b = _coerce_exprs(self, other)
2631 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2632
2633 def __rtruediv__(self, other):
2634 """Create the Z3 expression `other/self`."""
2635 return self.__rdiv__(other)
2636
2637 def __mod__(self, other):
2638 """Create the Z3 expression `other%self`.
2639
2640 >>> x = Int('x')
2641 >>> y = Int('y')
2642 >>> x % y
2643 x%y
2644 >>> simplify(IntVal(10) % IntVal(3))
2645 1
2646 """
2647 a, b = _coerce_exprs(self, other)
2648 if z3_debug():
2649 _z3_assert(a.is_int(), "Z3 integer expression expected")
2650 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2651
2652 def __rmod__(self, other):
2653 """Create the Z3 expression `other%self`.
2654
2655 >>> x = Int('x')
2656 >>> 10 % x
2657 10%x
2658 """
2659 a, b = _coerce_exprs(self, other)
2660 if z3_debug():
2661 _z3_assert(a.is_int(), "Z3 integer expression expected")
2662 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2663
2664 def __neg__(self):
2665 """Return an expression representing `-self`.
2666
2667 >>> x = Int('x')
2668 >>> -x
2669 -x
2670 >>> simplify(-(-x))
2671 x
2672 """
2673 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
2674
2675 def __pos__(self):
2676 """Return `self`.
2677
2678 >>> x = Int('x')
2679 >>> +x
2680 x
2681 """
2682 return self
2683
2684 def __le__(self, other):
2685 """Create the Z3 expression `other <= self`.
2686
2687 >>> x, y = Ints('x y')
2688 >>> x <= y
2689 x <= y
2690 >>> y = Real('y')
2691 >>> x <= y
2692 ToReal(x) <= y
2693 """
2694 a, b = _coerce_exprs(self, other)
2695 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2696
2697 def __lt__(self, other):
2698 """Create the Z3 expression `other < self`.
2699
2700 >>> x, y = Ints('x y')
2701 >>> x < y
2702 x < y
2703 >>> y = Real('y')
2704 >>> x < y
2705 ToReal(x) < y
2706 """
2707 a, b = _coerce_exprs(self, other)
2708 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2709
2710 def __gt__(self, other):
2711 """Create the Z3 expression `other > self`.
2712
2713 >>> x, y = Ints('x y')
2714 >>> x > y
2715 x > y
2716 >>> y = Real('y')
2717 >>> x > y
2718 ToReal(x) > y
2719 """
2720 a, b = _coerce_exprs(self, other)
2721 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2722
2723 def __ge__(self, other):
2724 """Create the Z3 expression `other >= self`.
2725
2726 >>> x, y = Ints('x y')
2727 >>> x >= y
2728 x >= y
2729 >>> y = Real('y')
2730 >>> x >= y
2731 ToReal(x) >= y
2732 """
2733 a, b = _coerce_exprs(self, other)
2734 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2735
2736
2738 """Return `True` if `a` is an arithmetical expression.
2739
2740 >>> x = Int('x')
2741 >>> is_arith(x)
2742 True
2743 >>> is_arith(x + 1)
2744 True
2745 >>> is_arith(1)
2746 False
2747 >>> is_arith(IntVal(1))
2748 True
2749 >>> y = Real('y')
2750 >>> is_arith(y)
2751 True
2752 >>> is_arith(y + 1)
2753 True
2754 """
2755 return isinstance(a, ArithRef)
2756
2757
2758def is_int(a):
2759 """Return `True` if `a` is an integer expression.
2760
2761 >>> x = Int('x')
2762 >>> is_int(x + 1)
2763 True
2764 >>> is_int(1)
2765 False
2766 >>> is_int(IntVal(1))
2767 True
2768 >>> y = Real('y')
2769 >>> is_int(y)
2770 False
2771 >>> is_int(y + 1)
2772 False
2773 """
2774 return is_arith(a) and a.is_int()
2775
2776
2777def is_real(a):
2778 """Return `True` if `a` is a real expression.
2779
2780 >>> x = Int('x')
2781 >>> is_real(x + 1)
2782 False
2783 >>> y = Real('y')
2784 >>> is_real(y)
2785 True
2786 >>> is_real(y + 1)
2787 True
2788 >>> is_real(1)
2789 False
2790 >>> is_real(RealVal(1))
2791 True
2792 """
2793 return is_arith(a) and a.is_real()
2794
2795
2796def _is_numeral(ctx, a):
2797 return Z3_is_numeral_ast(ctx.ref(), a)
2798
2799
2800def _is_algebraic(ctx, a):
2801 return Z3_is_algebraic_number(ctx.ref(), a)
2802
2803
2805 """Return `True` if `a` is an integer value of sort Int.
2806
2807 >>> is_int_value(IntVal(1))
2808 True
2809 >>> is_int_value(1)
2810 False
2811 >>> is_int_value(Int('x'))
2812 False
2813 >>> n = Int('x') + 1
2814 >>> n
2815 x + 1
2816 >>> n.arg(1)
2817 1
2818 >>> is_int_value(n.arg(1))
2819 True
2820 >>> is_int_value(RealVal("1/3"))
2821 False
2822 >>> is_int_value(RealVal(1))
2823 False
2824 """
2825 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2826
2827
2829 """Return `True` if `a` is rational value of sort Real.
2830
2831 >>> is_rational_value(RealVal(1))
2832 True
2833 >>> is_rational_value(RealVal("3/5"))
2834 True
2835 >>> is_rational_value(IntVal(1))
2836 False
2837 >>> is_rational_value(1)
2838 False
2839 >>> n = Real('x') + 1
2840 >>> n.arg(1)
2841 1
2842 >>> is_rational_value(n.arg(1))
2843 True
2844 >>> is_rational_value(Real('x'))
2845 False
2846 """
2847 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2848
2849
2851 """Return `True` if `a` is an algebraic value of sort Real.
2852
2853 >>> is_algebraic_value(RealVal("3/5"))
2854 False
2855 >>> n = simplify(Sqrt(2))
2856 >>> n
2857 1.4142135623?
2858 >>> is_algebraic_value(n)
2859 True
2860 """
2861 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2862
2863
2864def is_add(a):
2865 """Return `True` if `a` is an expression of the form b + c.
2866
2867 >>> x, y = Ints('x y')
2868 >>> is_add(x + y)
2869 True
2870 >>> is_add(x - y)
2871 False
2872 """
2873 return is_app_of(a, Z3_OP_ADD)
2874
2875
2876def is_mul(a):
2877 """Return `True` if `a` is an expression of the form b * c.
2878
2879 >>> x, y = Ints('x y')
2880 >>> is_mul(x * y)
2881 True
2882 >>> is_mul(x - y)
2883 False
2884 """
2885 return is_app_of(a, Z3_OP_MUL)
2886
2887
2888def is_sub(a):
2889 """Return `True` if `a` is an expression of the form b - c.
2890
2891 >>> x, y = Ints('x y')
2892 >>> is_sub(x - y)
2893 True
2894 >>> is_sub(x + y)
2895 False
2896 """
2897 return is_app_of(a, Z3_OP_SUB)
2898
2899
2900def is_div(a):
2901 """Return `True` if `a` is an expression of the form b / c.
2902
2903 >>> x, y = Reals('x y')
2904 >>> is_div(x / y)
2905 True
2906 >>> is_div(x + y)
2907 False
2908 >>> x, y = Ints('x y')
2909 >>> is_div(x / y)
2910 False
2911 >>> is_idiv(x / y)
2912 True
2913 """
2914 return is_app_of(a, Z3_OP_DIV)
2915
2916
2917def is_idiv(a):
2918 """Return `True` if `a` is an expression of the form b div c.
2919
2920 >>> x, y = Ints('x y')
2921 >>> is_idiv(x / y)
2922 True
2923 >>> is_idiv(x + y)
2924 False
2925 """
2926 return is_app_of(a, Z3_OP_IDIV)
2927
2928
2929def is_mod(a):
2930 """Return `True` if `a` is an expression of the form b % c.
2931
2932 >>> x, y = Ints('x y')
2933 >>> is_mod(x % y)
2934 True
2935 >>> is_mod(x + y)
2936 False
2937 """
2938 return is_app_of(a, Z3_OP_MOD)
2939
2940
2941def is_le(a):
2942 """Return `True` if `a` is an expression of the form b <= c.
2943
2944 >>> x, y = Ints('x y')
2945 >>> is_le(x <= y)
2946 True
2947 >>> is_le(x < y)
2948 False
2949 """
2950 return is_app_of(a, Z3_OP_LE)
2951
2952
2953def is_lt(a):
2954 """Return `True` if `a` is an expression of the form b < c.
2955
2956 >>> x, y = Ints('x y')
2957 >>> is_lt(x < y)
2958 True
2959 >>> is_lt(x == y)
2960 False
2961 """
2962 return is_app_of(a, Z3_OP_LT)
2963
2964
2965def is_ge(a):
2966 """Return `True` if `a` is an expression of the form b >= c.
2967
2968 >>> x, y = Ints('x y')
2969 >>> is_ge(x >= y)
2970 True
2971 >>> is_ge(x == y)
2972 False
2973 """
2974 return is_app_of(a, Z3_OP_GE)
2975
2976
2977def is_gt(a):
2978 """Return `True` if `a` is an expression of the form b > c.
2979
2980 >>> x, y = Ints('x y')
2981 >>> is_gt(x > y)
2982 True
2983 >>> is_gt(x == y)
2984 False
2985 """
2986 return is_app_of(a, Z3_OP_GT)
2987
2988
2990 """Return `True` if `a` is an expression of the form IsInt(b).
2991
2992 >>> x = Real('x')
2993 >>> is_is_int(IsInt(x))
2994 True
2995 >>> is_is_int(x)
2996 False
2997 """
2998 return is_app_of(a, Z3_OP_IS_INT)
2999
3000
3002 """Return `True` if `a` is an expression of the form ToReal(b).
3003
3004 >>> x = Int('x')
3005 >>> n = ToReal(x)
3006 >>> n
3007 ToReal(x)
3008 >>> is_to_real(n)
3009 True
3010 >>> is_to_real(x)
3011 False
3012 """
3013 return is_app_of(a, Z3_OP_TO_REAL)
3014
3015
3017 """Return `True` if `a` is an expression of the form ToInt(b).
3018
3019 >>> x = Real('x')
3020 >>> n = ToInt(x)
3021 >>> n
3022 ToInt(x)
3023 >>> is_to_int(n)
3024 True
3025 >>> is_to_int(x)
3026 False
3027 """
3028 return is_app_of(a, Z3_OP_TO_INT)
3029
3030
3032 """Integer values."""
3033
3034 def as_long(self):
3035 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3036
3037 >>> v = IntVal(1)
3038 >>> v + 1
3039 1 + 1
3040 >>> v.as_long() + 1
3041 2
3042 """
3043 if z3_debug():
3044 _z3_assert(self.is_int(), "Integer value expected")
3045 return int(self.as_string())
3046
3047 def as_string(self):
3048 """Return a Z3 integer numeral as a Python string.
3049 >>> v = IntVal(100)
3050 >>> v.as_string()
3051 '100'
3052 """
3053 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3054
3056 """Return a Z3 integer numeral as a Python binary string.
3057 >>> v = IntVal(10)
3058 >>> v.as_binary_string()
3059 '1010'
3060 """
3061 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3062
3063 def py_value(self):
3064 return self.as_long()
3065
3066
3068 """Rational values."""
3069
3070 def numerator(self):
3071 """ Return the numerator of a Z3 rational numeral.
3072
3073 >>> is_rational_value(RealVal("3/5"))
3074 True
3075 >>> n = RealVal("3/5")
3076 >>> n.numerator()
3077 3
3078 >>> is_rational_value(Q(3,5))
3079 True
3080 >>> Q(3,5).numerator()
3081 3
3082 """
3083 return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
3084
3085 def denominator(self):
3086 """ Return the denominator of a Z3 rational numeral.
3087
3088 >>> is_rational_value(Q(3,5))
3089 True
3090 >>> n = Q(3,5)
3091 >>> n.denominator()
3092 5
3093 """
3094 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
3095
3097 """ Return the numerator as a Python long.
3098
3099 >>> v = RealVal(10000000000)
3100 >>> v
3101 10000000000
3102 >>> v + 1
3103 10000000000 + 1
3104 >>> v.numerator_as_long() + 1 == 10000000001
3105 True
3106 """
3107 return self.numerator().as_long()
3108
3110 """ Return the denominator as a Python long.
3111
3112 >>> v = RealVal("1/3")
3113 >>> v
3114 1/3
3115 >>> v.denominator_as_long()
3116 3
3117 """
3118 return self.denominator().as_long()
3119
3120 def is_int(self):
3121 return False
3122
3123 def is_real(self):
3124 return True
3125
3126 def is_int_value(self):
3127 return self.denominator().is_int() and self.denominator_as_long() == 1
3128
3129 def as_long(self):
3130 _z3_assert(self.is_int_value(), "Expected integer fraction")
3131 return self.numerator_as_long()
3132
3133 def as_decimal(self, prec):
3134 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3135
3136 >>> v = RealVal("1/5")
3137 >>> v.as_decimal(3)
3138 '0.2'
3139 >>> v = RealVal("1/3")
3140 >>> v.as_decimal(3)
3141 '0.333?'
3142 """
3143 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3144
3145 def as_string(self):
3146 """Return a Z3 rational numeral as a Python string.
3147
3148 >>> v = Q(3,6)
3149 >>> v.as_string()
3150 '1/2'
3151 """
3152 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3153
3154 def as_fraction(self):
3155 """Return a Z3 rational as a Python Fraction object.
3156
3157 >>> v = RealVal("1/5")
3158 >>> v.as_fraction()
3159 Fraction(1, 5)
3160 """
3161 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3162
3163 def py_value(self):
3164 return Z3_get_numeral_double(self.ctx_ref(), self.as_ast())
3165
3166
3168 """Algebraic irrational values."""
3169
3170 def approx(self, precision=10):
3171 """Return a Z3 rational number that approximates the algebraic number `self`.
3172 The result `r` is such that |r - self| <= 1/10^precision
3173
3174 >>> x = simplify(Sqrt(2))
3175 >>> x.approx(20)
3176 6838717160008073720548335/4835703278458516698824704
3177 >>> x.approx(5)
3178 2965821/2097152
3179 """
3180 return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
3181
3182 def as_decimal(self, prec):
3183 """Return a string representation of the algebraic number `self` in decimal notation
3184 using `prec` decimal places.
3185
3186 >>> x = simplify(Sqrt(2))
3187 >>> x.as_decimal(10)
3188 '1.4142135623?'
3189 >>> x.as_decimal(20)
3190 '1.41421356237309504880?'
3191 """
3192 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3193
3194 def poly(self):
3195 return AstVector(Z3_algebraic_get_poly(self.ctx_ref(), self.as_ast()), self.ctx)
3196
3197 def index(self):
3198 return Z3_algebraic_get_i(self.ctx_ref(), self.as_ast())
3199
3200
3201def _py2expr(a, ctx=None):
3202 if isinstance(a, bool):
3203 return BoolVal(a, ctx)
3204 if _is_int(a):
3205 return IntVal(a, ctx)
3206 if isinstance(a, float):
3207 return RealVal(a, ctx)
3208 if isinstance(a, str):
3209 return StringVal(a, ctx)
3210 if is_expr(a):
3211 return a
3212 if z3_debug():
3213 _z3_assert(False, "Python bool, int, long or float expected")
3214
3215
3216def IntSort(ctx=None):
3217 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3218
3219 >>> IntSort()
3220 Int
3221 >>> x = Const('x', IntSort())
3222 >>> is_int(x)
3223 True
3224 >>> x.sort() == IntSort()
3225 True
3226 >>> x.sort() == BoolSort()
3227 False
3228 """
3229 ctx = _get_ctx(ctx)
3230 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3231
3232
3233def RealSort(ctx=None):
3234 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3235
3236 >>> RealSort()
3237 Real
3238 >>> x = Const('x', RealSort())
3239 >>> is_real(x)
3240 True
3241 >>> is_int(x)
3242 False
3243 >>> x.sort() == RealSort()
3244 True
3245 """
3246 ctx = _get_ctx(ctx)
3247 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3248
3249
3251 if isinstance(val, float):
3252 return str(int(val))
3253 elif isinstance(val, bool):
3254 if val:
3255 return "1"
3256 else:
3257 return "0"
3258 else:
3259 return str(val)
3260
3261
3262def IntVal(val, ctx=None):
3263 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3264
3265 >>> IntVal(1)
3266 1
3267 >>> IntVal("100")
3268 100
3269 """
3270 ctx = _get_ctx(ctx)
3271 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3272
3273
3274def RealVal(val, ctx=None):
3275 """Return a Z3 real value.
3276
3277 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3278 If `ctx=None`, then the global context is used.
3279
3280 >>> RealVal(1)
3281 1
3282 >>> RealVal(1).sort()
3283 Real
3284 >>> RealVal("3/5")
3285 3/5
3286 >>> RealVal("1.5")
3287 3/2
3288 """
3289 ctx = _get_ctx(ctx)
3290 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3291
3292
3293def RatVal(a, b, ctx=None):
3294 """Return a Z3 rational a/b.
3295
3296 If `ctx=None`, then the global context is used.
3297
3298 >>> RatVal(3,5)
3299 3/5
3300 >>> RatVal(3,5).sort()
3301 Real
3302 """
3303 if z3_debug():
3304 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3305 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3306 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3307
3308
3309def Q(a, b, ctx=None):
3310 """Return a Z3 rational a/b.
3311
3312 If `ctx=None`, then the global context is used.
3313
3314 >>> Q(3,5)
3315 3/5
3316 >>> Q(3,5).sort()
3317 Real
3318 """
3319 return simplify(RatVal(a, b, ctx=ctx))
3320
3321
3322def Int(name, ctx=None):
3323 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3324
3325 >>> x = Int('x')
3326 >>> is_int(x)
3327 True
3328 >>> is_int(x + 1)
3329 True
3330 """
3331 ctx = _get_ctx(ctx)
3332 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3333
3334
3335def Ints(names, ctx=None):
3336 """Return a tuple of Integer constants.
3337
3338 >>> x, y, z = Ints('x y z')
3339 >>> Sum(x, y, z)
3340 x + y + z
3341 """
3342 ctx = _get_ctx(ctx)
3343 if isinstance(names, str):
3344 names = names.split(" ")
3345 return [Int(name, ctx) for name in names]
3346
3347
3348def IntVector(prefix, sz, ctx=None):
3349 """Return a list of integer constants of size `sz`.
3350
3351 >>> X = IntVector('x', 3)
3352 >>> X
3353 [x__0, x__1, x__2]
3354 >>> Sum(X)
3355 x__0 + x__1 + x__2
3356 """
3357 ctx = _get_ctx(ctx)
3358 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3359
3360
3361def FreshInt(prefix="x", ctx=None):
3362 """Return a fresh integer constant in the given context using the given prefix.
3363
3364 >>> x = FreshInt()
3365 >>> y = FreshInt()
3366 >>> eq(x, y)
3367 False
3368 >>> x.sort()
3369 Int
3370 """
3371 ctx = _get_ctx(ctx)
3372 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3373
3374
3375def Real(name, ctx=None):
3376 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3377
3378 >>> x = Real('x')
3379 >>> is_real(x)
3380 True
3381 >>> is_real(x + 1)
3382 True
3383 """
3384 ctx = _get_ctx(ctx)
3385 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3386
3387
3388def Reals(names, ctx=None):
3389 """Return a tuple of real constants.
3390
3391 >>> x, y, z = Reals('x y z')
3392 >>> Sum(x, y, z)
3393 x + y + z
3394 >>> Sum(x, y, z).sort()
3395 Real
3396 """
3397 ctx = _get_ctx(ctx)
3398 if isinstance(names, str):
3399 names = names.split(" ")
3400 return [Real(name, ctx) for name in names]
3401
3402
3403def RealVector(prefix, sz, ctx=None):
3404 """Return a list of real constants of size `sz`.
3405
3406 >>> X = RealVector('x', 3)
3407 >>> X
3408 [x__0, x__1, x__2]
3409 >>> Sum(X)
3410 x__0 + x__1 + x__2
3411 >>> Sum(X).sort()
3412 Real
3413 """
3414 ctx = _get_ctx(ctx)
3415 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3416
3417
3418def FreshReal(prefix="b", ctx=None):
3419 """Return a fresh real constant in the given context using the given prefix.
3420
3421 >>> x = FreshReal()
3422 >>> y = FreshReal()
3423 >>> eq(x, y)
3424 False
3425 >>> x.sort()
3426 Real
3427 """
3428 ctx = _get_ctx(ctx)
3429 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3430
3431
3432def ToReal(a):
3433 """ Return the Z3 expression ToReal(a).
3434
3435 >>> x = Int('x')
3436 >>> x.sort()
3437 Int
3438 >>> n = ToReal(x)
3439 >>> n
3440 ToReal(x)
3441 >>> n.sort()
3442 Real
3443 """
3444 ctx = a.ctx
3445 if isinstance(a, BoolRef):
3446 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3447 if z3_debug():
3448 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3449 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3450
3451
3452def ToInt(a):
3453 """ Return the Z3 expression ToInt(a).
3454
3455 >>> x = Real('x')
3456 >>> x.sort()
3457 Real
3458 >>> n = ToInt(x)
3459 >>> n
3460 ToInt(x)
3461 >>> n.sort()
3462 Int
3463 """
3464 if z3_debug():
3465 _z3_assert(a.is_real(), "Z3 real expression expected.")
3466 ctx = a.ctx
3467 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3468
3469
3470def IsInt(a):
3471 """ Return the Z3 predicate IsInt(a).
3472
3473 >>> x = Real('x')
3474 >>> IsInt(x + "1/2")
3475 IsInt(x + 1/2)
3476 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3477 [x = 1/2]
3478 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3479 no solution
3480 """
3481 if z3_debug():
3482 _z3_assert(a.is_real(), "Z3 real expression expected.")
3483 ctx = a.ctx
3484 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3485
3486
3487def Sqrt(a, ctx=None):
3488 """ Return a Z3 expression which represents the square root of a.
3489
3490 >>> x = Real('x')
3491 >>> Sqrt(x)
3492 x**(1/2)
3493 """
3494 if not is_expr(a):
3495 ctx = _get_ctx(ctx)
3496 a = RealVal(a, ctx)
3497 return a ** "1/2"
3498
3499
3500def Cbrt(a, ctx=None):
3501 """ Return a Z3 expression which represents the cubic root of a.
3502
3503 >>> x = Real('x')
3504 >>> Cbrt(x)
3505 x**(1/3)
3506 """
3507 if not is_expr(a):
3508 ctx = _get_ctx(ctx)
3509 a = RealVal(a, ctx)
3510 return a ** "1/3"
3511
3512
3517
3518
3520 """Bit-vector sort."""
3521
3522 def size(self):
3523 """Return the size (number of bits) of the bit-vector sort `self`.
3524
3525 >>> b = BitVecSort(32)
3526 >>> b.size()
3527 32
3528 """
3529 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
3530
3531 def subsort(self, other):
3532 return is_bv_sort(other) and self.size() < other.size()
3533
3534 def cast(self, val):
3535 """Try to cast `val` as a Bit-Vector.
3536
3537 >>> b = BitVecSort(32)
3538 >>> b.cast(10)
3539 10
3540 >>> b.cast(10).sexpr()
3541 '#x0000000a'
3542 """
3543 if is_expr(val):
3544 if z3_debug():
3545 _z3_assert(self.ctx == val.ctx, "Context mismatch")
3546 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3547 return val
3548 else:
3549 return BitVecVal(val, self)
3550
3551
3553 """Return True if `s` is a Z3 bit-vector sort.
3554
3555 >>> is_bv_sort(BitVecSort(32))
3556 True
3557 >>> is_bv_sort(IntSort())
3558 False
3559 """
3560 return isinstance(s, BitVecSortRef)
3561
3562
3564 """Bit-vector expressions."""
3565
3566 def sort(self):
3567 """Return the sort of the bit-vector expression `self`.
3568
3569 >>> x = BitVec('x', 32)
3570 >>> x.sort()
3571 BitVec(32)
3572 >>> x.sort() == BitVecSort(32)
3573 True
3574 """
3575 return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3576
3577 def size(self):
3578 """Return the number of bits of the bit-vector expression `self`.
3579
3580 >>> x = BitVec('x', 32)
3581 >>> (x + 1).size()
3582 32
3583 >>> Concat(x, x).size()
3584 64
3585 """
3586 return self.sort().size()
3587
3588 def __add__(self, other):
3589 """Create the Z3 expression `self + other`.
3590
3591 >>> x = BitVec('x', 32)
3592 >>> y = BitVec('y', 32)
3593 >>> x + y
3594 x + y
3595 >>> (x + y).sort()
3596 BitVec(32)
3597 """
3598 a, b = _coerce_exprs(self, other)
3599 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3600
3601 def __radd__(self, other):
3602 """Create the Z3 expression `other + self`.
3603
3604 >>> x = BitVec('x', 32)
3605 >>> 10 + x
3606 10 + x
3607 """
3608 a, b = _coerce_exprs(self, other)
3609 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3610
3611 def __mul__(self, other):
3612 """Create the Z3 expression `self * other`.
3613
3614 >>> x = BitVec('x', 32)
3615 >>> y = BitVec('y', 32)
3616 >>> x * y
3617 x*y
3618 >>> (x * y).sort()
3619 BitVec(32)
3620 """
3621 a, b = _coerce_exprs(self, other)
3622 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3623
3624 def __rmul__(self, other):
3625 """Create the Z3 expression `other * self`.
3626
3627 >>> x = BitVec('x', 32)
3628 >>> 10 * x
3629 10*x
3630 """
3631 a, b = _coerce_exprs(self, other)
3632 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3633
3634 def __sub__(self, other):
3635 """Create the Z3 expression `self - other`.
3636
3637 >>> x = BitVec('x', 32)
3638 >>> y = BitVec('y', 32)
3639 >>> x - y
3640 x - y
3641 >>> (x - y).sort()
3642 BitVec(32)
3643 """
3644 a, b = _coerce_exprs(self, other)
3645 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3646
3647 def __rsub__(self, other):
3648 """Create the Z3 expression `other - self`.
3649
3650 >>> x = BitVec('x', 32)
3651 >>> 10 - x
3652 10 - x
3653 """
3654 a, b = _coerce_exprs(self, other)
3655 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3656
3657 def __or__(self, other):
3658 """Create the Z3 expression bitwise-or `self | other`.
3659
3660 >>> x = BitVec('x', 32)
3661 >>> y = BitVec('y', 32)
3662 >>> x | y
3663 x | y
3664 >>> (x | y).sort()
3665 BitVec(32)
3666 """
3667 a, b = _coerce_exprs(self, other)
3668 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3669
3670 def __ror__(self, other):
3671 """Create the Z3 expression bitwise-or `other | self`.
3672
3673 >>> x = BitVec('x', 32)
3674 >>> 10 | x
3675 10 | x
3676 """
3677 a, b = _coerce_exprs(self, other)
3678 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3679
3680 def __and__(self, other):
3681 """Create the Z3 expression bitwise-and `self & other`.
3682
3683 >>> x = BitVec('x', 32)
3684 >>> y = BitVec('y', 32)
3685 >>> x & y
3686 x & y
3687 >>> (x & y).sort()
3688 BitVec(32)
3689 """
3690 a, b = _coerce_exprs(self, other)
3691 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3692
3693 def __rand__(self, other):
3694 """Create the Z3 expression bitwise-or `other & self`.
3695
3696 >>> x = BitVec('x', 32)
3697 >>> 10 & x
3698 10 & x
3699 """
3700 a, b = _coerce_exprs(self, other)
3701 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3702
3703 def __xor__(self, other):
3704 """Create the Z3 expression bitwise-xor `self ^ other`.
3705
3706 >>> x = BitVec('x', 32)
3707 >>> y = BitVec('y', 32)
3708 >>> x ^ y
3709 x ^ y
3710 >>> (x ^ y).sort()
3711 BitVec(32)
3712 """
3713 a, b = _coerce_exprs(self, other)
3714 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3715
3716 def __rxor__(self, other):
3717 """Create the Z3 expression bitwise-xor `other ^ self`.
3718
3719 >>> x = BitVec('x', 32)
3720 >>> 10 ^ x
3721 10 ^ x
3722 """
3723 a, b = _coerce_exprs(self, other)
3724 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3725
3726 def __pos__(self):
3727 """Return `self`.
3728
3729 >>> x = BitVec('x', 32)
3730 >>> +x
3731 x
3732 """
3733 return self
3734
3735 def __neg__(self):
3736 """Return an expression representing `-self`.
3737
3738 >>> x = BitVec('x', 32)
3739 >>> -x
3740 -x
3741 >>> simplify(-(-x))
3742 x
3743 """
3744 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3745
3746 def __invert__(self):
3747 """Create the Z3 expression bitwise-not `~self`.
3748
3749 >>> x = BitVec('x', 32)
3750 >>> ~x
3751 ~x
3752 >>> simplify(~(~x))
3753 x
3754 """
3755 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3756
3757 def __div__(self, other):
3758 """Create the Z3 expression (signed) division `self / other`.
3759
3760 Use the function UDiv() for unsigned division.
3761
3762 >>> x = BitVec('x', 32)
3763 >>> y = BitVec('y', 32)
3764 >>> x / y
3765 x/y
3766 >>> (x / y).sort()
3767 BitVec(32)
3768 >>> (x / y).sexpr()
3769 '(bvsdiv x y)'
3770 >>> UDiv(x, y).sexpr()
3771 '(bvudiv x y)'
3772 """
3773 a, b = _coerce_exprs(self, other)
3774 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3775
3776 def __truediv__(self, other):
3777 """Create the Z3 expression (signed) division `self / other`."""
3778 return self.__div__(other)
3779
3780 def __rdiv__(self, other):
3781 """Create the Z3 expression (signed) division `other / self`.
3782
3783 Use the function UDiv() for unsigned division.
3784
3785 >>> x = BitVec('x', 32)
3786 >>> 10 / x
3787 10/x
3788 >>> (10 / x).sexpr()
3789 '(bvsdiv #x0000000a x)'
3790 >>> UDiv(10, x).sexpr()
3791 '(bvudiv #x0000000a x)'
3792 """
3793 a, b = _coerce_exprs(self, other)
3794 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3795
3796 def __rtruediv__(self, other):
3797 """Create the Z3 expression (signed) division `other / self`."""
3798 return self.__rdiv__(other)
3799
3800 def __mod__(self, other):
3801 """Create the Z3 expression (signed) mod `self % other`.
3802
3803 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3804
3805 >>> x = BitVec('x', 32)
3806 >>> y = BitVec('y', 32)
3807 >>> x % y
3808 x%y
3809 >>> (x % y).sort()
3810 BitVec(32)
3811 >>> (x % y).sexpr()
3812 '(bvsmod x y)'
3813 >>> URem(x, y).sexpr()
3814 '(bvurem x y)'
3815 >>> SRem(x, y).sexpr()
3816 '(bvsrem x y)'
3817 """
3818 a, b = _coerce_exprs(self, other)
3819 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3820
3821 def __rmod__(self, other):
3822 """Create the Z3 expression (signed) mod `other % self`.
3823
3824 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3825
3826 >>> x = BitVec('x', 32)
3827 >>> 10 % x
3828 10%x
3829 >>> (10 % x).sexpr()
3830 '(bvsmod #x0000000a x)'
3831 >>> URem(10, x).sexpr()
3832 '(bvurem #x0000000a x)'
3833 >>> SRem(10, x).sexpr()
3834 '(bvsrem #x0000000a x)'
3835 """
3836 a, b = _coerce_exprs(self, other)
3837 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3838
3839 def __le__(self, other):
3840 """Create the Z3 expression (signed) `other <= self`.
3841
3842 Use the function ULE() for unsigned less than or equal to.
3843
3844 >>> x, y = BitVecs('x y', 32)
3845 >>> x <= y
3846 x <= y
3847 >>> (x <= y).sexpr()
3848 '(bvsle x y)'
3849 >>> ULE(x, y).sexpr()
3850 '(bvule x y)'
3851 """
3852 a, b = _coerce_exprs(self, other)
3853 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3854
3855 def __lt__(self, other):
3856 """Create the Z3 expression (signed) `other < self`.
3857
3858 Use the function ULT() for unsigned less than.
3859
3860 >>> x, y = BitVecs('x y', 32)
3861 >>> x < y
3862 x < y
3863 >>> (x < y).sexpr()
3864 '(bvslt x y)'
3865 >>> ULT(x, y).sexpr()
3866 '(bvult x y)'
3867 """
3868 a, b = _coerce_exprs(self, other)
3869 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3870
3871 def __gt__(self, other):
3872 """Create the Z3 expression (signed) `other > self`.
3873
3874 Use the function UGT() for unsigned greater than.
3875
3876 >>> x, y = BitVecs('x y', 32)
3877 >>> x > y
3878 x > y
3879 >>> (x > y).sexpr()
3880 '(bvsgt x y)'
3881 >>> UGT(x, y).sexpr()
3882 '(bvugt x y)'
3883 """
3884 a, b = _coerce_exprs(self, other)
3885 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3886
3887 def __ge__(self, other):
3888 """Create the Z3 expression (signed) `other >= self`.
3889
3890 Use the function UGE() for unsigned greater than or equal to.
3891
3892 >>> x, y = BitVecs('x y', 32)
3893 >>> x >= y
3894 x >= y
3895 >>> (x >= y).sexpr()
3896 '(bvsge x y)'
3897 >>> UGE(x, y).sexpr()
3898 '(bvuge x y)'
3899 """
3900 a, b = _coerce_exprs(self, other)
3901 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3902
3903 def __rshift__(self, other):
3904 """Create the Z3 expression (arithmetical) right shift `self >> other`
3905
3906 Use the function LShR() for the right logical shift
3907
3908 >>> x, y = BitVecs('x y', 32)
3909 >>> x >> y
3910 x >> y
3911 >>> (x >> y).sexpr()
3912 '(bvashr x y)'
3913 >>> LShR(x, y).sexpr()
3914 '(bvlshr x y)'
3915 >>> BitVecVal(4, 3)
3916 4
3917 >>> BitVecVal(4, 3).as_signed_long()
3918 -4
3919 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3920 -2
3921 >>> simplify(BitVecVal(4, 3) >> 1)
3922 6
3923 >>> simplify(LShR(BitVecVal(4, 3), 1))
3924 2
3925 >>> simplify(BitVecVal(2, 3) >> 1)
3926 1
3927 >>> simplify(LShR(BitVecVal(2, 3), 1))
3928 1
3929 """
3930 a, b = _coerce_exprs(self, other)
3931 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3932
3933 def __lshift__(self, other):
3934 """Create the Z3 expression left shift `self << other`
3935
3936 >>> x, y = BitVecs('x y', 32)
3937 >>> x << y
3938 x << y
3939 >>> (x << y).sexpr()
3940 '(bvshl x y)'
3941 >>> simplify(BitVecVal(2, 3) << 1)
3942 4
3943 """
3944 a, b = _coerce_exprs(self, other)
3945 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3946
3947 def __rrshift__(self, other):
3948 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
3949
3950 Use the function LShR() for the right logical shift
3951
3952 >>> x = BitVec('x', 32)
3953 >>> 10 >> x
3954 10 >> x
3955 >>> (10 >> x).sexpr()
3956 '(bvashr #x0000000a x)'
3957 """
3958 a, b = _coerce_exprs(self, other)
3959 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3960
3961 def __rlshift__(self, other):
3962 """Create the Z3 expression left shift `other << self`.
3963
3964 Use the function LShR() for the right logical shift
3965
3966 >>> x = BitVec('x', 32)
3967 >>> 10 << x
3968 10 << x
3969 >>> (10 << x).sexpr()
3970 '(bvshl #x0000000a x)'
3971 """
3972 a, b = _coerce_exprs(self, other)
3973 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3974
3975
3977 """Bit-vector values."""
3978
3979 def as_long(self):
3980 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3981
3982 >>> v = BitVecVal(0xbadc0de, 32)
3983 >>> v
3984 195936478
3985 >>> print("0x%.8x" % v.as_long())
3986 0x0badc0de
3987 """
3988 return int(self.as_string())
3989
3991 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3992 The most significant bit is assumed to be the sign.
3993
3994 >>> BitVecVal(4, 3).as_signed_long()
3995 -4
3996 >>> BitVecVal(7, 3).as_signed_long()
3997 -1
3998 >>> BitVecVal(3, 3).as_signed_long()
3999 3
4000 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4001 -1
4002 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4003 -1
4004 """
4005 sz = self.size()
4006 val = self.as_long()
4007 if val >= 2**(sz - 1):
4008 val = val - 2**sz
4009 if val < -2**(sz - 1):
4010 val = val + 2**sz
4011 return int(val)
4012
4013 def as_string(self):
4014 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
4015
4017 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
4018
4019 def py_value(self):
4020 """Return the Python value of a Z3 bit-vector numeral."""
4021 return self.as_long()
4022
4023
4024
4025def is_bv(a):
4026 """Return `True` if `a` is a Z3 bit-vector expression.
4027
4028 >>> b = BitVec('b', 32)
4029 >>> is_bv(b)
4030 True
4031 >>> is_bv(b + 10)
4032 True
4033 >>> is_bv(Int('x'))
4034 False
4035 """
4036 return isinstance(a, BitVecRef)
4037
4038
4040 """Return `True` if `a` is a Z3 bit-vector numeral value.
4041
4042 >>> b = BitVec('b', 32)
4043 >>> is_bv_value(b)
4044 False
4045 >>> b = BitVecVal(10, 32)
4046 >>> b
4047 10
4048 >>> is_bv_value(b)
4049 True
4050 """
4051 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4052
4053
4054def BV2Int(a, is_signed=False):
4055 """Return the Z3 expression BV2Int(a).
4056
4057 >>> b = BitVec('b', 3)
4058 >>> BV2Int(b).sort()
4059 Int
4060 >>> x = Int('x')
4061 >>> x > BV2Int(b)
4062 x > BV2Int(b)
4063 >>> x > BV2Int(b, is_signed=False)
4064 x > BV2Int(b)
4065 >>> x > BV2Int(b, is_signed=True)
4066 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4067 >>> solve(x > BV2Int(b), b == 1, x < 3)
4068 [x = 2, b = 1]
4069 """
4070 if z3_debug():
4071 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4072 ctx = a.ctx
4073 # investigate problem with bv2int
4074 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4075
4076
4077def Int2BV(a, num_bits):
4078 """Return the z3 expression Int2BV(a, num_bits).
4079 It is a bit-vector of width num_bits and represents the
4080 modulo of a by 2^num_bits
4081 """
4082 ctx = a.ctx
4083 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4084
4085
4086def BitVecSort(sz, ctx=None):
4087 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4088
4089 >>> Byte = BitVecSort(8)
4090 >>> Word = BitVecSort(16)
4091 >>> Byte
4092 BitVec(8)
4093 >>> x = Const('x', Byte)
4094 >>> eq(x, BitVec('x', 8))
4095 True
4096 """
4097 ctx = _get_ctx(ctx)
4098 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4099
4100
4101def BitVecVal(val, bv, ctx=None):
4102 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4103
4104 >>> v = BitVecVal(10, 32)
4105 >>> v
4106 10
4107 >>> print("0x%.8x" % v.as_long())
4108 0x0000000a
4109 """
4110 if is_bv_sort(bv):
4111 ctx = bv.ctx
4112 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4113 else:
4114 ctx = _get_ctx(ctx)
4115 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4116
4117
4118def BitVec(name, bv, ctx=None):
4119 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4120 If `ctx=None`, then the global context is used.
4121
4122 >>> x = BitVec('x', 16)
4123 >>> is_bv(x)
4124 True
4125 >>> x.size()
4126 16
4127 >>> x.sort()
4128 BitVec(16)
4129 >>> word = BitVecSort(16)
4130 >>> x2 = BitVec('x', word)
4131 >>> eq(x, x2)
4132 True
4133 """
4134 if isinstance(bv, BitVecSortRef):
4135 ctx = bv.ctx
4136 else:
4137 ctx = _get_ctx(ctx)
4138 bv = BitVecSort(bv, ctx)
4139 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4140
4141
4142def BitVecs(names, bv, ctx=None):
4143 """Return a tuple of bit-vector constants of size bv.
4144
4145 >>> x, y, z = BitVecs('x y z', 16)
4146 >>> x.size()
4147 16
4148 >>> x.sort()
4149 BitVec(16)
4150 >>> Sum(x, y, z)
4151 0 + x + y + z
4152 >>> Product(x, y, z)
4153 1*x*y*z
4154 >>> simplify(Product(x, y, z))
4155 x*y*z
4156 """
4157 ctx = _get_ctx(ctx)
4158 if isinstance(names, str):
4159 names = names.split(" ")
4160 return [BitVec(name, bv, ctx) for name in names]
4161
4162
4163def Concat(*args):
4164 """Create a Z3 bit-vector concatenation expression.
4165
4166 >>> v = BitVecVal(1, 4)
4167 >>> Concat(v, v+1, v)
4168 Concat(Concat(1, 1 + 1), 1)
4169 >>> simplify(Concat(v, v+1, v))
4170 289
4171 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4172 121
4173 """
4174 args = _get_args(args)
4175 sz = len(args)
4176 if z3_debug():
4177 _z3_assert(sz >= 2, "At least two arguments expected.")
4178
4179 ctx = None
4180 for a in args:
4181 if is_expr(a):
4182 ctx = a.ctx
4183 break
4184 if is_seq(args[0]) or isinstance(args[0], str):
4185 args = [_coerce_seq(s, ctx) for s in args]
4186 if z3_debug():
4187 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4188 v = (Ast * sz)()
4189 for i in range(sz):
4190 v[i] = args[i].as_ast()
4191 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4192
4193 if is_re(args[0]):
4194 if z3_debug():
4195 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4196 v = (Ast * sz)()
4197 for i in range(sz):
4198 v[i] = args[i].as_ast()
4199 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4200
4201 if z3_debug():
4202 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4203 r = args[0]
4204 for i in range(sz - 1):
4205 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4206 return r
4207
4208
4209def Extract(high, low, a):
4210 """Create a Z3 bit-vector extraction expression.
4211 Extract is overloaded to also work on sequence extraction.
4212 The functions SubString and SubSeq are redirected to Extract.
4213 For this case, the arguments are reinterpreted as:
4214 high - is a sequence (string)
4215 low - is an offset
4216 a - is the length to be extracted
4217
4218 >>> x = BitVec('x', 8)
4219 >>> Extract(6, 2, x)
4220 Extract(6, 2, x)
4221 >>> Extract(6, 2, x).sort()
4222 BitVec(5)
4223 >>> simplify(Extract(StringVal("abcd"),2,1))
4224 "c"
4225 """
4226 if isinstance(high, str):
4227 high = StringVal(high)
4228 if is_seq(high):
4229 s = high
4230 offset, length = _coerce_exprs(low, a, s.ctx)
4231 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4232 if z3_debug():
4233 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4234 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4235 "First and second arguments must be non negative integers")
4236 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4237 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4238
4239
4241 if z3_debug():
4242 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4243
4244
4245def ULE(a, b):
4246 """Create the Z3 expression (unsigned) `other <= self`.
4247
4248 Use the operator <= for signed less than or equal to.
4249
4250 >>> x, y = BitVecs('x y', 32)
4251 >>> ULE(x, y)
4252 ULE(x, y)
4253 >>> (x <= y).sexpr()
4254 '(bvsle x y)'
4255 >>> ULE(x, y).sexpr()
4256 '(bvule x y)'
4257 """
4258 _check_bv_args(a, b)
4259 a, b = _coerce_exprs(a, b)
4260 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4261
4262
4263def ULT(a, b):
4264 """Create the Z3 expression (unsigned) `other < self`.
4265
4266 Use the operator < for signed less than.
4267
4268 >>> x, y = BitVecs('x y', 32)
4269 >>> ULT(x, y)
4270 ULT(x, y)
4271 >>> (x < y).sexpr()
4272 '(bvslt x y)'
4273 >>> ULT(x, y).sexpr()
4274 '(bvult x y)'
4275 """
4276 _check_bv_args(a, b)
4277 a, b = _coerce_exprs(a, b)
4278 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4279
4280
4281def UGE(a, b):
4282 """Create the Z3 expression (unsigned) `other >= self`.
4283
4284 Use the operator >= for signed greater than or equal to.
4285
4286 >>> x, y = BitVecs('x y', 32)
4287 >>> UGE(x, y)
4288 UGE(x, y)
4289 >>> (x >= y).sexpr()
4290 '(bvsge x y)'
4291 >>> UGE(x, y).sexpr()
4292 '(bvuge x y)'
4293 """
4294 _check_bv_args(a, b)
4295 a, b = _coerce_exprs(a, b)
4296 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4297
4298
4299def UGT(a, b):
4300 """Create the Z3 expression (unsigned) `other > self`.
4301
4302 Use the operator > for signed greater than.
4303
4304 >>> x, y = BitVecs('x y', 32)
4305 >>> UGT(x, y)
4306 UGT(x, y)
4307 >>> (x > y).sexpr()
4308 '(bvsgt x y)'
4309 >>> UGT(x, y).sexpr()
4310 '(bvugt x y)'
4311 """
4312 _check_bv_args(a, b)
4313 a, b = _coerce_exprs(a, b)
4314 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4315
4316
4317def UDiv(a, b):
4318 """Create the Z3 expression (unsigned) division `self / other`.
4319
4320 Use the operator / for signed division.
4321
4322 >>> x = BitVec('x', 32)
4323 >>> y = BitVec('y', 32)
4324 >>> UDiv(x, y)
4325 UDiv(x, y)
4326 >>> UDiv(x, y).sort()
4327 BitVec(32)
4328 >>> (x / y).sexpr()
4329 '(bvsdiv x y)'
4330 >>> UDiv(x, y).sexpr()
4331 '(bvudiv x y)'
4332 """
4333 _check_bv_args(a, b)
4334 a, b = _coerce_exprs(a, b)
4335 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4336
4337
4338def URem(a, b):
4339 """Create the Z3 expression (unsigned) remainder `self % other`.
4340
4341 Use the operator % for signed modulus, and SRem() for signed remainder.
4342
4343 >>> x = BitVec('x', 32)
4344 >>> y = BitVec('y', 32)
4345 >>> URem(x, y)
4346 URem(x, y)
4347 >>> URem(x, y).sort()
4348 BitVec(32)
4349 >>> (x % y).sexpr()
4350 '(bvsmod x y)'
4351 >>> URem(x, y).sexpr()
4352 '(bvurem x y)'
4353 """
4354 _check_bv_args(a, b)
4355 a, b = _coerce_exprs(a, b)
4356 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4357
4358
4359def SRem(a, b):
4360 """Create the Z3 expression signed remainder.
4361
4362 Use the operator % for signed modulus, and URem() for unsigned remainder.
4363
4364 >>> x = BitVec('x', 32)
4365 >>> y = BitVec('y', 32)
4366 >>> SRem(x, y)
4367 SRem(x, y)
4368 >>> SRem(x, y).sort()
4369 BitVec(32)
4370 >>> (x % y).sexpr()
4371 '(bvsmod x y)'
4372 >>> SRem(x, y).sexpr()
4373 '(bvsrem x y)'
4374 """
4375 _check_bv_args(a, b)
4376 a, b = _coerce_exprs(a, b)
4377 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4378
4379
4380def LShR(a, b):
4381 """Create the Z3 expression logical right shift.
4382
4383 Use the operator >> for the arithmetical right shift.
4384
4385 >>> x, y = BitVecs('x y', 32)
4386 >>> LShR(x, y)
4387 LShR(x, y)
4388 >>> (x >> y).sexpr()
4389 '(bvashr x y)'
4390 >>> LShR(x, y).sexpr()
4391 '(bvlshr x y)'
4392 >>> BitVecVal(4, 3)
4393 4
4394 >>> BitVecVal(4, 3).as_signed_long()
4395 -4
4396 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4397 -2
4398 >>> simplify(BitVecVal(4, 3) >> 1)
4399 6
4400 >>> simplify(LShR(BitVecVal(4, 3), 1))
4401 2
4402 >>> simplify(BitVecVal(2, 3) >> 1)
4403 1
4404 >>> simplify(LShR(BitVecVal(2, 3), 1))
4405 1
4406 """
4407 _check_bv_args(a, b)
4408 a, b = _coerce_exprs(a, b)
4409 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4410
4411
4412def RotateLeft(a, b):
4413 """Return an expression representing `a` rotated to the left `b` times.
4414
4415 >>> a, b = BitVecs('a b', 16)
4416 >>> RotateLeft(a, b)
4417 RotateLeft(a, b)
4418 >>> simplify(RotateLeft(a, 0))
4419 a
4420 >>> simplify(RotateLeft(a, 16))
4421 a
4422 """
4423 _check_bv_args(a, b)
4424 a, b = _coerce_exprs(a, b)
4425 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4426
4427
4428def RotateRight(a, b):
4429 """Return an expression representing `a` rotated to the right `b` times.
4430
4431 >>> a, b = BitVecs('a b', 16)
4432 >>> RotateRight(a, b)
4433 RotateRight(a, b)
4434 >>> simplify(RotateRight(a, 0))
4435 a
4436 >>> simplify(RotateRight(a, 16))
4437 a
4438 """
4439 _check_bv_args(a, b)
4440 a, b = _coerce_exprs(a, b)
4441 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4442
4443
4444def SignExt(n, a):
4445 """Return a bit-vector expression with `n` extra sign-bits.
4446
4447 >>> x = BitVec('x', 16)
4448 >>> n = SignExt(8, x)
4449 >>> n.size()
4450 24
4451 >>> n
4452 SignExt(8, x)
4453 >>> n.sort()
4454 BitVec(24)
4455 >>> v0 = BitVecVal(2, 2)
4456 >>> v0
4457 2
4458 >>> v0.size()
4459 2
4460 >>> v = simplify(SignExt(6, v0))
4461 >>> v
4462 254
4463 >>> v.size()
4464 8
4465 >>> print("%.x" % v.as_long())
4466 fe
4467 """
4468 if z3_debug():
4469 _z3_assert(_is_int(n), "First argument must be an integer")
4470 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4471 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4472
4473
4474def ZeroExt(n, a):
4475 """Return a bit-vector expression with `n` extra zero-bits.
4476
4477 >>> x = BitVec('x', 16)
4478 >>> n = ZeroExt(8, x)
4479 >>> n.size()
4480 24
4481 >>> n
4482 ZeroExt(8, x)
4483 >>> n.sort()
4484 BitVec(24)
4485 >>> v0 = BitVecVal(2, 2)
4486 >>> v0
4487 2
4488 >>> v0.size()
4489 2
4490 >>> v = simplify(ZeroExt(6, v0))
4491 >>> v
4492 2
4493 >>> v.size()
4494 8
4495 """
4496 if z3_debug():
4497 _z3_assert(_is_int(n), "First argument must be an integer")
4498 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4499 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4500
4501
4503 """Return an expression representing `n` copies of `a`.
4504
4505 >>> x = BitVec('x', 8)
4506 >>> n = RepeatBitVec(4, x)
4507 >>> n
4508 RepeatBitVec(4, x)
4509 >>> n.size()
4510 32
4511 >>> v0 = BitVecVal(10, 4)
4512 >>> print("%.x" % v0.as_long())
4513 a
4514 >>> v = simplify(RepeatBitVec(4, v0))
4515 >>> v.size()
4516 16
4517 >>> print("%.x" % v.as_long())
4518 aaaa
4519 """
4520 if z3_debug():
4521 _z3_assert(_is_int(n), "First argument must be an integer")
4522 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4523 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4524
4525
4527 """Return the reduction-and expression of `a`."""
4528 if z3_debug():
4529 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4530 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4531
4532
4533def BVRedOr(a):
4534 """Return the reduction-or expression of `a`."""
4535 if z3_debug():
4536 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4537 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4538
4539
4540def BVAddNoOverflow(a, b, signed):
4541 """A predicate the determines that bit-vector addition does not overflow"""
4542 _check_bv_args(a, b)
4543 a, b = _coerce_exprs(a, b)
4544 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4545
4546
4548 """A predicate the determines that signed bit-vector addition does not underflow"""
4549 _check_bv_args(a, b)
4550 a, b = _coerce_exprs(a, b)
4551 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4552
4553
4555 """A predicate the determines that bit-vector subtraction does not overflow"""
4556 _check_bv_args(a, b)
4557 a, b = _coerce_exprs(a, b)
4558 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4559
4560
4561def BVSubNoUnderflow(a, b, signed):
4562 """A predicate the determines that bit-vector subtraction does not underflow"""
4563 _check_bv_args(a, b)
4564 a, b = _coerce_exprs(a, b)
4565 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4566
4567
4569 """A predicate the determines that bit-vector signed division does not overflow"""
4570 _check_bv_args(a, b)
4571 a, b = _coerce_exprs(a, b)
4572 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4573
4574
4576 """A predicate the determines that bit-vector unary negation does not overflow"""
4577 if z3_debug():
4578 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4579 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4580
4581
4582def BVMulNoOverflow(a, b, signed):
4583 """A predicate the determines that bit-vector multiplication does not overflow"""
4584 _check_bv_args(a, b)
4585 a, b = _coerce_exprs(a, b)
4586 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4587
4588
4590 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4591 _check_bv_args(a, b)
4592 a, b = _coerce_exprs(a, b)
4593 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4594
4595
4596
4601
4603 """Array sorts."""
4604
4605 def domain(self):
4606 """Return the domain of the array sort `self`.
4607
4608 >>> A = ArraySort(IntSort(), BoolSort())
4609 >>> A.domain()
4610 Int
4611 """
4613
4614 def domain_n(self, i):
4615 """Return the domain of the array sort `self`.
4616 """
4617 return _to_sort_ref(Z3_get_array_sort_domain_n(self.ctx_ref(), self.ast, i), self.ctx)
4618
4619 def range(self):
4620 """Return the range of the array sort `self`.
4621
4622 >>> A = ArraySort(IntSort(), BoolSort())
4623 >>> A.range()
4624 Bool
4625 """
4626 return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
4627
4628
4630 """Array expressions. """
4631
4632 def sort(self):
4633 """Return the array sort of the array expression `self`.
4634
4635 >>> a = Array('a', IntSort(), BoolSort())
4636 >>> a.sort()
4637 Array(Int, Bool)
4638 """
4639 return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4640
4641 def domain(self):
4642 """Shorthand for `self.sort().domain()`.
4643
4644 >>> a = Array('a', IntSort(), BoolSort())
4645 >>> a.domain()
4646 Int
4647 """
4648 return self.sort().domain()
4649
4650 def domain_n(self, i):
4651 """Shorthand for self.sort().domain_n(i)`."""
4652 return self.sort().domain_n(i)
4653
4654 def range(self):
4655 """Shorthand for `self.sort().range()`.
4656
4657 >>> a = Array('a', IntSort(), BoolSort())
4658 >>> a.range()
4659 Bool
4660 """
4661 return self.sort().range()
4662
4663 def __getitem__(self, arg):
4664 """Return the Z3 expression `self[arg]`.
4665
4666 >>> a = Array('a', IntSort(), BoolSort())
4667 >>> i = Int('i')
4668 >>> a[i]
4669 a[i]
4670 >>> a[i].sexpr()
4671 '(select a i)'
4672 """
4673 return _array_select(self, arg)
4674
4675 def default(self):
4676 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)
4677
4678
4679def _array_select(ar, arg):
4680 if isinstance(arg, tuple):
4681 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4682 _args, sz = _to_ast_array(args)
4683 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4684 arg = ar.sort().domain().cast(arg)
4685 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4686
4687
4689 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4690
4691
4693 """Return `True` if `a` is a Z3 array expression.
4694
4695 >>> a = Array('a', IntSort(), IntSort())
4696 >>> is_array(a)
4697 True
4698 >>> is_array(Store(a, 0, 1))
4699 True
4700 >>> is_array(a[0])
4701 False
4702 """
4703 return isinstance(a, ArrayRef)
4704
4705
4707 """Return `True` if `a` is a Z3 constant array.
4708
4709 >>> a = K(IntSort(), 10)
4710 >>> is_const_array(a)
4711 True
4712 >>> a = Array('a', IntSort(), IntSort())
4713 >>> is_const_array(a)
4714 False
4715 """
4716 return is_app_of(a, Z3_OP_CONST_ARRAY)
4717
4718
4719def is_K(a):
4720 """Return `True` if `a` is a Z3 constant array.
4721
4722 >>> a = K(IntSort(), 10)
4723 >>> is_K(a)
4724 True
4725 >>> a = Array('a', IntSort(), IntSort())
4726 >>> is_K(a)
4727 False
4728 """
4729 return is_app_of(a, Z3_OP_CONST_ARRAY)
4730
4731
4732def is_map(a):
4733 """Return `True` if `a` is a Z3 map array expression.
4734
4735 >>> f = Function('f', IntSort(), IntSort())
4736 >>> b = Array('b', IntSort(), IntSort())
4737 >>> a = Map(f, b)
4738 >>> a
4739 Map(f, b)
4740 >>> is_map(a)
4741 True
4742 >>> is_map(b)
4743 False
4744 """
4745 return is_app_of(a, Z3_OP_ARRAY_MAP)
4746
4747
4749 """Return `True` if `a` is a Z3 default array expression.
4750 >>> d = Default(K(IntSort(), 10))
4751 >>> is_default(d)
4752 True
4753 """
4754 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4755
4756
4758 """Return the function declaration associated with a Z3 map array expression.
4759
4760 >>> f = Function('f', IntSort(), IntSort())
4761 >>> b = Array('b', IntSort(), IntSort())
4762 >>> a = Map(f, b)
4763 >>> eq(f, get_map_func(a))
4764 True
4765 >>> get_map_func(a)
4766 f
4767 >>> get_map_func(a)(0)
4768 f(0)
4769 """
4770 if z3_debug():
4771 _z3_assert(is_map(a), "Z3 array map expression expected.")
4772 return FuncDeclRef(
4774 a.ctx_ref(),
4775 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4776 ),
4777 ctx=a.ctx,
4778 )
4779
4780
4781def ArraySort(*sig):
4782 """Return the Z3 array sort with the given domain and range sorts.
4783
4784 >>> A = ArraySort(IntSort(), BoolSort())
4785 >>> A
4786 Array(Int, Bool)
4787 >>> A.domain()
4788 Int
4789 >>> A.range()
4790 Bool
4791 >>> AA = ArraySort(IntSort(), A)
4792 >>> AA
4793 Array(Int, Array(Int, Bool))
4794 """
4795 sig = _get_args(sig)
4796 if z3_debug():
4797 _z3_assert(len(sig) > 1, "At least two arguments expected")
4798 arity = len(sig) - 1
4799 r = sig[arity]
4800 d = sig[0]
4801 if z3_debug():
4802 for s in sig:
4803 _z3_assert(is_sort(s), "Z3 sort expected")
4804 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4805 ctx = d.ctx
4806 if len(sig) == 2:
4807 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4808 dom = (Sort * arity)()
4809 for i in range(arity):
4810 dom[i] = sig[i].ast
4811 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4812
4813
4814def Array(name, *sorts):
4815 """Return an array constant named `name` with the given domain and range sorts.
4816
4817 >>> a = Array('a', IntSort(), IntSort())
4818 >>> a.sort()
4819 Array(Int, Int)
4820 >>> a[0]
4821 a[0]
4822 """
4823 s = ArraySort(sorts)
4824 ctx = s.ctx
4825 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4826
4827
4828def Update(a, *args):
4829 """Return a Z3 store array expression.
4830
4831 >>> a = Array('a', IntSort(), IntSort())
4832 >>> i, v = Ints('i v')
4833 >>> s = Update(a, i, v)
4834 >>> s.sort()
4835 Array(Int, Int)
4836 >>> prove(s[i] == v)
4837 proved
4838 >>> j = Int('j')
4839 >>> prove(Implies(i != j, s[j] == a[j]))
4840 proved
4841 """
4842 if z3_debug():
4843 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4844 args = _get_args(args)
4845 ctx = a.ctx
4846 if len(args) <= 1:
4847 raise Z3Exception("array update requires index and value arguments")
4848 if len(args) == 2:
4849 i = args[0]
4850 v = args[1]
4851 i = a.sort().domain().cast(i)
4852 v = a.sort().range().cast(v)
4853 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4854 v = a.sort().range().cast(args[-1])
4855 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4856 _args, sz = _to_ast_array(idxs)
4857 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4858
4859
4860def Default(a):
4861 """ Return a default value for array expression.
4862 >>> b = K(IntSort(), 1)
4863 >>> prove(Default(b) == 1)
4864 proved
4865 """
4866 if z3_debug():
4867 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4868 return a.default()
4869
4870
4871def Store(a, *args):
4872 """Return a Z3 store array expression.
4873
4874 >>> a = Array('a', IntSort(), IntSort())
4875 >>> i, v = Ints('i v')
4876 >>> s = Store(a, i, v)
4877 >>> s.sort()
4878 Array(Int, Int)
4879 >>> prove(s[i] == v)
4880 proved
4881 >>> j = Int('j')
4882 >>> prove(Implies(i != j, s[j] == a[j]))
4883 proved
4884 """
4885 return Update(a, args)
4886
4887
4888def Select(a, *args):
4889 """Return a Z3 select array expression.
4890
4891 >>> a = Array('a', IntSort(), IntSort())
4892 >>> i = Int('i')
4893 >>> Select(a, i)
4894 a[i]
4895 >>> eq(Select(a, i), a[i])
4896 True
4897 """
4898 args = _get_args(args)
4899 if z3_debug():
4900 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4901 return a[args]
4902
4903
4904def Map(f, *args):
4905 """Return a Z3 map array expression.
4906
4907 >>> f = Function('f', IntSort(), IntSort(), IntSort())
4908 >>> a1 = Array('a1', IntSort(), IntSort())
4909 >>> a2 = Array('a2', IntSort(), IntSort())
4910 >>> b = Map(f, a1, a2)
4911 >>> b
4912 Map(f, a1, a2)
4913 >>> prove(b[0] == f(a1[0], a2[0]))
4914 proved
4915 """
4916 args = _get_args(args)
4917 if z3_debug():
4918 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
4919 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
4920 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
4921 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
4922 _args, sz = _to_ast_array(args)
4923 ctx = f.ctx
4924 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
4925
4926
4927def K(dom, v):
4928 """Return a Z3 constant array expression.
4929
4930 >>> a = K(IntSort(), 10)
4931 >>> a
4932 K(Int, 10)
4933 >>> a.sort()
4934 Array(Int, Int)
4935 >>> i = Int('i')
4936 >>> a[i]
4937 K(Int, 10)[i]
4938 >>> simplify(a[i])
4939 10
4940 """
4941 if z3_debug():
4942 _z3_assert(is_sort(dom), "Z3 sort expected")
4943 ctx = dom.ctx
4944 if not is_expr(v):
4945 v = _py2expr(v, ctx)
4946 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
4947
4948
4949def Ext(a, b):
4950 """Return extensionality index for one-dimensional arrays.
4951 >> a, b = Consts('a b', SetSort(IntSort()))
4952 >> Ext(a, b)
4953 Ext(a, b)
4954 """
4955 ctx = a.ctx
4956 if z3_debug():
4957 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
4958 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4959
4960
4961def SetHasSize(a, k):
4962 ctx = a.ctx
4963 k = _py2expr(k, ctx)
4964 return _to_expr_ref(Z3_mk_set_has_size(ctx.ref(), a.as_ast(), k.as_ast()), ctx)
4965
4966
4968 """Return `True` if `a` is a Z3 array select application.
4969
4970 >>> a = Array('a', IntSort(), IntSort())
4971 >>> is_select(a)
4972 False
4973 >>> i = Int('i')
4974 >>> is_select(a[i])
4975 True
4976 """
4977 return is_app_of(a, Z3_OP_SELECT)
4978
4979
4981 """Return `True` if `a` is a Z3 array store application.
4982
4983 >>> a = Array('a', IntSort(), IntSort())
4984 >>> is_store(a)
4985 False
4986 >>> is_store(Store(a, 0, 1))
4987 True
4988 """
4989 return is_app_of(a, Z3_OP_STORE)
4990
4991
4996
4997
4998def SetSort(s):
4999 """ Create a set sort over element sort s"""
5000 return ArraySort(s, BoolSort())
5001
5002
5004 """Create the empty set
5005 >>> EmptySet(IntSort())
5006 K(Int, False)
5007 """
5008 ctx = s.ctx
5009 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5010
5011
5012def FullSet(s):
5013 """Create the full set
5014 >>> FullSet(IntSort())
5015 K(Int, True)
5016 """
5017 ctx = s.ctx
5018 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5019
5020
5021def SetUnion(*args):
5022 """ Take the union of sets
5023 >>> a = Const('a', SetSort(IntSort()))
5024 >>> b = Const('b', SetSort(IntSort()))
5025 >>> SetUnion(a, b)
5026 union(a, b)
5027 """
5028 args = _get_args(args)
5029 ctx = _ctx_from_ast_arg_list(args)
5030 _args, sz = _to_ast_array(args)
5031 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5032
5033
5034def SetIntersect(*args):
5035 """ Take the union of sets
5036 >>> a = Const('a', SetSort(IntSort()))
5037 >>> b = Const('b', SetSort(IntSort()))
5038 >>> SetIntersect(a, b)
5039 intersection(a, b)
5040 """
5041 args = _get_args(args)
5042 ctx = _ctx_from_ast_arg_list(args)
5043 _args, sz = _to_ast_array(args)
5044 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5045
5046
5047def SetAdd(s, e):
5048 """ Add element e to set s
5049 >>> a = Const('a', SetSort(IntSort()))
5050 >>> SetAdd(a, 1)
5051 Store(a, 1, True)
5052 """
5053 ctx = _ctx_from_ast_arg_list([s, e])
5054 e = _py2expr(e, ctx)
5055 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5056
5057
5058def SetDel(s, e):
5059 """ Remove element e to set s
5060 >>> a = Const('a', SetSort(IntSort()))
5061 >>> SetDel(a, 1)
5062 Store(a, 1, False)
5063 """
5064 ctx = _ctx_from_ast_arg_list([s, e])
5065 e = _py2expr(e, ctx)
5066 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5067
5068
5070 """ The complement of set s
5071 >>> a = Const('a', SetSort(IntSort()))
5072 >>> SetComplement(a)
5073 complement(a)
5074 """
5075 ctx = s.ctx
5076 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5077
5078
5080 """ The set difference of a and b
5081 >>> a = Const('a', SetSort(IntSort()))
5082 >>> b = Const('b', SetSort(IntSort()))
5083 >>> SetDifference(a, b)
5084 setminus(a, b)
5085 """
5086 ctx = _ctx_from_ast_arg_list([a, b])
5087 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5088
5089
5090def IsMember(e, s):
5091 """ Check if e is a member of set s
5092 >>> a = Const('a', SetSort(IntSort()))
5093 >>> IsMember(1, a)
5094 a[1]
5095 """
5096 ctx = _ctx_from_ast_arg_list([s, e])
5097 e = _py2expr(e, ctx)
5098 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5099
5100
5101def IsSubset(a, b):
5102 """ Check if a is a subset of b
5103 >>> a = Const('a', SetSort(IntSort()))
5104 >>> b = Const('b', SetSort(IntSort()))
5105 >>> IsSubset(a, b)
5106 subset(a, b)
5107 """
5108 ctx = _ctx_from_ast_arg_list([a, b])
5109 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5110
5111
5112
5117
5119 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5120 if not isinstance(acc, tuple):
5121 return False
5122 if len(acc) != 2:
5123 return False
5124 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5125
5126
5128 """Helper class for declaring Z3 datatypes.
5129
5130 >>> List = Datatype('List')
5131 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5132 >>> List.declare('nil')
5133 >>> List = List.create()
5134 >>> # List is now a Z3 declaration
5135 >>> List.nil
5136 nil
5137 >>> List.cons(10, List.nil)
5138 cons(10, nil)
5139 >>> List.cons(10, List.nil).sort()
5140 List
5141 >>> cons = List.cons
5142 >>> nil = List.nil
5143 >>> car = List.car
5144 >>> cdr = List.cdr
5145 >>> n = cons(1, cons(0, nil))
5146 >>> n
5147 cons(1, cons(0, nil))
5148 >>> simplify(cdr(n))
5149 cons(0, nil)
5150 >>> simplify(car(n))
5151 1
5152 """
5153
5154 def __init__(self, name, ctx=None):
5155 self.ctx = _get_ctx(ctx)
5156 self.name = name
5158
5159 def __deepcopy__(self, memo={}):
5160 r = Datatype(self.name, self.ctx)
5161 r.constructors = copy.deepcopy(self.constructors)
5162 return r
5163
5164 def declare_core(self, name, rec_name, *args):
5165 if z3_debug():
5166 _z3_assert(isinstance(name, str), "String expected")
5167 _z3_assert(isinstance(rec_name, str), "String expected")
5168 _z3_assert(
5169 all([_valid_accessor(a) for a in args]),
5170 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5171 )
5172 self.constructors.append((name, rec_name, args))
5173
5174 def declare(self, name, *args):
5175 """Declare constructor named `name` with the given accessors `args`.
5176 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5177 or a reference to the datatypes being declared.
5178
5179 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5180 declares the constructor named `cons` that builds a new List using an integer and a List.
5181 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5182 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5183 we use the method create() to create the actual datatype in Z3.
5184
5185 >>> List = Datatype('List')
5186 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5187 >>> List.declare('nil')
5188 >>> List = List.create()
5189 """
5190 if z3_debug():
5191 _z3_assert(isinstance(name, str), "String expected")
5192 _z3_assert(name != "", "Constructor name cannot be empty")
5193 return self.declare_core(name, "is-" + name, *args)
5194
5195 def __repr__(self):
5196 return "Datatype(%s, %s)" % (self.name, self.constructors)
5197
5198 def create(self):
5199 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5200
5201 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5202
5203 >>> List = Datatype('List')
5204 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5205 >>> List.declare('nil')
5206 >>> List = List.create()
5207 >>> List.nil
5208 nil
5209 >>> List.cons(10, List.nil)
5210 cons(10, nil)
5211 """
5212 return CreateDatatypes([self])[0]
5213
5214
5216 """Auxiliary object used to create Z3 datatypes."""
5217
5218 def __init__(self, c, ctx):
5219 self.c = c
5220 self.ctx = ctx
5221
5222 def __del__(self):
5223 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5224 Z3_del_constructor(self.ctx.ref(), self.c)
5225
5226
5228 """Auxiliary object used to create Z3 datatypes."""
5229
5230 def __init__(self, c, ctx):
5231 self.c = c
5232 self.ctx = ctx
5233
5234 def __del__(self):
5235 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5236 Z3_del_constructor_list(self.ctx.ref(), self.c)
5237
5238
5240 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5241
5242 In the following example we define a Tree-List using two mutually recursive datatypes.
5243
5244 >>> TreeList = Datatype('TreeList')
5245 >>> Tree = Datatype('Tree')
5246 >>> # Tree has two constructors: leaf and node
5247 >>> Tree.declare('leaf', ('val', IntSort()))
5248 >>> # a node contains a list of trees
5249 >>> Tree.declare('node', ('children', TreeList))
5250 >>> TreeList.declare('nil')
5251 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5252 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5253 >>> Tree.val(Tree.leaf(10))
5254 val(leaf(10))
5255 >>> simplify(Tree.val(Tree.leaf(10)))
5256 10
5257 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5258 >>> n1
5259 node(cons(leaf(10), cons(leaf(20), nil)))
5260 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5261 >>> simplify(n2 == n1)
5262 False
5263 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5264 True
5265 """
5266 ds = _get_args(ds)
5267 if z3_debug():
5268 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5269 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5270 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5271 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5272 ctx = ds[0].ctx
5273 num = len(ds)
5274 names = (Symbol * num)()
5275 out = (Sort * num)()
5276 clists = (ConstructorList * num)()
5277 to_delete = []
5278 for i in range(num):
5279 d = ds[i]
5280 names[i] = to_symbol(d.name, ctx)
5281 num_cs = len(d.constructors)
5282 cs = (Constructor * num_cs)()
5283 for j in range(num_cs):
5284 c = d.constructors[j]
5285 cname = to_symbol(c[0], ctx)
5286 rname = to_symbol(c[1], ctx)
5287 fs = c[2]
5288 num_fs = len(fs)
5289 fnames = (Symbol * num_fs)()
5290 sorts = (Sort * num_fs)()
5291 refs = (ctypes.c_uint * num_fs)()
5292 for k in range(num_fs):
5293 fname = fs[k][0]
5294 ftype = fs[k][1]
5295 fnames[k] = to_symbol(fname, ctx)
5296 if isinstance(ftype, Datatype):
5297 if z3_debug():
5298 _z3_assert(
5299 ds.count(ftype) == 1,
5300 "One and only one occurrence of each datatype is expected",
5301 )
5302 sorts[k] = None
5303 refs[k] = ds.index(ftype)
5304 else:
5305 if z3_debug():
5306 _z3_assert(is_sort(ftype), "Z3 sort expected")
5307 sorts[k] = ftype.ast
5308 refs[k] = 0
5309 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5310 to_delete.append(ScopedConstructor(cs[j], ctx))
5311 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5312 to_delete.append(ScopedConstructorList(clists[i], ctx))
5313 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5314 result = []
5315 # Create a field for every constructor, recognizer and accessor
5316 for i in range(num):
5317 dref = DatatypeSortRef(out[i], ctx)
5318 num_cs = dref.num_constructors()
5319 for j in range(num_cs):
5320 cref = dref.constructor(j)
5321 cref_name = cref.name()
5322 cref_arity = cref.arity()
5323 if cref.arity() == 0:
5324 cref = cref()
5325 setattr(dref, cref_name, cref)
5326 rref = dref.recognizer(j)
5327 setattr(dref, "is_" + cref_name, rref)
5328 for k in range(cref_arity):
5329 aref = dref.accessor(j, k)
5330 setattr(dref, aref.name(), aref)
5331 result.append(dref)
5332 return tuple(result)
5333
5334
5336 """Datatype sorts."""
5337
5339 """Return the number of constructors in the given Z3 datatype.
5340
5341 >>> List = Datatype('List')
5342 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5343 >>> List.declare('nil')
5344 >>> List = List.create()
5345 >>> # List is now a Z3 declaration
5346 >>> List.num_constructors()
5347 2
5348 """
5350
5351 def constructor(self, idx):
5352 """Return a constructor of the datatype `self`.
5353
5354 >>> List = Datatype('List')
5355 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5356 >>> List.declare('nil')
5357 >>> List = List.create()
5358 >>> # List is now a Z3 declaration
5359 >>> List.num_constructors()
5360 2
5361 >>> List.constructor(0)
5362 cons
5363 >>> List.constructor(1)
5364 nil
5365 """
5366 if z3_debug():
5367 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5369
5370 def recognizer(self, idx):
5371 """In Z3, each constructor has an associated recognizer predicate.
5372
5373 If the constructor is named `name`, then the recognizer `is_name`.
5374
5375 >>> List = Datatype('List')
5376 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5377 >>> List.declare('nil')
5378 >>> List = List.create()
5379 >>> # List is now a Z3 declaration
5380 >>> List.num_constructors()
5381 2
5382 >>> List.recognizer(0)
5383 is(cons)
5384 >>> List.recognizer(1)
5385 is(nil)
5386 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5387 False
5388 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5389 True
5390 >>> l = Const('l', List)
5391 >>> simplify(List.is_cons(l))
5392 is(cons, l)
5393 """
5394 if z3_debug():
5395 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5396 return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
5397
5398 def accessor(self, i, j):
5399 """In Z3, each constructor has 0 or more accessor.
5400 The number of accessors is equal to the arity of the constructor.
5401
5402 >>> List = Datatype('List')
5403 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5404 >>> List.declare('nil')
5405 >>> List = List.create()
5406 >>> List.num_constructors()
5407 2
5408 >>> List.constructor(0)
5409 cons
5410 >>> num_accs = List.constructor(0).arity()
5411 >>> num_accs
5412 2
5413 >>> List.accessor(0, 0)
5414 car
5415 >>> List.accessor(0, 1)
5416 cdr
5417 >>> List.constructor(1)
5418 nil
5419 >>> num_accs = List.constructor(1).arity()
5420 >>> num_accs
5421 0
5422 """
5423 if z3_debug():
5424 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5425 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5426 return FuncDeclRef(
5428 ctx=self.ctx,
5429 )
5430
5431
5433 """Datatype expressions."""
5434
5435 def sort(self):
5436 """Return the datatype sort of the datatype expression `self`."""
5437 return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5438
5439def DatatypeSort(name, ctx = None):
5440 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype"""
5441 ctx = _get_ctx(ctx)
5442 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
5443
5444def TupleSort(name, sorts, ctx=None):
5445 """Create a named tuple sort base on a set of underlying sorts
5446 Example:
5447 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5448 """
5449 tuple = Datatype(name, ctx)
5450 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5451 tuple.declare(name, *projects)
5452 tuple = tuple.create()
5453 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5454
5455
5456def DisjointSum(name, sorts, ctx=None):
5457 """Create a named tagged union sort base on a set of underlying sorts
5458 Example:
5459 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5460 """
5461 sum = Datatype(name, ctx)
5462 for i in range(len(sorts)):
5463 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5464 sum = sum.create()
5465 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5466
5467
5468def EnumSort(name, values, ctx=None):
5469 """Return a new enumeration sort named `name` containing the given values.
5470
5471 The result is a pair (sort, list of constants).
5472 Example:
5473 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5474 """
5475 if z3_debug():
5476 _z3_assert(isinstance(name, str), "Name must be a string")
5477 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5478 _z3_assert(len(values) > 0, "At least one value expected")
5479 ctx = _get_ctx(ctx)
5480 num = len(values)
5481 _val_names = (Symbol * num)()
5482 for i in range(num):
5483 _val_names[i] = to_symbol(values[i], ctx)
5484 _values = (FuncDecl * num)()
5485 _testers = (FuncDecl * num)()
5486 name = to_symbol(name, ctx)
5487 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5488 V = []
5489 for i in range(num):
5490 V.append(FuncDeclRef(_values[i], ctx))
5491 V = [a() for a in V]
5492 return S, V
5493
5494
5499
5500
5502 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5503
5504 Consider using the function `args2params` to create instances of this object.
5505 """
5506
5507 def __init__(self, ctx=None, params=None):
5508 self.ctx = _get_ctx(ctx)
5509 if params is None:
5510 self.params = Z3_mk_params(self.ctx.ref())
5511 else:
5512 self.params = params
5513 Z3_params_inc_ref(self.ctx.ref(), self.params)
5514
5515 def __deepcopy__(self, memo={}):
5516 return ParamsRef(self.ctx, self.params)
5517
5518 def __del__(self):
5519 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5520 Z3_params_dec_ref(self.ctx.ref(), self.params)
5521
5522 def set(self, name, val):
5523 """Set parameter name with value val."""
5524 if z3_debug():
5525 _z3_assert(isinstance(name, str), "parameter name must be a string")
5526 name_sym = to_symbol(name, self.ctx)
5527 if isinstance(val, bool):
5528 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5529 elif _is_int(val):
5530 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5531 elif isinstance(val, float):
5532 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5533 elif isinstance(val, str):
5534 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5535 else:
5536 if z3_debug():
5537 _z3_assert(False, "invalid parameter value")
5538
5539 def __repr__(self):
5540 return Z3_params_to_string(self.ctx.ref(), self.params)
5541
5542 def validate(self, ds):
5543 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5544 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5545
5546
5547def args2params(arguments, keywords, ctx=None):
5548 """Convert python arguments into a Z3_params object.
5549 A ':' is added to the keywords, and '_' is replaced with '-'
5550
5551 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5552 (params model true relevancy 2 elim_and true)
5553 """
5554 if z3_debug():
5555 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5556 prev = None
5557 r = ParamsRef(ctx)
5558 for a in arguments:
5559 if prev is None:
5560 prev = a
5561 else:
5562 r.set(prev, a)
5563 prev = None
5564 for k in keywords:
5565 v = keywords[k]
5566 r.set(k, v)
5567 return r
5568
5569
5571 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5572 """
5573
5574 def __init__(self, descr, ctx=None):
5575 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5576 self.ctx = _get_ctx(ctx)
5577 self.descr = descr
5578 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5579
5580 def __deepcopy__(self, memo={}):
5581 return ParamsDescrsRef(self.descr, self.ctx)
5582
5583 def __del__(self):
5584 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5585 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5586
5587 def size(self):
5588 """Return the size of in the parameter description `self`.
5589 """
5590 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5591
5592 def __len__(self):
5593 """Return the size of in the parameter description `self`.
5594 """
5595 return self.size()
5596
5597 def get_name(self, i):
5598 """Return the i-th parameter name in the parameter description `self`.
5599 """
5600 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5601
5602 def get_kind(self, n):
5603 """Return the kind of the parameter named `n`.
5604 """
5605 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5606
5607 def get_documentation(self, n):
5608 """Return the documentation string of the parameter named `n`.
5609 """
5610 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5611
5612 def __getitem__(self, arg):
5613 if _is_int(arg):
5614 return self.get_name(arg)
5615 else:
5616 return self.get_kind(arg)
5617
5618 def __repr__(self):
5619 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5620
5621
5626
5627
5629 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5630
5631 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5632 A goal has a solution if one of its subgoals has a solution.
5633 A goal is unsatisfiable if all subgoals are unsatisfiable.
5634 """
5635
5636 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5637 if z3_debug():
5638 _z3_assert(goal is None or ctx is not None,
5639 "If goal is different from None, then ctx must be also different from None")
5640 self.ctx = _get_ctx(ctx)
5641 self.goal = goal
5642 if self.goal is None:
5643 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5644 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5645
5646 def __del__(self):
5647 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5648 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5649
5650 def depth(self):
5651 """Return the depth of the goal `self`.
5652 The depth corresponds to the number of tactics applied to `self`.
5653
5654 >>> x, y = Ints('x y')
5655 >>> g = Goal()
5656 >>> g.add(x == 0, y >= x + 1)
5657 >>> g.depth()
5658 0
5659 >>> r = Then('simplify', 'solve-eqs')(g)
5660 >>> # r has 1 subgoal
5661 >>> len(r)
5662 1
5663 >>> r[0].depth()
5664 2
5665 """
5666 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5667
5668 def inconsistent(self):
5669 """Return `True` if `self` contains the `False` constraints.
5670
5671 >>> x, y = Ints('x y')
5672 >>> g = Goal()
5673 >>> g.inconsistent()
5674 False
5675 >>> g.add(x == 0, x == 1)
5676 >>> g
5677 [x == 0, x == 1]
5678 >>> g.inconsistent()
5679 False
5680 >>> g2 = Tactic('propagate-values')(g)[0]
5681 >>> g2.inconsistent()
5682 True
5683 """
5684 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5685
5686 def prec(self):
5687 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5688
5689 >>> g = Goal()
5690 >>> g.prec() == Z3_GOAL_PRECISE
5691 True
5692 >>> x, y = Ints('x y')
5693 >>> g.add(x == y + 1)
5694 >>> g.prec() == Z3_GOAL_PRECISE
5695 True
5696 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5697 >>> g2 = t(g)[0]
5698 >>> g2
5699 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5700 >>> g2.prec() == Z3_GOAL_PRECISE
5701 False
5702 >>> g2.prec() == Z3_GOAL_UNDER
5703 True
5704 """
5705 return Z3_goal_precision(self.ctx.ref(), self.goal)
5706
5707 def precision(self):
5708 """Alias for `prec()`.
5709
5710 >>> g = Goal()
5711 >>> g.precision() == Z3_GOAL_PRECISE
5712 True
5713 """
5714 return self.prec()
5715
5716 def size(self):
5717 """Return the number of constraints in the goal `self`.
5718
5719 >>> g = Goal()
5720 >>> g.size()
5721 0
5722 >>> x, y = Ints('x y')
5723 >>> g.add(x == 0, y > x)
5724 >>> g.size()
5725 2
5726 """
5727 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5728
5729 def __len__(self):
5730 """Return the number of constraints in the goal `self`.
5731
5732 >>> g = Goal()
5733 >>> len(g)
5734 0
5735 >>> x, y = Ints('x y')
5736 >>> g.add(x == 0, y > x)
5737 >>> len(g)
5738 2
5739 """
5740 return self.size()
5741
5742 def get(self, i):
5743 """Return a constraint in the goal `self`.
5744
5745 >>> g = Goal()
5746 >>> x, y = Ints('x y')
5747 >>> g.add(x == 0, y > x)
5748 >>> g.get(0)
5749 x == 0
5750 >>> g.get(1)
5751 y > x
5752 """
5753 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5754
5755 def __getitem__(self, arg):
5756 """Return a constraint in the goal `self`.
5757
5758 >>> g = Goal()
5759 >>> x, y = Ints('x y')
5760 >>> g.add(x == 0, y > x)
5761 >>> g[0]
5762 x == 0
5763 >>> g[1]
5764 y > x
5765 """
5766 if arg >= len(self):
5767 raise IndexError
5768 return self.get(arg)
5769
5770 def assert_exprs(self, *args):
5771 """Assert constraints into the goal.
5772
5773 >>> x = Int('x')
5774 >>> g = Goal()
5775 >>> g.assert_exprs(x > 0, x < 2)
5776 >>> g
5777 [x > 0, x < 2]
5778 """
5779 args = _get_args(args)
5780 s = BoolSort(self.ctx)
5781 for arg in args:
5782 arg = s.cast(arg)
5783 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5784
5785 def append(self, *args):
5786 """Add constraints.
5787
5788 >>> x = Int('x')
5789 >>> g = Goal()
5790 >>> g.append(x > 0, x < 2)
5791 >>> g
5792 [x > 0, x < 2]
5793 """
5794 self.assert_exprs(*args)
5795
5796 def insert(self, *args):
5797 """Add constraints.
5798
5799 >>> x = Int('x')
5800 >>> g = Goal()
5801 >>> g.insert(x > 0, x < 2)
5802 >>> g
5803 [x > 0, x < 2]
5804 """
5805 self.assert_exprs(*args)
5806
5807 def add(self, *args):
5808 """Add constraints.
5809
5810 >>> x = Int('x')
5811 >>> g = Goal()
5812 >>> g.add(x > 0, x < 2)
5813 >>> g
5814 [x > 0, x < 2]
5815 """
5816 self.assert_exprs(*args)
5817
5818 def convert_model(self, model):
5819 """Retrieve model from a satisfiable goal
5820 >>> a, b = Ints('a b')
5821 >>> g = Goal()
5822 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5823 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5824 >>> r = t(g)
5825 >>> r[0]
5826 [Or(b == 0, b == 1), Not(0 <= b)]
5827 >>> r[1]
5828 [Or(b == 0, b == 1), Not(1 <= b)]
5829 >>> # Remark: the subgoal r[0] is unsatisfiable
5830 >>> # Creating a solver for solving the second subgoal
5831 >>> s = Solver()
5832 >>> s.add(r[1])
5833 >>> s.check()
5834 sat
5835 >>> s.model()
5836 [b = 0]
5837 >>> # Model s.model() does not assign a value to `a`
5838 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5839 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5840 >>> r[1].convert_model(s.model())
5841 [b = 0, a = 1]
5842 """
5843 if z3_debug():
5844 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5845 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5846
5847 def __repr__(self):
5848 return obj_to_string(self)
5849
5850 def sexpr(self):
5851 """Return a textual representation of the s-expression representing the goal."""
5852 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5853
5854 def dimacs(self, include_names=True):
5855 """Return a textual representation of the goal in DIMACS format."""
5856 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5857
5858 def translate(self, target):
5859 """Copy goal `self` to context `target`.
5860
5861 >>> x = Int('x')
5862 >>> g = Goal()
5863 >>> g.add(x > 10)
5864 >>> g
5865 [x > 10]
5866 >>> c2 = Context()
5867 >>> g2 = g.translate(c2)
5868 >>> g2
5869 [x > 10]
5870 >>> g.ctx == main_ctx()
5871 True
5872 >>> g2.ctx == c2
5873 True
5874 >>> g2.ctx == main_ctx()
5875 False
5876 """
5877 if z3_debug():
5878 _z3_assert(isinstance(target, Context), "target must be a context")
5879 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5880
5881 def __copy__(self):
5882 return self.translate(self.ctx)
5883
5884 def __deepcopy__(self, memo={}):
5885 return self.translate(self.ctx)
5886
5887 def simplify(self, *arguments, **keywords):
5888 """Return a new simplified goal.
5889
5890 This method is essentially invoking the simplify tactic.
5891
5892 >>> g = Goal()
5893 >>> x = Int('x')
5894 >>> g.add(x + 1 >= 2)
5895 >>> g
5896 [x + 1 >= 2]
5897 >>> g2 = g.simplify()
5898 >>> g2
5899 [x >= 1]
5900 >>> # g was not modified
5901 >>> g
5902 [x + 1 >= 2]
5903 """
5904 t = Tactic("simplify")
5905 return t.apply(self, *arguments, **keywords)[0]
5906
5907 def as_expr(self):
5908 """Return goal `self` as a single Z3 expression.
5909
5910 >>> x = Int('x')
5911 >>> g = Goal()
5912 >>> g.as_expr()
5913 True
5914 >>> g.add(x > 1)
5915 >>> g.as_expr()
5916 x > 1
5917 >>> g.add(x < 10)
5918 >>> g.as_expr()
5919 And(x > 1, x < 10)
5920 """
5921 sz = len(self)
5922 if sz == 0:
5923 return BoolVal(True, self.ctx)
5924 elif sz == 1:
5925 return self.get(0)
5926 else:
5927 return And([self.get(i) for i in range(len(self))], self.ctx)
5928
5929
5934
5935
5937 """A collection (vector) of ASTs."""
5938
5939 def __init__(self, v=None, ctx=None):
5940 self.vector = None
5941 if v is None:
5942 self.ctx = _get_ctx(ctx)
5943 self.vector = Z3_mk_ast_vector(self.ctx.ref())
5944 else:
5945 self.vector = v
5946 assert ctx is not None
5947 self.ctx = ctx
5948 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
5949
5950 def __del__(self):
5951 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
5952 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
5953
5954 def __len__(self):
5955 """Return the size of the vector `self`.
5956
5957 >>> A = AstVector()
5958 >>> len(A)
5959 0
5960 >>> A.push(Int('x'))
5961 >>> A.push(Int('x'))
5962 >>> len(A)
5963 2
5964 """
5965 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
5966
5967 def __getitem__(self, i):
5968 """Return the AST at position `i`.
5969
5970 >>> A = AstVector()
5971 >>> A.push(Int('x') + 1)
5972 >>> A.push(Int('y'))
5973 >>> A[0]
5974 x + 1
5975 >>> A[1]
5976 y
5977 """
5978
5979 if isinstance(i, int):
5980 if i < 0:
5981 i += self.__len__()
5982
5983 if i >= self.__len__():
5984 raise IndexError
5985 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
5986
5987 elif isinstance(i, slice):
5988 result = []
5989 for ii in range(*i.indices(self.__len__())):
5990 result.append(_to_ast_ref(
5991 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
5992 self.ctx,
5993 ))
5994 return result
5995
5996 def __setitem__(self, i, v):
5997 """Update AST at position `i`.
5998
5999 >>> A = AstVector()
6000 >>> A.push(Int('x') + 1)
6001 >>> A.push(Int('y'))
6002 >>> A[0]
6003 x + 1
6004 >>> A[0] = Int('x')
6005 >>> A[0]
6006 x
6007 """
6008 if i >= self.__len__():
6009 raise IndexError
6010 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6011
6012 def push(self, v):
6013 """Add `v` in the end of the vector.
6014
6015 >>> A = AstVector()
6016 >>> len(A)
6017 0
6018 >>> A.push(Int('x'))
6019 >>> len(A)
6020 1
6021 """
6022 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6023
6024 def resize(self, sz):
6025 """Resize the vector to `sz` elements.
6026
6027 >>> A = AstVector()
6028 >>> A.resize(10)
6029 >>> len(A)
6030 10
6031 >>> for i in range(10): A[i] = Int('x')
6032 >>> A[5]
6033 x
6034 """
6035 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6036
6037 def __contains__(self, item):
6038 """Return `True` if the vector contains `item`.
6039
6040 >>> x = Int('x')
6041 >>> A = AstVector()
6042 >>> x in A
6043 False
6044 >>> A.push(x)
6045 >>> x in A
6046 True
6047 >>> (x+1) in A
6048 False
6049 >>> A.push(x+1)
6050 >>> (x+1) in A
6051 True
6052 >>> A
6053 [x, x + 1]
6054 """
6055 for elem in self:
6056 if elem.eq(item):
6057 return True
6058 return False
6059
6060 def translate(self, other_ctx):
6061 """Copy vector `self` to context `other_ctx`.
6062
6063 >>> x = Int('x')
6064 >>> A = AstVector()
6065 >>> A.push(x)
6066 >>> c2 = Context()
6067 >>> B = A.translate(c2)
6068 >>> B
6069 [x]
6070 """
6071 return AstVector(
6072 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6073 ctx=other_ctx,
6074 )
6075
6076 def __copy__(self):
6077 return self.translate(self.ctx)
6078
6079 def __deepcopy__(self, memo={}):
6080 return self.translate(self.ctx)
6081
6082 def __repr__(self):
6083 return obj_to_string(self)
6084
6085 def sexpr(self):
6086 """Return a textual representation of the s-expression representing the vector."""
6087 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6088
6089
6094
6095
6097 """A mapping from ASTs to ASTs."""
6098
6099 def __init__(self, m=None, ctx=None):
6100 self.map = None
6101 if m is None:
6102 self.ctx = _get_ctx(ctx)
6103 self.map = Z3_mk_ast_map(self.ctx.ref())
6104 else:
6105 self.map = m
6106 assert ctx is not None
6107 self.ctx = ctx
6108 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6109
6110 def __deepcopy__(self, memo={}):
6111 return AstMap(self.map, self.ctx)
6112
6113 def __del__(self):
6114 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6115 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6116
6117 def __len__(self):
6118 """Return the size of the map.
6119
6120 >>> M = AstMap()
6121 >>> len(M)
6122 0
6123 >>> x = Int('x')
6124 >>> M[x] = IntVal(1)
6125 >>> len(M)
6126 1
6127 """
6128 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6129
6130 def __contains__(self, key):
6131 """Return `True` if the map contains key `key`.
6132
6133 >>> M = AstMap()
6134 >>> x = Int('x')
6135 >>> M[x] = x + 1
6136 >>> x in M
6137 True
6138 >>> x+1 in M
6139 False
6140 """
6141 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6142
6143 def __getitem__(self, key):
6144 """Retrieve the value associated with key `key`.
6145
6146 >>> M = AstMap()
6147 >>> x = Int('x')
6148 >>> M[x] = x + 1
6149 >>> M[x]
6150 x + 1
6151 """
6152 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6153
6154 def __setitem__(self, k, v):
6155 """Add/Update key `k` with value `v`.
6156
6157 >>> M = AstMap()
6158 >>> x = Int('x')
6159 >>> M[x] = x + 1
6160 >>> len(M)
6161 1
6162 >>> M[x]
6163 x + 1
6164 >>> M[x] = IntVal(1)
6165 >>> M[x]
6166 1
6167 """
6168 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6169
6170 def __repr__(self):
6171 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6172
6173 def erase(self, k):
6174 """Remove the entry associated with key `k`.
6175
6176 >>> M = AstMap()
6177 >>> x = Int('x')
6178 >>> M[x] = x + 1
6179 >>> len(M)
6180 1
6181 >>> M.erase(x)
6182 >>> len(M)
6183 0
6184 """
6185 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6186
6187 def reset(self):
6188 """Remove all entries from the map.
6189
6190 >>> M = AstMap()
6191 >>> x = Int('x')
6192 >>> M[x] = x + 1
6193 >>> M[x+x] = IntVal(1)
6194 >>> len(M)
6195 2
6196 >>> M.reset()
6197 >>> len(M)
6198 0
6199 """
6200 Z3_ast_map_reset(self.ctx.ref(), self.map)
6201
6202 def keys(self):
6203 """Return an AstVector containing all keys in the map.
6204
6205 >>> M = AstMap()
6206 >>> x = Int('x')
6207 >>> M[x] = x + 1
6208 >>> M[x+x] = IntVal(1)
6209 >>> M.keys()
6210 [x, x + x]
6211 """
6212 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6213
6214
6219
6220
6222 """Store the value of the interpretation of a function in a particular point."""
6223
6224 def __init__(self, entry, ctx):
6225 self.entry = entry
6226 self.ctx = ctx
6227 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6228
6229 def __deepcopy__(self, memo={}):
6230 return FuncEntry(self.entry, self.ctx)
6231
6232 def __del__(self):
6233 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6234 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6235
6236 def num_args(self):
6237 """Return the number of arguments in the given entry.
6238
6239 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6240 >>> s = Solver()
6241 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6242 >>> s.check()
6243 sat
6244 >>> m = s.model()
6245 >>> f_i = m[f]
6246 >>> f_i.num_entries()
6247 1
6248 >>> e = f_i.entry(0)
6249 >>> e.num_args()
6250 2
6251 """
6252 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6253
6254 def arg_value(self, idx):
6255 """Return the value of argument `idx`.
6256
6257 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6258 >>> s = Solver()
6259 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6260 >>> s.check()
6261 sat
6262 >>> m = s.model()
6263 >>> f_i = m[f]
6264 >>> f_i.num_entries()
6265 1
6266 >>> e = f_i.entry(0)
6267 >>> e
6268 [1, 2, 20]
6269 >>> e.num_args()
6270 2
6271 >>> e.arg_value(0)
6272 1
6273 >>> e.arg_value(1)
6274 2
6275 >>> try:
6276 ... e.arg_value(2)
6277 ... except IndexError:
6278 ... print("index error")
6279 index error
6280 """
6281 if idx >= self.num_args():
6282 raise IndexError
6283 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6284
6285 def value(self):
6286 """Return the value of the function at point `self`.
6287
6288 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6289 >>> s = Solver()
6290 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6291 >>> s.check()
6292 sat
6293 >>> m = s.model()
6294 >>> f_i = m[f]
6295 >>> f_i.num_entries()
6296 1
6297 >>> e = f_i.entry(0)
6298 >>> e
6299 [1, 2, 20]
6300 >>> e.num_args()
6301 2
6302 >>> e.value()
6303 20
6304 """
6305 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6306
6307 def as_list(self):
6308 """Return entry `self` as a Python list.
6309 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6310 >>> s = Solver()
6311 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6312 >>> s.check()
6313 sat
6314 >>> m = s.model()
6315 >>> f_i = m[f]
6316 >>> f_i.num_entries()
6317 1
6318 >>> e = f_i.entry(0)
6319 >>> e.as_list()
6320 [1, 2, 20]
6321 """
6322 args = [self.arg_value(i) for i in range(self.num_args())]
6323 args.append(self.value())
6324 return args
6325
6326 def __repr__(self):
6327 return repr(self.as_list())
6328
6329
6331 """Stores the interpretation of a function in a Z3 model."""
6332
6333 def __init__(self, f, ctx):
6334 self.f = f
6335 self.ctx = ctx
6336 if self.f is not None:
6337 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6338
6339 def __del__(self):
6340 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6341 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6342
6343 def else_value(self):
6344 """
6345 Return the `else` value for a function interpretation.
6346 Return None if Z3 did not specify the `else` value for
6347 this object.
6348
6349 >>> f = Function('f', IntSort(), IntSort())
6350 >>> s = Solver()
6351 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6352 >>> s.check()
6353 sat
6354 >>> m = s.model()
6355 >>> m[f]
6356 [2 -> 0, else -> 1]
6357 >>> m[f].else_value()
6358 1
6359 """
6360 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6361 if r:
6362 return _to_expr_ref(r, self.ctx)
6363 else:
6364 return None
6365
6366 def num_entries(self):
6367 """Return the number of entries/points in the function interpretation `self`.
6368
6369 >>> f = Function('f', IntSort(), IntSort())
6370 >>> s = Solver()
6371 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6372 >>> s.check()
6373 sat
6374 >>> m = s.model()
6375 >>> m[f]
6376 [2 -> 0, else -> 1]
6377 >>> m[f].num_entries()
6378 1
6379 """
6380 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6381
6382 def arity(self):
6383 """Return the number of arguments for each entry in the function interpretation `self`.
6384
6385 >>> f = Function('f', IntSort(), IntSort())
6386 >>> s = Solver()
6387 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6388 >>> s.check()
6389 sat
6390 >>> m = s.model()
6391 >>> m[f].arity()
6392 1
6393 """
6394 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6395
6396 def entry(self, idx):
6397 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6398
6399 >>> f = Function('f', IntSort(), IntSort())
6400 >>> s = Solver()
6401 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6402 >>> s.check()
6403 sat
6404 >>> m = s.model()
6405 >>> m[f]
6406 [2 -> 0, else -> 1]
6407 >>> m[f].num_entries()
6408 1
6409 >>> m[f].entry(0)
6410 [2, 0]
6411 """
6412 if idx >= self.num_entries():
6413 raise IndexError
6414 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6415
6416 def translate(self, other_ctx):
6417 """Copy model 'self' to context 'other_ctx'.
6418 """
6419 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6420
6421 def __copy__(self):
6422 return self.translate(self.ctx)
6423
6424 def __deepcopy__(self, memo={}):
6425 return self.translate(self.ctx)
6426
6427 def as_list(self):
6428 """Return the function interpretation as a Python list.
6429 >>> f = Function('f', IntSort(), IntSort())
6430 >>> s = Solver()
6431 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6432 >>> s.check()
6433 sat
6434 >>> m = s.model()
6435 >>> m[f]
6436 [2 -> 0, else -> 1]
6437 >>> m[f].as_list()
6438 [[2, 0], 1]
6439 """
6440 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6441 r.append(self.else_value())
6442 return r
6443
6444 def __repr__(self):
6445 return obj_to_string(self)
6446
6447
6449 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6450
6451 def __init__(self, m, ctx):
6452 assert ctx is not None
6453 self.model = m
6454 self.ctx = ctx
6455 Z3_model_inc_ref(self.ctx.ref(), self.model)
6456
6457 def __del__(self):
6458 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6459 Z3_model_dec_ref(self.ctx.ref(), self.model)
6460
6461 def __repr__(self):
6462 return obj_to_string(self)
6463
6464 def sexpr(self):
6465 """Return a textual representation of the s-expression representing the model."""
6466 return Z3_model_to_string(self.ctx.ref(), self.model)
6467
6468 def eval(self, t, model_completion=False):
6469 """Evaluate the expression `t` in the model `self`.
6470 If `model_completion` is enabled, then a default interpretation is automatically added
6471 for symbols that do not have an interpretation in the model `self`.
6472
6473 >>> x = Int('x')
6474 >>> s = Solver()
6475 >>> s.add(x > 0, x < 2)
6476 >>> s.check()
6477 sat
6478 >>> m = s.model()
6479 >>> m.eval(x + 1)
6480 2
6481 >>> m.eval(x == 1)
6482 True
6483 >>> y = Int('y')
6484 >>> m.eval(y + x)
6485 1 + y
6486 >>> m.eval(y)
6487 y
6488 >>> m.eval(y, model_completion=True)
6489 0
6490 >>> # Now, m contains an interpretation for y
6491 >>> m.eval(y + x)
6492 1
6493 """
6494 r = (Ast * 1)()
6495 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6496 return _to_expr_ref(r[0], self.ctx)
6497 raise Z3Exception("failed to evaluate expression in the model")
6498
6499 def evaluate(self, t, model_completion=False):
6500 """Alias for `eval`.
6501
6502 >>> x = Int('x')
6503 >>> s = Solver()
6504 >>> s.add(x > 0, x < 2)
6505 >>> s.check()
6506 sat
6507 >>> m = s.model()
6508 >>> m.evaluate(x + 1)
6509 2
6510 >>> m.evaluate(x == 1)
6511 True
6512 >>> y = Int('y')
6513 >>> m.evaluate(y + x)
6514 1 + y
6515 >>> m.evaluate(y)
6516 y
6517 >>> m.evaluate(y, model_completion=True)
6518 0
6519 >>> # Now, m contains an interpretation for y
6520 >>> m.evaluate(y + x)
6521 1
6522 """
6523 return self.eval(t, model_completion)
6524
6525 def __len__(self):
6526 """Return the number of constant and function declarations in the model `self`.
6527
6528 >>> f = Function('f', IntSort(), IntSort())
6529 >>> x = Int('x')
6530 >>> s = Solver()
6531 >>> s.add(x > 0, f(x) != x)
6532 >>> s.check()
6533 sat
6534 >>> m = s.model()
6535 >>> len(m)
6536 2
6537 """
6538 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6539 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6540 return num_consts + num_funcs
6541
6542 def get_interp(self, decl):
6543 """Return the interpretation for a given declaration or constant.
6544
6545 >>> f = Function('f', IntSort(), IntSort())
6546 >>> x = Int('x')
6547 >>> s = Solver()
6548 >>> s.add(x > 0, x < 2, f(x) == 0)
6549 >>> s.check()
6550 sat
6551 >>> m = s.model()
6552 >>> m[x]
6553 1
6554 >>> m[f]
6555 [else -> 0]
6556 """
6557 if z3_debug():
6558 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6559 if is_const(decl):
6560 decl = decl.decl()
6561 try:
6562 if decl.arity() == 0:
6563 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6564 if _r.value is None:
6565 return None
6566 r = _to_expr_ref(_r, self.ctx)
6567 if is_as_array(r):
6568 fi = self.get_interp(get_as_array_func(r))
6569 if fi is None:
6570 return fi
6571 e = fi.else_value()
6572 if e is None:
6573 return fi
6574 if fi.arity() != 1:
6575 return fi
6576 srt = decl.range()
6577 dom = srt.domain()
6578 e = K(dom, e)
6579 i = 0
6580 sz = fi.num_entries()
6581 n = fi.arity()
6582 while i < sz:
6583 fe = fi.entry(i)
6584 e = Store(e, fe.arg_value(0), fe.value())
6585 i += 1
6586 return e
6587 else:
6588 return r
6589 else:
6590 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6591 except Z3Exception:
6592 return None
6593
6594 def num_sorts(self):
6595 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6596
6597 >>> A = DeclareSort('A')
6598 >>> a, b = Consts('a b', A)
6599 >>> s = Solver()
6600 >>> s.add(a != b)
6601 >>> s.check()
6602 sat
6603 >>> m = s.model()
6604 >>> m.num_sorts()
6605 1
6606 """
6607 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6608
6609 def get_sort(self, idx):
6610 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6611
6612 >>> A = DeclareSort('A')
6613 >>> B = DeclareSort('B')
6614 >>> a1, a2 = Consts('a1 a2', A)
6615 >>> b1, b2 = Consts('b1 b2', B)
6616 >>> s = Solver()
6617 >>> s.add(a1 != a2, b1 != b2)
6618 >>> s.check()
6619 sat
6620 >>> m = s.model()
6621 >>> m.num_sorts()
6622 2
6623 >>> m.get_sort(0)
6624 A
6625 >>> m.get_sort(1)
6626 B
6627 """
6628 if idx >= self.num_sorts():
6629 raise IndexError
6630 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6631
6632 def sorts(self):
6633 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6634
6635 >>> A = DeclareSort('A')
6636 >>> B = DeclareSort('B')
6637 >>> a1, a2 = Consts('a1 a2', A)
6638 >>> b1, b2 = Consts('b1 b2', B)
6639 >>> s = Solver()
6640 >>> s.add(a1 != a2, b1 != b2)
6641 >>> s.check()
6642 sat
6643 >>> m = s.model()
6644 >>> m.sorts()
6645 [A, B]
6646 """
6647 return [self.get_sort(i) for i in range(self.num_sorts())]
6648
6649 def get_universe(self, s):
6650 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6651
6652 >>> A = DeclareSort('A')
6653 >>> a, b = Consts('a b', A)
6654 >>> s = Solver()
6655 >>> s.add(a != b)
6656 >>> s.check()
6657 sat
6658 >>> m = s.model()
6659 >>> m.get_universe(A)
6660 [A!val!1, A!val!0]
6661 """
6662 if z3_debug():
6663 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6664 try:
6665 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6666 except Z3Exception:
6667 return None
6668
6669 def __getitem__(self, idx):
6670 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6671 If `idx` is a declaration, then the actual interpretation is returned.
6672
6673 The elements can be retrieved using position or the actual declaration.
6674
6675 >>> f = Function('f', IntSort(), IntSort())
6676 >>> x = Int('x')
6677 >>> s = Solver()
6678 >>> s.add(x > 0, x < 2, f(x) == 0)
6679 >>> s.check()
6680 sat
6681 >>> m = s.model()
6682 >>> len(m)
6683 2
6684 >>> m[0]
6685 x
6686 >>> m[1]
6687 f
6688 >>> m[x]
6689 1
6690 >>> m[f]
6691 [else -> 0]
6692 >>> for d in m: print("%s -> %s" % (d, m[d]))
6693 x -> 1
6694 f -> [else -> 0]
6695 """
6696 if _is_int(idx):
6697 if idx >= len(self):
6698 raise IndexError
6699 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6700 if (idx < num_consts):
6701 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6702 else:
6703 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6704 if isinstance(idx, FuncDeclRef):
6705 return self.get_interp(idx)
6706 if is_const(idx):
6707 return self.get_interp(idx.decl())
6708 if isinstance(idx, SortRef):
6709 return self.get_universe(idx)
6710 if z3_debug():
6711 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6712 return None
6713
6714 def decls(self):
6715 """Return a list with all symbols that have an interpretation in the model `self`.
6716 >>> f = Function('f', IntSort(), IntSort())
6717 >>> x = Int('x')
6718 >>> s = Solver()
6719 >>> s.add(x > 0, x < 2, f(x) == 0)
6720 >>> s.check()
6721 sat
6722 >>> m = s.model()
6723 >>> m.decls()
6724 [x, f]
6725 """
6726 r = []
6727 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6728 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6729 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6730 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6731 return r
6732
6733 def update_value(self, x, value):
6734 """Update the interpretation of a constant"""
6735 if is_expr(x):
6736 x = x.decl()
6737 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6738 fi1 = value.f
6739 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6740 fi2 = FuncInterp(fi2, x.ctx)
6741 for i in range(value.num_entries()):
6742 e = value.entry(i)
6743 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6744 v = AstVector()
6745 for j in range(n):
6746 v.push(e.arg_value(j))
6747 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6748 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6749 return
6750 if not is_func_decl(x) or x.arity() != 0:
6751 raise Z3Exception("Expecting 0-ary function or constant expression")
6752 value = _py2expr(value)
6753 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6754
6755 def translate(self, target):
6756 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6757 """
6758 if z3_debug():
6759 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6760 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6761 return ModelRef(model, target)
6762
6763 def project(self, vars, fml):
6764 """Perform model-based projection on fml with respect to vars.
6765 Assume that the model satisfies fml. Then compute a projection fml_p, such
6766 that vars do not occur free in fml_p, fml_p is true in the model and
6767 fml_p => exists vars . fml
6768 """
6769 ctx = self.ctx.ref()
6770 _vars = (Ast * len(vars))()
6771 for i in range(len(vars)):
6772 _vars[i] = vars[i].as_ast()
6773 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6774
6775 def project_with_witness(self, vars, fml):
6776 """Perform model-based projection, but also include realizer terms for the projected variables"""
6777 ctx = self.ctx.ref()
6778 _vars = (Ast * len(vars))()
6779 for i in range(len(vars)):
6780 _vars[i] = vars[i].as_ast()
6781 defs = AstMap()
6782 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6783 result = _to_expr_ref(result, self.ctx)
6784 return result, defs
6785
6786
6787 def __copy__(self):
6788 return self.translate(self.ctx)
6789
6790 def __deepcopy__(self, memo={}):
6791 return self.translate(self.ctx)
6792
6793
6794def Model(ctx=None, eval = {}):
6795 ctx = _get_ctx(ctx)
6796 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6797 for k, v in eval.items():
6798 mdl.update_value(k, v)
6799 return mdl
6800
6801
6803 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6804 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6805
6806
6808 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6809 if z3_debug():
6810 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6811 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6812
6813
6818
6819
6821 """Statistics for `Solver.check()`."""
6822
6823 def __init__(self, stats, ctx):
6824 self.stats = stats
6825 self.ctx = ctx
6826 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6827
6828 def __deepcopy__(self, memo={}):
6829 return Statistics(self.stats, self.ctx)
6830
6831 def __del__(self):
6832 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6833 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6834
6835 def __repr__(self):
6836 if in_html_mode():
6837 out = io.StringIO()
6838 even = True
6839 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6840 for k, v in self:
6841 if even:
6842 out.write(u('<tr style="background-color:#CFCFCF">'))
6843 even = False
6844 else:
6845 out.write(u("<tr>"))
6846 even = True
6847 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6848 out.write(u("</table>"))
6849 return out.getvalue()
6850 else:
6851 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6852
6853 def __len__(self):
6854 """Return the number of statistical counters.
6855
6856 >>> x = Int('x')
6857 >>> s = Then('simplify', 'nlsat').solver()
6858 >>> s.add(x > 0)
6859 >>> s.check()
6860 sat
6861 >>> st = s.statistics()
6862 >>> len(st)
6863 7
6864 """
6865 return int(Z3_stats_size(self.ctx.ref(), self.stats))
6866
6867 def __getitem__(self, idx):
6868 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6869
6870 >>> x = Int('x')
6871 >>> s = Then('simplify', 'nlsat').solver()
6872 >>> s.add(x > 0)
6873 >>> s.check()
6874 sat
6875 >>> st = s.statistics()
6876 >>> len(st)
6877 7
6878 >>> st[0]
6879 ('nlsat propagations', 2)
6880 >>> st[1]
6881 ('nlsat restarts', 1)
6882 """
6883 if idx >= len(self):
6884 raise IndexError
6885 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6886 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6887 else:
6888 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6889 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
6890
6891 def keys(self):
6892 """Return the list of statistical counters.
6893
6894 >>> x = Int('x')
6895 >>> s = Then('simplify', 'nlsat').solver()
6896 >>> s.add(x > 0)
6897 >>> s.check()
6898 sat
6899 >>> st = s.statistics()
6900 """
6901 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
6902
6903 def get_key_value(self, key):
6904 """Return the value of a particular statistical counter.
6905
6906 >>> x = Int('x')
6907 >>> s = Then('simplify', 'nlsat').solver()
6908 >>> s.add(x > 0)
6909 >>> s.check()
6910 sat
6911 >>> st = s.statistics()
6912 >>> st.get_key_value('nlsat propagations')
6913 2
6914 """
6915 for idx in range(len(self)):
6916 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
6917 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6918 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6919 else:
6920 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6921 raise Z3Exception("unknown key")
6922
6923 def __getattr__(self, name):
6924 """Access the value of statistical using attributes.
6925
6926 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
6927 we should use '_' (e.g., 'nlsat_propagations').
6928
6929 >>> x = Int('x')
6930 >>> s = Then('simplify', 'nlsat').solver()
6931 >>> s.add(x > 0)
6932 >>> s.check()
6933 sat
6934 >>> st = s.statistics()
6935 >>> st.nlsat_propagations
6936 2
6937 >>> st.nlsat_stages
6938 2
6939 """
6940 key = name.replace("_", " ")
6941 try:
6942 return self.get_key_value(key)
6943 except Z3Exception:
6944 raise AttributeError
6945
6946
6951
6952
6954 """Represents the result of a satisfiability check: sat, unsat, unknown.
6955
6956 >>> s = Solver()
6957 >>> s.check()
6958 sat
6959 >>> r = s.check()
6960 >>> isinstance(r, CheckSatResult)
6961 True
6962 """
6963
6964 def __init__(self, r):
6965 self.r = r
6966
6967 def __deepcopy__(self, memo={}):
6968 return CheckSatResult(self.r)
6969
6970 def __eq__(self, other):
6971 return isinstance(other, CheckSatResult) and self.r == other.r
6972
6973 def __ne__(self, other):
6974 return not self.__eq__(other)
6975
6976 def __repr__(self):
6977 if in_html_mode():
6978 if self.r == Z3_L_TRUE:
6979 return "<b>sat</b>"
6980 elif self.r == Z3_L_FALSE:
6981 return "<b>unsat</b>"
6982 else:
6983 return "<b>unknown</b>"
6984 else:
6985 if self.r == Z3_L_TRUE:
6986 return "sat"
6987 elif self.r == Z3_L_FALSE:
6988 return "unsat"
6989 else:
6990 return "unknown"
6991
6992 def _repr_html_(self):
6993 in_html = in_html_mode()
6994 set_html_mode(True)
6995 res = repr(self)
6996 set_html_mode(in_html)
6997 return res
6998
6999
7000sat = CheckSatResult(Z3_L_TRUE)
7001unsat = CheckSatResult(Z3_L_FALSE)
7002unknown = CheckSatResult(Z3_L_UNDEF)
7003
7004
7006 """
7007 Solver API provides methods for implementing the main SMT 2.0 commands:
7008 push, pop, check, get-model, etc.
7009 """
7010
7011 def __init__(self, solver=None, ctx=None, logFile=None):
7012 assert solver is None or ctx is not None
7013 self.ctx = _get_ctx(ctx)
7014 self.backtrack_level = 4000000000
7015 self.solver = None
7016 if solver is None:
7017 self.solver = Z3_mk_solver(self.ctx.ref())
7018 else:
7019 self.solver = solver
7020 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7021 if logFile is not None:
7022 self.set("smtlib2_log", logFile)
7023
7024 def __del__(self):
7025 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7026 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7027
7028 def __enter__(self):
7029 self.push()
7030 return self
7031
7032 def __exit__(self, *exc_info):
7033 self.pop()
7034
7035 def set(self, *args, **keys):
7036 """Set a configuration option.
7037 The method `help()` return a string containing all available options.
7038
7039 >>> s = Solver()
7040 >>> # The option MBQI can be set using three different approaches.
7041 >>> s.set(mbqi=True)
7042 >>> s.set('MBQI', True)
7043 >>> s.set(':mbqi', True)
7044 """
7045 p = args2params(args, keys, self.ctx)
7046 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7047
7048 def push(self):
7049 """Create a backtracking point.
7050
7051 >>> x = Int('x')
7052 >>> s = Solver()
7053 >>> s.add(x > 0)
7054 >>> s
7055 [x > 0]
7056 >>> s.push()
7057 >>> s.add(x < 1)
7058 >>> s
7059 [x > 0, x < 1]
7060 >>> s.check()
7061 unsat
7062 >>> s.pop()
7063 >>> s.check()
7064 sat
7065 >>> s
7066 [x > 0]
7067 """
7068 Z3_solver_push(self.ctx.ref(), self.solver)
7069
7070 def pop(self, num=1):
7071 """Backtrack \\c num backtracking points.
7072
7073 >>> x = Int('x')
7074 >>> s = Solver()
7075 >>> s.add(x > 0)
7076 >>> s
7077 [x > 0]
7078 >>> s.push()
7079 >>> s.add(x < 1)
7080 >>> s
7081 [x > 0, x < 1]
7082 >>> s.check()
7083 unsat
7084 >>> s.pop()
7085 >>> s.check()
7086 sat
7087 >>> s
7088 [x > 0]
7089 """
7090 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7091
7092 def num_scopes(self):
7093 """Return the current number of backtracking points.
7094
7095 >>> s = Solver()
7096 >>> s.num_scopes()
7097 0
7098 >>> s.push()
7099 >>> s.num_scopes()
7100 1
7101 >>> s.push()
7102 >>> s.num_scopes()
7103 2
7104 >>> s.pop()
7105 >>> s.num_scopes()
7106 1
7107 """
7108 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7109
7110 def reset(self):
7111 """Remove all asserted constraints and backtracking points created using `push()`.
7112
7113 >>> x = Int('x')
7114 >>> s = Solver()
7115 >>> s.add(x > 0)
7116 >>> s
7117 [x > 0]
7118 >>> s.reset()
7119 >>> s
7120 []
7121 """
7122 Z3_solver_reset(self.ctx.ref(), self.solver)
7123
7124 def assert_exprs(self, *args):
7125 """Assert constraints into the solver.
7126
7127 >>> x = Int('x')
7128 >>> s = Solver()
7129 >>> s.assert_exprs(x > 0, x < 2)
7130 >>> s
7131 [x > 0, x < 2]
7132 """
7133 args = _get_args(args)
7134 s = BoolSort(self.ctx)
7135 for arg in args:
7136 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7137 for f in arg:
7138 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7139 else:
7140 arg = s.cast(arg)
7141 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7142
7143 def add(self, *args):
7144 """Assert constraints into the solver.
7145
7146 >>> x = Int('x')
7147 >>> s = Solver()
7148 >>> s.add(x > 0, x < 2)
7149 >>> s
7150 [x > 0, x < 2]
7151 """
7152 self.assert_exprs(*args)
7153
7154 def __iadd__(self, fml):
7155 self.add(fml)
7156 return self
7157
7158 def append(self, *args):
7159 """Assert constraints into the solver.
7160
7161 >>> x = Int('x')
7162 >>> s = Solver()
7163 >>> s.append(x > 0, x < 2)
7164 >>> s
7165 [x > 0, x < 2]
7166 """
7167 self.assert_exprs(*args)
7168
7169 def insert(self, *args):
7170 """Assert constraints into the solver.
7171
7172 >>> x = Int('x')
7173 >>> s = Solver()
7174 >>> s.insert(x > 0, x < 2)
7175 >>> s
7176 [x > 0, x < 2]
7177 """
7178 self.assert_exprs(*args)
7179
7180 def assert_and_track(self, a, p):
7181 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7182
7183 If `p` is a string, it will be automatically converted into a Boolean constant.
7184
7185 >>> x = Int('x')
7186 >>> p3 = Bool('p3')
7187 >>> s = Solver()
7188 >>> s.set(unsat_core=True)
7189 >>> s.assert_and_track(x > 0, 'p1')
7190 >>> s.assert_and_track(x != 1, 'p2')
7191 >>> s.assert_and_track(x < 0, p3)
7192 >>> print(s.check())
7193 unsat
7194 >>> c = s.unsat_core()
7195 >>> len(c)
7196 2
7197 >>> Bool('p1') in c
7198 True
7199 >>> Bool('p2') in c
7200 False
7201 >>> p3 in c
7202 True
7203 """
7204 if isinstance(p, str):
7205 p = Bool(p, self.ctx)
7206 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7207 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7208 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7209
7210 def check(self, *assumptions):
7211 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7212
7213 >>> x = Int('x')
7214 >>> s = Solver()
7215 >>> s.check()
7216 sat
7217 >>> s.add(x > 0, x < 2)
7218 >>> s.check()
7219 sat
7220 >>> s.model().eval(x)
7221 1
7222 >>> s.add(x < 1)
7223 >>> s.check()
7224 unsat
7225 >>> s.reset()
7226 >>> s.add(2**x == 4)
7227 >>> s.check()
7228 unknown
7229 """
7230 s = BoolSort(self.ctx)
7231 assumptions = _get_args(assumptions)
7232 num = len(assumptions)
7233 _assumptions = (Ast * num)()
7234 for i in range(num):
7235 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7236 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7237 return CheckSatResult(r)
7238
7239 def model(self):
7240 """Return a model for the last `check()`.
7241
7242 This function raises an exception if
7243 a model is not available (e.g., last `check()` returned unsat).
7244
7245 >>> s = Solver()
7246 >>> a = Int('a')
7247 >>> s.add(a + 2 == 0)
7248 >>> s.check()
7249 sat
7250 >>> s.model()
7251 [a = -2]
7252 """
7253 try:
7254 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7255 except Z3Exception:
7256 raise Z3Exception("model is not available")
7257
7258 def import_model_converter(self, other):
7259 """Import model converter from other into the current solver"""
7260 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7261
7262 def interrupt(self):
7263 """Interrupt the execution of the solver object.
7264 Remarks: This ensures that the interrupt applies only
7265 to the given solver object and it applies only if it is running.
7266 """
7267 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7268
7269 def unsat_core(self):
7270 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7271
7272 These are the assumptions Z3 used in the unsatisfiability proof.
7273 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7274 They may be also used to "retract" assumptions. Note that, assumptions are not really
7275 "soft constraints", but they can be used to implement them.
7276
7277 >>> p1, p2, p3 = Bools('p1 p2 p3')
7278 >>> x, y = Ints('x y')
7279 >>> s = Solver()
7280 >>> s.add(Implies(p1, x > 0))
7281 >>> s.add(Implies(p2, y > x))
7282 >>> s.add(Implies(p2, y < 1))
7283 >>> s.add(Implies(p3, y > -3))
7284 >>> s.check(p1, p2, p3)
7285 unsat
7286 >>> core = s.unsat_core()
7287 >>> len(core)
7288 2
7289 >>> p1 in core
7290 True
7291 >>> p2 in core
7292 True
7293 >>> p3 in core
7294 False
7295 >>> # "Retracting" p2
7296 >>> s.check(p1, p3)
7297 sat
7298 """
7299 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7300
7301 def consequences(self, assumptions, variables):
7302 """Determine fixed values for the variables based on the solver state and assumptions.
7303 >>> s = Solver()
7304 >>> a, b, c, d = Bools('a b c d')
7305 >>> s.add(Implies(a,b), Implies(b, c))
7306 >>> s.consequences([a],[b,c,d])
7307 (sat, [Implies(a, b), Implies(a, c)])
7308 >>> s.consequences([Not(c),d],[a,b,c,d])
7309 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7310 """
7311 if isinstance(assumptions, list):
7312 _asms = AstVector(None, self.ctx)
7313 for a in assumptions:
7314 _asms.push(a)
7315 assumptions = _asms
7316 if isinstance(variables, list):
7317 _vars = AstVector(None, self.ctx)
7318 for a in variables:
7319 _vars.push(a)
7320 variables = _vars
7321 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7322 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7323 consequences = AstVector(None, self.ctx)
7324 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7325 variables.vector, consequences.vector)
7326 sz = len(consequences)
7327 consequences = [consequences[i] for i in range(sz)]
7328 return CheckSatResult(r), consequences
7329
7330 def from_file(self, filename):
7331 """Parse assertions from a file"""
7332 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7333
7334 def from_string(self, s):
7335 """Parse assertions from a string"""
7336 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7337
7338 def cube(self, vars=None):
7339 """Get set of cubes
7340 The method takes an optional set of variables that restrict which
7341 variables may be used as a starting point for cubing.
7342 If vars is not None, then the first case split is based on a variable in
7343 this set.
7344 """
7345 self.cube_vs = AstVector(None, self.ctx)
7346 if vars is not None:
7347 for v in vars:
7348 self.cube_vs.push(v)
7349 while True:
7350 lvl = self.backtrack_level
7351 self.backtrack_level = 4000000000
7352 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7353 if (len(r) == 1 and is_false(r[0])):
7354 return
7355 yield r
7356 if (len(r) == 0):
7357 return
7358
7359 def cube_vars(self):
7360 """Access the set of variables that were touched by the most recently generated cube.
7361 This set of variables can be used as a starting point for additional cubes.
7362 The idea is that variables that appear in clauses that are reduced by the most recent
7363 cube are likely more useful to cube on."""
7364 return self.cube_vs
7365
7366 def root(self, t):
7367 """Retrieve congruence closure root of the term t relative to the current search state
7368 The function primarily works for SimpleSolver. Terms and variables that are
7369 eliminated during pre-processing are not visible to the congruence closure.
7370 """
7371 t = _py2expr(t, self.ctx)
7372 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7373
7374 def next(self, t):
7375 """Retrieve congruence closure sibling of the term t relative to the current search state
7376 The function primarily works for SimpleSolver. Terms and variables that are
7377 eliminated during pre-processing are not visible to the congruence closure.
7378 """
7379 t = _py2expr(t, self.ctx)
7380 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7381
7382 def explain_congruent(self, a, b):
7383 """Explain congruence of a and b relative to the current search state"""
7384 a = _py2expr(a, self.ctx)
7385 b = _py2expr(b, self.ctx)
7386 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7387
7388 def solve_for1(self, t):
7389 """Retrieve a solution for t relative to linear equations maintained in the current state.
7390 The function primarily works for SimpleSolver and when there is a solution using linear arithmetic."""
7391 t = _py2expr(t, self.ctx)
7392 return _to_expr_ref(Z3_solver_solve_for1(self.ctx.ref(), self.solver, t.ast), self.ctx)
7393
7394 def solve_for(self, ts):
7395 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7396 vars = AstVector(ctx=self.ctx);
7397 terms = AstVector(ctx=self.ctx);
7398 guards = AstVector(ctx=self.ctx);
7399 for t in ts:
7400 t = _py2expr(t, self.ctx)
7401 vars.push(t)
7402 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7403 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7404
7405
7406 def proof(self):
7407 """Return a proof for the last `check()`. Proof construction must be enabled."""
7408 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7409
7410 def assertions(self):
7411 """Return an AST vector containing all added constraints.
7412
7413 >>> s = Solver()
7414 >>> s.assertions()
7415 []
7416 >>> a = Int('a')
7417 >>> s.add(a > 0)
7418 >>> s.add(a < 10)
7419 >>> s.assertions()
7420 [a > 0, a < 10]
7421 """
7422 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7423
7424 def units(self):
7425 """Return an AST vector containing all currently inferred units.
7426 """
7427 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7428
7429 def non_units(self):
7430 """Return an AST vector containing all atomic formulas in solver state that are not units.
7431 """
7432 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7433
7434 def trail_levels(self):
7435 """Return trail and decision levels of the solver state after a check() call.
7436 """
7437 trail = self.trail()
7438 levels = (ctypes.c_uint * len(trail))()
7439 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7440 return trail, levels
7441
7442 def set_initial_value(self, var, value):
7443 """initialize the solver's state by setting the initial value of var to value
7444 """
7445 s = var.sort()
7446 value = s.cast(value)
7447 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7448
7449 def trail(self):
7450 """Return trail of the solver state after a check() call.
7451 """
7452 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7453
7454 def statistics(self):
7455 """Return statistics for the last `check()`.
7456
7457 >>> s = SimpleSolver()
7458 >>> x = Int('x')
7459 >>> s.add(x > 0)
7460 >>> s.check()
7461 sat
7462 >>> st = s.statistics()
7463 >>> st.get_key_value('final checks')
7464 1
7465 >>> len(st) > 0
7466 True
7467 >>> st[0] != 0
7468 True
7469 """
7470 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7471
7472 def reason_unknown(self):
7473 """Return a string describing why the last `check()` returned `unknown`.
7474
7475 >>> x = Int('x')
7476 >>> s = SimpleSolver()
7477 >>> s.add(2**x == 4)
7478 >>> s.check()
7479 unknown
7480 >>> s.reason_unknown()
7481 '(incomplete (theory arithmetic))'
7482 """
7483 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7484
7485 def help(self):
7486 """Display a string describing all available options."""
7487 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7488
7489 def param_descrs(self):
7490 """Return the parameter description set."""
7491 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7492
7493 def __repr__(self):
7494 """Return a formatted string with all added constraints."""
7495 return obj_to_string(self)
7496
7497 def translate(self, target):
7498 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7499
7500 >>> c1 = Context()
7501 >>> c2 = Context()
7502 >>> s1 = Solver(ctx=c1)
7503 >>> s2 = s1.translate(c2)
7504 """
7505 if z3_debug():
7506 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7507 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7508 return Solver(solver, target)
7509
7510 def __copy__(self):
7511 return self.translate(self.ctx)
7512
7513 def __deepcopy__(self, memo={}):
7514 return self.translate(self.ctx)
7515
7516 def sexpr(self):
7517 """Return a formatted string (in Lisp-like format) with all added constraints.
7518 We say the string is in s-expression format.
7519
7520 >>> x = Int('x')
7521 >>> s = Solver()
7522 >>> s.add(x > 0)
7523 >>> s.add(x < 2)
7524 >>> r = s.sexpr()
7525 """
7526 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7527
7528 def dimacs(self, include_names=True):
7529 """Return a textual representation of the solver in DIMACS format."""
7530 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7531
7532 def to_smt2(self):
7533 """return SMTLIB2 formatted benchmark for solver's assertions"""
7534 es = self.assertions()
7535 sz = len(es)
7536 sz1 = sz
7537 if sz1 > 0:
7538 sz1 -= 1
7539 v = (Ast * sz1)()
7540 for i in range(sz1):
7541 v[i] = es[i].as_ast()
7542 if sz > 0:
7543 e = es[sz1].as_ast()
7544 else:
7545 e = BoolVal(True, self.ctx).as_ast()
7546 return Z3_benchmark_to_smtlib_string(
7547 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7548 )
7549
7550
7551def SolverFor(logic, ctx=None, logFile=None):
7552 """Create a solver customized for the given logic.
7553
7554 The parameter `logic` is a string. It should be contains
7555 the name of a SMT-LIB logic.
7556 See http://www.smtlib.org/ for the name of all available logics.
7557
7558 >>> s = SolverFor("QF_LIA")
7559 >>> x = Int('x')
7560 >>> s.add(x > 0)
7561 >>> s.add(x < 2)
7562 >>> s.check()
7563 sat
7564 >>> s.model()
7565 [x = 1]
7566 """
7567 ctx = _get_ctx(ctx)
7568 logic = to_symbol(logic)
7569 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7570
7571
7572def SimpleSolver(ctx=None, logFile=None):
7573 """Return a simple general purpose solver with limited amount of preprocessing.
7574
7575 >>> s = SimpleSolver()
7576 >>> x = Int('x')
7577 >>> s.add(x > 0)
7578 >>> s.check()
7579 sat
7580 """
7581 ctx = _get_ctx(ctx)
7582 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7583
7584#########################################
7585#
7586# Fixedpoint
7587#
7588#########################################
7589
7590
7591class Fixedpoint(Z3PPObject):
7592 """Fixedpoint API provides methods for solving with recursive predicates"""
7593
7594 def __init__(self, fixedpoint=None, ctx=None):
7595 assert fixedpoint is None or ctx is not None
7596 self.ctx = _get_ctx(ctx)
7597 self.fixedpoint = None
7598 if fixedpoint is None:
7599 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7600 else:
7601 self.fixedpoint = fixedpoint
7602 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7603 self.vars = []
7604
7605 def __deepcopy__(self, memo={}):
7606 return FixedPoint(self.fixedpoint, self.ctx)
7607
7608 def __del__(self):
7609 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7610 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7611
7612 def set(self, *args, **keys):
7613 """Set a configuration option. The method `help()` return a string containing all available options.
7614 """
7615 p = args2params(args, keys, self.ctx)
7616 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7617
7618 def help(self):
7619 """Display a string describing all available options."""
7620 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7621
7622 def param_descrs(self):
7623 """Return the parameter description set."""
7624 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7625
7626 def assert_exprs(self, *args):
7627 """Assert constraints as background axioms for the fixedpoint solver."""
7628 args = _get_args(args)
7629 s = BoolSort(self.ctx)
7630 for arg in args:
7631 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7632 for f in arg:
7633 f = self.abstract(f)
7634 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7635 else:
7636 arg = s.cast(arg)
7637 arg = self.abstract(arg)
7638 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7639
7640 def add(self, *args):
7641 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7642 self.assert_exprs(*args)
7643
7644 def __iadd__(self, fml):
7645 self.add(fml)
7646 return self
7647
7648 def append(self, *args):
7649 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7650 self.assert_exprs(*args)
7651
7652 def insert(self, *args):
7653 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7654 self.assert_exprs(*args)
7655
7656 def add_rule(self, head, body=None, name=None):
7657 """Assert rules defining recursive predicates to the fixedpoint solver.
7658 >>> a = Bool('a')
7659 >>> b = Bool('b')
7660 >>> s = Fixedpoint()
7661 >>> s.register_relation(a.decl())
7662 >>> s.register_relation(b.decl())
7663 >>> s.fact(a)
7664 >>> s.rule(b, a)
7665 >>> s.query(b)
7666 sat
7667 """
7668 if name is None:
7669 name = ""
7670 name = to_symbol(name, self.ctx)
7671 if body is None:
7672 head = self.abstract(head)
7673 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7674 else:
7675 body = _get_args(body)
7676 f = self.abstract(Implies(And(body, self.ctx), head))
7677 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7678
7679 def rule(self, head, body=None, name=None):
7680 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7681 self.add_rule(head, body, name)
7682
7683 def fact(self, head, name=None):
7684 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7685 self.add_rule(head, None, name)
7686
7687 def query(self, *query):
7688 """Query the fixedpoint engine whether formula is derivable.
7689 You can also pass an tuple or list of recursive predicates.
7690 """
7691 query = _get_args(query)
7692 sz = len(query)
7693 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7694 _decls = (FuncDecl * sz)()
7695 i = 0
7696 for q in query:
7697 _decls[i] = q.ast
7698 i = i + 1
7699 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7700 else:
7701 if sz == 1:
7702 query = query[0]
7703 else:
7704 query = And(query, self.ctx)
7705 query = self.abstract(query, False)
7706 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7707 return CheckSatResult(r)
7708
7709 def query_from_lvl(self, lvl, *query):
7710 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7711 """
7712 query = _get_args(query)
7713 sz = len(query)
7714 if sz >= 1 and isinstance(query[0], FuncDecl):
7715 _z3_assert(False, "unsupported")
7716 else:
7717 if sz == 1:
7718 query = query[0]
7719 else:
7720 query = And(query)
7721 query = self.abstract(query, False)
7722 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7723 return CheckSatResult(r)
7724
7725 def update_rule(self, head, body, name):
7726 """update rule"""
7727 if name is None:
7728 name = ""
7729 name = to_symbol(name, self.ctx)
7730 body = _get_args(body)
7731 f = self.abstract(Implies(And(body, self.ctx), head))
7732 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7733
7734 def get_answer(self):
7735 """Retrieve answer from last query call."""
7736 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7737 return _to_expr_ref(r, self.ctx)
7738
7739 def get_ground_sat_answer(self):
7740 """Retrieve a ground cex from last query call."""
7741 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7742 return _to_expr_ref(r, self.ctx)
7743
7744 def get_rules_along_trace(self):
7745 """retrieve rules along the counterexample trace"""
7746 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7747
7748 def get_rule_names_along_trace(self):
7749 """retrieve rule names along the counterexample trace"""
7750 # this is a hack as I don't know how to return a list of symbols from C++;
7751 # obtain names as a single string separated by semicolons
7752 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7753 # split into individual names
7754 return names.split(";")
7755
7756 def get_num_levels(self, predicate):
7757 """Retrieve number of levels used for predicate in PDR engine"""
7758 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7759
7760 def get_cover_delta(self, level, predicate):
7761 """Retrieve properties known about predicate for the level'th unfolding.
7762 -1 is treated as the limit (infinity)
7763 """
7764 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7765 return _to_expr_ref(r, self.ctx)
7766
7767 def add_cover(self, level, predicate, property):
7768 """Add property to predicate for the level'th unfolding.
7769 -1 is treated as infinity (infinity)
7770 """
7771 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7772
7773 def register_relation(self, *relations):
7774 """Register relation as recursive"""
7775 relations = _get_args(relations)
7776 for f in relations:
7777 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7778
7779 def set_predicate_representation(self, f, *representations):
7780 """Control how relation is represented"""
7781 representations = _get_args(representations)
7782 representations = [to_symbol(s) for s in representations]
7783 sz = len(representations)
7784 args = (Symbol * sz)()
7785 for i in range(sz):
7786 args[i] = representations[i]
7787 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7788
7789 def parse_string(self, s):
7790 """Parse rules and queries from a string"""
7791 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7792
7793 def parse_file(self, f):
7794 """Parse rules and queries from a file"""
7795 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7796
7797 def get_rules(self):
7798 """retrieve rules that have been added to fixedpoint context"""
7799 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7800
7801 def get_assertions(self):
7802 """retrieve assertions that have been added to fixedpoint context"""
7803 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7804
7805 def __repr__(self):
7806 """Return a formatted string with all added rules and constraints."""
7807 return self.sexpr()
7808
7809 def sexpr(self):
7810 """Return a formatted string (in Lisp-like format) with all added constraints.
7811 We say the string is in s-expression format.
7812 """
7813 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7814
7815 def to_string(self, queries):
7816 """Return a formatted string (in Lisp-like format) with all added constraints.
7817 We say the string is in s-expression format.
7818 Include also queries.
7819 """
7820 args, len = _to_ast_array(queries)
7821 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7822
7823 def statistics(self):
7824 """Return statistics for the last `query()`.
7825 """
7826 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7827
7828 def reason_unknown(self):
7829 """Return a string describing why the last `query()` returned `unknown`.
7830 """
7831 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7832
7833 def declare_var(self, *vars):
7834 """Add variable or several variables.
7835 The added variable or variables will be bound in the rules
7836 and queries
7837 """
7838 vars = _get_args(vars)
7839 for v in vars:
7840 self.vars += [v]
7841
7842 def abstract(self, fml, is_forall=True):
7843 if self.vars == []:
7844 return fml
7845 if is_forall:
7846 return ForAll(self.vars, fml)
7847 else:
7848 return Exists(self.vars, fml)
7849
7850
7851#########################################
7852#
7853# Finite domains
7854#
7855#########################################
7856
7857class FiniteDomainSortRef(SortRef):
7858 """Finite domain sort."""
7859
7860 def size(self):
7861 """Return the size of the finite domain sort"""
7862 r = (ctypes.c_ulonglong * 1)()
7863 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7864 return r[0]
7865 else:
7866 raise Z3Exception("Failed to retrieve finite domain sort size")
7867
7868
7869def FiniteDomainSort(name, sz, ctx=None):
7870 """Create a named finite domain sort of a given size sz"""
7871 if not isinstance(name, Symbol):
7872 name = to_symbol(name)
7873 ctx = _get_ctx(ctx)
7874 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7875
7876
7877def is_finite_domain_sort(s):
7878 """Return True if `s` is a Z3 finite-domain sort.
7879
7880 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7881 True
7882 >>> is_finite_domain_sort(IntSort())
7883 False
7884 """
7885 return isinstance(s, FiniteDomainSortRef)
7886
7887
7888class FiniteDomainRef(ExprRef):
7889 """Finite-domain expressions."""
7890
7891 def sort(self):
7892 """Return the sort of the finite-domain expression `self`."""
7893 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7894
7895 def as_string(self):
7896 """Return a Z3 floating point expression as a Python string."""
7897 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7898
7899
7900def is_finite_domain(a):
7901 """Return `True` if `a` is a Z3 finite-domain expression.
7902
7903 >>> s = FiniteDomainSort('S', 100)
7904 >>> b = Const('b', s)
7905 >>> is_finite_domain(b)
7906 True
7907 >>> is_finite_domain(Int('x'))
7908 False
7909 """
7910 return isinstance(a, FiniteDomainRef)
7911
7912
7913class FiniteDomainNumRef(FiniteDomainRef):
7914 """Integer values."""
7915
7916 def as_long(self):
7917 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7918
7919 >>> s = FiniteDomainSort('S', 100)
7920 >>> v = FiniteDomainVal(3, s)
7921 >>> v
7922 3
7923 >>> v.as_long() + 1
7924 4
7925 """
7926 return int(self.as_string())
7927
7928 def as_string(self):
7929 """Return a Z3 finite-domain numeral as a Python string.
7930
7931 >>> s = FiniteDomainSort('S', 100)
7932 >>> v = FiniteDomainVal(42, s)
7933 >>> v.as_string()
7934 '42'
7935 """
7936 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
7937
7938
7939def FiniteDomainVal(val, sort, ctx=None):
7940 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
7941
7942 >>> s = FiniteDomainSort('S', 256)
7943 >>> FiniteDomainVal(255, s)
7944 255
7945 >>> FiniteDomainVal('100', s)
7946 100
7947 """
7948 if z3_debug():
7949 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
7950 ctx = sort.ctx
7951 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
7952
7953
7954def is_finite_domain_value(a):
7955 """Return `True` if `a` is a Z3 finite-domain value.
7956
7957 >>> s = FiniteDomainSort('S', 100)
7958 >>> b = Const('b', s)
7959 >>> is_finite_domain_value(b)
7960 False
7961 >>> b = FiniteDomainVal(10, s)
7962 >>> b
7963 10
7964 >>> is_finite_domain_value(b)
7965 True
7966 """
7967 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
7968
7969
7970#########################################
7971#
7972# Optimize
7973#
7974#########################################
7975
7976class OptimizeObjective:
7977 def __init__(self, opt, value, is_max):
7978 self._opt = opt
7979 self._value = value
7980 self._is_max = is_max
7981
7982 def lower(self):
7983 opt = self._opt
7984 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7985
7986 def upper(self):
7987 opt = self._opt
7988 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7989
7990 def lower_values(self):
7991 opt = self._opt
7992 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7993
7994 def upper_values(self):
7995 opt = self._opt
7996 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7997
7998 def value(self):
7999 if self._is_max:
8000 return self.upper()
8001 else:
8002 return self.lower()
8003
8004 def __str__(self):
8005 return "%s:%s" % (self._value, self._is_max)
8006
8007
8008_on_models = {}
8009
8010
8011def _global_on_model(ctx):
8012 (fn, mdl) = _on_models[ctx]
8013 fn(mdl)
8014
8015
8016_on_model_eh = on_model_eh_type(_global_on_model)
8017
8018
8019class Optimize(Z3PPObject):
8020 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8021
8022 def __init__(self, optimize=None, ctx=None):
8023 self.ctx = _get_ctx(ctx)
8024 if optimize is None:
8025 self.optimize = Z3_mk_optimize(self.ctx.ref())
8026 else:
8027 self.optimize = optimize
8028 self._on_models_id = None
8029 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8030
8031 def __deepcopy__(self, memo={}):
8032 return Optimize(self.optimize, self.ctx)
8033
8034 def __del__(self):
8035 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8036 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8037 if self._on_models_id is not None:
8038 del _on_models[self._on_models_id]
8039
8040 def __enter__(self):
8041 self.push()
8042 return self
8043
8044 def __exit__(self, *exc_info):
8045 self.pop()
8046
8047 def set(self, *args, **keys):
8048 """Set a configuration option.
8049 The method `help()` return a string containing all available options.
8050 """
8051 p = args2params(args, keys, self.ctx)
8052 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8053
8054 def help(self):
8055 """Display a string describing all available options."""
8056 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8057
8058 def param_descrs(self):
8059 """Return the parameter description set."""
8060 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8061
8062 def assert_exprs(self, *args):
8063 """Assert constraints as background axioms for the optimize solver."""
8064 args = _get_args(args)
8065 s = BoolSort(self.ctx)
8066 for arg in args:
8067 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8068 for f in arg:
8069 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8070 else:
8071 arg = s.cast(arg)
8072 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8073
8074 def add(self, *args):
8075 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8076 self.assert_exprs(*args)
8077
8078 def __iadd__(self, fml):
8079 self.add(fml)
8080 return self
8081
8082 def assert_and_track(self, a, p):
8083 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8084
8085 If `p` is a string, it will be automatically converted into a Boolean constant.
8086
8087 >>> x = Int('x')
8088 >>> p3 = Bool('p3')
8089 >>> s = Optimize()
8090 >>> s.assert_and_track(x > 0, 'p1')
8091 >>> s.assert_and_track(x != 1, 'p2')
8092 >>> s.assert_and_track(x < 0, p3)
8093 >>> print(s.check())
8094 unsat
8095 >>> c = s.unsat_core()
8096 >>> len(c)
8097 2
8098 >>> Bool('p1') in c
8099 True
8100 >>> Bool('p2') in c
8101 False
8102 >>> p3 in c
8103 True
8104 """
8105 if isinstance(p, str):
8106 p = Bool(p, self.ctx)
8107 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8108 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8109 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8110
8111 def add_soft(self, arg, weight="1", id=None):
8112 """Add soft constraint with optional weight and optional identifier.
8113 If no weight is supplied, then the penalty for violating the soft constraint
8114 is 1.
8115 Soft constraints are grouped by identifiers. Soft constraints that are
8116 added without identifiers are grouped by default.
8117 """
8118 if _is_int(weight):
8119 weight = "%d" % weight
8120 elif isinstance(weight, float):
8121 weight = "%f" % weight
8122 if not isinstance(weight, str):
8123 raise Z3Exception("weight should be a string or an integer")
8124 if id is None:
8125 id = ""
8126 id = to_symbol(id, self.ctx)
8127
8128 def asoft(a):
8129 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8130 return OptimizeObjective(self, v, False)
8131 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8132 return [asoft(a) for a in arg]
8133 return asoft(arg)
8134
8135 def set_initial_value(self, var, value):
8136 """initialize the solver's state by setting the initial value of var to value
8137 """
8138 s = var.sort()
8139 value = s.cast(value)
8140 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8141
8142 def maximize(self, arg):
8143 """Add objective function to maximize."""
8144 return OptimizeObjective(
8145 self,
8146 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8147 is_max=True,
8148 )
8149
8150 def minimize(self, arg):
8151 """Add objective function to minimize."""
8152 return OptimizeObjective(
8153 self,
8154 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8155 is_max=False,
8156 )
8157
8158 def push(self):
8159 """create a backtracking point for added rules, facts and assertions"""
8160 Z3_optimize_push(self.ctx.ref(), self.optimize)
8161
8162 def pop(self):
8163 """restore to previously created backtracking point"""
8164 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8165
8166 def check(self, *assumptions):
8167 """Check consistency and produce optimal values."""
8168 assumptions = _get_args(assumptions)
8169 num = len(assumptions)
8170 _assumptions = (Ast * num)()
8171 for i in range(num):
8172 _assumptions[i] = assumptions[i].as_ast()
8173 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8174
8175 def reason_unknown(self):
8176 """Return a string that describes why the last `check()` returned `unknown`."""
8177 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8178
8179 def model(self):
8180 """Return a model for the last check()."""
8181 try:
8182 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8183 except Z3Exception:
8184 raise Z3Exception("model is not available")
8185
8186 def unsat_core(self):
8187 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8188
8189 def lower(self, obj):
8190 if not isinstance(obj, OptimizeObjective):
8191 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8192 return obj.lower()
8193
8194 def upper(self, obj):
8195 if not isinstance(obj, OptimizeObjective):
8196 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8197 return obj.upper()
8198
8199 def lower_values(self, obj):
8200 if not isinstance(obj, OptimizeObjective):
8201 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8202 return obj.lower_values()
8203
8204 def upper_values(self, obj):
8205 if not isinstance(obj, OptimizeObjective):
8206 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8207 return obj.upper_values()
8208
8209 def from_file(self, filename):
8210 """Parse assertions and objectives from a file"""
8211 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8212
8213 def from_string(self, s):
8214 """Parse assertions and objectives from a string"""
8215 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8216
8217 def assertions(self):
8218 """Return an AST vector containing all added constraints."""
8219 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8220
8221 def objectives(self):
8222 """returns set of objective functions"""
8223 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8224
8225 def __repr__(self):
8226 """Return a formatted string with all added rules and constraints."""
8227 return self.sexpr()
8228
8229 def sexpr(self):
8230 """Return a formatted string (in Lisp-like format) with all added constraints.
8231 We say the string is in s-expression format.
8232 """
8233 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8234
8235 def statistics(self):
8236 """Return statistics for the last check`.
8237 """
8238 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8239
8240 def set_on_model(self, on_model):
8241 """Register a callback that is invoked with every incremental improvement to
8242 objective values. The callback takes a model as argument.
8243 The life-time of the model is limited to the callback so the
8244 model has to be (deep) copied if it is to be used after the callback
8245 """
8246 id = len(_on_models) + 41
8247 mdl = Model(self.ctx)
8248 _on_models[id] = (on_model, mdl)
8249 self._on_models_id = id
8250 Z3_optimize_register_model_eh(
8251 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8252 )
8253
8254
8255#########################################
8256#
8257# ApplyResult
8258#
8259#########################################
8260class ApplyResult(Z3PPObject):
8261 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8262 It also contains model and proof converters.
8263 """
8264
8265 def __init__(self, result, ctx):
8266 self.result = result
8267 self.ctx = ctx
8268 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8269
8270 def __deepcopy__(self, memo={}):
8271 return ApplyResult(self.result, self.ctx)
8272
8273 def __del__(self):
8274 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8275 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8276
8277 def __len__(self):
8278 """Return the number of subgoals in `self`.
8279
8280 >>> a, b = Ints('a b')
8281 >>> g = Goal()
8282 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8283 >>> t = Tactic('split-clause')
8284 >>> r = t(g)
8285 >>> len(r)
8286 2
8287 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8288 >>> len(t(g))
8289 4
8290 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8291 >>> len(t(g))
8292 1
8293 """
8294 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8295
8296 def __getitem__(self, idx):
8297 """Return one of the subgoals stored in ApplyResult object `self`.
8298
8299 >>> a, b = Ints('a b')
8300 >>> g = Goal()
8301 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8302 >>> t = Tactic('split-clause')
8303 >>> r = t(g)
8304 >>> r[0]
8305 [a == 0, Or(b == 0, b == 1), a > b]
8306 >>> r[1]
8307 [a == 1, Or(b == 0, b == 1), a > b]
8308 """
8309 if idx >= len(self):
8310 raise IndexError
8311 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8312
8313 def __repr__(self):
8314 return obj_to_string(self)
8315
8316 def sexpr(self):
8317 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8318 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8319
8320 def as_expr(self):
8321 """Return a Z3 expression consisting of all subgoals.
8322
8323 >>> x = Int('x')
8324 >>> g = Goal()
8325 >>> g.add(x > 1)
8326 >>> g.add(Or(x == 2, x == 3))
8327 >>> r = Tactic('simplify')(g)
8328 >>> r
8329 [[Not(x <= 1), Or(x == 2, x == 3)]]
8330 >>> r.as_expr()
8331 And(Not(x <= 1), Or(x == 2, x == 3))
8332 >>> r = Tactic('split-clause')(g)
8333 >>> r
8334 [[x > 1, x == 2], [x > 1, x == 3]]
8335 >>> r.as_expr()
8336 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8337 """
8338 sz = len(self)
8339 if sz == 0:
8340 return BoolVal(False, self.ctx)
8341 elif sz == 1:
8342 return self[0].as_expr()
8343 else:
8344 return Or([self[i].as_expr() for i in range(len(self))])
8345
8346#########################################
8347#
8348# Simplifiers
8349#
8350#########################################
8351
8352class Simplifier:
8353 """Simplifiers act as pre-processing utilities for solvers.
8354 Build a custom simplifier and add it to a solver"""
8355
8356 def __init__(self, simplifier, ctx=None):
8357 self.ctx = _get_ctx(ctx)
8358 self.simplifier = None
8359 if isinstance(simplifier, SimplifierObj):
8360 self.simplifier = simplifier
8361 elif isinstance(simplifier, list):
8362 simps = [Simplifier(s, ctx) for s in simplifier]
8363 self.simplifier = simps[0].simplifier
8364 for i in range(1, len(simps)):
8365 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8366 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8367 return
8368 else:
8369 if z3_debug():
8370 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8371 try:
8372 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8373 except Z3Exception:
8374 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8375 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8376
8377 def __deepcopy__(self, memo={}):
8378 return Simplifier(self.simplifier, self.ctx)
8379
8380 def __del__(self):
8381 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8382 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8383
8384 def using_params(self, *args, **keys):
8385 """Return a simplifier that uses the given configuration options"""
8386 p = args2params(args, keys, self.ctx)
8387 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8388
8389 def add(self, solver):
8390 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8391 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8392
8393 def help(self):
8394 """Display a string containing a description of the available options for the `self` simplifier."""
8395 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8396
8397 def param_descrs(self):
8398 """Return the parameter description set."""
8399 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8400
8401
8402#########################################
8403#
8404# Tactics
8405#
8406#########################################
8407
8408
8409class Tactic:
8410 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8411 A Tactic can be converted into a Solver using the method solver().
8412
8413 Several combinators are available for creating new tactics using the built-in ones:
8414 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8415 """
8416
8417 def __init__(self, tactic, ctx=None):
8418 self.ctx = _get_ctx(ctx)
8419 self.tactic = None
8420 if isinstance(tactic, TacticObj):
8421 self.tactic = tactic
8422 else:
8423 if z3_debug():
8424 _z3_assert(isinstance(tactic, str), "tactic name expected")
8425 try:
8426 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8427 except Z3Exception:
8428 raise Z3Exception("unknown tactic '%s'" % tactic)
8429 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8430
8431 def __deepcopy__(self, memo={}):
8432 return Tactic(self.tactic, self.ctx)
8433
8434 def __del__(self):
8435 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8436 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8437
8438 def solver(self, logFile=None):
8439 """Create a solver using the tactic `self`.
8440
8441 The solver supports the methods `push()` and `pop()`, but it
8442 will always solve each `check()` from scratch.
8443
8444 >>> t = Then('simplify', 'nlsat')
8445 >>> s = t.solver()
8446 >>> x = Real('x')
8447 >>> s.add(x**2 == 2, x > 0)
8448 >>> s.check()
8449 sat
8450 >>> s.model()
8451 [x = 1.4142135623?]
8452 """
8453 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8454
8455 def apply(self, goal, *arguments, **keywords):
8456 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8457
8458 >>> x, y = Ints('x y')
8459 >>> t = Tactic('solve-eqs')
8460 >>> t.apply(And(x == 0, y >= x + 1))
8461 [[y >= 1]]
8462 """
8463 if z3_debug():
8464 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8465 goal = _to_goal(goal)
8466 if len(arguments) > 0 or len(keywords) > 0:
8467 p = args2params(arguments, keywords, self.ctx)
8468 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8469 else:
8470 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8471
8472 def __call__(self, goal, *arguments, **keywords):
8473 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8474
8475 >>> x, y = Ints('x y')
8476 >>> t = Tactic('solve-eqs')
8477 >>> t(And(x == 0, y >= x + 1))
8478 [[y >= 1]]
8479 """
8480 return self.apply(goal, *arguments, **keywords)
8481
8482 def help(self):
8483 """Display a string containing a description of the available options for the `self` tactic."""
8484 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8485
8486 def param_descrs(self):
8487 """Return the parameter description set."""
8488 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8489
8490
8491def _to_goal(a):
8492 if isinstance(a, BoolRef):
8493 goal = Goal(ctx=a.ctx)
8494 goal.add(a)
8495 return goal
8496 else:
8497 return a
8498
8499
8500def _to_tactic(t, ctx=None):
8501 if isinstance(t, Tactic):
8502 return t
8503 else:
8504 return Tactic(t, ctx)
8505
8506
8507def _and_then(t1, t2, ctx=None):
8508 t1 = _to_tactic(t1, ctx)
8509 t2 = _to_tactic(t2, ctx)
8510 if z3_debug():
8511 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8512 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8513
8514
8515def _or_else(t1, t2, ctx=None):
8516 t1 = _to_tactic(t1, ctx)
8517 t2 = _to_tactic(t2, ctx)
8518 if z3_debug():
8519 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8520 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8521
8522
8523def AndThen(*ts, **ks):
8524 """Return a tactic that applies the tactics in `*ts` in sequence.
8525
8526 >>> x, y = Ints('x y')
8527 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8528 >>> t(And(x == 0, y > x + 1))
8529 [[Not(y <= 1)]]
8530 >>> t(And(x == 0, y > x + 1)).as_expr()
8531 Not(y <= 1)
8532 """
8533 if z3_debug():
8534 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8535 ctx = ks.get("ctx", None)
8536 num = len(ts)
8537 r = ts[0]
8538 for i in range(num - 1):
8539 r = _and_then(r, ts[i + 1], ctx)
8540 return r
8541
8542
8543def Then(*ts, **ks):
8544 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8545
8546 >>> x, y = Ints('x y')
8547 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8548 >>> t(And(x == 0, y > x + 1))
8549 [[Not(y <= 1)]]
8550 >>> t(And(x == 0, y > x + 1)).as_expr()
8551 Not(y <= 1)
8552 """
8553 return AndThen(*ts, **ks)
8554
8555
8556def OrElse(*ts, **ks):
8557 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8558
8559 >>> x = Int('x')
8560 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8561 >>> # Tactic split-clause fails if there is no clause in the given goal.
8562 >>> t(x == 0)
8563 [[x == 0]]
8564 >>> t(Or(x == 0, x == 1))
8565 [[x == 0], [x == 1]]
8566 """
8567 if z3_debug():
8568 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8569 ctx = ks.get("ctx", None)
8570 num = len(ts)
8571 r = ts[0]
8572 for i in range(num - 1):
8573 r = _or_else(r, ts[i + 1], ctx)
8574 return r
8575
8576
8577def ParOr(*ts, **ks):
8578 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8579
8580 >>> x = Int('x')
8581 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8582 >>> t(x + 1 == 2)
8583 [[x == 1]]
8584 """
8585 if z3_debug():
8586 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8587 ctx = _get_ctx(ks.get("ctx", None))
8588 ts = [_to_tactic(t, ctx) for t in ts]
8589 sz = len(ts)
8590 _args = (TacticObj * sz)()
8591 for i in range(sz):
8592 _args[i] = ts[i].tactic
8593 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8594
8595
8596def ParThen(t1, t2, ctx=None):
8597 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8598 The subgoals are processed in parallel.
8599
8600 >>> x, y = Ints('x y')
8601 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8602 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8603 [[x == 1, y == 2], [x == 2, y == 3]]
8604 """
8605 t1 = _to_tactic(t1, ctx)
8606 t2 = _to_tactic(t2, ctx)
8607 if z3_debug():
8608 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8609 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8610
8611
8612def ParAndThen(t1, t2, ctx=None):
8613 """Alias for ParThen(t1, t2, ctx)."""
8614 return ParThen(t1, t2, ctx)
8615
8616
8617def With(t, *args, **keys):
8618 """Return a tactic that applies tactic `t` using the given configuration options.
8619
8620 >>> x, y = Ints('x y')
8621 >>> t = With(Tactic('simplify'), som=True)
8622 >>> t((x + 1)*(y + 2) == 0)
8623 [[2*x + y + x*y == -2]]
8624 """
8625 ctx = keys.pop("ctx", None)
8626 t = _to_tactic(t, ctx)
8627 p = args2params(args, keys, t.ctx)
8628 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8629
8630
8631def WithParams(t, p):
8632 """Return a tactic that applies tactic `t` using the given configuration options.
8633
8634 >>> x, y = Ints('x y')
8635 >>> p = ParamsRef()
8636 >>> p.set("som", True)
8637 >>> t = WithParams(Tactic('simplify'), p)
8638 >>> t((x + 1)*(y + 2) == 0)
8639 [[2*x + y + x*y == -2]]
8640 """
8641 t = _to_tactic(t, None)
8642 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8643
8644
8645def Repeat(t, max=4294967295, ctx=None):
8646 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8647 or the maximum number of iterations `max` is reached.
8648
8649 >>> x, y = Ints('x y')
8650 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8651 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8652 >>> r = t(c)
8653 >>> for subgoal in r: print(subgoal)
8654 [x == 0, y == 0, x > y]
8655 [x == 0, y == 1, x > y]
8656 [x == 1, y == 0, x > y]
8657 [x == 1, y == 1, x > y]
8658 >>> t = Then(t, Tactic('propagate-values'))
8659 >>> t(c)
8660 [[x == 1, y == 0]]
8661 """
8662 t = _to_tactic(t, ctx)
8663 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8664
8665
8666def TryFor(t, ms, ctx=None):
8667 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8668
8669 If `t` does not terminate in `ms` milliseconds, then it fails.
8670 """
8671 t = _to_tactic(t, ctx)
8672 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8673
8674
8675def tactics(ctx=None):
8676 """Return a list of all available tactics in Z3.
8677
8678 >>> l = tactics()
8679 >>> l.count('simplify') == 1
8680 True
8681 """
8682 ctx = _get_ctx(ctx)
8683 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8684
8685
8686def tactic_description(name, ctx=None):
8687 """Return a short description for the tactic named `name`.
8688
8689 >>> d = tactic_description('simplify')
8690 """
8691 ctx = _get_ctx(ctx)
8692 return Z3_tactic_get_descr(ctx.ref(), name)
8693
8694
8695def describe_tactics():
8696 """Display a (tabular) description of all available tactics in Z3."""
8697 if in_html_mode():
8698 even = True
8699 print('<table border="1" cellpadding="2" cellspacing="0">')
8700 for t in tactics():
8701 if even:
8702 print('<tr style="background-color:#CFCFCF">')
8703 even = False
8704 else:
8705 print("<tr>")
8706 even = True
8707 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8708 print("</table>")
8709 else:
8710 for t in tactics():
8711 print("%s : %s" % (t, tactic_description(t)))
8712
8713
8714class Probe:
8715 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8716 to decide which solver and/or preprocessing step will be used.
8717 """
8718
8719 def __init__(self, probe, ctx=None):
8720 self.ctx = _get_ctx(ctx)
8721 self.probe = None
8722 if isinstance(probe, ProbeObj):
8723 self.probe = probe
8724 elif isinstance(probe, float):
8725 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8726 elif _is_int(probe):
8727 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8728 elif isinstance(probe, bool):
8729 if probe:
8730 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8731 else:
8732 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8733 else:
8734 if z3_debug():
8735 _z3_assert(isinstance(probe, str), "probe name expected")
8736 try:
8737 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8738 except Z3Exception:
8739 raise Z3Exception("unknown probe '%s'" % probe)
8740 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8741
8742 def __deepcopy__(self, memo={}):
8743 return Probe(self.probe, self.ctx)
8744
8745 def __del__(self):
8746 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8747 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8748
8749 def __lt__(self, other):
8750 """Return a probe that evaluates to "true" when the value returned by `self`
8751 is less than the value returned by `other`.
8752
8753 >>> p = Probe('size') < 10
8754 >>> x = Int('x')
8755 >>> g = Goal()
8756 >>> g.add(x > 0)
8757 >>> g.add(x < 10)
8758 >>> p(g)
8759 1.0
8760 """
8761 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8762
8763 def __gt__(self, other):
8764 """Return a probe that evaluates to "true" when the value returned by `self`
8765 is greater than the value returned by `other`.
8766
8767 >>> p = Probe('size') > 10
8768 >>> x = Int('x')
8769 >>> g = Goal()
8770 >>> g.add(x > 0)
8771 >>> g.add(x < 10)
8772 >>> p(g)
8773 0.0
8774 """
8775 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8776
8777 def __le__(self, other):
8778 """Return a probe that evaluates to "true" when the value returned by `self`
8779 is less than or equal to the value returned by `other`.
8780
8781 >>> p = Probe('size') <= 2
8782 >>> x = Int('x')
8783 >>> g = Goal()
8784 >>> g.add(x > 0)
8785 >>> g.add(x < 10)
8786 >>> p(g)
8787 1.0
8788 """
8789 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8790
8791 def __ge__(self, other):
8792 """Return a probe that evaluates to "true" when the value returned by `self`
8793 is greater than or equal to the value returned by `other`.
8794
8795 >>> p = Probe('size') >= 2
8796 >>> x = Int('x')
8797 >>> g = Goal()
8798 >>> g.add(x > 0)
8799 >>> g.add(x < 10)
8800 >>> p(g)
8801 1.0
8802 """
8803 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8804
8805 def __eq__(self, other):
8806 """Return a probe that evaluates to "true" when the value returned by `self`
8807 is equal to the value returned by `other`.
8808
8809 >>> p = Probe('size') == 2
8810 >>> x = Int('x')
8811 >>> g = Goal()
8812 >>> g.add(x > 0)
8813 >>> g.add(x < 10)
8814 >>> p(g)
8815 1.0
8816 """
8817 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8818
8819 def __ne__(self, other):
8820 """Return a probe that evaluates to "true" when the value returned by `self`
8821 is not equal to the value returned by `other`.
8822
8823 >>> p = Probe('size') != 2
8824 >>> x = Int('x')
8825 >>> g = Goal()
8826 >>> g.add(x > 0)
8827 >>> g.add(x < 10)
8828 >>> p(g)
8829 0.0
8830 """
8831 p = self.__eq__(other)
8832 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8833
8834 def __call__(self, goal):
8835 """Evaluate the probe `self` in the given goal.
8836
8837 >>> p = Probe('size')
8838 >>> x = Int('x')
8839 >>> g = Goal()
8840 >>> g.add(x > 0)
8841 >>> g.add(x < 10)
8842 >>> p(g)
8843 2.0
8844 >>> g.add(x < 20)
8845 >>> p(g)
8846 3.0
8847 >>> p = Probe('num-consts')
8848 >>> p(g)
8849 1.0
8850 >>> p = Probe('is-propositional')
8851 >>> p(g)
8852 0.0
8853 >>> p = Probe('is-qflia')
8854 >>> p(g)
8855 1.0
8856 """
8857 if z3_debug():
8858 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8859 goal = _to_goal(goal)
8860 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8861
8862
8863def is_probe(p):
8864 """Return `True` if `p` is a Z3 probe.
8865
8866 >>> is_probe(Int('x'))
8867 False
8868 >>> is_probe(Probe('memory'))
8869 True
8870 """
8871 return isinstance(p, Probe)
8872
8873
8874def _to_probe(p, ctx=None):
8875 if is_probe(p):
8876 return p
8877 else:
8878 return Probe(p, ctx)
8879
8880
8881def probes(ctx=None):
8882 """Return a list of all available probes in Z3.
8883
8884 >>> l = probes()
8885 >>> l.count('memory') == 1
8886 True
8887 """
8888 ctx = _get_ctx(ctx)
8889 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8890
8891
8892def probe_description(name, ctx=None):
8893 """Return a short description for the probe named `name`.
8894
8895 >>> d = probe_description('memory')
8896 """
8897 ctx = _get_ctx(ctx)
8898 return Z3_probe_get_descr(ctx.ref(), name)
8899
8900
8901def describe_probes():
8902 """Display a (tabular) description of all available probes in Z3."""
8903 if in_html_mode():
8904 even = True
8905 print('<table border="1" cellpadding="2" cellspacing="0">')
8906 for p in probes():
8907 if even:
8908 print('<tr style="background-color:#CFCFCF">')
8909 even = False
8910 else:
8911 print("<tr>")
8912 even = True
8913 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
8914 print("</table>")
8915 else:
8916 for p in probes():
8917 print("%s : %s" % (p, probe_description(p)))
8918
8919
8920def _probe_nary(f, args, ctx):
8921 if z3_debug():
8922 _z3_assert(len(args) > 0, "At least one argument expected")
8923 num = len(args)
8924 r = _to_probe(args[0], ctx)
8925 for i in range(num - 1):
8926 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
8927 return r
8928
8929
8930def _probe_and(args, ctx):
8931 return _probe_nary(Z3_probe_and, args, ctx)
8932
8933
8934def _probe_or(args, ctx):
8935 return _probe_nary(Z3_probe_or, args, ctx)
8936
8937
8938def FailIf(p, ctx=None):
8939 """Return a tactic that fails if the probe `p` evaluates to true.
8940 Otherwise, it returns the input goal unmodified.
8941
8942 In the following example, the tactic applies 'simplify' if and only if there are
8943 more than 2 constraints in the goal.
8944
8945 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
8946 >>> x, y = Ints('x y')
8947 >>> g = Goal()
8948 >>> g.add(x > 0)
8949 >>> g.add(y > 0)
8950 >>> t(g)
8951 [[x > 0, y > 0]]
8952 >>> g.add(x == y + 1)
8953 >>> t(g)
8954 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8955 """
8956 p = _to_probe(p, ctx)
8957 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
8958
8959
8960def When(p, t, ctx=None):
8961 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
8962 Otherwise, it returns the input goal unmodified.
8963
8964 >>> t = When(Probe('size') > 2, Tactic('simplify'))
8965 >>> x, y = Ints('x y')
8966 >>> g = Goal()
8967 >>> g.add(x > 0)
8968 >>> g.add(y > 0)
8969 >>> t(g)
8970 [[x > 0, y > 0]]
8971 >>> g.add(x == y + 1)
8972 >>> t(g)
8973 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8974 """
8975 p = _to_probe(p, ctx)
8976 t = _to_tactic(t, ctx)
8977 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
8978
8979
8980def Cond(p, t1, t2, ctx=None):
8981 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
8982
8983 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
8984 """
8985 p = _to_probe(p, ctx)
8986 t1 = _to_tactic(t1, ctx)
8987 t2 = _to_tactic(t2, ctx)
8988 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
8989
8990#########################################
8991#
8992# Utils
8993#
8994#########################################
8995
8996
8997def simplify(a, *arguments, **keywords):
8998 """Simplify the expression `a` using the given options.
8999
9000 This function has many options. Use `help_simplify` to obtain the complete list.
9001
9002 >>> x = Int('x')
9003 >>> y = Int('y')
9004 >>> simplify(x + 1 + y + x + 1)
9005 2 + 2*x + y
9006 >>> simplify((x + 1)*(y + 1), som=True)
9007 1 + x + y + x*y
9008 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9009 And(Not(x == y), Not(x == 1), Not(y == 1))
9010 >>> simplify(And(x == 0, y == 1), elim_and=True)
9011 Not(Or(Not(x == 0), Not(y == 1)))
9012 """
9013 if z3_debug():
9014 _z3_assert(is_expr(a), "Z3 expression expected")
9015 if len(arguments) > 0 or len(keywords) > 0:
9016 p = args2params(arguments, keywords, a.ctx)
9017 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9018 else:
9019 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9020
9021
9022def help_simplify():
9023 """Return a string describing all options available for Z3 `simplify` procedure."""
9024 print(Z3_simplify_get_help(main_ctx().ref()))
9025
9026
9027def simplify_param_descrs():
9028 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9029 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9030
9031
9032def substitute(t, *m):
9033 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9034 Every occurrence in t of from is replaced with to.
9035
9036 >>> x = Int('x')
9037 >>> y = Int('y')
9038 >>> substitute(x + 1, (x, y + 1))
9039 y + 1 + 1
9040 >>> f = Function('f', IntSort(), IntSort())
9041 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9042 1 + 1
9043 """
9044 if isinstance(m, tuple):
9045 m1 = _get_args(m)
9046 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9047 m = m1
9048 if z3_debug():
9049 _z3_assert(is_expr(t), "Z3 expression expected")
9050 _z3_assert(
9051 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9052 "Z3 invalid substitution, expression pairs expected.")
9053 _z3_assert(
9054 all([p[0].sort().eq(p[1].sort()) for p in m]),
9055 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9056 num = len(m)
9057 _from = (Ast * num)()
9058 _to = (Ast * num)()
9059 for i in range(num):
9060 _from[i] = m[i][0].as_ast()
9061 _to[i] = m[i][1].as_ast()
9062 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9063
9064
9065def substitute_vars(t, *m):
9066 """Substitute the free variables in t with the expression in m.
9067
9068 >>> v0 = Var(0, IntSort())
9069 >>> v1 = Var(1, IntSort())
9070 >>> x = Int('x')
9071 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9072 >>> # replace v0 with x+1 and v1 with x
9073 >>> substitute_vars(f(v0, v1), x + 1, x)
9074 f(x + 1, x)
9075 """
9076 if z3_debug():
9077 _z3_assert(is_expr(t), "Z3 expression expected")
9078 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9079 num = len(m)
9080 _to = (Ast * num)()
9081 for i in range(num):
9082 _to[i] = m[i].as_ast()
9083 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9084
9085def substitute_funs(t, *m):
9086 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9087 Every occurrence in to of the function from is replaced with the expression to.
9088 The expression to can have free variables, that refer to the arguments of from.
9089 For examples, see
9090 """
9091 if isinstance(m, tuple):
9092 m1 = _get_args(m)
9093 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9094 m = m1
9095 if z3_debug():
9096 _z3_assert(is_expr(t), "Z3 expression expected")
9097 _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.")
9098 num = len(m)
9099 _from = (FuncDecl * num)()
9100 _to = (Ast * num)()
9101 for i in range(num):
9102 _from[i] = m[i][0].as_func_decl()
9103 _to[i] = m[i][1].as_ast()
9104 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9105
9106
9107def Sum(*args):
9108 """Create the sum of the Z3 expressions.
9109
9110 >>> a, b, c = Ints('a b c')
9111 >>> Sum(a, b, c)
9112 a + b + c
9113 >>> Sum([a, b, c])
9114 a + b + c
9115 >>> A = IntVector('a', 5)
9116 >>> Sum(A)
9117 a__0 + a__1 + a__2 + a__3 + a__4
9118 """
9119 args = _get_args(args)
9120 if len(args) == 0:
9121 return 0
9122 ctx = _ctx_from_ast_arg_list(args)
9123 if ctx is None:
9124 return _reduce(lambda a, b: a + b, args, 0)
9125 args = _coerce_expr_list(args, ctx)
9126 if is_bv(args[0]):
9127 return _reduce(lambda a, b: a + b, args, 0)
9128 else:
9129 _args, sz = _to_ast_array(args)
9130 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9131
9132
9133def Product(*args):
9134 """Create the product of the Z3 expressions.
9135
9136 >>> a, b, c = Ints('a b c')
9137 >>> Product(a, b, c)
9138 a*b*c
9139 >>> Product([a, b, c])
9140 a*b*c
9141 >>> A = IntVector('a', 5)
9142 >>> Product(A)
9143 a__0*a__1*a__2*a__3*a__4
9144 """
9145 args = _get_args(args)
9146 if len(args) == 0:
9147 return 1
9148 ctx = _ctx_from_ast_arg_list(args)
9149 if ctx is None:
9150 return _reduce(lambda a, b: a * b, args, 1)
9151 args = _coerce_expr_list(args, ctx)
9152 if is_bv(args[0]):
9153 return _reduce(lambda a, b: a * b, args, 1)
9154 else:
9155 _args, sz = _to_ast_array(args)
9156 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9157
9158def Abs(arg):
9159 """Create the absolute value of an arithmetic expression"""
9160 return If(arg > 0, arg, -arg)
9161
9162
9163def AtMost(*args):
9164 """Create an at-most Pseudo-Boolean k constraint.
9165
9166 >>> a, b, c = Bools('a b c')
9167 >>> f = AtMost(a, b, c, 2)
9168 """
9169 args = _get_args(args)
9170 if z3_debug():
9171 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9172 ctx = _ctx_from_ast_arg_list(args)
9173 if z3_debug():
9174 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9175 args1 = _coerce_expr_list(args[:-1], ctx)
9176 k = args[-1]
9177 _args, sz = _to_ast_array(args1)
9178 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9179
9180
9181def AtLeast(*args):
9182 """Create an at-least Pseudo-Boolean k constraint.
9183
9184 >>> a, b, c = Bools('a b c')
9185 >>> f = AtLeast(a, b, c, 2)
9186 """
9187 args = _get_args(args)
9188 if z3_debug():
9189 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9190 ctx = _ctx_from_ast_arg_list(args)
9191 if z3_debug():
9192 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9193 args1 = _coerce_expr_list(args[:-1], ctx)
9194 k = args[-1]
9195 _args, sz = _to_ast_array(args1)
9196 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9197
9198
9199def _reorder_pb_arg(arg):
9200 a, b = arg
9201 if not _is_int(b) and _is_int(a):
9202 return b, a
9203 return arg
9204
9205
9206def _pb_args_coeffs(args, default_ctx=None):
9207 args = _get_args_ast_list(args)
9208 if len(args) == 0:
9209 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9210 args = [_reorder_pb_arg(arg) for arg in args]
9211 args, coeffs = zip(*args)
9212 if z3_debug():
9213 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9214 ctx = _ctx_from_ast_arg_list(args)
9215 if z3_debug():
9216 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9217 args = _coerce_expr_list(args, ctx)
9218 _args, sz = _to_ast_array(args)
9219 _coeffs = (ctypes.c_int * len(coeffs))()
9220 for i in range(len(coeffs)):
9221 _z3_check_cint_overflow(coeffs[i], "coefficient")
9222 _coeffs[i] = coeffs[i]
9223 return ctx, sz, _args, _coeffs, args
9224
9225
9226def PbLe(args, k):
9227 """Create a Pseudo-Boolean inequality k constraint.
9228
9229 >>> a, b, c = Bools('a b c')
9230 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9231 """
9232 _z3_check_cint_overflow(k, "k")
9233 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9234 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9235
9236
9237def PbGe(args, k):
9238 """Create a Pseudo-Boolean inequality k constraint.
9239
9240 >>> a, b, c = Bools('a b c')
9241 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9242 """
9243 _z3_check_cint_overflow(k, "k")
9244 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9245 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9246
9247
9248def PbEq(args, k, ctx=None):
9249 """Create a Pseudo-Boolean equality k constraint.
9250
9251 >>> a, b, c = Bools('a b c')
9252 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9253 """
9254 _z3_check_cint_overflow(k, "k")
9255 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9256 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9257
9258
9259def solve(*args, **keywords):
9260 """Solve the constraints `*args`.
9261
9262 This is a simple function for creating demonstrations. It creates a solver,
9263 configure it using the options in `keywords`, adds the constraints
9264 in `args`, and invokes check.
9265
9266 >>> a = Int('a')
9267 >>> solve(a > 0, a < 2)
9268 [a = 1]
9269 """
9270 show = keywords.pop("show", False)
9271 s = Solver()
9272 s.set(**keywords)
9273 s.add(*args)
9274 if show:
9275 print(s)
9276 r = s.check()
9277 if r == unsat:
9278 print("no solution")
9279 elif r == unknown:
9280 print("failed to solve")
9281 try:
9282 print(s.model())
9283 except Z3Exception:
9284 return
9285 else:
9286 print(s.model())
9287
9288
9289def solve_using(s, *args, **keywords):
9290 """Solve the constraints `*args` using solver `s`.
9291
9292 This is a simple function for creating demonstrations. It is similar to `solve`,
9293 but it uses the given solver `s`.
9294 It configures solver `s` using the options in `keywords`, adds the constraints
9295 in `args`, and invokes check.
9296 """
9297 show = keywords.pop("show", False)
9298 if z3_debug():
9299 _z3_assert(isinstance(s, Solver), "Solver object expected")
9300 s.set(**keywords)
9301 s.add(*args)
9302 if show:
9303 print("Problem:")
9304 print(s)
9305 r = s.check()
9306 if r == unsat:
9307 print("no solution")
9308 elif r == unknown:
9309 print("failed to solve")
9310 try:
9311 print(s.model())
9312 except Z3Exception:
9313 return
9314 else:
9315 if show:
9316 print("Solution:")
9317 print(s.model())
9318
9319
9320def prove(claim, show=False, **keywords):
9321 """Try to prove the given claim.
9322
9323 This is a simple function for creating demonstrations. It tries to prove
9324 `claim` by showing the negation is unsatisfiable.
9325
9326 >>> p, q = Bools('p q')
9327 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9328 proved
9329 """
9330 if z3_debug():
9331 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9332 s = Solver()
9333 s.set(**keywords)
9334 s.add(Not(claim))
9335 if show:
9336 print(s)
9337 r = s.check()
9338 if r == unsat:
9339 print("proved")
9340 elif r == unknown:
9341 print("failed to prove")
9342 print(s.model())
9343 else:
9344 print("counterexample")
9345 print(s.model())
9346
9347
9348def _solve_html(*args, **keywords):
9349 """Version of function `solve` that renders HTML output."""
9350 show = keywords.pop("show", False)
9351 s = Solver()
9352 s.set(**keywords)
9353 s.add(*args)
9354 if show:
9355 print("<b>Problem:</b>")
9356 print(s)
9357 r = s.check()
9358 if r == unsat:
9359 print("<b>no solution</b>")
9360 elif r == unknown:
9361 print("<b>failed to solve</b>")
9362 try:
9363 print(s.model())
9364 except Z3Exception:
9365 return
9366 else:
9367 if show:
9368 print("<b>Solution:</b>")
9369 print(s.model())
9370
9371
9372def _solve_using_html(s, *args, **keywords):
9373 """Version of function `solve_using` that renders HTML."""
9374 show = keywords.pop("show", False)
9375 if z3_debug():
9376 _z3_assert(isinstance(s, Solver), "Solver object expected")
9377 s.set(**keywords)
9378 s.add(*args)
9379 if show:
9380 print("<b>Problem:</b>")
9381 print(s)
9382 r = s.check()
9383 if r == unsat:
9384 print("<b>no solution</b>")
9385 elif r == unknown:
9386 print("<b>failed to solve</b>")
9387 try:
9388 print(s.model())
9389 except Z3Exception:
9390 return
9391 else:
9392 if show:
9393 print("<b>Solution:</b>")
9394 print(s.model())
9395
9396
9397def _prove_html(claim, show=False, **keywords):
9398 """Version of function `prove` that renders HTML."""
9399 if z3_debug():
9400 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9401 s = Solver()
9402 s.set(**keywords)
9403 s.add(Not(claim))
9404 if show:
9405 print(s)
9406 r = s.check()
9407 if r == unsat:
9408 print("<b>proved</b>")
9409 elif r == unknown:
9410 print("<b>failed to prove</b>")
9411 print(s.model())
9412 else:
9413 print("<b>counterexample</b>")
9414 print(s.model())
9415
9416
9417def _dict2sarray(sorts, ctx):
9418 sz = len(sorts)
9419 _names = (Symbol * sz)()
9420 _sorts = (Sort * sz)()
9421 i = 0
9422 for k in sorts:
9423 v = sorts[k]
9424 if z3_debug():
9425 _z3_assert(isinstance(k, str), "String expected")
9426 _z3_assert(is_sort(v), "Z3 sort expected")
9427 _names[i] = to_symbol(k, ctx)
9428 _sorts[i] = v.ast
9429 i = i + 1
9430 return sz, _names, _sorts
9431
9432
9433def _dict2darray(decls, ctx):
9434 sz = len(decls)
9435 _names = (Symbol * sz)()
9436 _decls = (FuncDecl * sz)()
9437 i = 0
9438 for k in decls:
9439 v = decls[k]
9440 if z3_debug():
9441 _z3_assert(isinstance(k, str), "String expected")
9442 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9443 _names[i] = to_symbol(k, ctx)
9444 if is_const(v):
9445 _decls[i] = v.decl().ast
9446 else:
9447 _decls[i] = v.ast
9448 i = i + 1
9449 return sz, _names, _decls
9450
9451class ParserContext:
9452 def __init__(self, ctx= None):
9453 self.ctx = _get_ctx(ctx)
9454 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9455 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9456
9457 def __del__(self):
9458 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9459 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9460 self.pctx = None
9461
9462 def add_sort(self, sort):
9463 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9464
9465 def add_decl(self, decl):
9466 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9467
9468 def from_string(self, s):
9469 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9470
9471def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9472 """Parse a string in SMT 2.0 format using the given sorts and decls.
9473
9474 The arguments sorts and decls are Python dictionaries used to initialize
9475 the symbol table used for the SMT 2.0 parser.
9476
9477 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9478 [x > 0, x < 10]
9479 >>> x, y = Ints('x y')
9480 >>> f = Function('f', IntSort(), IntSort())
9481 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9482 [x + f(y) > 0]
9483 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9484 [a > 0]
9485 """
9486 ctx = _get_ctx(ctx)
9487 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9488 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9489 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9490
9491
9492def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9493 """Parse a file in SMT 2.0 format using the given sorts and decls.
9494
9495 This function is similar to parse_smt2_string().
9496 """
9497 ctx = _get_ctx(ctx)
9498 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9499 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9500 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9501
9502
9503#########################################
9504#
9505# Floating-Point Arithmetic
9506#
9507#########################################
9508
9509
9510# Global default rounding mode
9511_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9512_dflt_fpsort_ebits = 11
9513_dflt_fpsort_sbits = 53
9514
9515
9516def get_default_rounding_mode(ctx=None):
9517 """Retrieves the global default rounding mode."""
9518 global _dflt_rounding_mode
9519 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9520 return RTZ(ctx)
9521 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9522 return RTN(ctx)
9523 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9524 return RTP(ctx)
9525 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9526 return RNE(ctx)
9527 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9528 return RNA(ctx)
9529
9530
9531_ROUNDING_MODES = frozenset({
9532 Z3_OP_FPA_RM_TOWARD_ZERO,
9533 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9534 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9535 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9536 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9537})
9538
9539
9540def set_default_rounding_mode(rm, ctx=None):
9541 global _dflt_rounding_mode
9542 if is_fprm_value(rm):
9543 _dflt_rounding_mode = rm.kind()
9544 else:
9545 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9546 _dflt_rounding_mode = rm
9547
9548
9549def get_default_fp_sort(ctx=None):
9550 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9551
9552
9553def set_default_fp_sort(ebits, sbits, ctx=None):
9554 global _dflt_fpsort_ebits
9555 global _dflt_fpsort_sbits
9556 _dflt_fpsort_ebits = ebits
9557 _dflt_fpsort_sbits = sbits
9558
9559
9560def _dflt_rm(ctx=None):
9561 return get_default_rounding_mode(ctx)
9562
9563
9564def _dflt_fps(ctx=None):
9565 return get_default_fp_sort(ctx)
9566
9567
9568def _coerce_fp_expr_list(alist, ctx):
9569 first_fp_sort = None
9570 for a in alist:
9571 if is_fp(a):
9572 if first_fp_sort is None:
9573 first_fp_sort = a.sort()
9574 elif first_fp_sort == a.sort():
9575 pass # OK, same as before
9576 else:
9577 # we saw at least 2 different float sorts; something will
9578 # throw a sort mismatch later, for now assume None.
9579 first_fp_sort = None
9580 break
9581
9582 r = []
9583 for i in range(len(alist)):
9584 a = alist[i]
9585 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9586 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9587 r.append(FPVal(a, None, first_fp_sort, ctx))
9588 else:
9589 r.append(a)
9590 return _coerce_expr_list(r, ctx)
9591
9592
9593# FP Sorts
9594
9595class FPSortRef(SortRef):
9596 """Floating-point sort."""
9597
9598 def ebits(self):
9599 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9600 >>> b = FPSort(8, 24)
9601 >>> b.ebits()
9602 8
9603 """
9604 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9605
9606 def sbits(self):
9607 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9608 >>> b = FPSort(8, 24)
9609 >>> b.sbits()
9610 24
9611 """
9612 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9613
9614 def cast(self, val):
9615 """Try to cast `val` as a floating-point expression.
9616 >>> b = FPSort(8, 24)
9617 >>> b.cast(1.0)
9618 1
9619 >>> b.cast(1.0).sexpr()
9620 '(fp #b0 #x7f #b00000000000000000000000)'
9621 """
9622 if is_expr(val):
9623 if z3_debug():
9624 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9625 return val
9626 else:
9627 return FPVal(val, None, self, self.ctx)
9628
9629
9630def Float16(ctx=None):
9631 """Floating-point 16-bit (half) sort."""
9632 ctx = _get_ctx(ctx)
9633 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9634
9635
9636def FloatHalf(ctx=None):
9637 """Floating-point 16-bit (half) sort."""
9638 ctx = _get_ctx(ctx)
9639 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9640
9641
9642def Float32(ctx=None):
9643 """Floating-point 32-bit (single) sort."""
9644 ctx = _get_ctx(ctx)
9645 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9646
9647
9648def FloatSingle(ctx=None):
9649 """Floating-point 32-bit (single) sort."""
9650 ctx = _get_ctx(ctx)
9651 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9652
9653
9654def Float64(ctx=None):
9655 """Floating-point 64-bit (double) sort."""
9656 ctx = _get_ctx(ctx)
9657 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9658
9659
9660def FloatDouble(ctx=None):
9661 """Floating-point 64-bit (double) sort."""
9662 ctx = _get_ctx(ctx)
9663 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9664
9665
9666def Float128(ctx=None):
9667 """Floating-point 128-bit (quadruple) sort."""
9668 ctx = _get_ctx(ctx)
9669 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9670
9671
9672def FloatQuadruple(ctx=None):
9673 """Floating-point 128-bit (quadruple) sort."""
9674 ctx = _get_ctx(ctx)
9675 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9676
9677
9678class FPRMSortRef(SortRef):
9679 """"Floating-point rounding mode sort."""
9680
9681
9682def is_fp_sort(s):
9683 """Return True if `s` is a Z3 floating-point sort.
9684
9685 >>> is_fp_sort(FPSort(8, 24))
9686 True
9687 >>> is_fp_sort(IntSort())
9688 False
9689 """
9690 return isinstance(s, FPSortRef)
9691
9692
9693def is_fprm_sort(s):
9694 """Return True if `s` is a Z3 floating-point rounding mode sort.
9695
9696 >>> is_fprm_sort(FPSort(8, 24))
9697 False
9698 >>> is_fprm_sort(RNE().sort())
9699 True
9700 """
9701 return isinstance(s, FPRMSortRef)
9702
9703# FP Expressions
9704
9705
9706class FPRef(ExprRef):
9707 """Floating-point expressions."""
9708
9709 def sort(self):
9710 """Return the sort of the floating-point expression `self`.
9711
9712 >>> x = FP('1.0', FPSort(8, 24))
9713 >>> x.sort()
9714 FPSort(8, 24)
9715 >>> x.sort() == FPSort(8, 24)
9716 True
9717 """
9718 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9719
9720 def ebits(self):
9721 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9722 >>> b = FPSort(8, 24)
9723 >>> b.ebits()
9724 8
9725 """
9726 return self.sort().ebits()
9727
9728 def sbits(self):
9729 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9730 >>> b = FPSort(8, 24)
9731 >>> b.sbits()
9732 24
9733 """
9734 return self.sort().sbits()
9735
9736 def as_string(self):
9737 """Return a Z3 floating point expression as a Python string."""
9738 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9739
9740 def __le__(self, other):
9741 return fpLEQ(self, other, self.ctx)
9742
9743 def __lt__(self, other):
9744 return fpLT(self, other, self.ctx)
9745
9746 def __ge__(self, other):
9747 return fpGEQ(self, other, self.ctx)
9748
9749 def __gt__(self, other):
9750 return fpGT(self, other, self.ctx)
9751
9752 def __add__(self, other):
9753 """Create the Z3 expression `self + other`.
9754
9755 >>> x = FP('x', FPSort(8, 24))
9756 >>> y = FP('y', FPSort(8, 24))
9757 >>> x + y
9758 x + y
9759 >>> (x + y).sort()
9760 FPSort(8, 24)
9761 """
9762 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9763 return fpAdd(_dflt_rm(), a, b, self.ctx)
9764
9765 def __radd__(self, other):
9766 """Create the Z3 expression `other + self`.
9767
9768 >>> x = FP('x', FPSort(8, 24))
9769 >>> 10 + x
9770 1.25*(2**3) + x
9771 """
9772 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9773 return fpAdd(_dflt_rm(), a, b, self.ctx)
9774
9775 def __sub__(self, other):
9776 """Create the Z3 expression `self - other`.
9777
9778 >>> x = FP('x', FPSort(8, 24))
9779 >>> y = FP('y', FPSort(8, 24))
9780 >>> x - y
9781 x - y
9782 >>> (x - y).sort()
9783 FPSort(8, 24)
9784 """
9785 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9786 return fpSub(_dflt_rm(), a, b, self.ctx)
9787
9788 def __rsub__(self, other):
9789 """Create the Z3 expression `other - self`.
9790
9791 >>> x = FP('x', FPSort(8, 24))
9792 >>> 10 - x
9793 1.25*(2**3) - x
9794 """
9795 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9796 return fpSub(_dflt_rm(), a, b, self.ctx)
9797
9798 def __mul__(self, other):
9799 """Create the Z3 expression `self * other`.
9800
9801 >>> x = FP('x', FPSort(8, 24))
9802 >>> y = FP('y', FPSort(8, 24))
9803 >>> x * y
9804 x * y
9805 >>> (x * y).sort()
9806 FPSort(8, 24)
9807 >>> 10 * y
9808 1.25*(2**3) * y
9809 """
9810 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9811 return fpMul(_dflt_rm(), a, b, self.ctx)
9812
9813 def __rmul__(self, other):
9814 """Create the Z3 expression `other * self`.
9815
9816 >>> x = FP('x', FPSort(8, 24))
9817 >>> y = FP('y', FPSort(8, 24))
9818 >>> x * y
9819 x * y
9820 >>> x * 10
9821 x * 1.25*(2**3)
9822 """
9823 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9824 return fpMul(_dflt_rm(), a, b, self.ctx)
9825
9826 def __pos__(self):
9827 """Create the Z3 expression `+self`."""
9828 return self
9829
9830 def __neg__(self):
9831 """Create the Z3 expression `-self`.
9832
9833 >>> x = FP('x', Float32())
9834 >>> -x
9835 -x
9836 """
9837 return fpNeg(self)
9838
9839 def __div__(self, other):
9840 """Create the Z3 expression `self / other`.
9841
9842 >>> x = FP('x', FPSort(8, 24))
9843 >>> y = FP('y', FPSort(8, 24))
9844 >>> x / y
9845 x / y
9846 >>> (x / y).sort()
9847 FPSort(8, 24)
9848 >>> 10 / y
9849 1.25*(2**3) / y
9850 """
9851 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9852 return fpDiv(_dflt_rm(), a, b, self.ctx)
9853
9854 def __rdiv__(self, other):
9855 """Create the Z3 expression `other / self`.
9856
9857 >>> x = FP('x', FPSort(8, 24))
9858 >>> y = FP('y', FPSort(8, 24))
9859 >>> x / y
9860 x / y
9861 >>> x / 10
9862 x / 1.25*(2**3)
9863 """
9864 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9865 return fpDiv(_dflt_rm(), a, b, self.ctx)
9866
9867 def __truediv__(self, other):
9868 """Create the Z3 expression division `self / other`."""
9869 return self.__div__(other)
9870
9871 def __rtruediv__(self, other):
9872 """Create the Z3 expression division `other / self`."""
9873 return self.__rdiv__(other)
9874
9875 def __mod__(self, other):
9876 """Create the Z3 expression mod `self % other`."""
9877 return fpRem(self, other)
9878
9879 def __rmod__(self, other):
9880 """Create the Z3 expression mod `other % self`."""
9881 return fpRem(other, self)
9882
9883
9884class FPRMRef(ExprRef):
9885 """Floating-point rounding mode expressions"""
9886
9887 def as_string(self):
9888 """Return a Z3 floating point expression as a Python string."""
9889 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9890
9891
9892def RoundNearestTiesToEven(ctx=None):
9893 ctx = _get_ctx(ctx)
9894 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9895
9896
9897def RNE(ctx=None):
9898 ctx = _get_ctx(ctx)
9899 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9900
9901
9902def RoundNearestTiesToAway(ctx=None):
9903 ctx = _get_ctx(ctx)
9904 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9905
9906
9907def RNA(ctx=None):
9908 ctx = _get_ctx(ctx)
9909 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9910
9911
9912def RoundTowardPositive(ctx=None):
9913 ctx = _get_ctx(ctx)
9914 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9915
9916
9917def RTP(ctx=None):
9918 ctx = _get_ctx(ctx)
9919 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9920
9921
9922def RoundTowardNegative(ctx=None):
9923 ctx = _get_ctx(ctx)
9924 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9925
9926
9927def RTN(ctx=None):
9928 ctx = _get_ctx(ctx)
9929 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9930
9931
9932def RoundTowardZero(ctx=None):
9933 ctx = _get_ctx(ctx)
9934 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9935
9936
9937def RTZ(ctx=None):
9938 ctx = _get_ctx(ctx)
9939 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9940
9941
9942def is_fprm(a):
9943 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
9944
9945 >>> rm = RNE()
9946 >>> is_fprm(rm)
9947 True
9948 >>> rm = 1.0
9949 >>> is_fprm(rm)
9950 False
9951 """
9952 return isinstance(a, FPRMRef)
9953
9954
9955def is_fprm_value(a):
9956 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
9957 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
9958
9959# FP Numerals
9960
9961
9962class FPNumRef(FPRef):
9963 """The sign of the numeral.
9964
9965 >>> x = FPVal(+1.0, FPSort(8, 24))
9966 >>> x.sign()
9967 False
9968 >>> x = FPVal(-1.0, FPSort(8, 24))
9969 >>> x.sign()
9970 True
9971 """
9972
9973 def sign(self):
9974 num = (ctypes.c_int)()
9975 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
9976 if nsign is False:
9977 raise Z3Exception("error retrieving the sign of a numeral.")
9978 return num.value != 0
9979
9980 """The sign of a floating-point numeral as a bit-vector expression.
9981
9982 Remark: NaN's are invalid arguments.
9983 """
9984
9985 def sign_as_bv(self):
9986 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9987
9988 """The significand of the numeral.
9989
9990 >>> x = FPVal(2.5, FPSort(8, 24))
9991 >>> x.significand()
9992 1.25
9993 """
9994
9995 def significand(self):
9996 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
9997
9998 """The significand of the numeral as a long.
9999
10000 >>> x = FPVal(2.5, FPSort(8, 24))
10001 >>> x.significand_as_long()
10002 1.25
10003 """
10004
10005 def significand_as_long(self):
10006 ptr = (ctypes.c_ulonglong * 1)()
10007 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10008 raise Z3Exception("error retrieving the significand of a numeral.")
10009 return ptr[0]
10010
10011 """The significand of the numeral as a bit-vector expression.
10012
10013 Remark: NaN are invalid arguments.
10014 """
10015
10016 def significand_as_bv(self):
10017 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10018
10019 """The exponent of the numeral.
10020
10021 >>> x = FPVal(2.5, FPSort(8, 24))
10022 >>> x.exponent()
10023 1
10024 """
10025
10026 def exponent(self, biased=True):
10027 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10028
10029 """The exponent of the numeral as a long.
10030
10031 >>> x = FPVal(2.5, FPSort(8, 24))
10032 >>> x.exponent_as_long()
10033 1
10034 """
10035
10036 def exponent_as_long(self, biased=True):
10037 ptr = (ctypes.c_longlong * 1)()
10038 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10039 raise Z3Exception("error retrieving the exponent of a numeral.")
10040 return ptr[0]
10041
10042 """The exponent of the numeral as a bit-vector expression.
10043
10044 Remark: NaNs are invalid arguments.
10045 """
10046
10047 def exponent_as_bv(self, biased=True):
10048 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10049
10050 """Indicates whether the numeral is a NaN."""
10051
10052 def isNaN(self):
10053 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10054
10055 """Indicates whether the numeral is +oo or -oo."""
10056
10057 def isInf(self):
10058 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10059
10060 """Indicates whether the numeral is +zero or -zero."""
10061
10062 def isZero(self):
10063 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10064
10065 """Indicates whether the numeral is normal."""
10066
10067 def isNormal(self):
10068 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10069
10070 """Indicates whether the numeral is subnormal."""
10071
10072 def isSubnormal(self):
10073 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10074
10075 """Indicates whether the numeral is positive."""
10076
10077 def isPositive(self):
10078 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10079
10080 """Indicates whether the numeral is negative."""
10081
10082 def isNegative(self):
10083 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10084
10085 """
10086 The string representation of the numeral.
10087
10088 >>> x = FPVal(20, FPSort(8, 24))
10089 >>> x.as_string()
10090 1.25*(2**4)
10091 """
10092
10093 def as_string(self):
10094 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10095 return ("FPVal(%s, %s)" % (s, self.sort()))
10096
10097 def py_value(self):
10098 bv = simplify(fpToIEEEBV(self))
10099 binary = bv.py_value()
10100 if not isinstance(binary, int):
10101 return None
10102 # Decode the IEEE 754 binary representation
10103 import struct
10104 bytes_rep = binary.to_bytes(8, byteorder='big')
10105 return struct.unpack('>d', bytes_rep)[0]
10106
10107
10108def is_fp(a):
10109 """Return `True` if `a` is a Z3 floating-point expression.
10110
10111 >>> b = FP('b', FPSort(8, 24))
10112 >>> is_fp(b)
10113 True
10114 >>> is_fp(b + 1.0)
10115 True
10116 >>> is_fp(Int('x'))
10117 False
10118 """
10119 return isinstance(a, FPRef)
10120
10121
10122def is_fp_value(a):
10123 """Return `True` if `a` is a Z3 floating-point numeral value.
10124
10125 >>> b = FP('b', FPSort(8, 24))
10126 >>> is_fp_value(b)
10127 False
10128 >>> b = FPVal(1.0, FPSort(8, 24))
10129 >>> b
10130 1
10131 >>> is_fp_value(b)
10132 True
10133 """
10134 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10135
10136
10137def FPSort(ebits, sbits, ctx=None):
10138 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10139
10140 >>> Single = FPSort(8, 24)
10141 >>> Double = FPSort(11, 53)
10142 >>> Single
10143 FPSort(8, 24)
10144 >>> x = Const('x', Single)
10145 >>> eq(x, FP('x', FPSort(8, 24)))
10146 True
10147 """
10148 ctx = _get_ctx(ctx)
10149 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10150
10151
10152def _to_float_str(val, exp=0):
10153 if isinstance(val, float):
10154 if math.isnan(val):
10155 res = "NaN"
10156 elif val == 0.0:
10157 sone = math.copysign(1.0, val)
10158 if sone < 0.0:
10159 return "-0.0"
10160 else:
10161 return "+0.0"
10162 elif val == float("+inf"):
10163 res = "+oo"
10164 elif val == float("-inf"):
10165 res = "-oo"
10166 else:
10167 v = val.as_integer_ratio()
10168 num = v[0]
10169 den = v[1]
10170 rvs = str(num) + "/" + str(den)
10171 res = rvs + "p" + _to_int_str(exp)
10172 elif isinstance(val, bool):
10173 if val:
10174 res = "1.0"
10175 else:
10176 res = "0.0"
10177 elif _is_int(val):
10178 res = str(val)
10179 elif isinstance(val, str):
10180 inx = val.find("*(2**")
10181 if inx == -1:
10182 res = val
10183 elif val[-1] == ")":
10184 res = val[0:inx]
10185 exp = str(int(val[inx + 5:-1]) + int(exp))
10186 else:
10187 _z3_assert(False, "String does not have floating-point numeral form.")
10188 elif z3_debug():
10189 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10190 if exp == 0:
10191 return res
10192 else:
10193 return res + "p" + exp
10194
10195
10196def fpNaN(s):
10197 """Create a Z3 floating-point NaN term.
10198
10199 >>> s = FPSort(8, 24)
10200 >>> set_fpa_pretty(True)
10201 >>> fpNaN(s)
10202 NaN
10203 >>> pb = get_fpa_pretty()
10204 >>> set_fpa_pretty(False)
10205 >>> fpNaN(s)
10206 fpNaN(FPSort(8, 24))
10207 >>> set_fpa_pretty(pb)
10208 """
10209 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10210 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10211
10212
10213def fpPlusInfinity(s):
10214 """Create a Z3 floating-point +oo term.
10215
10216 >>> s = FPSort(8, 24)
10217 >>> pb = get_fpa_pretty()
10218 >>> set_fpa_pretty(True)
10219 >>> fpPlusInfinity(s)
10220 +oo
10221 >>> set_fpa_pretty(False)
10222 >>> fpPlusInfinity(s)
10223 fpPlusInfinity(FPSort(8, 24))
10224 >>> set_fpa_pretty(pb)
10225 """
10226 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10227 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10228
10229
10230def fpMinusInfinity(s):
10231 """Create a Z3 floating-point -oo term."""
10232 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10233 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10234
10235
10236def fpInfinity(s, negative):
10237 """Create a Z3 floating-point +oo or -oo term."""
10238 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10239 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10240 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10241
10242
10243def fpPlusZero(s):
10244 """Create a Z3 floating-point +0.0 term."""
10245 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10246 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10247
10248
10249def fpMinusZero(s):
10250 """Create a Z3 floating-point -0.0 term."""
10251 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10252 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10253
10254
10255def fpZero(s, negative):
10256 """Create a Z3 floating-point +0.0 or -0.0 term."""
10257 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10258 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10259 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10260
10261
10262def FPVal(sig, exp=None, fps=None, ctx=None):
10263 """Return a floating-point value of value `val` and sort `fps`.
10264 If `ctx=None`, then the global context is used.
10265
10266 >>> v = FPVal(20.0, FPSort(8, 24))
10267 >>> v
10268 1.25*(2**4)
10269 >>> print("0x%.8x" % v.exponent_as_long(False))
10270 0x00000004
10271 >>> v = FPVal(2.25, FPSort(8, 24))
10272 >>> v
10273 1.125*(2**1)
10274 >>> v = FPVal(-2.25, FPSort(8, 24))
10275 >>> v
10276 -1.125*(2**1)
10277 >>> FPVal(-0.0, FPSort(8, 24))
10278 -0.0
10279 >>> FPVal(0.0, FPSort(8, 24))
10280 +0.0
10281 >>> FPVal(+0.0, FPSort(8, 24))
10282 +0.0
10283 """
10284 ctx = _get_ctx(ctx)
10285 if is_fp_sort(exp):
10286 fps = exp
10287 exp = None
10288 elif fps is None:
10289 fps = _dflt_fps(ctx)
10290 _z3_assert(is_fp_sort(fps), "sort mismatch")
10291 if exp is None:
10292 exp = 0
10293 val = _to_float_str(sig)
10294 if val == "NaN" or val == "nan":
10295 return fpNaN(fps)
10296 elif val == "-0.0":
10297 return fpMinusZero(fps)
10298 elif val == "0.0" or val == "+0.0":
10299 return fpPlusZero(fps)
10300 elif val == "+oo" or val == "+inf" or val == "+Inf":
10301 return fpPlusInfinity(fps)
10302 elif val == "-oo" or val == "-inf" or val == "-Inf":
10303 return fpMinusInfinity(fps)
10304 else:
10305 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10306
10307
10308def FP(name, fpsort, ctx=None):
10309 """Return a floating-point constant named `name`.
10310 `fpsort` is the floating-point sort.
10311 If `ctx=None`, then the global context is used.
10312
10313 >>> x = FP('x', FPSort(8, 24))
10314 >>> is_fp(x)
10315 True
10316 >>> x.ebits()
10317 8
10318 >>> x.sort()
10319 FPSort(8, 24)
10320 >>> word = FPSort(8, 24)
10321 >>> x2 = FP('x', word)
10322 >>> eq(x, x2)
10323 True
10324 """
10325 if isinstance(fpsort, FPSortRef) and ctx is None:
10326 ctx = fpsort.ctx
10327 else:
10328 ctx = _get_ctx(ctx)
10329 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10330
10331
10332def FPs(names, fpsort, ctx=None):
10333 """Return an array of floating-point constants.
10334
10335 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10336 >>> x.sort()
10337 FPSort(8, 24)
10338 >>> x.sbits()
10339 24
10340 >>> x.ebits()
10341 8
10342 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10343 (x + y) * z
10344 """
10345 ctx = _get_ctx(ctx)
10346 if isinstance(names, str):
10347 names = names.split(" ")
10348 return [FP(name, fpsort, ctx) for name in names]
10349
10350
10351def fpAbs(a, ctx=None):
10352 """Create a Z3 floating-point absolute value expression.
10353
10354 >>> s = FPSort(8, 24)
10355 >>> rm = RNE()
10356 >>> x = FPVal(1.0, s)
10357 >>> fpAbs(x)
10358 fpAbs(1)
10359 >>> y = FPVal(-20.0, s)
10360 >>> y
10361 -1.25*(2**4)
10362 >>> fpAbs(y)
10363 fpAbs(-1.25*(2**4))
10364 >>> fpAbs(-1.25*(2**4))
10365 fpAbs(-1.25*(2**4))
10366 >>> fpAbs(x).sort()
10367 FPSort(8, 24)
10368 """
10369 ctx = _get_ctx(ctx)
10370 [a] = _coerce_fp_expr_list([a], ctx)
10371 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10372
10373
10374def fpNeg(a, ctx=None):
10375 """Create a Z3 floating-point addition expression.
10376
10377 >>> s = FPSort(8, 24)
10378 >>> rm = RNE()
10379 >>> x = FP('x', s)
10380 >>> fpNeg(x)
10381 -x
10382 >>> fpNeg(x).sort()
10383 FPSort(8, 24)
10384 """
10385 ctx = _get_ctx(ctx)
10386 [a] = _coerce_fp_expr_list([a], ctx)
10387 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10388
10389
10390def _mk_fp_unary(f, rm, a, ctx):
10391 ctx = _get_ctx(ctx)
10392 [a] = _coerce_fp_expr_list([a], ctx)
10393 if z3_debug():
10394 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10395 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10396 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10397
10398
10399def _mk_fp_unary_pred(f, a, ctx):
10400 ctx = _get_ctx(ctx)
10401 [a] = _coerce_fp_expr_list([a], ctx)
10402 if z3_debug():
10403 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10404 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10405
10406
10407def _mk_fp_bin(f, rm, a, b, ctx):
10408 ctx = _get_ctx(ctx)
10409 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10410 if z3_debug():
10411 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10412 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10413 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10414
10415
10416def _mk_fp_bin_norm(f, a, b, ctx):
10417 ctx = _get_ctx(ctx)
10418 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10419 if z3_debug():
10420 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10421 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10422
10423
10424def _mk_fp_bin_pred(f, a, b, ctx):
10425 ctx = _get_ctx(ctx)
10426 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10427 if z3_debug():
10428 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10429 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10430
10431
10432def _mk_fp_tern(f, rm, a, b, c, ctx):
10433 ctx = _get_ctx(ctx)
10434 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10435 if z3_debug():
10436 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10437 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10438 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10439 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10440
10441
10442def fpAdd(rm, a, b, ctx=None):
10443 """Create a Z3 floating-point addition expression.
10444
10445 >>> s = FPSort(8, 24)
10446 >>> rm = RNE()
10447 >>> x = FP('x', s)
10448 >>> y = FP('y', s)
10449 >>> fpAdd(rm, x, y)
10450 x + y
10451 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10452 fpAdd(RTZ(), x, y)
10453 >>> fpAdd(rm, x, y).sort()
10454 FPSort(8, 24)
10455 """
10456 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10457
10458
10459def fpSub(rm, a, b, ctx=None):
10460 """Create a Z3 floating-point subtraction expression.
10461
10462 >>> s = FPSort(8, 24)
10463 >>> rm = RNE()
10464 >>> x = FP('x', s)
10465 >>> y = FP('y', s)
10466 >>> fpSub(rm, x, y)
10467 x - y
10468 >>> fpSub(rm, x, y).sort()
10469 FPSort(8, 24)
10470 """
10471 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10472
10473
10474def fpMul(rm, a, b, ctx=None):
10475 """Create a Z3 floating-point multiplication expression.
10476
10477 >>> s = FPSort(8, 24)
10478 >>> rm = RNE()
10479 >>> x = FP('x', s)
10480 >>> y = FP('y', s)
10481 >>> fpMul(rm, x, y)
10482 x * y
10483 >>> fpMul(rm, x, y).sort()
10484 FPSort(8, 24)
10485 """
10486 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10487
10488
10489def fpDiv(rm, a, b, ctx=None):
10490 """Create a Z3 floating-point division expression.
10491
10492 >>> s = FPSort(8, 24)
10493 >>> rm = RNE()
10494 >>> x = FP('x', s)
10495 >>> y = FP('y', s)
10496 >>> fpDiv(rm, x, y)
10497 x / y
10498 >>> fpDiv(rm, x, y).sort()
10499 FPSort(8, 24)
10500 """
10501 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10502
10503
10504def fpRem(a, b, ctx=None):
10505 """Create a Z3 floating-point remainder expression.
10506
10507 >>> s = FPSort(8, 24)
10508 >>> x = FP('x', s)
10509 >>> y = FP('y', s)
10510 >>> fpRem(x, y)
10511 fpRem(x, y)
10512 >>> fpRem(x, y).sort()
10513 FPSort(8, 24)
10514 """
10515 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10516
10517
10518def fpMin(a, b, ctx=None):
10519 """Create a Z3 floating-point minimum expression.
10520
10521 >>> s = FPSort(8, 24)
10522 >>> rm = RNE()
10523 >>> x = FP('x', s)
10524 >>> y = FP('y', s)
10525 >>> fpMin(x, y)
10526 fpMin(x, y)
10527 >>> fpMin(x, y).sort()
10528 FPSort(8, 24)
10529 """
10530 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10531
10532
10533def fpMax(a, b, ctx=None):
10534 """Create a Z3 floating-point maximum expression.
10535
10536 >>> s = FPSort(8, 24)
10537 >>> rm = RNE()
10538 >>> x = FP('x', s)
10539 >>> y = FP('y', s)
10540 >>> fpMax(x, y)
10541 fpMax(x, y)
10542 >>> fpMax(x, y).sort()
10543 FPSort(8, 24)
10544 """
10545 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10546
10547
10548def fpFMA(rm, a, b, c, ctx=None):
10549 """Create a Z3 floating-point fused multiply-add expression.
10550 """
10551 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10552
10553
10554def fpSqrt(rm, a, ctx=None):
10555 """Create a Z3 floating-point square root expression.
10556 """
10557 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10558
10559
10560def fpRoundToIntegral(rm, a, ctx=None):
10561 """Create a Z3 floating-point roundToIntegral expression.
10562 """
10563 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10564
10565
10566def fpIsNaN(a, ctx=None):
10567 """Create a Z3 floating-point isNaN expression.
10568
10569 >>> s = FPSort(8, 24)
10570 >>> x = FP('x', s)
10571 >>> y = FP('y', s)
10572 >>> fpIsNaN(x)
10573 fpIsNaN(x)
10574 """
10575 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10576
10577
10578def fpIsInf(a, ctx=None):
10579 """Create a Z3 floating-point isInfinite expression.
10580
10581 >>> s = FPSort(8, 24)
10582 >>> x = FP('x', s)
10583 >>> fpIsInf(x)
10584 fpIsInf(x)
10585 """
10586 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10587
10588
10589def fpIsZero(a, ctx=None):
10590 """Create a Z3 floating-point isZero expression.
10591 """
10592 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10593
10594
10595def fpIsNormal(a, ctx=None):
10596 """Create a Z3 floating-point isNormal expression.
10597 """
10598 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10599
10600
10601def fpIsSubnormal(a, ctx=None):
10602 """Create a Z3 floating-point isSubnormal expression.
10603 """
10604 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10605
10606
10607def fpIsNegative(a, ctx=None):
10608 """Create a Z3 floating-point isNegative expression.
10609 """
10610 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10611
10612
10613def fpIsPositive(a, ctx=None):
10614 """Create a Z3 floating-point isPositive expression.
10615 """
10616 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10617
10618
10619def _check_fp_args(a, b):
10620 if z3_debug():
10621 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10622
10623
10624def fpLT(a, b, ctx=None):
10625 """Create the Z3 floating-point expression `other < self`.
10626
10627 >>> x, y = FPs('x y', FPSort(8, 24))
10628 >>> fpLT(x, y)
10629 x < y
10630 >>> (x < y).sexpr()
10631 '(fp.lt x y)'
10632 """
10633 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10634
10635
10636def fpLEQ(a, b, ctx=None):
10637 """Create the Z3 floating-point expression `other <= self`.
10638
10639 >>> x, y = FPs('x y', FPSort(8, 24))
10640 >>> fpLEQ(x, y)
10641 x <= y
10642 >>> (x <= y).sexpr()
10643 '(fp.leq x y)'
10644 """
10645 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10646
10647
10648def fpGT(a, b, ctx=None):
10649 """Create the Z3 floating-point expression `other > self`.
10650
10651 >>> x, y = FPs('x y', FPSort(8, 24))
10652 >>> fpGT(x, y)
10653 x > y
10654 >>> (x > y).sexpr()
10655 '(fp.gt x y)'
10656 """
10657 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10658
10659
10660def fpGEQ(a, b, ctx=None):
10661 """Create the Z3 floating-point expression `other >= self`.
10662
10663 >>> x, y = FPs('x y', FPSort(8, 24))
10664 >>> fpGEQ(x, y)
10665 x >= y
10666 >>> (x >= y).sexpr()
10667 '(fp.geq x y)'
10668 """
10669 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10670
10671
10672def fpEQ(a, b, ctx=None):
10673 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10674
10675 >>> x, y = FPs('x y', FPSort(8, 24))
10676 >>> fpEQ(x, y)
10677 fpEQ(x, y)
10678 >>> fpEQ(x, y).sexpr()
10679 '(fp.eq x y)'
10680 """
10681 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10682
10683
10684def fpNEQ(a, b, ctx=None):
10685 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10686
10687 >>> x, y = FPs('x y', FPSort(8, 24))
10688 >>> fpNEQ(x, y)
10689 Not(fpEQ(x, y))
10690 >>> (x != y).sexpr()
10691 '(distinct x y)'
10692 """
10693 return Not(fpEQ(a, b, ctx))
10694
10695
10696def fpFP(sgn, exp, sig, ctx=None):
10697 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10698
10699 >>> s = FPSort(8, 24)
10700 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10701 >>> print(x)
10702 fpFP(1, 127, 4194304)
10703 >>> xv = FPVal(-1.5, s)
10704 >>> print(xv)
10705 -1.5
10706 >>> slvr = Solver()
10707 >>> slvr.add(fpEQ(x, xv))
10708 >>> slvr.check()
10709 sat
10710 >>> xv = FPVal(+1.5, s)
10711 >>> print(xv)
10712 1.5
10713 >>> slvr = Solver()
10714 >>> slvr.add(fpEQ(x, xv))
10715 >>> slvr.check()
10716 unsat
10717 """
10718 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10719 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10720 ctx = _get_ctx(ctx)
10721 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10722 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10723
10724
10725def fpToFP(a1, a2=None, a3=None, ctx=None):
10726 """Create a Z3 floating-point conversion expression from other term sorts
10727 to floating-point.
10728
10729 From a bit-vector term in IEEE 754-2008 format:
10730 >>> x = FPVal(1.0, Float32())
10731 >>> x_bv = fpToIEEEBV(x)
10732 >>> simplify(fpToFP(x_bv, Float32()))
10733 1
10734
10735 From a floating-point term with different precision:
10736 >>> x = FPVal(1.0, Float32())
10737 >>> x_db = fpToFP(RNE(), x, Float64())
10738 >>> x_db.sort()
10739 FPSort(11, 53)
10740
10741 From a real term:
10742 >>> x_r = RealVal(1.5)
10743 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10744 1.5
10745
10746 From a signed bit-vector term:
10747 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10748 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10749 -1.25*(2**2)
10750 """
10751 ctx = _get_ctx(ctx)
10752 if is_bv(a1) and is_fp_sort(a2):
10753 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10754 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10755 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10756 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10757 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10758 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10759 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10760 else:
10761 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10762
10763
10764def fpBVToFP(v, sort, ctx=None):
10765 """Create a Z3 floating-point conversion expression that represents the
10766 conversion from a bit-vector term to a floating-point term.
10767
10768 >>> x_bv = BitVecVal(0x3F800000, 32)
10769 >>> x_fp = fpBVToFP(x_bv, Float32())
10770 >>> x_fp
10771 fpToFP(1065353216)
10772 >>> simplify(x_fp)
10773 1
10774 """
10775 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10776 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10777 ctx = _get_ctx(ctx)
10778 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10779
10780
10781def fpFPToFP(rm, v, sort, ctx=None):
10782 """Create a Z3 floating-point conversion expression that represents the
10783 conversion from a floating-point term to a floating-point term of different precision.
10784
10785 >>> x_sgl = FPVal(1.0, Float32())
10786 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10787 >>> x_dbl
10788 fpToFP(RNE(), 1)
10789 >>> simplify(x_dbl)
10790 1
10791 >>> x_dbl.sort()
10792 FPSort(11, 53)
10793 """
10794 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10795 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10796 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10797 ctx = _get_ctx(ctx)
10798 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10799
10800
10801def fpRealToFP(rm, v, sort, ctx=None):
10802 """Create a Z3 floating-point conversion expression that represents the
10803 conversion from a real term to a floating-point term.
10804
10805 >>> x_r = RealVal(1.5)
10806 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10807 >>> x_fp
10808 fpToFP(RNE(), 3/2)
10809 >>> simplify(x_fp)
10810 1.5
10811 """
10812 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10813 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10814 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10815 ctx = _get_ctx(ctx)
10816 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10817
10818
10819def fpSignedToFP(rm, v, sort, ctx=None):
10820 """Create a Z3 floating-point conversion expression that represents the
10821 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10822
10823 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10824 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10825 >>> x_fp
10826 fpToFP(RNE(), 4294967291)
10827 >>> simplify(x_fp)
10828 -1.25*(2**2)
10829 """
10830 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10831 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10832 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10833 ctx = _get_ctx(ctx)
10834 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10835
10836
10837def fpUnsignedToFP(rm, v, sort, ctx=None):
10838 """Create a Z3 floating-point conversion expression that represents the
10839 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10840
10841 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10842 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10843 >>> x_fp
10844 fpToFPUnsigned(RNE(), 4294967291)
10845 >>> simplify(x_fp)
10846 1*(2**32)
10847 """
10848 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10849 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10850 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10851 ctx = _get_ctx(ctx)
10852 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10853
10854
10855def fpToFPUnsigned(rm, x, s, ctx=None):
10856 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10857 if z3_debug():
10858 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10859 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10860 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10861 ctx = _get_ctx(ctx)
10862 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10863
10864
10865def fpToSBV(rm, x, s, ctx=None):
10866 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10867
10868 >>> x = FP('x', FPSort(8, 24))
10869 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10870 >>> print(is_fp(x))
10871 True
10872 >>> print(is_bv(y))
10873 True
10874 >>> print(is_fp(y))
10875 False
10876 >>> print(is_bv(x))
10877 False
10878 """
10879 if z3_debug():
10880 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10881 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10882 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10883 ctx = _get_ctx(ctx)
10884 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10885
10886
10887def fpToUBV(rm, x, s, ctx=None):
10888 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10889
10890 >>> x = FP('x', FPSort(8, 24))
10891 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10892 >>> print(is_fp(x))
10893 True
10894 >>> print(is_bv(y))
10895 True
10896 >>> print(is_fp(y))
10897 False
10898 >>> print(is_bv(x))
10899 False
10900 """
10901 if z3_debug():
10902 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10903 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10904 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10905 ctx = _get_ctx(ctx)
10906 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10907
10908
10909def fpToReal(x, ctx=None):
10910 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
10911
10912 >>> x = FP('x', FPSort(8, 24))
10913 >>> y = fpToReal(x)
10914 >>> print(is_fp(x))
10915 True
10916 >>> print(is_real(y))
10917 True
10918 >>> print(is_fp(y))
10919 False
10920 >>> print(is_real(x))
10921 False
10922 """
10923 if z3_debug():
10924 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10925 ctx = _get_ctx(ctx)
10926 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
10927
10928
10929def fpToIEEEBV(x, ctx=None):
10930 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
10931
10932 The size of the resulting bit-vector is automatically determined.
10933
10934 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
10935 knows only one NaN and it will always produce the same bit-vector representation of
10936 that NaN.
10937
10938 >>> x = FP('x', FPSort(8, 24))
10939 >>> y = fpToIEEEBV(x)
10940 >>> print(is_fp(x))
10941 True
10942 >>> print(is_bv(y))
10943 True
10944 >>> print(is_fp(y))
10945 False
10946 >>> print(is_bv(x))
10947 False
10948 """
10949 if z3_debug():
10950 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10951 ctx = _get_ctx(ctx)
10952 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
10953
10954
10955#########################################
10956#
10957# Strings, Sequences and Regular expressions
10958#
10959#########################################
10960
10961class SeqSortRef(SortRef):
10962 """Sequence sort."""
10963
10964 def is_string(self):
10965 """Determine if sort is a string
10966 >>> s = StringSort()
10967 >>> s.is_string()
10968 True
10969 >>> s = SeqSort(IntSort())
10970 >>> s.is_string()
10971 False
10972 """
10973 return Z3_is_string_sort(self.ctx_ref(), self.ast)
10974
10975 def basis(self):
10976 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10977
10978class CharSortRef(SortRef):
10979 """Character sort."""
10980
10981
10982def StringSort(ctx=None):
10983 """Create a string sort
10984 >>> s = StringSort()
10985 >>> print(s)
10986 String
10987 """
10988 ctx = _get_ctx(ctx)
10989 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
10990
10991def CharSort(ctx=None):
10992 """Create a character sort
10993 >>> ch = CharSort()
10994 >>> print(ch)
10995 Char
10996 """
10997 ctx = _get_ctx(ctx)
10998 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
10999
11000
11001def SeqSort(s):
11002 """Create a sequence sort over elements provided in the argument
11003 >>> s = SeqSort(IntSort())
11004 >>> s == Unit(IntVal(1)).sort()
11005 True
11006 """
11007 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11008
11009
11010class SeqRef(ExprRef):
11011 """Sequence expression."""
11012
11013 def sort(self):
11014 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11015
11016 def __add__(self, other):
11017 return Concat(self, other)
11018
11019 def __radd__(self, other):
11020 return Concat(other, self)
11021
11022 def __getitem__(self, i):
11023 if _is_int(i):
11024 i = IntVal(i, self.ctx)
11025 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11026
11027 def at(self, i):
11028 if _is_int(i):
11029 i = IntVal(i, self.ctx)
11030 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11031
11032 def is_string(self):
11033 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11034
11035 def is_string_value(self):
11036 return Z3_is_string(self.ctx_ref(), self.as_ast())
11037
11038 def as_string(self):
11039 """Return a string representation of sequence expression."""
11040 if self.is_string_value():
11041 string_length = ctypes.c_uint()
11042 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11043 return string_at(chars, size=string_length.value).decode("latin-1")
11044 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11045
11046 def py_value(self):
11047 return self.as_string()
11048
11049 def __le__(self, other):
11050 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11051
11052 def __lt__(self, other):
11053 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11054
11055 def __ge__(self, other):
11056 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11057
11058 def __gt__(self, other):
11059 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11060
11061
11062def _coerce_char(ch, ctx=None):
11063 if isinstance(ch, str):
11064 ctx = _get_ctx(ctx)
11065 ch = CharVal(ch, ctx)
11066 if not is_expr(ch):
11067 raise Z3Exception("Character expression expected")
11068 return ch
11069
11070class CharRef(ExprRef):
11071 """Character expression."""
11072
11073 def __le__(self, other):
11074 other = _coerce_char(other, self.ctx)
11075 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11076
11077 def to_int(self):
11078 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11079
11080 def to_bv(self):
11081 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11082
11083 def is_digit(self):
11084 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11085
11086
11087def CharVal(ch, ctx=None):
11088 ctx = _get_ctx(ctx)
11089 if isinstance(ch, str):
11090 ch = ord(ch)
11091 if not isinstance(ch, int):
11092 raise Z3Exception("character value should be an ordinal")
11093 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11094
11095def CharFromBv(bv):
11096 if not is_expr(bv):
11097 raise Z3Exception("Bit-vector expression needed")
11098 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11099
11100def CharToBv(ch, ctx=None):
11101 ch = _coerce_char(ch, ctx)
11102 return ch.to_bv()
11103
11104def CharToInt(ch, ctx=None):
11105 ch = _coerce_char(ch, ctx)
11106 return ch.to_int()
11107
11108def CharIsDigit(ch, ctx=None):
11109 ch = _coerce_char(ch, ctx)
11110 return ch.is_digit()
11111
11112def _coerce_seq(s, ctx=None):
11113 if isinstance(s, str):
11114 ctx = _get_ctx(ctx)
11115 s = StringVal(s, ctx)
11116 if not is_expr(s):
11117 raise Z3Exception("Non-expression passed as a sequence")
11118 if not is_seq(s):
11119 raise Z3Exception("Non-sequence passed as a sequence")
11120 return s
11121
11122
11123def _get_ctx2(a, b, ctx=None):
11124 if is_expr(a):
11125 return a.ctx
11126 if is_expr(b):
11127 return b.ctx
11128 if ctx is None:
11129 ctx = main_ctx()
11130 return ctx
11131
11132
11133def is_seq(a):
11134 """Return `True` if `a` is a Z3 sequence expression.
11135 >>> print (is_seq(Unit(IntVal(0))))
11136 True
11137 >>> print (is_seq(StringVal("abc")))
11138 True
11139 """
11140 return isinstance(a, SeqRef)
11141
11142
11143def is_string(a):
11144 """Return `True` if `a` is a Z3 string expression.
11145 >>> print (is_string(StringVal("ab")))
11146 True
11147 """
11148 return isinstance(a, SeqRef) and a.is_string()
11149
11150
11151def is_string_value(a):
11152 """return 'True' if 'a' is a Z3 string constant expression.
11153 >>> print (is_string_value(StringVal("a")))
11154 True
11155 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11156 False
11157 """
11158 return isinstance(a, SeqRef) and a.is_string_value()
11159
11160def StringVal(s, ctx=None):
11161 """create a string expression"""
11162 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11163 ctx = _get_ctx(ctx)
11164 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11165
11166
11167def String(name, ctx=None):
11168 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11169
11170 >>> x = String('x')
11171 """
11172 ctx = _get_ctx(ctx)
11173 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11174
11175
11176def Strings(names, ctx=None):
11177 """Return a tuple of String constants. """
11178 ctx = _get_ctx(ctx)
11179 if isinstance(names, str):
11180 names = names.split(" ")
11181 return [String(name, ctx) for name in names]
11182
11183
11184def SubString(s, offset, length):
11185 """Extract substring or subsequence starting at offset"""
11186 return Extract(s, offset, length)
11187
11188
11189def SubSeq(s, offset, length):
11190 """Extract substring or subsequence starting at offset"""
11191 return Extract(s, offset, length)
11192
11193
11194def Empty(s):
11195 """Create the empty sequence of the given sort
11196 >>> e = Empty(StringSort())
11197 >>> e2 = StringVal("")
11198 >>> print(e.eq(e2))
11199 True
11200 >>> e3 = Empty(SeqSort(IntSort()))
11201 >>> print(e3)
11202 Empty(Seq(Int))
11203 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11204 >>> print(e4)
11205 Empty(ReSort(Seq(Int)))
11206 """
11207 if isinstance(s, SeqSortRef):
11208 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11209 if isinstance(s, ReSortRef):
11210 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11211 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11212
11213
11214def Full(s):
11215 """Create the regular expression that accepts the universal language
11216 >>> e = Full(ReSort(SeqSort(IntSort())))
11217 >>> print(e)
11218 Full(ReSort(Seq(Int)))
11219 >>> e1 = Full(ReSort(StringSort()))
11220 >>> print(e1)
11221 Full(ReSort(String))
11222 """
11223 if isinstance(s, ReSortRef):
11224 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11225 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11226
11227
11228
11229def Unit(a):
11230 """Create a singleton sequence"""
11231 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11232
11233
11234def PrefixOf(a, b):
11235 """Check if 'a' is a prefix of 'b'
11236 >>> s1 = PrefixOf("ab", "abc")
11237 >>> simplify(s1)
11238 True
11239 >>> s2 = PrefixOf("bc", "abc")
11240 >>> simplify(s2)
11241 False
11242 """
11243 ctx = _get_ctx2(a, b)
11244 a = _coerce_seq(a, ctx)
11245 b = _coerce_seq(b, ctx)
11246 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11247
11248
11249def SuffixOf(a, b):
11250 """Check if 'a' is a suffix of 'b'
11251 >>> s1 = SuffixOf("ab", "abc")
11252 >>> simplify(s1)
11253 False
11254 >>> s2 = SuffixOf("bc", "abc")
11255 >>> simplify(s2)
11256 True
11257 """
11258 ctx = _get_ctx2(a, b)
11259 a = _coerce_seq(a, ctx)
11260 b = _coerce_seq(b, ctx)
11261 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11262
11263
11264def Contains(a, b):
11265 """Check if 'a' contains 'b'
11266 >>> s1 = Contains("abc", "ab")
11267 >>> simplify(s1)
11268 True
11269 >>> s2 = Contains("abc", "bc")
11270 >>> simplify(s2)
11271 True
11272 >>> x, y, z = Strings('x y z')
11273 >>> s3 = Contains(Concat(x,y,z), y)
11274 >>> simplify(s3)
11275 True
11276 """
11277 ctx = _get_ctx2(a, b)
11278 a = _coerce_seq(a, ctx)
11279 b = _coerce_seq(b, ctx)
11280 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11281
11282
11283def Replace(s, src, dst):
11284 """Replace the first occurrence of 'src' by 'dst' in 's'
11285 >>> r = Replace("aaa", "a", "b")
11286 >>> simplify(r)
11287 "baa"
11288 """
11289 ctx = _get_ctx2(dst, s)
11290 if ctx is None and is_expr(src):
11291 ctx = src.ctx
11292 src = _coerce_seq(src, ctx)
11293 dst = _coerce_seq(dst, ctx)
11294 s = _coerce_seq(s, ctx)
11295 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11296
11297
11298def IndexOf(s, substr, offset=None):
11299 """Retrieve the index of substring within a string starting at a specified offset.
11300 >>> simplify(IndexOf("abcabc", "bc", 0))
11301 1
11302 >>> simplify(IndexOf("abcabc", "bc", 2))
11303 4
11304 """
11305 if offset is None:
11306 offset = IntVal(0)
11307 ctx = None
11308 if is_expr(offset):
11309 ctx = offset.ctx
11310 ctx = _get_ctx2(s, substr, ctx)
11311 s = _coerce_seq(s, ctx)
11312 substr = _coerce_seq(substr, ctx)
11313 if _is_int(offset):
11314 offset = IntVal(offset, ctx)
11315 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11316
11317
11318def LastIndexOf(s, substr):
11319 """Retrieve the last index of substring within a string"""
11320 ctx = None
11321 ctx = _get_ctx2(s, substr, ctx)
11322 s = _coerce_seq(s, ctx)
11323 substr = _coerce_seq(substr, ctx)
11324 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11325
11326
11327def Length(s):
11328 """Obtain the length of a sequence 's'
11329 >>> l = Length(StringVal("abc"))
11330 >>> simplify(l)
11331 3
11332 """
11333 s = _coerce_seq(s)
11334 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11335
11336def SeqMap(f, s):
11337 """Map function 'f' over sequence 's'"""
11338 ctx = _get_ctx2(f, s)
11339 s = _coerce_seq(s, ctx)
11340 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11341
11342def SeqMapI(f, i, s):
11343 """Map function 'f' over sequence 's' at index 'i'"""
11344 ctx = _get_ctx(f, s)
11345 s = _coerce_seq(s, ctx)
11346 if not is_expr(i):
11347 i = _py2expr(i)
11348 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11349
11350def SeqFoldLeft(f, a, s):
11351 ctx = _get_ctx2(f, s)
11352 s = _coerce_seq(s, ctx)
11353 a = _py2expr(a)
11354 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11355
11356def SeqFoldLeftI(f, i, a, s):
11357 ctx = _get_ctx2(f, s)
11358 s = _coerce_seq(s, ctx)
11359 a = _py2expr(a)
11360 i = _py2epxr(i)
11361 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11362
11363def StrToInt(s):
11364 """Convert string expression to integer
11365 >>> a = StrToInt("1")
11366 >>> simplify(1 == a)
11367 True
11368 >>> b = StrToInt("2")
11369 >>> simplify(1 == b)
11370 False
11371 >>> c = StrToInt(IntToStr(2))
11372 >>> simplify(1 == c)
11373 False
11374 """
11375 s = _coerce_seq(s)
11376 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11377
11378
11379def IntToStr(s):
11380 """Convert integer expression to string"""
11381 if not is_expr(s):
11382 s = _py2expr(s)
11383 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11384
11385
11386def StrToCode(s):
11387 """Convert a unit length string to integer code"""
11388 if not is_expr(s):
11389 s = _py2expr(s)
11390 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11391
11392def StrFromCode(c):
11393 """Convert code to a string"""
11394 if not is_expr(c):
11395 c = _py2expr(c)
11396 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11397
11398def Re(s, ctx=None):
11399 """The regular expression that accepts sequence 's'
11400 >>> s1 = Re("ab")
11401 >>> s2 = Re(StringVal("ab"))
11402 >>> s3 = Re(Unit(BoolVal(True)))
11403 """
11404 s = _coerce_seq(s, ctx)
11405 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11406
11407
11408# Regular expressions
11409
11410class ReSortRef(SortRef):
11411 """Regular expression sort."""
11412
11413 def basis(self):
11414 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11415
11416
11417def ReSort(s):
11418 if is_ast(s):
11419 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11420 if s is None or isinstance(s, Context):
11421 ctx = _get_ctx(s)
11422 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11423 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11424
11425
11426class ReRef(ExprRef):
11427 """Regular expressions."""
11428
11429 def __add__(self, other):
11430 return Union(self, other)
11431
11432
11433def is_re(s):
11434 return isinstance(s, ReRef)
11435
11436
11437def InRe(s, re):
11438 """Create regular expression membership test
11439 >>> re = Union(Re("a"),Re("b"))
11440 >>> print (simplify(InRe("a", re)))
11441 True
11442 >>> print (simplify(InRe("b", re)))
11443 True
11444 >>> print (simplify(InRe("c", re)))
11445 False
11446 """
11447 s = _coerce_seq(s, re.ctx)
11448 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11449
11450
11451def Union(*args):
11452 """Create union of regular expressions.
11453 >>> re = Union(Re("a"), Re("b"), Re("c"))
11454 >>> print (simplify(InRe("d", re)))
11455 False
11456 """
11457 args = _get_args(args)
11458 sz = len(args)
11459 if z3_debug():
11460 _z3_assert(sz > 0, "At least one argument expected.")
11461 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11462 if sz == 1:
11463 return args[0]
11464 ctx = args[0].ctx
11465 v = (Ast * sz)()
11466 for i in range(sz):
11467 v[i] = args[i].as_ast()
11468 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11469
11470
11471def Intersect(*args):
11472 """Create intersection of regular expressions.
11473 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11474 """
11475 args = _get_args(args)
11476 sz = len(args)
11477 if z3_debug():
11478 _z3_assert(sz > 0, "At least one argument expected.")
11479 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11480 if sz == 1:
11481 return args[0]
11482 ctx = args[0].ctx
11483 v = (Ast * sz)()
11484 for i in range(sz):
11485 v[i] = args[i].as_ast()
11486 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11487
11488
11489def Plus(re):
11490 """Create the regular expression accepting one or more repetitions of argument.
11491 >>> re = Plus(Re("a"))
11492 >>> print(simplify(InRe("aa", re)))
11493 True
11494 >>> print(simplify(InRe("ab", re)))
11495 False
11496 >>> print(simplify(InRe("", re)))
11497 False
11498 """
11499 if z3_debug():
11500 _z3_assert(is_expr(re), "expression expected")
11501 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11502
11503
11504def Option(re):
11505 """Create the regular expression that optionally accepts the argument.
11506 >>> re = Option(Re("a"))
11507 >>> print(simplify(InRe("a", re)))
11508 True
11509 >>> print(simplify(InRe("", re)))
11510 True
11511 >>> print(simplify(InRe("aa", re)))
11512 False
11513 """
11514 if z3_debug():
11515 _z3_assert(is_expr(re), "expression expected")
11516 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11517
11518
11519def Complement(re):
11520 """Create the complement regular expression."""
11521 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11522
11523
11524def Star(re):
11525 """Create the regular expression accepting zero or more repetitions of argument.
11526 >>> re = Star(Re("a"))
11527 >>> print(simplify(InRe("aa", re)))
11528 True
11529 >>> print(simplify(InRe("ab", re)))
11530 False
11531 >>> print(simplify(InRe("", re)))
11532 True
11533 """
11534 if z3_debug():
11535 _z3_assert(is_expr(re), "expression expected")
11536 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11537
11538
11539def Loop(re, lo, hi=0):
11540 """Create the regular expression accepting between a lower and upper bound repetitions
11541 >>> re = Loop(Re("a"), 1, 3)
11542 >>> print(simplify(InRe("aa", re)))
11543 True
11544 >>> print(simplify(InRe("aaaa", re)))
11545 False
11546 >>> print(simplify(InRe("", re)))
11547 False
11548 """
11549 if z3_debug():
11550 _z3_assert(is_expr(re), "expression expected")
11551 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11552
11553
11554def Range(lo, hi, ctx=None):
11555 """Create the range regular expression over two sequences of length 1
11556 >>> range = Range("a","z")
11557 >>> print(simplify(InRe("b", range)))
11558 True
11559 >>> print(simplify(InRe("bb", range)))
11560 False
11561 """
11562 lo = _coerce_seq(lo, ctx)
11563 hi = _coerce_seq(hi, ctx)
11564 if z3_debug():
11565 _z3_assert(is_expr(lo), "expression expected")
11566 _z3_assert(is_expr(hi), "expression expected")
11567 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11568
11569def Diff(a, b, ctx=None):
11570 """Create the difference regular expression
11571 """
11572 if z3_debug():
11573 _z3_assert(is_expr(a), "expression expected")
11574 _z3_assert(is_expr(b), "expression expected")
11575 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11576
11577def AllChar(regex_sort, ctx=None):
11578 """Create a regular expression that accepts all single character strings
11579 """
11580 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11581
11582# Special Relations
11583
11584
11585def PartialOrder(a, index):
11586 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11587
11588
11589def LinearOrder(a, index):
11590 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11591
11592
11593def TreeOrder(a, index):
11594 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11595
11596
11597def PiecewiseLinearOrder(a, index):
11598 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11599
11600
11601def TransitiveClosure(f):
11602 """Given a binary relation R, such that the two arguments have the same sort
11603 create the transitive closure relation R+.
11604 The transitive closure R+ is a new relation.
11605 """
11606 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11607
11608def to_Ast(ptr,):
11609 ast = Ast(ptr)
11610 super(ctypes.c_void_p, ast).__init__(ptr)
11611 return ast
11612
11613def to_ContextObj(ptr,):
11614 ctx = ContextObj(ptr)
11615 super(ctypes.c_void_p, ctx).__init__(ptr)
11616 return ctx
11617
11618def to_AstVectorObj(ptr,):
11619 v = AstVectorObj(ptr)
11620 super(ctypes.c_void_p, v).__init__(ptr)
11621 return v
11622
11623# NB. my-hacky-class only works for a single instance of OnClause
11624# it should be replaced with a proper correlation between OnClause
11625# and object references that can be passed over the FFI.
11626# for UserPropagator we use a global dictionary, which isn't great code.
11627
11628_my_hacky_class = None
11629def on_clause_eh(ctx, p, n, dep, clause):
11630 onc = _my_hacky_class
11631 p = _to_expr_ref(to_Ast(p), onc.ctx)
11632 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11633 deps = [dep[i] for i in range(n)]
11634 onc.on_clause(p, deps, clause)
11635
11636_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11637
11638class OnClause:
11639 def __init__(self, s, on_clause):
11640 self.s = s
11641 self.ctx = s.ctx
11642 self.on_clause = on_clause
11643 self.idx = 22
11644 global _my_hacky_class
11645 _my_hacky_class = self
11646 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11647
11648
11649class PropClosures:
11650 def __init__(self):
11651 self.bases = {}
11652 self.lock = None
11653
11654 def set_threaded(self):
11655 if self.lock is None:
11656 import threading
11657 self.lock = threading.Lock()
11658
11659 def get(self, ctx):
11660 if self.lock:
11661 with self.lock:
11662 r = self.bases[ctx]
11663 else:
11664 r = self.bases[ctx]
11665 return r
11666
11667 def set(self, ctx, r):
11668 if self.lock:
11669 with self.lock:
11670 self.bases[ctx] = r
11671 else:
11672 self.bases[ctx] = r
11673
11674 def insert(self, r):
11675 if self.lock:
11676 with self.lock:
11677 id = len(self.bases) + 3
11678 self.bases[id] = r
11679 else:
11680 id = len(self.bases) + 3
11681 self.bases[id] = r
11682 return id
11683
11684
11685_prop_closures = None
11686
11687
11688def ensure_prop_closures():
11689 global _prop_closures
11690 if _prop_closures is None:
11691 _prop_closures = PropClosures()
11692
11693
11694def user_prop_push(ctx, cb):
11695 prop = _prop_closures.get(ctx)
11696 prop.cb = cb
11697 prop.push()
11698
11699
11700def user_prop_pop(ctx, cb, num_scopes):
11701 prop = _prop_closures.get(ctx)
11702 prop.cb = cb
11703 prop.pop(num_scopes)
11704
11705
11706def user_prop_fresh(ctx, _new_ctx):
11707 _prop_closures.set_threaded()
11708 prop = _prop_closures.get(ctx)
11709 nctx = Context()
11710 Z3_del_context(nctx.ctx)
11711 new_ctx = to_ContextObj(_new_ctx)
11712 nctx.ctx = new_ctx
11713 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11714 nctx.owner = False
11715 new_prop = prop.fresh(nctx)
11716 _prop_closures.set(new_prop.id, new_prop)
11717 return new_prop.id
11718
11719
11720def user_prop_fixed(ctx, cb, id, value):
11721 prop = _prop_closures.get(ctx)
11722 old_cb = prop.cb
11723 prop.cb = cb
11724 id = _to_expr_ref(to_Ast(id), prop.ctx())
11725 value = _to_expr_ref(to_Ast(value), prop.ctx())
11726 prop.fixed(id, value)
11727 prop.cb = old_cb
11728
11729def user_prop_created(ctx, cb, id):
11730 prop = _prop_closures.get(ctx)
11731 old_cb = prop.cb
11732 prop.cb = cb
11733 id = _to_expr_ref(to_Ast(id), prop.ctx())
11734 prop.created(id)
11735 prop.cb = old_cb
11736
11737
11738def user_prop_final(ctx, cb):
11739 prop = _prop_closures.get(ctx)
11740 old_cb = prop.cb
11741 prop.cb = cb
11742 prop.final()
11743 prop.cb = old_cb
11744
11745def user_prop_eq(ctx, cb, x, y):
11746 prop = _prop_closures.get(ctx)
11747 old_cb = prop.cb
11748 prop.cb = cb
11749 x = _to_expr_ref(to_Ast(x), prop.ctx())
11750 y = _to_expr_ref(to_Ast(y), prop.ctx())
11751 prop.eq(x, y)
11752 prop.cb = old_cb
11753
11754def user_prop_diseq(ctx, cb, x, y):
11755 prop = _prop_closures.get(ctx)
11756 old_cb = prop.cb
11757 prop.cb = cb
11758 x = _to_expr_ref(to_Ast(x), prop.ctx())
11759 y = _to_expr_ref(to_Ast(y), prop.ctx())
11760 prop.diseq(x, y)
11761 prop.cb = old_cb
11762
11763def user_prop_decide(ctx, cb, t_ref, idx, phase):
11764 prop = _prop_closures.get(ctx)
11765 old_cb = prop.cb
11766 prop.cb = cb
11767 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11768 prop.decide(t, idx, phase)
11769 prop.cb = old_cb
11770
11771
11772_user_prop_push = Z3_push_eh(user_prop_push)
11773_user_prop_pop = Z3_pop_eh(user_prop_pop)
11774_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11775_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11776_user_prop_created = Z3_created_eh(user_prop_created)
11777_user_prop_final = Z3_final_eh(user_prop_final)
11778_user_prop_eq = Z3_eq_eh(user_prop_eq)
11779_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11780_user_prop_decide = Z3_decide_eh(user_prop_decide)
11781
11782
11783def PropagateFunction(name, *sig):
11784 """Create a function that gets tracked by user propagator.
11785 Every term headed by this function symbol is tracked.
11786 If a term is fixed and the fixed callback is registered a
11787 callback is invoked that the term headed by this function is fixed.
11788 """
11789 sig = _get_args(sig)
11790 if z3_debug():
11791 _z3_assert(len(sig) > 0, "At least two arguments expected")
11792 arity = len(sig) - 1
11793 rng = sig[arity]
11794 if z3_debug():
11795 _z3_assert(is_sort(rng), "Z3 sort expected")
11796 dom = (Sort * arity)()
11797 for i in range(arity):
11798 if z3_debug():
11799 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11800 dom[i] = sig[i].ast
11801 ctx = rng.ctx
11802 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11803
11804
11805
11806class UserPropagateBase:
11807
11808 #
11809 # Either solver is set or ctx is set.
11810 # Propagators that are created through callbacks
11811 # to "fresh" inherit the context of that is supplied
11812 # as argument to the callback.
11813 # This context should not be deleted. It is owned by the solver.
11814 #
11815 def __init__(self, s, ctx=None):
11816 assert s is None or ctx is None
11817 ensure_prop_closures()
11818 self.solver = s
11819 self._ctx = None
11820 self.fresh_ctx = None
11821 self.cb = None
11822 self.id = _prop_closures.insert(self)
11823 self.fixed = None
11824 self.final = None
11825 self.eq = None
11826 self.diseq = None
11827 self.decide = None
11828 self.created = None
11829 if ctx:
11830 self.fresh_ctx = ctx
11831 if s:
11832 Z3_solver_propagate_init(self.ctx_ref(),
11833 s.solver,
11834 ctypes.c_void_p(self.id),
11835 _user_prop_push,
11836 _user_prop_pop,
11837 _user_prop_fresh)
11838
11839 def __del__(self):
11840 if self._ctx:
11841 self._ctx.ctx = None
11842
11843 def ctx(self):
11844 if self.fresh_ctx:
11845 return self.fresh_ctx
11846 else:
11847 return self.solver.ctx
11848
11849 def ctx_ref(self):
11850 return self.ctx().ref()
11851
11852 def add_fixed(self, fixed):
11853 assert not self.fixed
11854 assert not self._ctx
11855 if self.solver:
11856 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11857 self.fixed = fixed
11858
11859 def add_created(self, created):
11860 assert not self.created
11861 assert not self._ctx
11862 if self.solver:
11863 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
11864 self.created = created
11865
11866 def add_final(self, final):
11867 assert not self.final
11868 assert not self._ctx
11869 if self.solver:
11870 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
11871 self.final = final
11872
11873 def add_eq(self, eq):
11874 assert not self.eq
11875 assert not self._ctx
11876 if self.solver:
11877 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
11878 self.eq = eq
11879
11880 def add_diseq(self, diseq):
11881 assert not self.diseq
11882 assert not self._ctx
11883 if self.solver:
11884 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
11885 self.diseq = diseq
11886
11887 def add_decide(self, decide):
11888 assert not self.decide
11889 assert not self._ctx
11890 if self.solver:
11891 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
11892 self.decide = decide
11893
11894 def push(self):
11895 raise Z3Exception("push needs to be overwritten")
11896
11897 def pop(self, num_scopes):
11898 raise Z3Exception("pop needs to be overwritten")
11899
11900 def fresh(self, new_ctx):
11901 raise Z3Exception("fresh needs to be overwritten")
11902
11903 def add(self, e):
11904 assert not self._ctx
11905 if self.solver:
11906 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
11907 else:
11908 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
11909
11910 #
11911 # Tell the solver to perform the next split on a given term
11912 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
11913 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
11914 #
11915 def next_split(self, t, idx, phase):
11916 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
11917
11918 #
11919 # Propagation can only be invoked as during a fixed or final callback.
11920 #
11921 def propagate(self, e, ids, eqs=[]):
11922 _ids, num_fixed = _to_ast_array(ids)
11923 num_eqs = len(eqs)
11924 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
11925 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
11926 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
11927 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
11928
11929 def conflict(self, deps = [], eqs = []):
11930 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3170
as_decimal(self, prec)
Definition z3py.py:3182
__rmod__(self, other)
Definition z3py.py:2652
__mod__(self, other)
Definition z3py.py:2637
__pow__(self, other)
Definition z3py.py:2561
__gt__(self, other)
Definition z3py.py:2710
__lt__(self, other)
Definition z3py.py:2697
__rtruediv__(self, other)
Definition z3py.py:2633
__rmul__(self, other)
Definition z3py.py:2528
__rsub__(self, other)
Definition z3py.py:2551
__add__(self, other)
Definition z3py.py:2490
__sub__(self, other)
Definition z3py.py:2538
is_real(self)
Definition z3py.py:2479
is_int(self)
Definition z3py.py:2465
__radd__(self, other)
Definition z3py.py:2503
__truediv__(self, other)
Definition z3py.py:2612
__le__(self, other)
Definition z3py.py:2684
__rpow__(self, other)
Definition z3py.py:2575
__pos__(self)
Definition z3py.py:2675
sort(self)
Definition z3py.py:2455
__mul__(self, other)
Definition z3py.py:2513
__rdiv__(self, other)
Definition z3py.py:2616
__ge__(self, other)
Definition z3py.py:2723
__neg__(self)
Definition z3py.py:2664
__div__(self, other)
Definition z3py.py:2589
Arithmetic.
Definition z3py.py:2360
subsort(self, other)
Definition z3py.py:2394
cast(self, val)
Definition z3py.py:2398
domain(self)
Definition z3py.py:4641
domain_n(self, i)
Definition z3py.py:4650
__getitem__(self, arg)
Definition z3py.py:4663
range(self)
Definition z3py.py:4654
sort(self)
Definition z3py.py:4632
default(self)
Definition z3py.py:4675
domain_n(self, i)
Definition z3py.py:4614
erase(self, k)
Definition z3py.py:6173
__deepcopy__(self, memo={})
Definition z3py.py:6110
__init__(self, m=None, ctx=None)
Definition z3py.py:6099
__repr__(self)
Definition z3py.py:6170
__len__(self)
Definition z3py.py:6117
keys(self)
Definition z3py.py:6202
__setitem__(self, k, v)
Definition z3py.py:6154
__contains__(self, key)
Definition z3py.py:6130
__del__(self)
Definition z3py.py:6113
__getitem__(self, key)
Definition z3py.py:6143
reset(self)
Definition z3py.py:6187
__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
py_value(self)
Definition z3py.py:450
__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:6079
translate(self, other_ctx)
Definition z3py.py:6060
__repr__(self)
Definition z3py.py:6082
__len__(self)
Definition z3py.py:5954
__init__(self, v=None, ctx=None)
Definition z3py.py:5939
push(self, v)
Definition z3py.py:6012
__getitem__(self, i)
Definition z3py.py:5967
sexpr(self)
Definition z3py.py:6085
__del__(self)
Definition z3py.py:5950
__setitem__(self, i, v)
Definition z3py.py:5996
__contains__(self, item)
Definition z3py.py:6037
__copy__(self)
Definition z3py.py:6076
resize(self, sz)
Definition z3py.py:6024
as_binary_string(self)
Definition z3py.py:4016
as_signed_long(self)
Definition z3py.py:3990
as_string(self)
Definition z3py.py:4013
__and__(self, other)
Definition z3py.py:3680
__rmod__(self, other)
Definition z3py.py:3821
__rrshift__(self, other)
Definition z3py.py:3947
__mod__(self, other)
Definition z3py.py:3800
__or__(self, other)
Definition z3py.py:3657
__rlshift__(self, other)
Definition z3py.py:3961
__gt__(self, other)
Definition z3py.py:3871
__lt__(self, other)
Definition z3py.py:3855
__invert__(self)
Definition z3py.py:3746
__rtruediv__(self, other)
Definition z3py.py:3796
__rmul__(self, other)
Definition z3py.py:3624
__rxor__(self, other)
Definition z3py.py:3716
__ror__(self, other)
Definition z3py.py:3670
__rsub__(self, other)
Definition z3py.py:3647
__add__(self, other)
Definition z3py.py:3588
__sub__(self, other)
Definition z3py.py:3634
__radd__(self, other)
Definition z3py.py:3601
size(self)
Definition z3py.py:3577
__rand__(self, other)
Definition z3py.py:3693
__truediv__(self, other)
Definition z3py.py:3776
__le__(self, other)
Definition z3py.py:3839
__xor__(self, other)
Definition z3py.py:3703
__lshift__(self, other)
Definition z3py.py:3933
__pos__(self)
Definition z3py.py:3726
sort(self)
Definition z3py.py:3566
__mul__(self, other)
Definition z3py.py:3611
__rdiv__(self, other)
Definition z3py.py:3780
__ge__(self, other)
Definition z3py.py:3887
__neg__(self)
Definition z3py.py:3735
__rshift__(self, other)
Definition z3py.py:3903
__div__(self, other)
Definition z3py.py:3757
Bit-Vectors.
Definition z3py.py:3519
subsort(self, other)
Definition z3py.py:3531
cast(self, val)
Definition z3py.py:3534
__and__(self, other)
Definition z3py.py:1611
__or__(self, other)
Definition z3py.py:1614
__invert__(self)
Definition z3py.py:1620
__rmul__(self, other)
Definition z3py.py:1597
__add__(self, other)
Definition z3py.py:1589
py_value(self)
Definition z3py.py:1623
__radd__(self, other)
Definition z3py.py:1594
__xor__(self, other)
Definition z3py.py:1617
sort(self)
Definition z3py.py:1586
__mul__(self, other)
Definition z3py.py:1600
Booleans.
Definition z3py.py:1547
subsort(self, other)
Definition z3py.py:1573
is_bool(self)
Definition z3py.py:1579
cast(self, val)
Definition z3py.py:1550
__deepcopy__(self, memo={})
Definition z3py.py:6967
__eq__(self, other)
Definition z3py.py:6970
__ne__(self, other)
Definition z3py.py:6973
__init__(self, r)
Definition z3py.py:6964
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:5159
create(self)
Definition z3py.py:5198
__init__(self, name, ctx=None)
Definition z3py.py:5154
__repr__(self)
Definition z3py.py:5195
list constructors
Definition z3py.py:5157
declare(self, name, *args)
Definition z3py.py:5174
declare_core(self, name, rec_name, *args)
Definition z3py.py:5164
constructor(self, idx)
Definition z3py.py:5351
accessor(self, i, j)
Definition z3py.py:5398
num_constructors(self)
Definition z3py.py:5338
recognizer(self, idx)
Definition z3py.py:5370
Expressions.
Definition z3py.py:987
as_ast(self)
Definition z3py.py:998
__hash__(self)
Definition z3py.py:1044
kind(self)
Definition z3py.py:1084
children(self)
Definition z3py.py:1128
serialize(self)
Definition z3py.py:1146
get_id(self)
Definition z3py.py:1001
num_args(self)
Definition z3py.py:1091
__eq__(self, other)
Definition z3py.py:1027
__ne__(self, other)
Definition z3py.py:1048
from_string(self, s)
Definition z3py.py:1143
sort_kind(self)
Definition z3py.py:1016
arg(self, idx)
Definition z3py.py:1107
sort(self)
Definition z3py.py:1004
params(self)
Definition z3py.py:1066
decl(self)
Definition z3py.py:1069
Function Declarations.
Definition z3py.py:744
as_func_decl(self)
Definition z3py.py:758
domain(self, i)
Definition z3py.py:782
as_ast(self)
Definition z3py.py:752
__call__(self, *args)
Definition z3py.py:845
arity(self)
Definition z3py.py:772
get_id(self)
Definition z3py.py:755
range(self)
Definition z3py.py:794
params(self)
Definition z3py.py:817
Definition z3py.py:6221
__deepcopy__(self, memo={})
Definition z3py.py:6229
ctx
Definition z3py.py:6226
__repr__(self)
Definition z3py.py:6326
num_args(self)
Definition z3py.py:6236
entry
Definition z3py.py:6225
value(self)
Definition z3py.py:6285
__init__(self, entry, ctx)
Definition z3py.py:6224
__del__(self)
Definition z3py.py:6232
as_list(self)
Definition z3py.py:6307
arg_value(self, idx)
Definition z3py.py:6254
__deepcopy__(self, memo={})
Definition z3py.py:6424
translate(self, other_ctx)
Definition z3py.py:6416
arity(self)
Definition z3py.py:6382
__repr__(self)
Definition z3py.py:6444
num_entries(self)
Definition z3py.py:6366
__init__(self, f, ctx)
Definition z3py.py:6333
__del__(self)
Definition z3py.py:6339
as_list(self)
Definition z3py.py:6427
else_value(self)
Definition z3py.py:6343
entry(self, idx)
Definition z3py.py:6396
__copy__(self)
Definition z3py.py:6421
__deepcopy__(self, memo={})
Definition z3py.py:5884
get(self, i)
Definition z3py.py:5742
prec(self)
Definition z3py.py:5686
translate(self, target)
Definition z3py.py:5858
append(self, *args)
Definition z3py.py:5785
as_expr(self)
Definition z3py.py:5907
assert_exprs(self, *args)
Definition z3py.py:5770
__repr__(self)
Definition z3py.py:5847
__len__(self)
Definition z3py.py:5729
inconsistent(self)
Definition z3py.py:5668
dimacs(self, include_names=True)
Definition z3py.py:5854
__getitem__(self, arg)
Definition z3py.py:5755
size(self)
Definition z3py.py:5716
precision(self)
Definition z3py.py:5707
simplify(self, *arguments, **keywords)
Definition z3py.py:5887
sexpr(self)
Definition z3py.py:5850
add(self, *args)
Definition z3py.py:5807
__del__(self)
Definition z3py.py:5646
convert_model(self, model)
Definition z3py.py:5818
insert(self, *args)
Definition z3py.py:5796
depth(self)
Definition z3py.py:5650
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5636
__copy__(self)
Definition z3py.py:5881
as_binary_string(self)
Definition z3py.py:3055
py_value(self)
Definition z3py.py:3063
as_long(self)
Definition z3py.py:3034
as_string(self)
Definition z3py.py:3047
__deepcopy__(self, memo={})
Definition z3py.py:6790
eval(self, t, model_completion=False)
Definition z3py.py:6468
translate(self, target)
Definition z3py.py:6755
__getitem__(self, idx)
Definition z3py.py:6669
num_sorts(self)
Definition z3py.py:6594
get_universe(self, s)
Definition z3py.py:6649
get_sort(self, idx)
Definition z3py.py:6609
project(self, vars, fml)
Definition z3py.py:6763
__repr__(self)
Definition z3py.py:6461
__len__(self)
Definition z3py.py:6525
get_interp(self, decl)
Definition z3py.py:6542
__init__(self, m, ctx)
Definition z3py.py:6451
sexpr(self)
Definition z3py.py:6464
sorts(self)
Definition z3py.py:6632
__del__(self)
Definition z3py.py:6457
decls(self)
Definition z3py.py:6714
project_with_witness(self, vars, fml)
Definition z3py.py:6775
update_value(self, x, value)
Definition z3py.py:6733
evaluate(self, t, model_completion=False)
Definition z3py.py:6499
__copy__(self)
Definition z3py.py:6787
__deepcopy__(self, memo={})
Definition z3py.py:5580
__init__(self, descr, ctx=None)
Definition z3py.py:5574
get_kind(self, n)
Definition z3py.py:5602
get_documentation(self, n)
Definition z3py.py:5607
__getitem__(self, arg)
Definition z3py.py:5612
get_name(self, i)
Definition z3py.py:5597
Parameter Sets.
Definition z3py.py:5501
__deepcopy__(self, memo={})
Definition z3py.py:5515
validate(self, ds)
Definition z3py.py:5542
__repr__(self)
Definition z3py.py:5539
__init__(self, ctx=None, params=None)
Definition z3py.py:5507
set(self, name, val)
Definition z3py.py:5522
__del__(self)
Definition z3py.py:5518
Patterns.
Definition z3py.py:1983
as_ast(self)
Definition z3py.py:1988
get_id(self)
Definition z3py.py:1991
Quantifiers.
Definition z3py.py:2050
num_no_patterns(self)
Definition z3py.py:2168
no_pattern(self, idx)
Definition z3py.py:2172
num_patterns(self)
Definition z3py.py:2138
var_name(self, idx)
Definition z3py.py:2201
__getitem__(self, arg)
Definition z3py.py:2107
var_sort(self, idx)
Definition z3py.py:2217
pattern(self, idx)
Definition z3py.py:2150
numerator_as_long(self)
Definition z3py.py:3096
is_int_value(self)
Definition z3py.py:3126
as_fraction(self)
Definition z3py.py:3154
py_value(self)
Definition z3py.py:3163
numerator(self)
Definition z3py.py:3070
is_real(self)
Definition z3py.py:3123
as_long(self)
Definition z3py.py:3129
is_int(self)
Definition z3py.py:3120
denominator_as_long(self)
Definition z3py.py:3109
as_string(self)
Definition z3py.py:3145
denominator(self)
Definition z3py.py:3085
as_decimal(self, prec)
Definition z3py.py:3133
__init__(self, c, ctx)
Definition z3py.py:5218
__init__(self, c, ctx)
Definition z3py.py:5230
Strings, Sequences and Regular expressions.
Definition z3py.py:10961
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7011
assert_and_track(self, a, p)
Definition z3py.py:7180
num_scopes(self)
Definition z3py.py:7092
append(self, *args)
Definition z3py.py:7158
__iadd__(self, fml)
Definition z3py.py:7154
pop(self, num=1)
Definition z3py.py:7070
import_model_converter(self, other)
Definition z3py.py:7258
assert_exprs(self, *args)
Definition z3py.py:7124
model(self)
Definition z3py.py:7239
set(self, *args, **keys)
Definition z3py.py:7035
__enter__(self)
Definition z3py.py:7028
add(self, *args)
Definition z3py.py:7143
__del__(self)
Definition z3py.py:7024
int backtrack_level
Definition z3py.py:7014
insert(self, *args)
Definition z3py.py:7169
check(self, *assumptions)
Definition z3py.py:7210
push(self)
Definition z3py.py:7048
__exit__(self, *exc_info)
Definition z3py.py:7032
reset(self)
Definition z3py.py:7110
subsort(self, other)
Definition z3py.py:589
as_ast(self)
Definition z3py.py:566
__hash__(self)
Definition z3py.py:646
kind(self)
Definition z3py.py:572
get_id(self)
Definition z3py.py:569
__eq__(self, other)
Definition z3py.py:622
__ne__(self, other)
Definition z3py.py:635
cast(self, val)
Definition z3py.py:597
name(self)
Definition z3py.py:612
Statistics.
Definition z3py.py:6820
__deepcopy__(self, memo={})
Definition z3py.py:6828
__getattr__(self, name)
Definition z3py.py:6923
__getitem__(self, idx)
Definition z3py.py:6867
__init__(self, stats, ctx)
Definition z3py.py:6823
__repr__(self)
Definition z3py.py:6835
__len__(self)
Definition z3py.py:6853
__del__(self)
Definition z3py.py:6831
get_key_value(self, key)
Definition z3py.py:6903
subsort(self, other)
Definition z3py.py:720
cast(self, val)
Definition z3py.py:723
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.
double Z3_API Z3_get_numeral_double(Z3_context c, Z3_ast a)
Return numeral as a double.
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:3201
RotateRight(a, b)
Definition z3py.py:4428
_symbol2py(ctx, s)
Definition z3py.py:132
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4101
BVSNegNoOverflow(a)
Definition z3py.py:4575
SetAdd(s, e)
Definition z3py.py:5047
SetSort(s)
Sets.
Definition z3py.py:4998
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1235
UGT(a, b)
Definition z3py.py:4299
is_probe(p)
Definition z3py.py:8863
is_lt(a)
Definition z3py.py:2953
Var(idx, s)
Definition z3py.py:1503
SetDel(s, e)
Definition z3py.py:5058
BoolSort(ctx=None)
Definition z3py.py:1753
is_bv_sort(s)
Definition z3py.py:3552
_ctx_from_ast_args(*args)
Definition z3py.py:515
RatVal(a, b, ctx=None)
Definition z3py.py:3293
_to_func_decl_ref(a, ctx)
Definition z3py.py:931
SetUnion(*args)
Definition z3py.py:5021
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5118
BitVec(name, bv, ctx=None)
Definition z3py.py:4118
DeclareSort(name, ctx=None)
Definition z3py.py:699
EmptySet(s)
Definition z3py.py:5003
BVMulNoUnderflow(a, b)
Definition z3py.py:4589
CreateDatatypes(*ds)
Definition z3py.py:5239
is_func_decl(a)
Definition z3py.py:876
get_as_array_func(n)
Definition z3py.py:6807
Distinct(*args)
Definition z3py.py:1437
is_distinct(a)
Definition z3py.py:1741
RecAddDefinition(f, args, body)
Definition z3py.py:953
ToInt(a)
Definition z3py.py:3452
Implies(a, b, ctx=None)
Definition z3py.py:1847
UGE(a, b)
Definition z3py.py:4281
Ext(a, b)
Definition z3py.py:4949
_to_ast_array(args)
Definition z3py.py:527
_check_bv_args(a, b)
Definition z3py.py:4240
RealSort(ctx=None)
Definition z3py.py:3233
IsSubset(a, b)
Definition z3py.py:5101
DeclareTypeVar(name, ctx=None)
Definition z3py.py:727
_get_args_ast_list(args)
Definition z3py.py:158
_to_ref_array(ref, args)
Definition z3py.py:535
get_map_func(a)
Definition z3py.py:4757
_z3_check_cint_overflow(n, name)
Definition z3py.py:110
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5444
is_sort(s)
Definition z3py.py:651
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1263
is_select(a)
Definition z3py.py:4967
SignExt(n, a)
Definition z3py.py:4444
Int(name, ctx=None)
Definition z3py.py:3322
Bools(names, ctx=None)
Definition z3py.py:1802
_probe_and(args, ctx)
Definition z3py.py:8930
Int2BV(a, num_bits)
Definition z3py.py:4077
Lambda(vs, body)
Definition z3py.py:2333
_to_param_value(val)
Definition z3py.py:168
FreshFunction(*sig)
Definition z3py.py:912
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3403
BVRedOr(a)
Definition z3py.py:4533
is_true(a)
Definition z3py.py:1651
SRem(a, b)
Definition z3py.py:4359
is_le(a)
Definition z3py.py:2941
is_idiv(a)
Definition z3py.py:2917
set_option(*args, **kws)
Definition z3py.py:301
_ast_kind(ctx, a)
Definition z3py.py:495
is_bv(a)
Definition z3py.py:4025
SetDifference(a, b)
Definition z3py.py:5079
_get_ctx(ctx)
Definition z3py.py:260
BitVecs(names, bv, ctx=None)
Definition z3py.py:4142
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1818
is_mul(a)
Definition z3py.py:2876
_has_probe(args)
Definition z3py.py:1903
IsMember(e, s)
Definition z3py.py:5090
get_param(name)
Definition z3py.py:307
BVAddNoUnderflow(a, b)
Definition z3py.py:4547
deserialize(st)
Definition z3py.py:1152
Extract(high, low, a)
Definition z3py.py:4209
Function(name, *sig)
Definition z3py.py:889
get_version()
Definition z3py.py:92
FreshConst(sort, prefix="c")
Definition z3py.py:1497
ULT(a, b)
Definition z3py.py:4263
EnumSort(name, values, ctx=None)
Definition z3py.py:5468
_to_int_str(val)
Definition z3py.py:3250
is_algebraic_value(a)
Definition z3py.py:2850
is_bv_value(a)
Definition z3py.py:4039
BVSDivNoOverflow(a, b)
Definition z3py.py:4568
SetIntersect(*args)
Definition z3py.py:5034
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:8997
BV2Int(a, is_signed=False)
Definition z3py.py:4054
RealVar(idx, ctx=None)
Definition z3py.py:1518
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3361
is_div(a)
Definition z3py.py:2900
_to_ast_ref(a, ctx)
Definition z3py.py:543
_to_func_decl_array(args)
Definition z3py.py:519
disable_trace(msg)
Definition z3py.py:79
is_map(a)
Definition z3py.py:4732
is_not(a)
Definition z3py.py:1719
Or(*args)
Definition z3py.py:1944
is_re(s)
Definition z3py.py:11433
is_bool(a)
Definition z3py.py:1633
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5547
Consts(names, sort)
Definition z3py.py:1482
Cond(p, t1, t2, ctx=None)
Definition z3py.py:8980
is_mod(a)
Definition z3py.py:2929
_to_pattern(arg)
Definition z3py.py:2037
is_arith(a)
Definition z3py.py:2737
If(a, b, c, ctx=None)
Definition z3py.py:1414
is_app_of(a, k)
Definition z3py.py:1401
is_app(a)
Definition z3py.py:1298
_sort(ctx, a)
Definition z3py.py:695
z3_error_handler(c, e)
Definition z3py.py:174
Reals(names, ctx=None)
Definition z3py.py:3388
is_int_value(a)
Definition z3py.py:2804
set_param(*args, **kws)
Definition z3py.py:271
is_pattern(a)
Definition z3py.py:1995
is_add(a)
Definition z3py.py:2864
is_to_int(a)
Definition z3py.py:3016
_coerce_seq(s, ctx=None)
Definition z3py.py:11112
is_ge(a)
Definition z3py.py:2965
is_sub(a)
Definition z3py.py:2888
is_implies(a)
Definition z3py.py:1707
ULE(a, b)
Definition z3py.py:4245
is_real(a)
Definition z3py.py:2777
is_arith_sort(s)
Definition z3py.py:2436
FullSet(s)
Definition z3py.py:5012
to_symbol(s, ctx=None)
Definition z3py.py:124
is_array(a)
Definition z3py.py:4692
_get_args(args)
Definition z3py.py:144
And(*args)
Definition z3py.py:1911
RepeatBitVec(n, a)
Definition z3py.py:4502
SetHasSize(a, k)
Definition z3py.py:4961
is_to_real(a)
Definition z3py.py:3001
get_version_string()
Definition z3py.py:83
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3418
Array(name, *sorts)
Definition z3py.py:4814
Concat(*args)
Definition z3py.py:4163
_reduce(func, sequence, initial)
Definition z3py.py:1256
is_false(a)
Definition z3py.py:1669
_is_algebraic(ctx, a)
Definition z3py.py:2800
Ints(names, ctx=None)
Definition z3py.py:3335
Select(a, *args)
Definition z3py.py:4888
Const(name, sort)
Definition z3py.py:1470
is_array_sort(a)
Definition z3py.py:4688
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4540
is_int(a)
Definition z3py.py:2758
Real(name, ctx=None)
Definition z3py.py:3375
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1833
BitVecSort(sz, ctx=None)
Definition z3py.py:4086
open_log(fname)
Definition z3py.py:114
is_and(a)
Definition z3py.py:1683
RecFunction(name, *sig)
Definition z3py.py:935
get_ctx(ctx)
Definition z3py.py:267
Model(ctx=None, eval={})
Definition z3py.py:6794
BVSubNoOverflow(a, b)
Definition z3py.py:4554
is_default(a)
Definition z3py.py:4748
is_K(a)
Definition z3py.py:4719
Bool(name, ctx=None)
Definition z3py.py:1790
_is_int(v)
Definition z3py.py:68
is_const_array(a)
Definition z3py.py:4706
Sqrt(a, ctx=None)
Definition z3py.py:3487
main_ctx()
Definition z3py.py:239
Default(a)
Definition z3py.py:4860
is_is_int(a)
Definition z3py.py:2989
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:501
SetComplement(s)
Definition z3py.py:5069
is_as_array(n)
Definition z3py.py:6802
is_store(a)
Definition z3py.py:4980
eq(a, b)
Definition z3py.py:476
is_quantifier(a)
Definition z3py.py:2245
is_eq(a)
Definition z3py.py:1731
reset_params()
Definition z3py.py:295
_mk_bin(f, a, b)
Definition z3py.py:1461
K(dom, v)
Definition z3py.py:4927
Xor(a, b, ctx=None)
Definition z3py.py:1861
Store(a, *args)
Definition z3py.py:4871
mk_not(a)
Definition z3py.py:1896
is_expr(a)
Definition z3py.py:1275
_array_select(ar, arg)
Definition z3py.py:4679
is_or(a)
Definition z3py.py:1695
is_const(a)
Definition z3py.py:1324
BoolVal(val, ctx=None)
Definition z3py.py:1771
RealVal(val, ctx=None)
Definition z3py.py:3274
z3_debug()
Definition z3py.py:62
get_full_version()
Definition z3py.py:101
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3348
_coerce_expr_merge(s, a)
Definition z3py.py:1216
LShR(a, b)
Definition z3py.py:4380
RealVarVector(n, ctx=None)
Definition z3py.py:1529
ArraySort(*sig)
Definition z3py.py:4781
Map(f, *args)
Definition z3py.py:4904
is_rational_value(a)
Definition z3py.py:2828
_probe_or(args, ctx)
Definition z3py.py:8934
is_gt(a)
Definition z3py.py:2977
BVRedAnd(a)
Definition z3py.py:4526
Cbrt(a, ctx=None)
Definition z3py.py:3500
_to_expr_ref(a, ctx)
Definition z3py.py:1166
is_ast(a)
Definition z3py.py:455
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5456
IntSort(ctx=None)
Definition z3py.py:3216
is_seq(a)
Definition z3py.py:11133
Not(a, ctx=None)
Definition z3py.py:1877
_to_sort_ref(s, ctx)
Definition z3py.py:664
enable_trace(msg)
Definition z3py.py:75
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2312
ToReal(a)
Definition z3py.py:3432
URem(a, b)
Definition z3py.py:4338
StringVal(s, ctx=None)
Definition z3py.py:11160
IsInt(a)
Definition z3py.py:3470
_is_numeral(ctx, a)
Definition z3py.py:2796
MultiPattern(*args)
Definition z3py.py:2013
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2294
ZeroExt(n, a)
Definition z3py.py:4474
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:559
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4561
UDiv(a, b)
Definition z3py.py:4317
DatatypeSort(name, ctx=None)
Definition z3py.py:5439
Q(a, b, ctx=None)
Definition z3py.py:3309
Update(a, *args)
Definition z3py.py:4828
get_var_index(a)
Definition z3py.py:1368
append_log(s)
Definition z3py.py:119
is_var(a)
Definition z3py.py:1343
IntVal(val, ctx=None)
Definition z3py.py:3262
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4582
RotateLeft(a, b)
Definition z3py.py:4412
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2259
_z3_assert(cond, msg)
Definition z3py.py:105