Z3
 
Loading...
Searching...
No Matches
z3py.py
Go to the documentation of this file.
8
9"""Z3 is a high performance theorem prover developed at Microsoft Research.
10
11Z3 is used in many applications such as: software/hardware verification and testing,
12constraint solving, analysis of hybrid systems, security, biology (in silico analysis),
13and geometrical problems.
14
15
16Please send feedback, comments and/or corrections on the Issue tracker for
17https://github.com/Z3prover/z3.git. Your comments are very valuable.
18
19Small example:
20
21>>> x = Int('x')
22>>> y = Int('y')
23>>> s = Solver()
24>>> s.add(x > 0)
25>>> s.add(x < 2)
26>>> s.add(y == x + 1)
27>>> s.check()
28sat
29>>> m = s.model()
30>>> m[x]
311
32>>> m[y]
332
34
35Z3 exceptions:
36
37>>> try:
38... x = BitVec('x', 32)
39... y = Bool('y')
40... # the expression x + y is type incorrect
41... n = x + y
42... except Z3Exception as ex:
43... print("failed: %s" % ex)
44failed: sort mismatch
45"""
46from . import z3core
47from .z3core import *
48from .z3types import *
49from .z3consts import *
50from .z3printer import *
51from fractions import Fraction
52import sys
53import io
54import math
55import copy
56if sys.version_info.major >= 3:
57 from typing import Iterable
58
59Z3_DEBUG = __debug__
60
61
63 global Z3_DEBUG
64 return Z3_DEBUG
65
66
67if sys.version_info.major < 3:
68 def _is_int(v):
69 return isinstance(v, (int, long))
70else:
71 def _is_int(v):
72 return isinstance(v, int)
73
74
75def enable_trace(msg):
77
78
81
82
84 major = ctypes.c_uint(0)
85 minor = ctypes.c_uint(0)
86 build = ctypes.c_uint(0)
87 rev = ctypes.c_uint(0)
88 Z3_get_version(major, minor, build, rev)
89 return "%s.%s.%s" % (major.value, minor.value, build.value)
90
91
93 major = ctypes.c_uint(0)
94 minor = ctypes.c_uint(0)
95 build = ctypes.c_uint(0)
96 rev = ctypes.c_uint(0)
97 Z3_get_version(major, minor, build, rev)
98 return (major.value, minor.value, build.value, rev.value)
99
100
102 return Z3_get_full_version()
103
104
105def _z3_assert(cond, msg):
106 if not cond:
107 raise Z3Exception(msg)
108
109
111 _z3_assert(ctypes.c_int(n).value == n, name + " is too large")
112
113
114def open_log(fname):
115 """Log interaction to a file. This function must be invoked immediately after init(). """
116 Z3_open_log(fname)
117
118
120 """Append user-defined string to interaction log. """
122
123
124def to_symbol(s, ctx=None):
125 """Convert an integer or string into a Z3 symbol."""
126 if _is_int(s):
127 return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
128 else:
129 return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
130
131
132def _symbol2py(ctx, s):
133 """Convert a Z3 symbol back into a Python object. """
134 if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
135 return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
136 else:
137 return Z3_get_symbol_string(ctx.ref(), s)
138
139# Hack for having nary functions that can receive one argument that is the
140# list of arguments.
141# Use this when function takes a single list of arguments
142
143
144def _get_args(args):
145 try:
146 if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
147 return args[0]
148 elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)):
149 return [arg for arg in args[0]]
150 else:
151 return args
152 except TypeError: # len is not necessarily defined when args is not a sequence (use reflection?)
153 return args
154
155# Use this when function takes multiple arguments
156
157
159 try:
160 if isinstance(args, (set, AstVector, tuple)):
161 return [arg for arg in args]
162 else:
163 return args
164 except Exception:
165 return args
166
167
169 if isinstance(val, bool):
170 return "true" if val else "false"
171 return str(val)
172
173
175 # Do nothing error handler, just avoid exit(0)
176 # The wrappers in z3core.py will raise a Z3Exception if an error is detected
177 return
178
179
180class Context:
181 """A Context manages all other Z3 objects, global configuration options, etc.
182
183 Z3Py uses a default global context. For most applications this is sufficient.
184 An application may use multiple Z3 contexts. Objects created in one context
185 cannot be used in another one. However, several objects may be "translated" from
186 one context to another. It is not safe to access Z3 objects from multiple threads.
187 The only exception is the method `interrupt()` that can be used to interrupt() a long
188 computation.
189 The initialization method receives global configuration options for the new context.
190 """
191
192 def __init__(self, *args, **kws):
193 if z3_debug():
194 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
195 conf = Z3_mk_config()
196 for key in kws:
197 value = kws[key]
198 Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
199 prev = None
200 for a in args:
201 if prev is None:
202 prev = a
203 else:
204 Z3_set_param_value(conf, str(prev), _to_param_value(a))
205 prev = None
207 self.owner = True
208 self.eh = Z3_set_error_handler(self.ctx, z3_error_handler)
209 Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
210 Z3_del_config(conf)
211
212 def __del__(self):
213 if Z3_del_context is not None and self.owner:
214 Z3_del_context(self.ctx)
215 self.ctx = None
216 self.eh = None
217
218 def ref(self):
219 """Return a reference to the actual C pointer to the Z3 context."""
220 return self.ctx
221
222 def interrupt(self):
223 """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
224
225 This method can be invoked from a thread different from the one executing the
226 interruptible procedure.
227 """
228 Z3_interrupt(self.ref())
229
230 def param_descrs(self):
231 """Return the global parameter description set."""
232 return ParamDescrsRef(Z3_get_global_param_descrs(self.ref()), self)
233
234
235# Global Z3 context
236_main_ctx = None
237
238
240 """Return a reference to the global Z3 context.
241
242 >>> x = Real('x')
243 >>> x.ctx == main_ctx()
244 True
245 >>> c = Context()
246 >>> c == main_ctx()
247 False
248 >>> x2 = Real('x', c)
249 >>> x2.ctx == c
250 True
251 >>> eq(x, x2)
252 False
253 """
254 global _main_ctx
255 if _main_ctx is None:
256 _main_ctx = Context()
257 return _main_ctx
258
259
260def _get_ctx(ctx):
261 if ctx is None:
262 return main_ctx()
263 else:
264 return ctx
265
266
267def get_ctx(ctx):
268 return _get_ctx(ctx)
269
270
271def set_param(*args, **kws):
272 """Set Z3 global (or module) parameters.
273
274 >>> set_param(precision=10)
275 """
276 if z3_debug():
277 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
278 new_kws = {}
279 for k in kws:
280 v = kws[k]
281 if not set_pp_option(k, v):
282 new_kws[k] = v
283 for key in new_kws:
284 value = new_kws[key]
285 Z3_global_param_set(str(key).upper(), _to_param_value(value))
286 prev = None
287 for a in args:
288 if prev is None:
289 prev = a
290 else:
292 prev = None
293
294
296 """Reset all global (or module) parameters.
297 """
299
300
301def set_option(*args, **kws):
302 """Alias for 'set_param' for backward compatibility.
303 """
304 return set_param(*args, **kws)
305
306
307def get_param(name):
308 """Return the value of a Z3 global (or module) parameter
309
310 >>> get_param('nlsat.reorder')
311 'true'
312 """
313 ptr = (ctypes.c_char_p * 1)()
314 if Z3_global_param_get(str(name), ptr):
315 r = z3core._to_pystr(ptr[0])
316 return r
317 raise Z3Exception("failed to retrieve value for '%s'" % name)
318
319
324
325# Mark objects that use pretty printer
326
327
329 """Superclass for all Z3 objects that have support for pretty printing."""
330
331 def use_pp(self):
332 return True
333
334 def _repr_html_(self):
335 in_html = in_html_mode()
336 set_html_mode(True)
337 res = repr(self)
338 set_html_mode(in_html)
339 return res
340
341
343 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
344
345 def __init__(self, ast, ctx=None):
346 self.ast = ast
347 self.ctx = _get_ctx(ctx)
348 Z3_inc_ref(self.ctx.ref(), self.as_ast())
349
350 def __del__(self):
351 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
352 Z3_dec_ref(self.ctx.ref(), self.as_ast())
353 self.ast = None
354
355 def __deepcopy__(self, memo={}):
356 return _to_ast_ref(self.ast, self.ctx)
357
358 def __str__(self):
359 return obj_to_string(self)
360
361 def __repr__(self):
362 return obj_to_string(self)
363
364 def __eq__(self, other):
365 return self.eq(other)
366
367 def __hash__(self):
368 return self.hash()
369
370 def __nonzero__(self):
371 return self.__bool__()
372
373 def __bool__(self):
374 if is_true(self):
375 return True
376 elif is_false(self):
377 return False
378 elif is_eq(self) and self.num_args() == 2:
379 return self.arg(0).eq(self.arg(1))
380 else:
381 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
382
383 def sexpr(self):
384 """Return a string representing the AST node in s-expression notation.
385
386 >>> x = Int('x')
387 >>> ((x + 1)*x).sexpr()
388 '(* (+ x 1) x)'
389 """
390 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
391
392 def as_ast(self):
393 """Return a pointer to the corresponding C Z3_ast object."""
394 return self.ast
395
396 def get_id(self):
397 """Return unique identifier for object. It can be used for hash-tables and maps."""
398 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
399
400 def ctx_ref(self):
401 """Return a reference to the C context where this AST node is stored."""
402 return self.ctx.ref()
403
404 def eq(self, other):
405 """Return `True` if `self` and `other` are structurally identical.
406
407 >>> x = Int('x')
408 >>> n1 = x + 1
409 >>> n2 = 1 + x
410 >>> n1.eq(n2)
411 False
412 >>> n1 = simplify(n1)
413 >>> n2 = simplify(n2)
414 >>> n1.eq(n2)
415 True
416 """
417 if z3_debug():
418 _z3_assert(is_ast(other), "Z3 AST expected")
419 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
420
421 def translate(self, target):
422 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
423
424 >>> c1 = Context()
425 >>> c2 = Context()
426 >>> x = Int('x', c1)
427 >>> y = Int('y', c2)
428 >>> # Nodes in different contexts can't be mixed.
429 >>> # However, we can translate nodes from one context to another.
430 >>> x.translate(c2) + y
431 x + y
432 """
433 if z3_debug():
434 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
435 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
436
437 def __copy__(self):
438 return self.translate(self.ctx)
439
440 def hash(self):
441 """Return a hashcode for the `self`.
442
443 >>> n1 = simplify(Int('x') + 1)
444 >>> n2 = simplify(2 + Int('x') - 1)
445 >>> n1.hash() == n2.hash()
446 True
447 """
448 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
449
450
451def is_ast(a):
452 """Return `True` if `a` is an AST node.
453
454 >>> is_ast(10)
455 False
456 >>> is_ast(IntVal(10))
457 True
458 >>> is_ast(Int('x'))
459 True
460 >>> is_ast(BoolSort())
461 True
462 >>> is_ast(Function('f', IntSort(), IntSort()))
463 True
464 >>> is_ast("x")
465 False
466 >>> is_ast(Solver())
467 False
468 """
469 return isinstance(a, AstRef)
470
471
472def eq(a, b):
473 """Return `True` if `a` and `b` are structurally identical AST nodes.
474
475 >>> x = Int('x')
476 >>> y = Int('y')
477 >>> eq(x, y)
478 False
479 >>> eq(x + 1, x + 1)
480 True
481 >>> eq(x + 1, 1 + x)
482 False
483 >>> eq(simplify(x + 1), simplify(1 + x))
484 True
485 """
486 if z3_debug():
487 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
488 return a.eq(b)
489
490
491def _ast_kind(ctx, a):
492 if is_ast(a):
493 a = a.as_ast()
494 return Z3_get_ast_kind(ctx.ref(), a)
495
496
497def _ctx_from_ast_arg_list(args, default_ctx=None):
498 ctx = None
499 for a in args:
500 if is_ast(a) or is_probe(a):
501 if ctx is None:
502 ctx = a.ctx
503 else:
504 if z3_debug():
505 _z3_assert(ctx == a.ctx, "Context mismatch")
506 if ctx is None:
507 ctx = default_ctx
508 return ctx
509
510
512 return _ctx_from_ast_arg_list(args)
513
514
516 sz = len(args)
517 _args = (FuncDecl * sz)()
518 for i in range(sz):
519 _args[i] = args[i].as_func_decl()
520 return _args, sz
521
522
524 sz = len(args)
525 _args = (Ast * sz)()
526 for i in range(sz):
527 _args[i] = args[i].as_ast()
528 return _args, sz
529
530
531def _to_ref_array(ref, args):
532 sz = len(args)
533 _args = (ref * sz)()
534 for i in range(sz):
535 _args[i] = args[i].as_ast()
536 return _args, sz
537
538
539def _to_ast_ref(a, ctx):
540 k = _ast_kind(ctx, a)
541 if k == Z3_SORT_AST:
542 return _to_sort_ref(a, ctx)
543 elif k == Z3_FUNC_DECL_AST:
544 return _to_func_decl_ref(a, ctx)
545 else:
546 return _to_expr_ref(a, ctx)
547
548
549
554
555def _sort_kind(ctx, s):
556 return Z3_get_sort_kind(ctx.ref(), s)
557
558
560 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
561
562 def as_ast(self):
563 return Z3_sort_to_ast(self.ctx_ref(), self.ast)
564
565 def get_id(self):
566 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
567
568 def kind(self):
569 """Return the Z3 internal kind of a sort.
570 This method can be used to test if `self` is one of the Z3 builtin sorts.
571
572 >>> b = BoolSort()
573 >>> b.kind() == Z3_BOOL_SORT
574 True
575 >>> b.kind() == Z3_INT_SORT
576 False
577 >>> A = ArraySort(IntSort(), IntSort())
578 >>> A.kind() == Z3_ARRAY_SORT
579 True
580 >>> A.kind() == Z3_INT_SORT
581 False
582 """
583 return _sort_kind(self.ctx, self.ast)
584
585 def subsort(self, other):
586 """Return `True` if `self` is a subsort of `other`.
587
588 >>> IntSort().subsort(RealSort())
589 True
590 """
591 return False
592
593 def cast(self, val):
594 """Try to cast `val` as an element of sort `self`.
595
596 This method is used in Z3Py to convert Python objects such as integers,
597 floats, longs and strings into Z3 expressions.
598
599 >>> x = Int('x')
600 >>> RealSort().cast(x)
601 ToReal(x)
602 """
603 if z3_debug():
604 _z3_assert(is_expr(val), "Z3 expression expected")
605 _z3_assert(self.eq(val.sort()), "Sort mismatch")
606 return val
607
608 def name(self):
609 """Return the name (string) of sort `self`.
610
611 >>> BoolSort().name()
612 'Bool'
613 >>> ArraySort(IntSort(), IntSort()).name()
614 'Array'
615 """
616 return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
617
618 def __eq__(self, other):
619 """Return `True` if `self` and `other` are the same Z3 sort.
620
621 >>> p = Bool('p')
622 >>> p.sort() == BoolSort()
623 True
624 >>> p.sort() == IntSort()
625 False
626 """
627 if other is None:
628 return False
629 return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
630
631 def __ne__(self, other):
632 """Return `True` if `self` and `other` are not the same Z3 sort.
633
634 >>> p = Bool('p')
635 >>> p.sort() != BoolSort()
636 False
637 >>> p.sort() != IntSort()
638 True
639 """
640 return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
641
642 def __hash__(self):
643 """ Hash code. """
644 return AstRef.__hash__(self)
645
646
647def is_sort(s):
648 """Return `True` if `s` is a Z3 sort.
649
650 >>> is_sort(IntSort())
651 True
652 >>> is_sort(Int('x'))
653 False
654 >>> is_expr(Int('x'))
655 True
656 """
657 return isinstance(s, SortRef)
658
659
660def _to_sort_ref(s, ctx):
661 if z3_debug():
662 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
663 k = _sort_kind(ctx, s)
664 if k == Z3_BOOL_SORT:
665 return BoolSortRef(s, ctx)
666 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
667 return ArithSortRef(s, ctx)
668 elif k == Z3_BV_SORT:
669 return BitVecSortRef(s, ctx)
670 elif k == Z3_ARRAY_SORT:
671 return ArraySortRef(s, ctx)
672 elif k == Z3_DATATYPE_SORT:
673 return DatatypeSortRef(s, ctx)
674 elif k == Z3_FINITE_DOMAIN_SORT:
675 return FiniteDomainSortRef(s, ctx)
676 elif k == Z3_FLOATING_POINT_SORT:
677 return FPSortRef(s, ctx)
678 elif k == Z3_ROUNDING_MODE_SORT:
679 return FPRMSortRef(s, ctx)
680 elif k == Z3_RE_SORT:
681 return ReSortRef(s, ctx)
682 elif k == Z3_SEQ_SORT:
683 return SeqSortRef(s, ctx)
684 elif k == Z3_CHAR_SORT:
685 return CharSortRef(s, ctx)
686 elif k == Z3_TYPE_VAR:
687 return TypeVarRef(s, ctx)
688 return SortRef(s, ctx)
689
690
691def _sort(ctx, a):
692 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
693
694
695def DeclareSort(name, ctx=None):
696 """Create a new uninterpreted sort named `name`.
697
698 If `ctx=None`, then the new sort is declared in the global Z3Py context.
699
700 >>> A = DeclareSort('A')
701 >>> a = Const('a', A)
702 >>> b = Const('b', A)
703 >>> a.sort() == A
704 True
705 >>> b.sort() == A
706 True
707 >>> a == b
708 a == b
709 """
710 ctx = _get_ctx(ctx)
711 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
712
714 """Type variable reference"""
715
716 def subsort(self, other):
717 return True
718
719 def cast(self, val):
720 return val
721
722
723def DeclareTypeVar(name, ctx=None):
724 """Create a new type variable named `name`.
725
726 If `ctx=None`, then the new sort is declared in the global Z3Py context.
727
728 """
729 ctx = _get_ctx(ctx)
730 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
731
732
733
738
739
741 """Function declaration. Every constant and function have an associated declaration.
742
743 The declaration assigns a name, a sort (i.e., type), and for function
744 the sort (i.e., type) of each of its arguments. Note that, in Z3,
745 a constant is a function with 0 arguments.
746 """
747
748 def as_ast(self):
749 return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
750
751 def get_id(self):
752 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
753
754 def as_func_decl(self):
755 return self.ast
756
757 def name(self):
758 """Return the name of the function declaration `self`.
759
760 >>> f = Function('f', IntSort(), IntSort())
761 >>> f.name()
762 'f'
763 >>> isinstance(f.name(), str)
764 True
765 """
766 return _symbol2py(self.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
767
768 def arity(self):
769 """Return the number of arguments of a function declaration.
770 If `self` is a constant, then `self.arity()` is 0.
771
772 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
773 >>> f.arity()
774 2
775 """
776 return int(Z3_get_arity(self.ctx_ref(), self.ast))
777
778 def domain(self, i):
779 """Return the sort of the argument `i` of a function declaration.
780 This method assumes that `0 <= i < self.arity()`.
781
782 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
783 >>> f.domain(0)
784 Int
785 >>> f.domain(1)
786 Real
787 """
788 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
789
790 def range(self):
791 """Return the sort of the range of a function declaration.
792 For constants, this is the sort of the constant.
793
794 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
795 >>> f.range()
796 Bool
797 """
798 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.ast), self.ctx)
799
800 def kind(self):
801 """Return the internal kind of a function declaration.
802 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
803
804 >>> x = Int('x')
805 >>> d = (x + 1).decl()
806 >>> d.kind() == Z3_OP_ADD
807 True
808 >>> d.kind() == Z3_OP_MUL
809 False
810 """
811 return Z3_get_decl_kind(self.ctx_ref(), self.ast)
812
813 def params(self):
814 ctx = self.ctx
815 n = Z3_get_decl_num_parameters(self.ctx_ref(), self.ast)
816 result = [None for i in range(n)]
817 for i in range(n):
818 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.ast, i)
819 if k == Z3_PARAMETER_INT:
820 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.ast, i)
821 elif k == Z3_PARAMETER_DOUBLE:
822 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.ast, i)
823 elif k == Z3_PARAMETER_RATIONAL:
824 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.ast, i)
825 elif k == Z3_PARAMETER_SYMBOL:
826 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.ast, i)
827 elif k == Z3_PARAMETER_SORT:
828 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.ast, i), ctx)
829 elif k == Z3_PARAMETER_AST:
830 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.ast, i), ctx)
831 elif k == Z3_PARAMETER_FUNC_DECL:
832 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.ast, i), ctx)
833 else:
834 assert(False)
835 return result
836
837 def __call__(self, *args):
838 """Create a Z3 application expression using the function `self`, and the given arguments.
839
840 The arguments must be Z3 expressions. This method assumes that
841 the sorts of the elements in `args` match the sorts of the
842 domain. Limited coercion is supported. For example, if
843 args[0] is a Python integer, and the function expects a Z3
844 integer, then the argument is automatically converted into a
845 Z3 integer.
846
847 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
848 >>> x = Int('x')
849 >>> y = Real('y')
850 >>> f(x, y)
851 f(x, y)
852 >>> f(x, x)
853 f(x, ToReal(x))
854 """
855 args = _get_args(args)
856 num = len(args)
857 _args = (Ast * num)()
858 saved = []
859 for i in range(num):
860 # self.domain(i).cast(args[i]) may create a new Z3 expression,
861 # then we must save in 'saved' to prevent it from being garbage collected.
862 tmp = self.domain(i).cast(args[i])
863 saved.append(tmp)
864 _args[i] = tmp.as_ast()
865 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
866
867
869 """Return `True` if `a` is a Z3 function declaration.
870
871 >>> f = Function('f', IntSort(), IntSort())
872 >>> is_func_decl(f)
873 True
874 >>> x = Real('x')
875 >>> is_func_decl(x)
876 False
877 """
878 return isinstance(a, FuncDeclRef)
879
880
881def Function(name, *sig):
882 """Create a new Z3 uninterpreted function with the given sorts.
883
884 >>> f = Function('f', IntSort(), IntSort())
885 >>> f(f(0))
886 f(f(0))
887 """
888 sig = _get_args(sig)
889 if z3_debug():
890 _z3_assert(len(sig) > 0, "At least two arguments expected")
891 arity = len(sig) - 1
892 rng = sig[arity]
893 if z3_debug():
894 _z3_assert(is_sort(rng), "Z3 sort expected")
895 dom = (Sort * arity)()
896 for i in range(arity):
897 if z3_debug():
898 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
899 dom[i] = sig[i].ast
900 ctx = rng.ctx
901 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
902
903
905 """Create a new fresh Z3 uninterpreted function with the given sorts.
906 """
907 sig = _get_args(sig)
908 if z3_debug():
909 _z3_assert(len(sig) > 0, "At least two arguments expected")
910 arity = len(sig) - 1
911 rng = sig[arity]
912 if z3_debug():
913 _z3_assert(is_sort(rng), "Z3 sort expected")
914 dom = (z3.Sort * arity)()
915 for i in range(arity):
916 if z3_debug():
917 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
918 dom[i] = sig[i].ast
919 ctx = rng.ctx
920 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
921
922
924 return FuncDeclRef(a, ctx)
925
926
927def RecFunction(name, *sig):
928 """Create a new Z3 recursive with the given sorts."""
929 sig = _get_args(sig)
930 if z3_debug():
931 _z3_assert(len(sig) > 0, "At least two arguments expected")
932 arity = len(sig) - 1
933 rng = sig[arity]
934 if z3_debug():
935 _z3_assert(is_sort(rng), "Z3 sort expected")
936 dom = (Sort * arity)()
937 for i in range(arity):
938 if z3_debug():
939 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
940 dom[i] = sig[i].ast
941 ctx = rng.ctx
942 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
943
944
945def RecAddDefinition(f, args, body):
946 """Set the body of a recursive function.
947 Recursive definitions can be simplified if they are applied to ground
948 arguments.
949 >>> ctx = Context()
950 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
951 >>> n = Int('n', ctx)
952 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
953 >>> simplify(fac(5))
954 120
955 >>> s = Solver(ctx=ctx)
956 >>> s.add(fac(n) < 3)
957 >>> s.check()
958 sat
959 >>> s.model().eval(fac(5))
960 120
961 """
962 if is_app(args):
963 args = [args]
964 ctx = body.ctx
965 args = _get_args(args)
966 n = len(args)
967 _args = (Ast * n)()
968 for i in range(n):
969 _args[i] = args[i].ast
970 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
971
972
977
978
980 """Constraints, formulas and terms are expressions in Z3.
981
982 Expressions are ASTs. Every expression has a sort.
983 There are three main kinds of expressions:
984 function applications, quantifiers and bounded variables.
985 A constant is a function application with 0 arguments.
986 For quantifier free problems, all expressions are
987 function applications.
988 """
989
990 def as_ast(self):
991 return self.ast
992
993 def get_id(self):
994 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
995
996 def sort(self):
997 """Return the sort of expression `self`.
998
999 >>> x = Int('x')
1000 >>> (x + 1).sort()
1001 Int
1002 >>> y = Real('y')
1003 >>> (x + y).sort()
1004 Real
1005 """
1006 return _sort(self.ctx, self.as_ast())
1007
1008 def sort_kind(self):
1009 """Shorthand for `self.sort().kind()`.
1010
1011 >>> a = Array('a', IntSort(), IntSort())
1012 >>> a.sort_kind() == Z3_ARRAY_SORT
1013 True
1014 >>> a.sort_kind() == Z3_INT_SORT
1015 False
1016 """
1017 return self.sort().kind()
1018
1019 def __eq__(self, other):
1020 """Return a Z3 expression that represents the constraint `self == other`.
1021
1022 If `other` is `None`, then this method simply returns `False`.
1023
1024 >>> a = Int('a')
1025 >>> b = Int('b')
1026 >>> a == b
1027 a == b
1028 >>> a is None
1029 False
1030 """
1031 if other is None:
1032 return False
1033 a, b = _coerce_exprs(self, other)
1034 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
1035
1036 def __hash__(self):
1037 """ Hash code. """
1038 return AstRef.__hash__(self)
1039
1040 def __ne__(self, other):
1041 """Return a Z3 expression that represents the constraint `self != other`.
1042
1043 If `other` is `None`, then this method simply returns `True`.
1044
1045 >>> a = Int('a')
1046 >>> b = Int('b')
1047 >>> a != b
1048 a != b
1049 >>> a is not None
1050 True
1051 """
1052 if other is None:
1053 return True
1054 a, b = _coerce_exprs(self, other)
1055 _args, sz = _to_ast_array((a, b))
1056 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
1057
1058 def params(self):
1059 return self.decl().params()
1060
1061 def decl(self):
1062 """Return the Z3 function declaration associated with a Z3 application.
1063
1064 >>> f = Function('f', IntSort(), IntSort())
1065 >>> a = Int('a')
1066 >>> t = f(a)
1067 >>> eq(t.decl(), f)
1068 True
1069 >>> (a + 1).decl()
1070 +
1071 """
1072 if z3_debug():
1073 _z3_assert(is_app(self), "Z3 application expected")
1074 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_ast()), self.ctx)
1075
1076 def kind(self):
1077 """Return the Z3 internal kind of a function application."""
1078 if z3_debug():
1079 _z3_assert(is_app(self), "Z3 application expected")
1081
1082
1083 def num_args(self):
1084 """Return the number of arguments of a Z3 application.
1085
1086 >>> a = Int('a')
1087 >>> b = Int('b')
1088 >>> (a + b).num_args()
1089 2
1090 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1091 >>> t = f(a, b, 0)
1092 >>> t.num_args()
1093 3
1094 """
1095 if z3_debug():
1096 _z3_assert(is_app(self), "Z3 application expected")
1097 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_ast()))
1098
1099 def arg(self, idx):
1100 """Return argument `idx` of the application `self`.
1101
1102 This method assumes that `self` is a function application with at least `idx+1` arguments.
1103
1104 >>> a = Int('a')
1105 >>> b = Int('b')
1106 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1107 >>> t = f(a, b, 0)
1108 >>> t.arg(0)
1109 a
1110 >>> t.arg(1)
1111 b
1112 >>> t.arg(2)
1113 0
1114 """
1115 if z3_debug():
1116 _z3_assert(is_app(self), "Z3 application expected")
1117 _z3_assert(idx < self.num_args(), "Invalid argument index")
1118 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_ast(), idx), self.ctx)
1119
1120 def children(self):
1121 """Return a list containing the children of the given expression
1122
1123 >>> a = Int('a')
1124 >>> b = Int('b')
1125 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1126 >>> t = f(a, b, 0)
1127 >>> t.children()
1128 [a, b, 0]
1129 """
1130 if is_app(self):
1131 return [self.arg(i) for i in range(self.num_args())]
1132 else:
1133 return []
1134
1135 def from_string(self, s):
1136 pass
1137
1138 def serialize(self):
1139 s = Solver()
1140 f = Function('F', self.sort(), BoolSort(self.ctx))
1141 s.add(f(self))
1142 return s.sexpr()
1143
1145 """inverse function to the serialize method on ExprRef.
1146 It is made available to make it easier for users to serialize expressions back and forth between
1147 strings. Solvers can be serialized using the 'sexpr()' method.
1148 """
1149 s = Solver()
1150 s.from_string(st)
1151 if len(s.assertions()) != 1:
1152 raise Z3Exception("single assertion expected")
1153 fml = s.assertions()[0]
1154 if fml.num_args() != 1:
1155 raise Z3Exception("dummy function 'F' expected")
1156 return fml.arg(0)
1157
1158def _to_expr_ref(a, ctx):
1159 if isinstance(a, Pattern):
1160 return PatternRef(a, ctx)
1161 ctx_ref = ctx.ref()
1162 k = Z3_get_ast_kind(ctx_ref, a)
1163 if k == Z3_QUANTIFIER_AST:
1164 return QuantifierRef(a, ctx)
1165 sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1166 if sk == Z3_BOOL_SORT:
1167 return BoolRef(a, ctx)
1168 if sk == Z3_INT_SORT:
1169 if k == Z3_NUMERAL_AST:
1170 return IntNumRef(a, ctx)
1171 return ArithRef(a, ctx)
1172 if sk == Z3_REAL_SORT:
1173 if k == Z3_NUMERAL_AST:
1174 return RatNumRef(a, ctx)
1175 if _is_algebraic(ctx, a):
1176 return AlgebraicNumRef(a, ctx)
1177 return ArithRef(a, ctx)
1178 if sk == Z3_BV_SORT:
1179 if k == Z3_NUMERAL_AST:
1180 return BitVecNumRef(a, ctx)
1181 else:
1182 return BitVecRef(a, ctx)
1183 if sk == Z3_ARRAY_SORT:
1184 return ArrayRef(a, ctx)
1185 if sk == Z3_DATATYPE_SORT:
1186 return DatatypeRef(a, ctx)
1187 if sk == Z3_FLOATING_POINT_SORT:
1188 if k == Z3_APP_AST and _is_numeral(ctx, a):
1189 return FPNumRef(a, ctx)
1190 else:
1191 return FPRef(a, ctx)
1192 if sk == Z3_FINITE_DOMAIN_SORT:
1193 if k == Z3_NUMERAL_AST:
1194 return FiniteDomainNumRef(a, ctx)
1195 else:
1196 return FiniteDomainRef(a, ctx)
1197 if sk == Z3_ROUNDING_MODE_SORT:
1198 return FPRMRef(a, ctx)
1199 if sk == Z3_SEQ_SORT:
1200 return SeqRef(a, ctx)
1201 if sk == Z3_CHAR_SORT:
1202 return CharRef(a, ctx)
1203 if sk == Z3_RE_SORT:
1204 return ReRef(a, ctx)
1205 return ExprRef(a, ctx)
1206
1207
1209 if is_expr(a):
1210 s1 = a.sort()
1211 if s is None:
1212 return s1
1213 if s1.eq(s):
1214 return s
1215 elif s.subsort(s1):
1216 return s1
1217 elif s1.subsort(s):
1218 return s
1219 else:
1220 if z3_debug():
1221 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1222 _z3_assert(False, "sort mismatch")
1223 else:
1224 return s
1225
1226
1227def _coerce_exprs(a, b, ctx=None):
1228 if not is_expr(a) and not is_expr(b):
1229 a = _py2expr(a, ctx)
1230 b = _py2expr(b, ctx)
1231 if isinstance(a, str) and isinstance(b, SeqRef):
1232 a = StringVal(a, b.ctx)
1233 if isinstance(b, str) and isinstance(a, SeqRef):
1234 b = StringVal(b, a.ctx)
1235 if isinstance(a, float) and isinstance(b, ArithRef):
1236 a = RealVal(a, b.ctx)
1237 if isinstance(b, float) and isinstance(a, ArithRef):
1238 b = RealVal(b, a.ctx)
1239
1240 s = None
1241 s = _coerce_expr_merge(s, a)
1242 s = _coerce_expr_merge(s, b)
1243 a = s.cast(a)
1244 b = s.cast(b)
1245 return (a, b)
1246
1247
1248def _reduce(func, sequence, initial):
1249 result = initial
1250 for element in sequence:
1251 result = func(result, element)
1252 return result
1253
1254
1255def _coerce_expr_list(alist, ctx=None):
1256 has_expr = False
1257 for a in alist:
1258 if is_expr(a):
1259 has_expr = True
1260 break
1261 if not has_expr:
1262 alist = [_py2expr(a, ctx) for a in alist]
1263 s = _reduce(_coerce_expr_merge, alist, None)
1264 return [s.cast(a) for a in alist]
1265
1266
1267def is_expr(a):
1268 """Return `True` if `a` is a Z3 expression.
1269
1270 >>> a = Int('a')
1271 >>> is_expr(a)
1272 True
1273 >>> is_expr(a + 1)
1274 True
1275 >>> is_expr(IntSort())
1276 False
1277 >>> is_expr(1)
1278 False
1279 >>> is_expr(IntVal(1))
1280 True
1281 >>> x = Int('x')
1282 >>> is_expr(ForAll(x, x >= 0))
1283 True
1284 >>> is_expr(FPVal(1.0))
1285 True
1286 """
1287 return isinstance(a, ExprRef)
1288
1289
1290def is_app(a):
1291 """Return `True` if `a` is a Z3 function application.
1292
1293 Note that, constants are function applications with 0 arguments.
1294
1295 >>> a = Int('a')
1296 >>> is_app(a)
1297 True
1298 >>> is_app(a + 1)
1299 True
1300 >>> is_app(IntSort())
1301 False
1302 >>> is_app(1)
1303 False
1304 >>> is_app(IntVal(1))
1305 True
1306 >>> x = Int('x')
1307 >>> is_app(ForAll(x, x >= 0))
1308 False
1309 """
1310 if not isinstance(a, ExprRef):
1311 return False
1312 k = _ast_kind(a.ctx, a)
1313 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1314
1315
1317 """Return `True` if `a` is Z3 constant/variable expression.
1318
1319 >>> a = Int('a')
1320 >>> is_const(a)
1321 True
1322 >>> is_const(a + 1)
1323 False
1324 >>> is_const(1)
1325 False
1326 >>> is_const(IntVal(1))
1327 True
1328 >>> x = Int('x')
1329 >>> is_const(ForAll(x, x >= 0))
1330 False
1331 """
1332 return is_app(a) and a.num_args() == 0
1333
1334
1335def is_var(a):
1336 """Return `True` if `a` is variable.
1337
1338 Z3 uses de-Bruijn indices for representing bound variables in
1339 quantifiers.
1340
1341 >>> x = Int('x')
1342 >>> is_var(x)
1343 False
1344 >>> is_const(x)
1345 True
1346 >>> f = Function('f', IntSort(), IntSort())
1347 >>> # Z3 replaces x with bound variables when ForAll is executed.
1348 >>> q = ForAll(x, f(x) == x)
1349 >>> b = q.body()
1350 >>> b
1351 f(Var(0)) == Var(0)
1352 >>> b.arg(1)
1353 Var(0)
1354 >>> is_var(b.arg(1))
1355 True
1356 """
1357 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1358
1359
1361 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1362
1363 >>> x = Int('x')
1364 >>> y = Int('y')
1365 >>> is_var(x)
1366 False
1367 >>> is_const(x)
1368 True
1369 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1370 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1371 >>> q = ForAll([x, y], f(x, y) == x + y)
1372 >>> q.body()
1373 f(Var(1), Var(0)) == Var(1) + Var(0)
1374 >>> b = q.body()
1375 >>> b.arg(0)
1376 f(Var(1), Var(0))
1377 >>> v1 = b.arg(0).arg(0)
1378 >>> v2 = b.arg(0).arg(1)
1379 >>> v1
1380 Var(1)
1381 >>> v2
1382 Var(0)
1383 >>> get_var_index(v1)
1384 1
1385 >>> get_var_index(v2)
1386 0
1387 """
1388 if z3_debug():
1389 _z3_assert(is_var(a), "Z3 bound variable expected")
1390 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1391
1392
1393def is_app_of(a, k):
1394 """Return `True` if `a` is an application of the given kind `k`.
1395
1396 >>> x = Int('x')
1397 >>> n = x + 1
1398 >>> is_app_of(n, Z3_OP_ADD)
1399 True
1400 >>> is_app_of(n, Z3_OP_MUL)
1401 False
1402 """
1403 return is_app(a) and a.kind() == k
1404
1405
1406def If(a, b, c, ctx=None):
1407 """Create a Z3 if-then-else expression.
1408
1409 >>> x = Int('x')
1410 >>> y = Int('y')
1411 >>> max = If(x > y, x, y)
1412 >>> max
1413 If(x > y, x, y)
1414 >>> simplify(max)
1415 If(x <= y, y, x)
1416 """
1417 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1418 return Cond(a, b, c, ctx)
1419 else:
1420 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1421 s = BoolSort(ctx)
1422 a = s.cast(a)
1423 b, c = _coerce_exprs(b, c, ctx)
1424 if z3_debug():
1425 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1426 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1427
1428
1429def Distinct(*args):
1430 """Create a Z3 distinct expression.
1431
1432 >>> x = Int('x')
1433 >>> y = Int('y')
1434 >>> Distinct(x, y)
1435 x != y
1436 >>> z = Int('z')
1437 >>> Distinct(x, y, z)
1438 Distinct(x, y, z)
1439 >>> simplify(Distinct(x, y, z))
1440 Distinct(x, y, z)
1441 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1442 And(Not(x == y), Not(x == z), Not(y == z))
1443 """
1444 args = _get_args(args)
1445 ctx = _ctx_from_ast_arg_list(args)
1446 if z3_debug():
1447 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1448 args = _coerce_expr_list(args, ctx)
1449 _args, sz = _to_ast_array(args)
1450 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1451
1452
1453def _mk_bin(f, a, b):
1454 args = (Ast * 2)()
1455 if z3_debug():
1456 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1457 args[0] = a.as_ast()
1458 args[1] = b.as_ast()
1459 return f(a.ctx.ref(), 2, args)
1460
1461
1462def Const(name, sort):
1463 """Create a constant of the given sort.
1464
1465 >>> Const('x', IntSort())
1466 x
1467 """
1468 if z3_debug():
1469 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1470 ctx = sort.ctx
1471 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1472
1473
1474def Consts(names, sort):
1475 """Create several constants of the given sort.
1476
1477 `names` is a string containing the names of all constants to be created.
1478 Blank spaces separate the names of different constants.
1479
1480 >>> x, y, z = Consts('x y z', IntSort())
1481 >>> x + y + z
1482 x + y + z
1483 """
1484 if isinstance(names, str):
1485 names = names.split(" ")
1486 return [Const(name, sort) for name in names]
1487
1488
1489def FreshConst(sort, prefix="c"):
1490 """Create a fresh constant of a specified sort"""
1491 ctx = _get_ctx(sort.ctx)
1492 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1493
1494
1495def Var(idx, s):
1496 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1497 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1498 declarations.
1499
1500 >>> Var(0, IntSort())
1501 Var(0)
1502 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1503 False
1504 """
1505 if z3_debug():
1506 _z3_assert(is_sort(s), "Z3 sort expected")
1507 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1508
1509
1510def RealVar(idx, ctx=None):
1511 """
1512 Create a real free variable. Free variables are used to create quantified formulas.
1513 They are also used to create polynomials.
1514
1515 >>> RealVar(0)
1516 Var(0)
1517 """
1518 return Var(idx, RealSort(ctx))
1519
1520
1521def RealVarVector(n, ctx=None):
1522 """
1523 Create a list of Real free variables.
1524 The variables have ids: 0, 1, ..., n-1
1525
1526 >>> x0, x1, x2, x3 = RealVarVector(4)
1527 >>> x2
1528 Var(2)
1529 """
1530 return [RealVar(i, ctx) for i in range(n)]
1531
1532
1537
1538
1540 """Boolean sort."""
1541
1542 def cast(self, val):
1543 """Try to cast `val` as a Boolean.
1544
1545 >>> x = BoolSort().cast(True)
1546 >>> x
1547 True
1548 >>> is_expr(x)
1549 True
1550 >>> is_expr(True)
1551 False
1552 >>> x.sort()
1553 Bool
1554 """
1555 if isinstance(val, bool):
1556 return BoolVal(val, self.ctx)
1557 if z3_debug():
1558 if not is_expr(val):
1559 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1560 _z3_assert(is_expr(val), msg % (val, type(val)))
1561 if not self.eq(val.sort()):
1562 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1563 return val
1564
1565 def subsort(self, other):
1566 return isinstance(other, ArithSortRef)
1567
1568 def is_int(self):
1569 return True
1570
1571 def is_bool(self):
1572 return True
1573
1574
1576 """All Boolean expressions are instances of this class."""
1577
1578 def sort(self):
1579 return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
1580
1581 def __add__(self, other):
1582 if isinstance(other, BoolRef):
1583 other = If(other, 1, 0)
1584 return If(self, 1, 0) + other
1585
1586 def __radd__(self, other):
1587 return self + other
1588
1589 def __rmul__(self, other):
1590 return self * other
1591
1592 def __mul__(self, other):
1593 """Create the Z3 expression `self * other`.
1594 """
1595 if isinstance(other, int) and other == 1:
1596 return If(self, 1, 0)
1597 if isinstance(other, int) and other == 0:
1598 return IntVal(0, self.ctx)
1599 if isinstance(other, BoolRef):
1600 other = If(other, 1, 0)
1601 return If(self, other, 0)
1602
1603 def __and__(self, other):
1604 return And(self, other)
1605
1606 def __or__(self, other):
1607 return Or(self, other)
1608
1609 def __xor__(self, other):
1610 return Xor(self, other)
1611
1612 def __invert__(self):
1613 return Not(self)
1614
1615
1616
1617
1618def is_bool(a):
1619 """Return `True` if `a` is a Z3 Boolean expression.
1620
1621 >>> p = Bool('p')
1622 >>> is_bool(p)
1623 True
1624 >>> q = Bool('q')
1625 >>> is_bool(And(p, q))
1626 True
1627 >>> x = Real('x')
1628 >>> is_bool(x)
1629 False
1630 >>> is_bool(x == 0)
1631 True
1632 """
1633 return isinstance(a, BoolRef)
1634
1635
1636def is_true(a):
1637 """Return `True` if `a` is the Z3 true expression.
1638
1639 >>> p = Bool('p')
1640 >>> is_true(p)
1641 False
1642 >>> is_true(simplify(p == p))
1643 True
1644 >>> x = Real('x')
1645 >>> is_true(x == 0)
1646 False
1647 >>> # True is a Python Boolean expression
1648 >>> is_true(True)
1649 False
1650 """
1651 return is_app_of(a, Z3_OP_TRUE)
1652
1653
1655 """Return `True` if `a` is the Z3 false expression.
1656
1657 >>> p = Bool('p')
1658 >>> is_false(p)
1659 False
1660 >>> is_false(False)
1661 False
1662 >>> is_false(BoolVal(False))
1663 True
1664 """
1665 return is_app_of(a, Z3_OP_FALSE)
1666
1667
1668def is_and(a):
1669 """Return `True` if `a` is a Z3 and expression.
1670
1671 >>> p, q = Bools('p q')
1672 >>> is_and(And(p, q))
1673 True
1674 >>> is_and(Or(p, q))
1675 False
1676 """
1677 return is_app_of(a, Z3_OP_AND)
1678
1679
1680def is_or(a):
1681 """Return `True` if `a` is a Z3 or expression.
1682
1683 >>> p, q = Bools('p q')
1684 >>> is_or(Or(p, q))
1685 True
1686 >>> is_or(And(p, q))
1687 False
1688 """
1689 return is_app_of(a, Z3_OP_OR)
1690
1691
1693 """Return `True` if `a` is a Z3 implication expression.
1694
1695 >>> p, q = Bools('p q')
1696 >>> is_implies(Implies(p, q))
1697 True
1698 >>> is_implies(And(p, q))
1699 False
1700 """
1701 return is_app_of(a, Z3_OP_IMPLIES)
1702
1703
1704def is_not(a):
1705 """Return `True` if `a` is a Z3 not expression.
1706
1707 >>> p = Bool('p')
1708 >>> is_not(p)
1709 False
1710 >>> is_not(Not(p))
1711 True
1712 """
1713 return is_app_of(a, Z3_OP_NOT)
1714
1715
1716def is_eq(a):
1717 """Return `True` if `a` is a Z3 equality expression.
1718
1719 >>> x, y = Ints('x y')
1720 >>> is_eq(x == y)
1721 True
1722 """
1723 return is_app_of(a, Z3_OP_EQ)
1724
1725
1727 """Return `True` if `a` is a Z3 distinct expression.
1728
1729 >>> x, y, z = Ints('x y z')
1730 >>> is_distinct(x == y)
1731 False
1732 >>> is_distinct(Distinct(x, y, z))
1733 True
1734 """
1735 return is_app_of(a, Z3_OP_DISTINCT)
1736
1737
1738def BoolSort(ctx=None):
1739 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1740
1741 >>> BoolSort()
1742 Bool
1743 >>> p = Const('p', BoolSort())
1744 >>> is_bool(p)
1745 True
1746 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1747 >>> r(0, 1)
1748 r(0, 1)
1749 >>> is_bool(r(0, 1))
1750 True
1751 """
1752 ctx = _get_ctx(ctx)
1753 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1754
1755
1756def BoolVal(val, ctx=None):
1757 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1758
1759 >>> BoolVal(True)
1760 True
1761 >>> is_true(BoolVal(True))
1762 True
1763 >>> is_true(True)
1764 False
1765 >>> is_false(BoolVal(False))
1766 True
1767 """
1768 ctx = _get_ctx(ctx)
1769 if val:
1770 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1771 else:
1772 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1773
1774
1775def Bool(name, ctx=None):
1776 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1777
1778 >>> p = Bool('p')
1779 >>> q = Bool('q')
1780 >>> And(p, q)
1781 And(p, q)
1782 """
1783 ctx = _get_ctx(ctx)
1784 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1785
1786
1787def Bools(names, ctx=None):
1788 """Return a tuple of Boolean constants.
1789
1790 `names` is a single string containing all names separated by blank spaces.
1791 If `ctx=None`, then the global context is used.
1792
1793 >>> p, q, r = Bools('p q r')
1794 >>> And(p, Or(q, r))
1795 And(p, Or(q, r))
1796 """
1797 ctx = _get_ctx(ctx)
1798 if isinstance(names, str):
1799 names = names.split(" ")
1800 return [Bool(name, ctx) for name in names]
1801
1802
1803def BoolVector(prefix, sz, ctx=None):
1804 """Return a list of Boolean constants of size `sz`.
1805
1806 The constants are named using the given prefix.
1807 If `ctx=None`, then the global context is used.
1808
1809 >>> P = BoolVector('p', 3)
1810 >>> P
1811 [p__0, p__1, p__2]
1812 >>> And(P)
1813 And(p__0, p__1, p__2)
1814 """
1815 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1816
1817
1818def FreshBool(prefix="b", ctx=None):
1819 """Return a fresh Boolean constant in the given context using the given prefix.
1820
1821 If `ctx=None`, then the global context is used.
1822
1823 >>> b1 = FreshBool()
1824 >>> b2 = FreshBool()
1825 >>> eq(b1, b2)
1826 False
1827 """
1828 ctx = _get_ctx(ctx)
1829 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1830
1831
1832def Implies(a, b, ctx=None):
1833 """Create a Z3 implies expression.
1834
1835 >>> p, q = Bools('p q')
1836 >>> Implies(p, q)
1837 Implies(p, q)
1838 """
1839 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1840 s = BoolSort(ctx)
1841 a = s.cast(a)
1842 b = s.cast(b)
1843 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1844
1845
1846def Xor(a, b, ctx=None):
1847 """Create a Z3 Xor expression.
1848
1849 >>> p, q = Bools('p q')
1850 >>> Xor(p, q)
1851 Xor(p, q)
1852 >>> simplify(Xor(p, q))
1853 Not(p == q)
1854 """
1855 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1856 s = BoolSort(ctx)
1857 a = s.cast(a)
1858 b = s.cast(b)
1859 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1860
1861
1862def Not(a, ctx=None):
1863 """Create a Z3 not expression or probe.
1864
1865 >>> p = Bool('p')
1866 >>> Not(Not(p))
1867 Not(Not(p))
1868 >>> simplify(Not(Not(p)))
1869 p
1870 """
1871 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1872 if is_probe(a):
1873 # Not is also used to build probes
1874 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1875 else:
1876 s = BoolSort(ctx)
1877 a = s.cast(a)
1878 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1879
1880
1881def mk_not(a):
1882 if is_not(a):
1883 return a.arg(0)
1884 else:
1885 return Not(a)
1886
1887
1888def _has_probe(args):
1889 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1890 for arg in args:
1891 if is_probe(arg):
1892 return True
1893 return False
1894
1895
1896def And(*args):
1897 """Create a Z3 and-expression or and-probe.
1898
1899 >>> p, q, r = Bools('p q r')
1900 >>> And(p, q, r)
1901 And(p, q, r)
1902 >>> P = BoolVector('p', 5)
1903 >>> And(P)
1904 And(p__0, p__1, p__2, p__3, p__4)
1905 """
1906 last_arg = None
1907 if len(args) > 0:
1908 last_arg = args[len(args) - 1]
1909 if isinstance(last_arg, Context):
1910 ctx = args[len(args) - 1]
1911 args = args[:len(args) - 1]
1912 elif len(args) == 1 and isinstance(args[0], AstVector):
1913 ctx = args[0].ctx
1914 args = [a for a in args[0]]
1915 else:
1916 ctx = None
1917 args = _get_args(args)
1918 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1919 if z3_debug():
1920 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1921 if _has_probe(args):
1922 return _probe_and(args, ctx)
1923 else:
1924 args = _coerce_expr_list(args, ctx)
1925 _args, sz = _to_ast_array(args)
1926 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
1927
1928
1929def Or(*args):
1930 """Create a Z3 or-expression or or-probe.
1931
1932 >>> p, q, r = Bools('p q r')
1933 >>> Or(p, q, r)
1934 Or(p, q, r)
1935 >>> P = BoolVector('p', 5)
1936 >>> Or(P)
1937 Or(p__0, p__1, p__2, p__3, p__4)
1938 """
1939 last_arg = None
1940 if len(args) > 0:
1941 last_arg = args[len(args) - 1]
1942 if isinstance(last_arg, Context):
1943 ctx = args[len(args) - 1]
1944 args = args[:len(args) - 1]
1945 elif len(args) == 1 and isinstance(args[0], AstVector):
1946 ctx = args[0].ctx
1947 args = [a for a in args[0]]
1948 else:
1949 ctx = None
1950 args = _get_args(args)
1951 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1952 if z3_debug():
1953 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1954 if _has_probe(args):
1955 return _probe_or(args, ctx)
1956 else:
1957 args = _coerce_expr_list(args, ctx)
1958 _args, sz = _to_ast_array(args)
1959 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
1960
1961
1966
1967
1969 """Patterns are hints for quantifier instantiation.
1970
1971 """
1972
1973 def as_ast(self):
1974 return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
1975
1976 def get_id(self):
1977 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1978
1979
1981 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
1982
1983 >>> f = Function('f', IntSort(), IntSort())
1984 >>> x = Int('x')
1985 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
1986 >>> q
1987 ForAll(x, f(x) == 0)
1988 >>> q.num_patterns()
1989 1
1990 >>> is_pattern(q.pattern(0))
1991 True
1992 >>> q.pattern(0)
1993 f(Var(0))
1994 """
1995 return isinstance(a, PatternRef)
1996
1997
1998def MultiPattern(*args):
1999 """Create a Z3 multi-pattern using the given expressions `*args`
2000
2001 >>> f = Function('f', IntSort(), IntSort())
2002 >>> g = Function('g', IntSort(), IntSort())
2003 >>> x = Int('x')
2004 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2005 >>> q
2006 ForAll(x, f(x) != g(x))
2007 >>> q.num_patterns()
2008 1
2009 >>> is_pattern(q.pattern(0))
2010 True
2011 >>> q.pattern(0)
2012 MultiPattern(f(Var(0)), g(Var(0)))
2013 """
2014 if z3_debug():
2015 _z3_assert(len(args) > 0, "At least one argument expected")
2016 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2017 ctx = args[0].ctx
2018 args, sz = _to_ast_array(args)
2019 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2020
2021
2023 if is_pattern(arg):
2024 return arg
2025 else:
2026 return MultiPattern(arg)
2027
2028
2033
2034
2036 """Universally and Existentially quantified formulas."""
2037
2038 def as_ast(self):
2039 return self.ast
2040
2041 def get_id(self):
2042 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2043
2044 def sort(self):
2045 """Return the Boolean sort or sort of Lambda."""
2046 if self.is_lambda():
2047 return _sort(self.ctx, self.as_ast())
2048 return BoolSort(self.ctx)
2049
2050 def is_forall(self):
2051 """Return `True` if `self` is a universal quantifier.
2052
2053 >>> f = Function('f', IntSort(), IntSort())
2054 >>> x = Int('x')
2055 >>> q = ForAll(x, f(x) == 0)
2056 >>> q.is_forall()
2057 True
2058 >>> q = Exists(x, f(x) != 0)
2059 >>> q.is_forall()
2060 False
2061 """
2063
2064 def is_exists(self):
2065 """Return `True` if `self` is an existential quantifier.
2066
2067 >>> f = Function('f', IntSort(), IntSort())
2068 >>> x = Int('x')
2069 >>> q = ForAll(x, f(x) == 0)
2070 >>> q.is_exists()
2071 False
2072 >>> q = Exists(x, f(x) != 0)
2073 >>> q.is_exists()
2074 True
2075 """
2076 return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
2077
2078 def is_lambda(self):
2079 """Return `True` if `self` is a lambda expression.
2080
2081 >>> f = Function('f', IntSort(), IntSort())
2082 >>> x = Int('x')
2083 >>> q = Lambda(x, f(x))
2084 >>> q.is_lambda()
2085 True
2086 >>> q = Exists(x, f(x) != 0)
2087 >>> q.is_lambda()
2088 False
2089 """
2090 return Z3_is_lambda(self.ctx_ref(), self.ast)
2091
2092 def __getitem__(self, arg):
2093 """Return the Z3 expression `self[arg]`.
2094 """
2095 if z3_debug():
2096 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2097 return _array_select(self, arg)
2098
2099 def weight(self):
2100 """Return the weight annotation of `self`.
2101
2102 >>> f = Function('f', IntSort(), IntSort())
2103 >>> x = Int('x')
2104 >>> q = ForAll(x, f(x) == 0)
2105 >>> q.weight()
2106 1
2107 >>> q = ForAll(x, f(x) == 0, weight=10)
2108 >>> q.weight()
2109 10
2110 """
2111 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
2112
2113 def skolem_id(self):
2114 """Return the skolem id of `self`.
2115 """
2116 return _symbol2py(self.ctx, Z3_get_quantifier_skolem_id(self.ctx_ref(), self.ast))
2117
2118 def qid(self):
2119 """Return the quantifier id of `self`.
2120 """
2121 return _symbol2py(self.ctx, Z3_get_quantifier_id(self.ctx_ref(), self.ast))
2122
2123 def num_patterns(self):
2124 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2125
2126 >>> f = Function('f', IntSort(), IntSort())
2127 >>> g = Function('g', IntSort(), IntSort())
2128 >>> x = Int('x')
2129 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2130 >>> q.num_patterns()
2131 2
2132 """
2133 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
2134
2135 def pattern(self, idx):
2136 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2137
2138 >>> f = Function('f', IntSort(), IntSort())
2139 >>> g = Function('g', IntSort(), IntSort())
2140 >>> x = Int('x')
2141 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2142 >>> q.num_patterns()
2143 2
2144 >>> q.pattern(0)
2145 f(Var(0))
2146 >>> q.pattern(1)
2147 g(Var(0))
2148 """
2149 if z3_debug():
2150 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2151 return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2152
2154 """Return the number of no-patterns."""
2155 return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
2156
2157 def no_pattern(self, idx):
2158 """Return a no-pattern."""
2159 if z3_debug():
2160 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2161 return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2162
2163 def body(self):
2164 """Return the expression being quantified.
2165
2166 >>> f = Function('f', IntSort(), IntSort())
2167 >>> x = Int('x')
2168 >>> q = ForAll(x, f(x) == 0)
2169 >>> q.body()
2170 f(Var(0)) == 0
2171 """
2172 return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
2173
2174 def num_vars(self):
2175 """Return the number of variables bounded by this quantifier.
2176
2177 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2178 >>> x = Int('x')
2179 >>> y = Int('y')
2180 >>> q = ForAll([x, y], f(x, y) >= x)
2181 >>> q.num_vars()
2182 2
2183 """
2184 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
2185
2186 def var_name(self, idx):
2187 """Return a string representing a name used when displaying the quantifier.
2188
2189 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2190 >>> x = Int('x')
2191 >>> y = Int('y')
2192 >>> q = ForAll([x, y], f(x, y) >= x)
2193 >>> q.var_name(0)
2194 'x'
2195 >>> q.var_name(1)
2196 'y'
2197 """
2198 if z3_debug():
2199 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2200 return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
2201
2202 def var_sort(self, idx):
2203 """Return the sort of a bound variable.
2204
2205 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2206 >>> x = Int('x')
2207 >>> y = Real('y')
2208 >>> q = ForAll([x, y], f(x, y) >= x)
2209 >>> q.var_sort(0)
2210 Int
2211 >>> q.var_sort(1)
2212 Real
2213 """
2214 if z3_debug():
2215 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2216 return _to_sort_ref(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
2217
2218 def children(self):
2219 """Return a list containing a single element self.body()
2220
2221 >>> f = Function('f', IntSort(), IntSort())
2222 >>> x = Int('x')
2223 >>> q = ForAll(x, f(x) == 0)
2224 >>> q.children()
2225 [f(Var(0)) == 0]
2226 """
2227 return [self.body()]
2228
2229
2231 """Return `True` if `a` is a Z3 quantifier.
2232
2233 >>> f = Function('f', IntSort(), IntSort())
2234 >>> x = Int('x')
2235 >>> q = ForAll(x, f(x) == 0)
2236 >>> is_quantifier(q)
2237 True
2238 >>> is_quantifier(f(x))
2239 False
2240 """
2241 return isinstance(a, QuantifierRef)
2242
2243
2244def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2245 if z3_debug():
2246 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2247 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2248 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2249 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2250 if is_app(vs):
2251 ctx = vs.ctx
2252 vs = [vs]
2253 else:
2254 ctx = vs[0].ctx
2255 if not is_expr(body):
2256 body = BoolVal(body, ctx)
2257 num_vars = len(vs)
2258 if num_vars == 0:
2259 return body
2260 _vs = (Ast * num_vars)()
2261 for i in range(num_vars):
2262 # TODO: Check if is constant
2263 _vs[i] = vs[i].as_ast()
2264 patterns = [_to_pattern(p) for p in patterns]
2265 num_pats = len(patterns)
2266 _pats = (Pattern * num_pats)()
2267 for i in range(num_pats):
2268 _pats[i] = patterns[i].ast
2269 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2270 qid = to_symbol(qid, ctx)
2271 skid = to_symbol(skid, ctx)
2272 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2273 num_vars, _vs,
2274 num_pats, _pats,
2275 num_no_pats, _no_pats,
2276 body.as_ast()), ctx)
2277
2278
2279def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2280 """Create a Z3 forall formula.
2281
2282 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2283
2284 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2285 >>> x = Int('x')
2286 >>> y = Int('y')
2287 >>> ForAll([x, y], f(x, y) >= x)
2288 ForAll([x, y], f(x, y) >= x)
2289 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2290 ForAll([x, y], f(x, y) >= x)
2291 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2292 ForAll([x, y], f(x, y) >= x)
2293 """
2294 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2295
2296
2297def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2298 """Create a Z3 exists formula.
2299
2300 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2301
2302
2303 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2304 >>> x = Int('x')
2305 >>> y = Int('y')
2306 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2307 >>> q
2308 Exists([x, y], f(x, y) >= x)
2309 >>> is_quantifier(q)
2310 True
2311 >>> r = Tactic('nnf')(q).as_expr()
2312 >>> is_quantifier(r)
2313 False
2314 """
2315 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2316
2317
2318def Lambda(vs, body):
2319 """Create a Z3 lambda expression.
2320
2321 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2322 >>> mem0 = Array('mem0', IntSort(), IntSort())
2323 >>> lo, hi, e, i = Ints('lo hi e i')
2324 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2325 >>> mem1
2326 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2327 """
2328 ctx = body.ctx
2329 if is_app(vs):
2330 vs = [vs]
2331 num_vars = len(vs)
2332 _vs = (Ast * num_vars)()
2333 for i in range(num_vars):
2334 # TODO: Check if is constant
2335 _vs[i] = vs[i].as_ast()
2336 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2337
2338
2343
2344
2346 """Real and Integer sorts."""
2347
2348 def is_real(self):
2349 """Return `True` if `self` is of the sort Real.
2350
2351 >>> x = Real('x')
2352 >>> x.is_real()
2353 True
2354 >>> (x + 1).is_real()
2355 True
2356 >>> x = Int('x')
2357 >>> x.is_real()
2358 False
2359 """
2360 return self.kind() == Z3_REAL_SORT
2361
2362 def is_int(self):
2363 """Return `True` if `self` is of the sort Integer.
2364
2365 >>> x = Int('x')
2366 >>> x.is_int()
2367 True
2368 >>> (x + 1).is_int()
2369 True
2370 >>> x = Real('x')
2371 >>> x.is_int()
2372 False
2373 """
2374 return self.kind() == Z3_INT_SORT
2375
2376 def is_bool(self):
2377 return False
2378
2379 def subsort(self, other):
2380 """Return `True` if `self` is a subsort of `other`."""
2381 return self.is_int() and is_arith_sort(other) and other.is_real()
2382
2383 def cast(self, val):
2384 """Try to cast `val` as an Integer or Real.
2385
2386 >>> IntSort().cast(10)
2387 10
2388 >>> is_int(IntSort().cast(10))
2389 True
2390 >>> is_int(10)
2391 False
2392 >>> RealSort().cast(10)
2393 10
2394 >>> is_real(RealSort().cast(10))
2395 True
2396 """
2397 if is_expr(val):
2398 if z3_debug():
2399 _z3_assert(self.ctx == val.ctx, "Context mismatch")
2400 val_s = val.sort()
2401 if self.eq(val_s):
2402 return val
2403 if val_s.is_int() and self.is_real():
2404 return ToReal(val)
2405 if val_s.is_bool() and self.is_int():
2406 return If(val, 1, 0)
2407 if val_s.is_bool() and self.is_real():
2408 return ToReal(If(val, 1, 0))
2409 if z3_debug():
2410 _z3_assert(False, "Z3 Integer/Real expression expected")
2411 else:
2412 if self.is_int():
2413 return IntVal(val, self.ctx)
2414 if self.is_real():
2415 return RealVal(val, self.ctx)
2416 if z3_debug():
2417 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2418 _z3_assert(False, msg % self)
2419
2420
2422 """Return `True` if s is an arithmetical sort (type).
2423
2424 >>> is_arith_sort(IntSort())
2425 True
2426 >>> is_arith_sort(RealSort())
2427 True
2428 >>> is_arith_sort(BoolSort())
2429 False
2430 >>> n = Int('x') + 1
2431 >>> is_arith_sort(n.sort())
2432 True
2433 """
2434 return isinstance(s, ArithSortRef)
2435
2436
2438 """Integer and Real expressions."""
2439
2440 def sort(self):
2441 """Return the sort (type) of the arithmetical expression `self`.
2442
2443 >>> Int('x').sort()
2444 Int
2445 >>> (Real('x') + 1).sort()
2446 Real
2447 """
2448 return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
2449
2450 def is_int(self):
2451 """Return `True` if `self` is an integer expression.
2452
2453 >>> x = Int('x')
2454 >>> x.is_int()
2455 True
2456 >>> (x + 1).is_int()
2457 True
2458 >>> y = Real('y')
2459 >>> (x + y).is_int()
2460 False
2461 """
2462 return self.sort().is_int()
2463
2464 def is_real(self):
2465 """Return `True` if `self` is an real expression.
2466
2467 >>> x = Real('x')
2468 >>> x.is_real()
2469 True
2470 >>> (x + 1).is_real()
2471 True
2472 """
2473 return self.sort().is_real()
2474
2475 def __add__(self, other):
2476 """Create the Z3 expression `self + other`.
2477
2478 >>> x = Int('x')
2479 >>> y = Int('y')
2480 >>> x + y
2481 x + y
2482 >>> (x + y).sort()
2483 Int
2484 """
2485 a, b = _coerce_exprs(self, other)
2486 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctx)
2487
2488 def __radd__(self, other):
2489 """Create the Z3 expression `other + self`.
2490
2491 >>> x = Int('x')
2492 >>> 10 + x
2493 10 + x
2494 """
2495 a, b = _coerce_exprs(self, other)
2496 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctx)
2497
2498 def __mul__(self, other):
2499 """Create the Z3 expression `self * other`.
2500
2501 >>> x = Real('x')
2502 >>> y = Real('y')
2503 >>> x * y
2504 x*y
2505 >>> (x * y).sort()
2506 Real
2507 """
2508 if isinstance(other, BoolRef):
2509 return If(other, self, 0)
2510 a, b = _coerce_exprs(self, other)
2511 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
2512
2513 def __rmul__(self, other):
2514 """Create the Z3 expression `other * self`.
2515
2516 >>> x = Real('x')
2517 >>> 10 * x
2518 10*x
2519 """
2520 a, b = _coerce_exprs(self, other)
2521 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctx)
2522
2523 def __sub__(self, other):
2524 """Create the Z3 expression `self - other`.
2525
2526 >>> x = Int('x')
2527 >>> y = Int('y')
2528 >>> x - y
2529 x - y
2530 >>> (x - y).sort()
2531 Int
2532 """
2533 a, b = _coerce_exprs(self, other)
2534 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctx)
2535
2536 def __rsub__(self, other):
2537 """Create the Z3 expression `other - self`.
2538
2539 >>> x = Int('x')
2540 >>> 10 - x
2541 10 - x
2542 """
2543 a, b = _coerce_exprs(self, other)
2544 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctx)
2545
2546 def __pow__(self, other):
2547 """Create the Z3 expression `self**other` (** is the power operator).
2548
2549 >>> x = Real('x')
2550 >>> x**3
2551 x**3
2552 >>> (x**3).sort()
2553 Real
2554 >>> simplify(IntVal(2)**8)
2555 256
2556 """
2557 a, b = _coerce_exprs(self, other)
2558 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2559
2560 def __rpow__(self, other):
2561 """Create the Z3 expression `other**self` (** is the power operator).
2562
2563 >>> x = Real('x')
2564 >>> 2**x
2565 2**x
2566 >>> (2**x).sort()
2567 Real
2568 >>> simplify(2**IntVal(8))
2569 256
2570 """
2571 a, b = _coerce_exprs(self, other)
2572 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2573
2574 def __div__(self, other):
2575 """Create the Z3 expression `other/self`.
2576
2577 >>> x = Int('x')
2578 >>> y = Int('y')
2579 >>> x/y
2580 x/y
2581 >>> (x/y).sort()
2582 Int
2583 >>> (x/y).sexpr()
2584 '(div x y)'
2585 >>> x = Real('x')
2586 >>> y = Real('y')
2587 >>> x/y
2588 x/y
2589 >>> (x/y).sort()
2590 Real
2591 >>> (x/y).sexpr()
2592 '(/ x y)'
2593 """
2594 a, b = _coerce_exprs(self, other)
2595 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2596
2597 def __truediv__(self, other):
2598 """Create the Z3 expression `other/self`."""
2599 return self.__div__(other)
2600
2601 def __rdiv__(self, other):
2602 """Create the Z3 expression `other/self`.
2603
2604 >>> x = Int('x')
2605 >>> 10/x
2606 10/x
2607 >>> (10/x).sexpr()
2608 '(div 10 x)'
2609 >>> x = Real('x')
2610 >>> 10/x
2611 10/x
2612 >>> (10/x).sexpr()
2613 '(/ 10.0 x)'
2614 """
2615 a, b = _coerce_exprs(self, other)
2616 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2617
2618 def __rtruediv__(self, other):
2619 """Create the Z3 expression `other/self`."""
2620 return self.__rdiv__(other)
2621
2622 def __mod__(self, other):
2623 """Create the Z3 expression `other%self`.
2624
2625 >>> x = Int('x')
2626 >>> y = Int('y')
2627 >>> x % y
2628 x%y
2629 >>> simplify(IntVal(10) % IntVal(3))
2630 1
2631 """
2632 a, b = _coerce_exprs(self, other)
2633 if z3_debug():
2634 _z3_assert(a.is_int(), "Z3 integer expression expected")
2635 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2636
2637 def __rmod__(self, other):
2638 """Create the Z3 expression `other%self`.
2639
2640 >>> x = Int('x')
2641 >>> 10 % x
2642 10%x
2643 """
2644 a, b = _coerce_exprs(self, other)
2645 if z3_debug():
2646 _z3_assert(a.is_int(), "Z3 integer expression expected")
2647 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2648
2649 def __neg__(self):
2650 """Return an expression representing `-self`.
2651
2652 >>> x = Int('x')
2653 >>> -x
2654 -x
2655 >>> simplify(-(-x))
2656 x
2657 """
2658 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
2659
2660 def __pos__(self):
2661 """Return `self`.
2662
2663 >>> x = Int('x')
2664 >>> +x
2665 x
2666 """
2667 return self
2668
2669 def __le__(self, other):
2670 """Create the Z3 expression `other <= self`.
2671
2672 >>> x, y = Ints('x y')
2673 >>> x <= y
2674 x <= y
2675 >>> y = Real('y')
2676 >>> x <= y
2677 ToReal(x) <= y
2678 """
2679 a, b = _coerce_exprs(self, other)
2680 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2681
2682 def __lt__(self, other):
2683 """Create the Z3 expression `other < self`.
2684
2685 >>> x, y = Ints('x y')
2686 >>> x < y
2687 x < y
2688 >>> y = Real('y')
2689 >>> x < y
2690 ToReal(x) < y
2691 """
2692 a, b = _coerce_exprs(self, other)
2693 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2694
2695 def __gt__(self, other):
2696 """Create the Z3 expression `other > self`.
2697
2698 >>> x, y = Ints('x y')
2699 >>> x > y
2700 x > y
2701 >>> y = Real('y')
2702 >>> x > y
2703 ToReal(x) > y
2704 """
2705 a, b = _coerce_exprs(self, other)
2706 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2707
2708 def __ge__(self, other):
2709 """Create the Z3 expression `other >= self`.
2710
2711 >>> x, y = Ints('x y')
2712 >>> x >= y
2713 x >= y
2714 >>> y = Real('y')
2715 >>> x >= y
2716 ToReal(x) >= y
2717 """
2718 a, b = _coerce_exprs(self, other)
2719 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2720
2721
2723 """Return `True` if `a` is an arithmetical expression.
2724
2725 >>> x = Int('x')
2726 >>> is_arith(x)
2727 True
2728 >>> is_arith(x + 1)
2729 True
2730 >>> is_arith(1)
2731 False
2732 >>> is_arith(IntVal(1))
2733 True
2734 >>> y = Real('y')
2735 >>> is_arith(y)
2736 True
2737 >>> is_arith(y + 1)
2738 True
2739 """
2740 return isinstance(a, ArithRef)
2741
2742
2743def is_int(a):
2744 """Return `True` if `a` is an integer expression.
2745
2746 >>> x = Int('x')
2747 >>> is_int(x + 1)
2748 True
2749 >>> is_int(1)
2750 False
2751 >>> is_int(IntVal(1))
2752 True
2753 >>> y = Real('y')
2754 >>> is_int(y)
2755 False
2756 >>> is_int(y + 1)
2757 False
2758 """
2759 return is_arith(a) and a.is_int()
2760
2761
2762def is_real(a):
2763 """Return `True` if `a` is a real expression.
2764
2765 >>> x = Int('x')
2766 >>> is_real(x + 1)
2767 False
2768 >>> y = Real('y')
2769 >>> is_real(y)
2770 True
2771 >>> is_real(y + 1)
2772 True
2773 >>> is_real(1)
2774 False
2775 >>> is_real(RealVal(1))
2776 True
2777 """
2778 return is_arith(a) and a.is_real()
2779
2780
2781def _is_numeral(ctx, a):
2782 return Z3_is_numeral_ast(ctx.ref(), a)
2783
2784
2785def _is_algebraic(ctx, a):
2786 return Z3_is_algebraic_number(ctx.ref(), a)
2787
2788
2790 """Return `True` if `a` is an integer value of sort Int.
2791
2792 >>> is_int_value(IntVal(1))
2793 True
2794 >>> is_int_value(1)
2795 False
2796 >>> is_int_value(Int('x'))
2797 False
2798 >>> n = Int('x') + 1
2799 >>> n
2800 x + 1
2801 >>> n.arg(1)
2802 1
2803 >>> is_int_value(n.arg(1))
2804 True
2805 >>> is_int_value(RealVal("1/3"))
2806 False
2807 >>> is_int_value(RealVal(1))
2808 False
2809 """
2810 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2811
2812
2814 """Return `True` if `a` is rational value of sort Real.
2815
2816 >>> is_rational_value(RealVal(1))
2817 True
2818 >>> is_rational_value(RealVal("3/5"))
2819 True
2820 >>> is_rational_value(IntVal(1))
2821 False
2822 >>> is_rational_value(1)
2823 False
2824 >>> n = Real('x') + 1
2825 >>> n.arg(1)
2826 1
2827 >>> is_rational_value(n.arg(1))
2828 True
2829 >>> is_rational_value(Real('x'))
2830 False
2831 """
2832 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2833
2834
2836 """Return `True` if `a` is an algebraic value of sort Real.
2837
2838 >>> is_algebraic_value(RealVal("3/5"))
2839 False
2840 >>> n = simplify(Sqrt(2))
2841 >>> n
2842 1.4142135623?
2843 >>> is_algebraic_value(n)
2844 True
2845 """
2846 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2847
2848
2849def is_add(a):
2850 """Return `True` if `a` is an expression of the form b + c.
2851
2852 >>> x, y = Ints('x y')
2853 >>> is_add(x + y)
2854 True
2855 >>> is_add(x - y)
2856 False
2857 """
2858 return is_app_of(a, Z3_OP_ADD)
2859
2860
2861def is_mul(a):
2862 """Return `True` if `a` is an expression of the form b * c.
2863
2864 >>> x, y = Ints('x y')
2865 >>> is_mul(x * y)
2866 True
2867 >>> is_mul(x - y)
2868 False
2869 """
2870 return is_app_of(a, Z3_OP_MUL)
2871
2872
2873def is_sub(a):
2874 """Return `True` if `a` is an expression of the form b - c.
2875
2876 >>> x, y = Ints('x y')
2877 >>> is_sub(x - y)
2878 True
2879 >>> is_sub(x + y)
2880 False
2881 """
2882 return is_app_of(a, Z3_OP_SUB)
2883
2884
2885def is_div(a):
2886 """Return `True` if `a` is an expression of the form b / c.
2887
2888 >>> x, y = Reals('x y')
2889 >>> is_div(x / y)
2890 True
2891 >>> is_div(x + y)
2892 False
2893 >>> x, y = Ints('x y')
2894 >>> is_div(x / y)
2895 False
2896 >>> is_idiv(x / y)
2897 True
2898 """
2899 return is_app_of(a, Z3_OP_DIV)
2900
2901
2902def is_idiv(a):
2903 """Return `True` if `a` is an expression of the form b div c.
2904
2905 >>> x, y = Ints('x y')
2906 >>> is_idiv(x / y)
2907 True
2908 >>> is_idiv(x + y)
2909 False
2910 """
2911 return is_app_of(a, Z3_OP_IDIV)
2912
2913
2914def is_mod(a):
2915 """Return `True` if `a` is an expression of the form b % c.
2916
2917 >>> x, y = Ints('x y')
2918 >>> is_mod(x % y)
2919 True
2920 >>> is_mod(x + y)
2921 False
2922 """
2923 return is_app_of(a, Z3_OP_MOD)
2924
2925
2926def is_le(a):
2927 """Return `True` if `a` is an expression of the form b <= c.
2928
2929 >>> x, y = Ints('x y')
2930 >>> is_le(x <= y)
2931 True
2932 >>> is_le(x < y)
2933 False
2934 """
2935 return is_app_of(a, Z3_OP_LE)
2936
2937
2938def is_lt(a):
2939 """Return `True` if `a` is an expression of the form b < c.
2940
2941 >>> x, y = Ints('x y')
2942 >>> is_lt(x < y)
2943 True
2944 >>> is_lt(x == y)
2945 False
2946 """
2947 return is_app_of(a, Z3_OP_LT)
2948
2949
2950def is_ge(a):
2951 """Return `True` if `a` is an expression of the form b >= c.
2952
2953 >>> x, y = Ints('x y')
2954 >>> is_ge(x >= y)
2955 True
2956 >>> is_ge(x == y)
2957 False
2958 """
2959 return is_app_of(a, Z3_OP_GE)
2960
2961
2962def is_gt(a):
2963 """Return `True` if `a` is an expression of the form b > c.
2964
2965 >>> x, y = Ints('x y')
2966 >>> is_gt(x > y)
2967 True
2968 >>> is_gt(x == y)
2969 False
2970 """
2971 return is_app_of(a, Z3_OP_GT)
2972
2973
2975 """Return `True` if `a` is an expression of the form IsInt(b).
2976
2977 >>> x = Real('x')
2978 >>> is_is_int(IsInt(x))
2979 True
2980 >>> is_is_int(x)
2981 False
2982 """
2983 return is_app_of(a, Z3_OP_IS_INT)
2984
2985
2987 """Return `True` if `a` is an expression of the form ToReal(b).
2988
2989 >>> x = Int('x')
2990 >>> n = ToReal(x)
2991 >>> n
2992 ToReal(x)
2993 >>> is_to_real(n)
2994 True
2995 >>> is_to_real(x)
2996 False
2997 """
2998 return is_app_of(a, Z3_OP_TO_REAL)
2999
3000
3002 """Return `True` if `a` is an expression of the form ToInt(b).
3003
3004 >>> x = Real('x')
3005 >>> n = ToInt(x)
3006 >>> n
3007 ToInt(x)
3008 >>> is_to_int(n)
3009 True
3010 >>> is_to_int(x)
3011 False
3012 """
3013 return is_app_of(a, Z3_OP_TO_INT)
3014
3015
3017 """Integer values."""
3018
3019 def as_long(self):
3020 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3021
3022 >>> v = IntVal(1)
3023 >>> v + 1
3024 1 + 1
3025 >>> v.as_long() + 1
3026 2
3027 """
3028 if z3_debug():
3029 _z3_assert(self.is_int(), "Integer value expected")
3030 return int(self.as_string())
3031
3032 def as_string(self):
3033 """Return a Z3 integer numeral as a Python string.
3034 >>> v = IntVal(100)
3035 >>> v.as_string()
3036 '100'
3037 """
3038 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3039
3041 """Return a Z3 integer numeral as a Python binary string.
3042 >>> v = IntVal(10)
3043 >>> v.as_binary_string()
3044 '1010'
3045 """
3046 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3047
3048
3050 """Rational values."""
3051
3052 def numerator(self):
3053 """ Return the numerator of a Z3 rational numeral.
3054
3055 >>> is_rational_value(RealVal("3/5"))
3056 True
3057 >>> n = RealVal("3/5")
3058 >>> n.numerator()
3059 3
3060 >>> is_rational_value(Q(3,5))
3061 True
3062 >>> Q(3,5).numerator()
3063 3
3064 """
3065 return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
3066
3067 def denominator(self):
3068 """ Return the denominator of a Z3 rational numeral.
3069
3070 >>> is_rational_value(Q(3,5))
3071 True
3072 >>> n = Q(3,5)
3073 >>> n.denominator()
3074 5
3075 """
3076 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
3077
3079 """ Return the numerator as a Python long.
3080
3081 >>> v = RealVal(10000000000)
3082 >>> v
3083 10000000000
3084 >>> v + 1
3085 10000000000 + 1
3086 >>> v.numerator_as_long() + 1 == 10000000001
3087 True
3088 """
3089 return self.numerator().as_long()
3090
3092 """ Return the denominator as a Python long.
3093
3094 >>> v = RealVal("1/3")
3095 >>> v
3096 1/3
3097 >>> v.denominator_as_long()
3098 3
3099 """
3100 return self.denominator().as_long()
3101
3102 def is_int(self):
3103 return False
3104
3105 def is_real(self):
3106 return True
3107
3108 def is_int_value(self):
3109 return self.denominator().is_int() and self.denominator_as_long() == 1
3110
3111 def as_long(self):
3112 _z3_assert(self.is_int_value(), "Expected integer fraction")
3113 return self.numerator_as_long()
3114
3115 def as_decimal(self, prec):
3116 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3117
3118 >>> v = RealVal("1/5")
3119 >>> v.as_decimal(3)
3120 '0.2'
3121 >>> v = RealVal("1/3")
3122 >>> v.as_decimal(3)
3123 '0.333?'
3124 """
3125 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3126
3127 def as_string(self):
3128 """Return a Z3 rational numeral as a Python string.
3129
3130 >>> v = Q(3,6)
3131 >>> v.as_string()
3132 '1/2'
3133 """
3134 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3135
3136 def as_fraction(self):
3137 """Return a Z3 rational as a Python Fraction object.
3138
3139 >>> v = RealVal("1/5")
3140 >>> v.as_fraction()
3141 Fraction(1, 5)
3142 """
3143 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3144
3145
3147 """Algebraic irrational values."""
3148
3149 def approx(self, precision=10):
3150 """Return a Z3 rational number that approximates the algebraic number `self`.
3151 The result `r` is such that |r - self| <= 1/10^precision
3152
3153 >>> x = simplify(Sqrt(2))
3154 >>> x.approx(20)
3155 6838717160008073720548335/4835703278458516698824704
3156 >>> x.approx(5)
3157 2965821/2097152
3158 """
3159 return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
3160
3161 def as_decimal(self, prec):
3162 """Return a string representation of the algebraic number `self` in decimal notation
3163 using `prec` decimal places.
3164
3165 >>> x = simplify(Sqrt(2))
3166 >>> x.as_decimal(10)
3167 '1.4142135623?'
3168 >>> x.as_decimal(20)
3169 '1.41421356237309504880?'
3170 """
3171 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3172
3173 def poly(self):
3174 return AstVector(Z3_algebraic_get_poly(self.ctx_ref(), self.as_ast()), self.ctx)
3175
3176 def index(self):
3177 return Z3_algebraic_get_i(self.ctx_ref(), self.as_ast())
3178
3179
3180def _py2expr(a, ctx=None):
3181 if isinstance(a, bool):
3182 return BoolVal(a, ctx)
3183 if _is_int(a):
3184 return IntVal(a, ctx)
3185 if isinstance(a, float):
3186 return RealVal(a, ctx)
3187 if isinstance(a, str):
3188 return StringVal(a, ctx)
3189 if is_expr(a):
3190 return a
3191 if z3_debug():
3192 _z3_assert(False, "Python bool, int, long or float expected")
3193
3194
3195def IntSort(ctx=None):
3196 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3197
3198 >>> IntSort()
3199 Int
3200 >>> x = Const('x', IntSort())
3201 >>> is_int(x)
3202 True
3203 >>> x.sort() == IntSort()
3204 True
3205 >>> x.sort() == BoolSort()
3206 False
3207 """
3208 ctx = _get_ctx(ctx)
3209 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3210
3211
3212def RealSort(ctx=None):
3213 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3214
3215 >>> RealSort()
3216 Real
3217 >>> x = Const('x', RealSort())
3218 >>> is_real(x)
3219 True
3220 >>> is_int(x)
3221 False
3222 >>> x.sort() == RealSort()
3223 True
3224 """
3225 ctx = _get_ctx(ctx)
3226 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3227
3228
3230 if isinstance(val, float):
3231 return str(int(val))
3232 elif isinstance(val, bool):
3233 if val:
3234 return "1"
3235 else:
3236 return "0"
3237 else:
3238 return str(val)
3239
3240
3241def IntVal(val, ctx=None):
3242 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3243
3244 >>> IntVal(1)
3245 1
3246 >>> IntVal("100")
3247 100
3248 """
3249 ctx = _get_ctx(ctx)
3250 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3251
3252
3253def RealVal(val, ctx=None):
3254 """Return a Z3 real value.
3255
3256 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3257 If `ctx=None`, then the global context is used.
3258
3259 >>> RealVal(1)
3260 1
3261 >>> RealVal(1).sort()
3262 Real
3263 >>> RealVal("3/5")
3264 3/5
3265 >>> RealVal("1.5")
3266 3/2
3267 """
3268 ctx = _get_ctx(ctx)
3269 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3270
3271
3272def RatVal(a, b, ctx=None):
3273 """Return a Z3 rational a/b.
3274
3275 If `ctx=None`, then the global context is used.
3276
3277 >>> RatVal(3,5)
3278 3/5
3279 >>> RatVal(3,5).sort()
3280 Real
3281 """
3282 if z3_debug():
3283 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3284 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3285 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3286
3287
3288def Q(a, b, ctx=None):
3289 """Return a Z3 rational a/b.
3290
3291 If `ctx=None`, then the global context is used.
3292
3293 >>> Q(3,5)
3294 3/5
3295 >>> Q(3,5).sort()
3296 Real
3297 """
3298 return simplify(RatVal(a, b, ctx=ctx))
3299
3300
3301def Int(name, ctx=None):
3302 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3303
3304 >>> x = Int('x')
3305 >>> is_int(x)
3306 True
3307 >>> is_int(x + 1)
3308 True
3309 """
3310 ctx = _get_ctx(ctx)
3311 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3312
3313
3314def Ints(names, ctx=None):
3315 """Return a tuple of Integer constants.
3316
3317 >>> x, y, z = Ints('x y z')
3318 >>> Sum(x, y, z)
3319 x + y + z
3320 """
3321 ctx = _get_ctx(ctx)
3322 if isinstance(names, str):
3323 names = names.split(" ")
3324 return [Int(name, ctx) for name in names]
3325
3326
3327def IntVector(prefix, sz, ctx=None):
3328 """Return a list of integer constants of size `sz`.
3329
3330 >>> X = IntVector('x', 3)
3331 >>> X
3332 [x__0, x__1, x__2]
3333 >>> Sum(X)
3334 x__0 + x__1 + x__2
3335 """
3336 ctx = _get_ctx(ctx)
3337 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3338
3339
3340def FreshInt(prefix="x", ctx=None):
3341 """Return a fresh integer constant in the given context using the given prefix.
3342
3343 >>> x = FreshInt()
3344 >>> y = FreshInt()
3345 >>> eq(x, y)
3346 False
3347 >>> x.sort()
3348 Int
3349 """
3350 ctx = _get_ctx(ctx)
3351 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3352
3353
3354def Real(name, ctx=None):
3355 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3356
3357 >>> x = Real('x')
3358 >>> is_real(x)
3359 True
3360 >>> is_real(x + 1)
3361 True
3362 """
3363 ctx = _get_ctx(ctx)
3364 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3365
3366
3367def Reals(names, ctx=None):
3368 """Return a tuple of real constants.
3369
3370 >>> x, y, z = Reals('x y z')
3371 >>> Sum(x, y, z)
3372 x + y + z
3373 >>> Sum(x, y, z).sort()
3374 Real
3375 """
3376 ctx = _get_ctx(ctx)
3377 if isinstance(names, str):
3378 names = names.split(" ")
3379 return [Real(name, ctx) for name in names]
3380
3381
3382def RealVector(prefix, sz, ctx=None):
3383 """Return a list of real constants of size `sz`.
3384
3385 >>> X = RealVector('x', 3)
3386 >>> X
3387 [x__0, x__1, x__2]
3388 >>> Sum(X)
3389 x__0 + x__1 + x__2
3390 >>> Sum(X).sort()
3391 Real
3392 """
3393 ctx = _get_ctx(ctx)
3394 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3395
3396
3397def FreshReal(prefix="b", ctx=None):
3398 """Return a fresh real constant in the given context using the given prefix.
3399
3400 >>> x = FreshReal()
3401 >>> y = FreshReal()
3402 >>> eq(x, y)
3403 False
3404 >>> x.sort()
3405 Real
3406 """
3407 ctx = _get_ctx(ctx)
3408 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3409
3410
3411def ToReal(a):
3412 """ Return the Z3 expression ToReal(a).
3413
3414 >>> x = Int('x')
3415 >>> x.sort()
3416 Int
3417 >>> n = ToReal(x)
3418 >>> n
3419 ToReal(x)
3420 >>> n.sort()
3421 Real
3422 """
3423 if z3_debug():
3424 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3425 ctx = a.ctx
3426 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3427
3428
3429def ToInt(a):
3430 """ Return the Z3 expression ToInt(a).
3431
3432 >>> x = Real('x')
3433 >>> x.sort()
3434 Real
3435 >>> n = ToInt(x)
3436 >>> n
3437 ToInt(x)
3438 >>> n.sort()
3439 Int
3440 """
3441 if z3_debug():
3442 _z3_assert(a.is_real(), "Z3 real expression expected.")
3443 ctx = a.ctx
3444 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3445
3446
3447def IsInt(a):
3448 """ Return the Z3 predicate IsInt(a).
3449
3450 >>> x = Real('x')
3451 >>> IsInt(x + "1/2")
3452 IsInt(x + 1/2)
3453 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3454 [x = 1/2]
3455 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3456 no solution
3457 """
3458 if z3_debug():
3459 _z3_assert(a.is_real(), "Z3 real expression expected.")
3460 ctx = a.ctx
3461 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3462
3463
3464def Sqrt(a, ctx=None):
3465 """ Return a Z3 expression which represents the square root of a.
3466
3467 >>> x = Real('x')
3468 >>> Sqrt(x)
3469 x**(1/2)
3470 """
3471 if not is_expr(a):
3472 ctx = _get_ctx(ctx)
3473 a = RealVal(a, ctx)
3474 return a ** "1/2"
3475
3476
3477def Cbrt(a, ctx=None):
3478 """ Return a Z3 expression which represents the cubic root of a.
3479
3480 >>> x = Real('x')
3481 >>> Cbrt(x)
3482 x**(1/3)
3483 """
3484 if not is_expr(a):
3485 ctx = _get_ctx(ctx)
3486 a = RealVal(a, ctx)
3487 return a ** "1/3"
3488
3489
3494
3495
3497 """Bit-vector sort."""
3498
3499 def size(self):
3500 """Return the size (number of bits) of the bit-vector sort `self`.
3501
3502 >>> b = BitVecSort(32)
3503 >>> b.size()
3504 32
3505 """
3506 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
3507
3508 def subsort(self, other):
3509 return is_bv_sort(other) and self.size() < other.size()
3510
3511 def cast(self, val):
3512 """Try to cast `val` as a Bit-Vector.
3513
3514 >>> b = BitVecSort(32)
3515 >>> b.cast(10)
3516 10
3517 >>> b.cast(10).sexpr()
3518 '#x0000000a'
3519 """
3520 if is_expr(val):
3521 if z3_debug():
3522 _z3_assert(self.ctx == val.ctx, "Context mismatch")
3523 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3524 return val
3525 else:
3526 return BitVecVal(val, self)
3527
3528
3530 """Return True if `s` is a Z3 bit-vector sort.
3531
3532 >>> is_bv_sort(BitVecSort(32))
3533 True
3534 >>> is_bv_sort(IntSort())
3535 False
3536 """
3537 return isinstance(s, BitVecSortRef)
3538
3539
3541 """Bit-vector expressions."""
3542
3543 def sort(self):
3544 """Return the sort of the bit-vector expression `self`.
3545
3546 >>> x = BitVec('x', 32)
3547 >>> x.sort()
3548 BitVec(32)
3549 >>> x.sort() == BitVecSort(32)
3550 True
3551 """
3552 return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3553
3554 def size(self):
3555 """Return the number of bits of the bit-vector expression `self`.
3556
3557 >>> x = BitVec('x', 32)
3558 >>> (x + 1).size()
3559 32
3560 >>> Concat(x, x).size()
3561 64
3562 """
3563 return self.sort().size()
3564
3565 def __add__(self, other):
3566 """Create the Z3 expression `self + other`.
3567
3568 >>> x = BitVec('x', 32)
3569 >>> y = BitVec('y', 32)
3570 >>> x + y
3571 x + y
3572 >>> (x + y).sort()
3573 BitVec(32)
3574 """
3575 a, b = _coerce_exprs(self, other)
3576 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3577
3578 def __radd__(self, other):
3579 """Create the Z3 expression `other + self`.
3580
3581 >>> x = BitVec('x', 32)
3582 >>> 10 + x
3583 10 + x
3584 """
3585 a, b = _coerce_exprs(self, other)
3586 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3587
3588 def __mul__(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_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3600
3601 def __rmul__(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_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3610
3611 def __sub__(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_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3623
3624 def __rsub__(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_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3633
3634 def __or__(self, other):
3635 """Create the Z3 expression bitwise-or `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_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3646
3647 def __ror__(self, other):
3648 """Create the Z3 expression bitwise-or `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_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3656
3657 def __and__(self, other):
3658 """Create the Z3 expression bitwise-and `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_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3669
3670 def __rand__(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_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3679
3680 def __xor__(self, other):
3681 """Create the Z3 expression bitwise-xor `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_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3692
3693 def __rxor__(self, other):
3694 """Create the Z3 expression bitwise-xor `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_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3702
3703 def __pos__(self):
3704 """Return `self`.
3705
3706 >>> x = BitVec('x', 32)
3707 >>> +x
3708 x
3709 """
3710 return self
3711
3712 def __neg__(self):
3713 """Return an expression representing `-self`.
3714
3715 >>> x = BitVec('x', 32)
3716 >>> -x
3717 -x
3718 >>> simplify(-(-x))
3719 x
3720 """
3721 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3722
3723 def __invert__(self):
3724 """Create the Z3 expression bitwise-not `~self`.
3725
3726 >>> x = BitVec('x', 32)
3727 >>> ~x
3728 ~x
3729 >>> simplify(~(~x))
3730 x
3731 """
3732 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3733
3734 def __div__(self, other):
3735 """Create the Z3 expression (signed) division `self / other`.
3736
3737 Use the function UDiv() for unsigned division.
3738
3739 >>> x = BitVec('x', 32)
3740 >>> y = BitVec('y', 32)
3741 >>> x / y
3742 x/y
3743 >>> (x / y).sort()
3744 BitVec(32)
3745 >>> (x / y).sexpr()
3746 '(bvsdiv x y)'
3747 >>> UDiv(x, y).sexpr()
3748 '(bvudiv x y)'
3749 """
3750 a, b = _coerce_exprs(self, other)
3751 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3752
3753 def __truediv__(self, other):
3754 """Create the Z3 expression (signed) division `self / other`."""
3755 return self.__div__(other)
3756
3757 def __rdiv__(self, other):
3758 """Create the Z3 expression (signed) division `other / self`.
3759
3760 Use the function UDiv() for unsigned division.
3761
3762 >>> x = BitVec('x', 32)
3763 >>> 10 / x
3764 10/x
3765 >>> (10 / x).sexpr()
3766 '(bvsdiv #x0000000a x)'
3767 >>> UDiv(10, x).sexpr()
3768 '(bvudiv #x0000000a x)'
3769 """
3770 a, b = _coerce_exprs(self, other)
3771 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3772
3773 def __rtruediv__(self, other):
3774 """Create the Z3 expression (signed) division `other / self`."""
3775 return self.__rdiv__(other)
3776
3777 def __mod__(self, other):
3778 """Create the Z3 expression (signed) mod `self % other`.
3779
3780 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3781
3782 >>> x = BitVec('x', 32)
3783 >>> y = BitVec('y', 32)
3784 >>> x % y
3785 x%y
3786 >>> (x % y).sort()
3787 BitVec(32)
3788 >>> (x % y).sexpr()
3789 '(bvsmod x y)'
3790 >>> URem(x, y).sexpr()
3791 '(bvurem x y)'
3792 >>> SRem(x, y).sexpr()
3793 '(bvsrem x y)'
3794 """
3795 a, b = _coerce_exprs(self, other)
3796 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3797
3798 def __rmod__(self, other):
3799 """Create the Z3 expression (signed) mod `other % self`.
3800
3801 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3802
3803 >>> x = BitVec('x', 32)
3804 >>> 10 % x
3805 10%x
3806 >>> (10 % x).sexpr()
3807 '(bvsmod #x0000000a x)'
3808 >>> URem(10, x).sexpr()
3809 '(bvurem #x0000000a x)'
3810 >>> SRem(10, x).sexpr()
3811 '(bvsrem #x0000000a x)'
3812 """
3813 a, b = _coerce_exprs(self, other)
3814 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3815
3816 def __le__(self, other):
3817 """Create the Z3 expression (signed) `other <= self`.
3818
3819 Use the function ULE() for unsigned less than or equal to.
3820
3821 >>> x, y = BitVecs('x y', 32)
3822 >>> x <= y
3823 x <= y
3824 >>> (x <= y).sexpr()
3825 '(bvsle x y)'
3826 >>> ULE(x, y).sexpr()
3827 '(bvule x y)'
3828 """
3829 a, b = _coerce_exprs(self, other)
3830 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3831
3832 def __lt__(self, other):
3833 """Create the Z3 expression (signed) `other < self`.
3834
3835 Use the function ULT() for unsigned less than.
3836
3837 >>> x, y = BitVecs('x y', 32)
3838 >>> x < y
3839 x < y
3840 >>> (x < y).sexpr()
3841 '(bvslt x y)'
3842 >>> ULT(x, y).sexpr()
3843 '(bvult x y)'
3844 """
3845 a, b = _coerce_exprs(self, other)
3846 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3847
3848 def __gt__(self, other):
3849 """Create the Z3 expression (signed) `other > self`.
3850
3851 Use the function UGT() for unsigned greater than.
3852
3853 >>> x, y = BitVecs('x y', 32)
3854 >>> x > y
3855 x > y
3856 >>> (x > y).sexpr()
3857 '(bvsgt x y)'
3858 >>> UGT(x, y).sexpr()
3859 '(bvugt x y)'
3860 """
3861 a, b = _coerce_exprs(self, other)
3862 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3863
3864 def __ge__(self, other):
3865 """Create the Z3 expression (signed) `other >= self`.
3866
3867 Use the function UGE() for unsigned greater than or equal to.
3868
3869 >>> x, y = BitVecs('x y', 32)
3870 >>> x >= y
3871 x >= y
3872 >>> (x >= y).sexpr()
3873 '(bvsge x y)'
3874 >>> UGE(x, y).sexpr()
3875 '(bvuge x y)'
3876 """
3877 a, b = _coerce_exprs(self, other)
3878 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3879
3880 def __rshift__(self, other):
3881 """Create the Z3 expression (arithmetical) right shift `self >> other`
3882
3883 Use the function LShR() for the right logical shift
3884
3885 >>> x, y = BitVecs('x y', 32)
3886 >>> x >> y
3887 x >> y
3888 >>> (x >> y).sexpr()
3889 '(bvashr x y)'
3890 >>> LShR(x, y).sexpr()
3891 '(bvlshr x y)'
3892 >>> BitVecVal(4, 3)
3893 4
3894 >>> BitVecVal(4, 3).as_signed_long()
3895 -4
3896 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3897 -2
3898 >>> simplify(BitVecVal(4, 3) >> 1)
3899 6
3900 >>> simplify(LShR(BitVecVal(4, 3), 1))
3901 2
3902 >>> simplify(BitVecVal(2, 3) >> 1)
3903 1
3904 >>> simplify(LShR(BitVecVal(2, 3), 1))
3905 1
3906 """
3907 a, b = _coerce_exprs(self, other)
3908 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3909
3910 def __lshift__(self, other):
3911 """Create the Z3 expression left shift `self << other`
3912
3913 >>> x, y = BitVecs('x y', 32)
3914 >>> x << y
3915 x << y
3916 >>> (x << y).sexpr()
3917 '(bvshl x y)'
3918 >>> simplify(BitVecVal(2, 3) << 1)
3919 4
3920 """
3921 a, b = _coerce_exprs(self, other)
3922 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3923
3924 def __rrshift__(self, other):
3925 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
3926
3927 Use the function LShR() for the right logical shift
3928
3929 >>> x = BitVec('x', 32)
3930 >>> 10 >> x
3931 10 >> x
3932 >>> (10 >> x).sexpr()
3933 '(bvashr #x0000000a x)'
3934 """
3935 a, b = _coerce_exprs(self, other)
3936 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3937
3938 def __rlshift__(self, other):
3939 """Create the Z3 expression left shift `other << self`.
3940
3941 Use the function LShR() for the right logical shift
3942
3943 >>> x = BitVec('x', 32)
3944 >>> 10 << x
3945 10 << x
3946 >>> (10 << x).sexpr()
3947 '(bvshl #x0000000a x)'
3948 """
3949 a, b = _coerce_exprs(self, other)
3950 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3951
3952
3954 """Bit-vector values."""
3955
3956 def as_long(self):
3957 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3958
3959 >>> v = BitVecVal(0xbadc0de, 32)
3960 >>> v
3961 195936478
3962 >>> print("0x%.8x" % v.as_long())
3963 0x0badc0de
3964 """
3965 return int(self.as_string())
3966
3968 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3969 The most significant bit is assumed to be the sign.
3970
3971 >>> BitVecVal(4, 3).as_signed_long()
3972 -4
3973 >>> BitVecVal(7, 3).as_signed_long()
3974 -1
3975 >>> BitVecVal(3, 3).as_signed_long()
3976 3
3977 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
3978 -1
3979 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
3980 -1
3981 """
3982 sz = self.size()
3983 val = self.as_long()
3984 if val >= 2**(sz - 1):
3985 val = val - 2**sz
3986 if val < -2**(sz - 1):
3987 val = val + 2**sz
3988 return int(val)
3989
3990 def as_string(self):
3991 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3992
3994 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3995
3996
3997def is_bv(a):
3998 """Return `True` if `a` is a Z3 bit-vector expression.
3999
4000 >>> b = BitVec('b', 32)
4001 >>> is_bv(b)
4002 True
4003 >>> is_bv(b + 10)
4004 True
4005 >>> is_bv(Int('x'))
4006 False
4007 """
4008 return isinstance(a, BitVecRef)
4009
4010
4012 """Return `True` if `a` is a Z3 bit-vector numeral value.
4013
4014 >>> b = BitVec('b', 32)
4015 >>> is_bv_value(b)
4016 False
4017 >>> b = BitVecVal(10, 32)
4018 >>> b
4019 10
4020 >>> is_bv_value(b)
4021 True
4022 """
4023 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4024
4025
4026def BV2Int(a, is_signed=False):
4027 """Return the Z3 expression BV2Int(a).
4028
4029 >>> b = BitVec('b', 3)
4030 >>> BV2Int(b).sort()
4031 Int
4032 >>> x = Int('x')
4033 >>> x > BV2Int(b)
4034 x > BV2Int(b)
4035 >>> x > BV2Int(b, is_signed=False)
4036 x > BV2Int(b)
4037 >>> x > BV2Int(b, is_signed=True)
4038 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4039 >>> solve(x > BV2Int(b), b == 1, x < 3)
4040 [x = 2, b = 1]
4041 """
4042 if z3_debug():
4043 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4044 ctx = a.ctx
4045 # investigate problem with bv2int
4046 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4047
4048
4049def Int2BV(a, num_bits):
4050 """Return the z3 expression Int2BV(a, num_bits).
4051 It is a bit-vector of width num_bits and represents the
4052 modulo of a by 2^num_bits
4053 """
4054 ctx = a.ctx
4055 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4056
4057
4058def BitVecSort(sz, ctx=None):
4059 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4060
4061 >>> Byte = BitVecSort(8)
4062 >>> Word = BitVecSort(16)
4063 >>> Byte
4064 BitVec(8)
4065 >>> x = Const('x', Byte)
4066 >>> eq(x, BitVec('x', 8))
4067 True
4068 """
4069 ctx = _get_ctx(ctx)
4070 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4071
4072
4073def BitVecVal(val, bv, ctx=None):
4074 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4075
4076 >>> v = BitVecVal(10, 32)
4077 >>> v
4078 10
4079 >>> print("0x%.8x" % v.as_long())
4080 0x0000000a
4081 """
4082 if is_bv_sort(bv):
4083 ctx = bv.ctx
4084 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4085 else:
4086 ctx = _get_ctx(ctx)
4087 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4088
4089
4090def BitVec(name, bv, ctx=None):
4091 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4092 If `ctx=None`, then the global context is used.
4093
4094 >>> x = BitVec('x', 16)
4095 >>> is_bv(x)
4096 True
4097 >>> x.size()
4098 16
4099 >>> x.sort()
4100 BitVec(16)
4101 >>> word = BitVecSort(16)
4102 >>> x2 = BitVec('x', word)
4103 >>> eq(x, x2)
4104 True
4105 """
4106 if isinstance(bv, BitVecSortRef):
4107 ctx = bv.ctx
4108 else:
4109 ctx = _get_ctx(ctx)
4110 bv = BitVecSort(bv, ctx)
4111 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4112
4113
4114def BitVecs(names, bv, ctx=None):
4115 """Return a tuple of bit-vector constants of size bv.
4116
4117 >>> x, y, z = BitVecs('x y z', 16)
4118 >>> x.size()
4119 16
4120 >>> x.sort()
4121 BitVec(16)
4122 >>> Sum(x, y, z)
4123 0 + x + y + z
4124 >>> Product(x, y, z)
4125 1*x*y*z
4126 >>> simplify(Product(x, y, z))
4127 x*y*z
4128 """
4129 ctx = _get_ctx(ctx)
4130 if isinstance(names, str):
4131 names = names.split(" ")
4132 return [BitVec(name, bv, ctx) for name in names]
4133
4134
4135def Concat(*args):
4136 """Create a Z3 bit-vector concatenation expression.
4137
4138 >>> v = BitVecVal(1, 4)
4139 >>> Concat(v, v+1, v)
4140 Concat(Concat(1, 1 + 1), 1)
4141 >>> simplify(Concat(v, v+1, v))
4142 289
4143 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4144 121
4145 """
4146 args = _get_args(args)
4147 sz = len(args)
4148 if z3_debug():
4149 _z3_assert(sz >= 2, "At least two arguments expected.")
4150
4151 ctx = None
4152 for a in args:
4153 if is_expr(a):
4154 ctx = a.ctx
4155 break
4156 if is_seq(args[0]) or isinstance(args[0], str):
4157 args = [_coerce_seq(s, ctx) for s in args]
4158 if z3_debug():
4159 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4160 v = (Ast * sz)()
4161 for i in range(sz):
4162 v[i] = args[i].as_ast()
4163 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4164
4165 if is_re(args[0]):
4166 if z3_debug():
4167 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4168 v = (Ast * sz)()
4169 for i in range(sz):
4170 v[i] = args[i].as_ast()
4171 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4172
4173 if z3_debug():
4174 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4175 r = args[0]
4176 for i in range(sz - 1):
4177 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4178 return r
4179
4180
4181def Extract(high, low, a):
4182 """Create a Z3 bit-vector extraction expression.
4183 Extract is overloaded to also work on sequence extraction.
4184 The functions SubString and SubSeq are redirected to Extract.
4185 For this case, the arguments are reinterpreted as:
4186 high - is a sequence (string)
4187 low - is an offset
4188 a - is the length to be extracted
4189
4190 >>> x = BitVec('x', 8)
4191 >>> Extract(6, 2, x)
4192 Extract(6, 2, x)
4193 >>> Extract(6, 2, x).sort()
4194 BitVec(5)
4195 >>> simplify(Extract(StringVal("abcd"),2,1))
4196 "c"
4197 """
4198 if isinstance(high, str):
4199 high = StringVal(high)
4200 if is_seq(high):
4201 s = high
4202 offset, length = _coerce_exprs(low, a, s.ctx)
4203 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4204 if z3_debug():
4205 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4206 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4207 "First and second arguments must be non negative integers")
4208 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4209 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4210
4211
4213 if z3_debug():
4214 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4215
4216
4217def ULE(a, b):
4218 """Create the Z3 expression (unsigned) `other <= self`.
4219
4220 Use the operator <= for signed less than or equal to.
4221
4222 >>> x, y = BitVecs('x y', 32)
4223 >>> ULE(x, y)
4224 ULE(x, y)
4225 >>> (x <= y).sexpr()
4226 '(bvsle x y)'
4227 >>> ULE(x, y).sexpr()
4228 '(bvule x y)'
4229 """
4230 _check_bv_args(a, b)
4231 a, b = _coerce_exprs(a, b)
4232 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4233
4234
4235def ULT(a, b):
4236 """Create the Z3 expression (unsigned) `other < self`.
4237
4238 Use the operator < for signed less than.
4239
4240 >>> x, y = BitVecs('x y', 32)
4241 >>> ULT(x, y)
4242 ULT(x, y)
4243 >>> (x < y).sexpr()
4244 '(bvslt x y)'
4245 >>> ULT(x, y).sexpr()
4246 '(bvult x y)'
4247 """
4248 _check_bv_args(a, b)
4249 a, b = _coerce_exprs(a, b)
4250 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4251
4252
4253def UGE(a, b):
4254 """Create the Z3 expression (unsigned) `other >= self`.
4255
4256 Use the operator >= for signed greater than or equal to.
4257
4258 >>> x, y = BitVecs('x y', 32)
4259 >>> UGE(x, y)
4260 UGE(x, y)
4261 >>> (x >= y).sexpr()
4262 '(bvsge x y)'
4263 >>> UGE(x, y).sexpr()
4264 '(bvuge x y)'
4265 """
4266 _check_bv_args(a, b)
4267 a, b = _coerce_exprs(a, b)
4268 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4269
4270
4271def UGT(a, b):
4272 """Create the Z3 expression (unsigned) `other > self`.
4273
4274 Use the operator > for signed greater than.
4275
4276 >>> x, y = BitVecs('x y', 32)
4277 >>> UGT(x, y)
4278 UGT(x, y)
4279 >>> (x > y).sexpr()
4280 '(bvsgt x y)'
4281 >>> UGT(x, y).sexpr()
4282 '(bvugt x y)'
4283 """
4284 _check_bv_args(a, b)
4285 a, b = _coerce_exprs(a, b)
4286 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4287
4288
4289def UDiv(a, b):
4290 """Create the Z3 expression (unsigned) division `self / other`.
4291
4292 Use the operator / for signed division.
4293
4294 >>> x = BitVec('x', 32)
4295 >>> y = BitVec('y', 32)
4296 >>> UDiv(x, y)
4297 UDiv(x, y)
4298 >>> UDiv(x, y).sort()
4299 BitVec(32)
4300 >>> (x / y).sexpr()
4301 '(bvsdiv x y)'
4302 >>> UDiv(x, y).sexpr()
4303 '(bvudiv x y)'
4304 """
4305 _check_bv_args(a, b)
4306 a, b = _coerce_exprs(a, b)
4307 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4308
4309
4310def URem(a, b):
4311 """Create the Z3 expression (unsigned) remainder `self % other`.
4312
4313 Use the operator % for signed modulus, and SRem() for signed remainder.
4314
4315 >>> x = BitVec('x', 32)
4316 >>> y = BitVec('y', 32)
4317 >>> URem(x, y)
4318 URem(x, y)
4319 >>> URem(x, y).sort()
4320 BitVec(32)
4321 >>> (x % y).sexpr()
4322 '(bvsmod x y)'
4323 >>> URem(x, y).sexpr()
4324 '(bvurem x y)'
4325 """
4326 _check_bv_args(a, b)
4327 a, b = _coerce_exprs(a, b)
4328 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4329
4330
4331def SRem(a, b):
4332 """Create the Z3 expression signed remainder.
4333
4334 Use the operator % for signed modulus, and URem() for unsigned remainder.
4335
4336 >>> x = BitVec('x', 32)
4337 >>> y = BitVec('y', 32)
4338 >>> SRem(x, y)
4339 SRem(x, y)
4340 >>> SRem(x, y).sort()
4341 BitVec(32)
4342 >>> (x % y).sexpr()
4343 '(bvsmod x y)'
4344 >>> SRem(x, y).sexpr()
4345 '(bvsrem x y)'
4346 """
4347 _check_bv_args(a, b)
4348 a, b = _coerce_exprs(a, b)
4349 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4350
4351
4352def LShR(a, b):
4353 """Create the Z3 expression logical right shift.
4354
4355 Use the operator >> for the arithmetical right shift.
4356
4357 >>> x, y = BitVecs('x y', 32)
4358 >>> LShR(x, y)
4359 LShR(x, y)
4360 >>> (x >> y).sexpr()
4361 '(bvashr x y)'
4362 >>> LShR(x, y).sexpr()
4363 '(bvlshr x y)'
4364 >>> BitVecVal(4, 3)
4365 4
4366 >>> BitVecVal(4, 3).as_signed_long()
4367 -4
4368 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4369 -2
4370 >>> simplify(BitVecVal(4, 3) >> 1)
4371 6
4372 >>> simplify(LShR(BitVecVal(4, 3), 1))
4373 2
4374 >>> simplify(BitVecVal(2, 3) >> 1)
4375 1
4376 >>> simplify(LShR(BitVecVal(2, 3), 1))
4377 1
4378 """
4379 _check_bv_args(a, b)
4380 a, b = _coerce_exprs(a, b)
4381 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4382
4383
4384def RotateLeft(a, b):
4385 """Return an expression representing `a` rotated to the left `b` times.
4386
4387 >>> a, b = BitVecs('a b', 16)
4388 >>> RotateLeft(a, b)
4389 RotateLeft(a, b)
4390 >>> simplify(RotateLeft(a, 0))
4391 a
4392 >>> simplify(RotateLeft(a, 16))
4393 a
4394 """
4395 _check_bv_args(a, b)
4396 a, b = _coerce_exprs(a, b)
4397 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4398
4399
4400def RotateRight(a, b):
4401 """Return an expression representing `a` rotated to the right `b` times.
4402
4403 >>> a, b = BitVecs('a b', 16)
4404 >>> RotateRight(a, b)
4405 RotateRight(a, b)
4406 >>> simplify(RotateRight(a, 0))
4407 a
4408 >>> simplify(RotateRight(a, 16))
4409 a
4410 """
4411 _check_bv_args(a, b)
4412 a, b = _coerce_exprs(a, b)
4413 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4414
4415
4416def SignExt(n, a):
4417 """Return a bit-vector expression with `n` extra sign-bits.
4418
4419 >>> x = BitVec('x', 16)
4420 >>> n = SignExt(8, x)
4421 >>> n.size()
4422 24
4423 >>> n
4424 SignExt(8, x)
4425 >>> n.sort()
4426 BitVec(24)
4427 >>> v0 = BitVecVal(2, 2)
4428 >>> v0
4429 2
4430 >>> v0.size()
4431 2
4432 >>> v = simplify(SignExt(6, v0))
4433 >>> v
4434 254
4435 >>> v.size()
4436 8
4437 >>> print("%.x" % v.as_long())
4438 fe
4439 """
4440 if z3_debug():
4441 _z3_assert(_is_int(n), "First argument must be an integer")
4442 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4443 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4444
4445
4446def ZeroExt(n, a):
4447 """Return a bit-vector expression with `n` extra zero-bits.
4448
4449 >>> x = BitVec('x', 16)
4450 >>> n = ZeroExt(8, x)
4451 >>> n.size()
4452 24
4453 >>> n
4454 ZeroExt(8, x)
4455 >>> n.sort()
4456 BitVec(24)
4457 >>> v0 = BitVecVal(2, 2)
4458 >>> v0
4459 2
4460 >>> v0.size()
4461 2
4462 >>> v = simplify(ZeroExt(6, v0))
4463 >>> v
4464 2
4465 >>> v.size()
4466 8
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_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4472
4473
4475 """Return an expression representing `n` copies of `a`.
4476
4477 >>> x = BitVec('x', 8)
4478 >>> n = RepeatBitVec(4, x)
4479 >>> n
4480 RepeatBitVec(4, x)
4481 >>> n.size()
4482 32
4483 >>> v0 = BitVecVal(10, 4)
4484 >>> print("%.x" % v0.as_long())
4485 a
4486 >>> v = simplify(RepeatBitVec(4, v0))
4487 >>> v.size()
4488 16
4489 >>> print("%.x" % v.as_long())
4490 aaaa
4491 """
4492 if z3_debug():
4493 _z3_assert(_is_int(n), "First argument must be an integer")
4494 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4495 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4496
4497
4499 """Return the reduction-and expression of `a`."""
4500 if z3_debug():
4501 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4502 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4503
4504
4505def BVRedOr(a):
4506 """Return the reduction-or expression of `a`."""
4507 if z3_debug():
4508 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4509 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4510
4511
4512def BVAddNoOverflow(a, b, signed):
4513 """A predicate the determines that bit-vector addition does not overflow"""
4514 _check_bv_args(a, b)
4515 a, b = _coerce_exprs(a, b)
4516 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4517
4518
4520 """A predicate the determines that signed bit-vector addition does not underflow"""
4521 _check_bv_args(a, b)
4522 a, b = _coerce_exprs(a, b)
4523 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4524
4525
4527 """A predicate the determines that bit-vector subtraction does not overflow"""
4528 _check_bv_args(a, b)
4529 a, b = _coerce_exprs(a, b)
4530 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4531
4532
4533def BVSubNoUnderflow(a, b, signed):
4534 """A predicate the determines that bit-vector subtraction does not underflow"""
4535 _check_bv_args(a, b)
4536 a, b = _coerce_exprs(a, b)
4537 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4538
4539
4541 """A predicate the determines that bit-vector signed division does not overflow"""
4542 _check_bv_args(a, b)
4543 a, b = _coerce_exprs(a, b)
4544 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4545
4546
4548 """A predicate the determines that bit-vector unary negation does not overflow"""
4549 if z3_debug():
4550 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4551 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4552
4553
4554def BVMulNoOverflow(a, b, signed):
4555 """A predicate the determines that bit-vector multiplication does not overflow"""
4556 _check_bv_args(a, b)
4557 a, b = _coerce_exprs(a, b)
4558 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4559
4560
4562 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4563 _check_bv_args(a, b)
4564 a, b = _coerce_exprs(a, b)
4565 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4566
4567
4568
4573
4575 """Array sorts."""
4576
4577 def domain(self):
4578 """Return the domain of the array sort `self`.
4579
4580 >>> A = ArraySort(IntSort(), BoolSort())
4581 >>> A.domain()
4582 Int
4583 """
4585
4586 def domain_n(self, i):
4587 """Return the domain of the array sort `self`.
4588 """
4589 return _to_sort_ref(Z3_get_array_sort_domain_n(self.ctx_ref(), self.ast, i), self.ctx)
4590
4591 def range(self):
4592 """Return the range of the array sort `self`.
4593
4594 >>> A = ArraySort(IntSort(), BoolSort())
4595 >>> A.range()
4596 Bool
4597 """
4598 return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
4599
4600
4602 """Array expressions. """
4603
4604 def sort(self):
4605 """Return the array sort of the array expression `self`.
4606
4607 >>> a = Array('a', IntSort(), BoolSort())
4608 >>> a.sort()
4609 Array(Int, Bool)
4610 """
4611 return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4612
4613 def domain(self):
4614 """Shorthand for `self.sort().domain()`.
4615
4616 >>> a = Array('a', IntSort(), BoolSort())
4617 >>> a.domain()
4618 Int
4619 """
4620 return self.sort().domain()
4621
4622 def domain_n(self, i):
4623 """Shorthand for self.sort().domain_n(i)`."""
4624 return self.sort().domain_n(i)
4625
4626 def range(self):
4627 """Shorthand for `self.sort().range()`.
4628
4629 >>> a = Array('a', IntSort(), BoolSort())
4630 >>> a.range()
4631 Bool
4632 """
4633 return self.sort().range()
4634
4635 def __getitem__(self, arg):
4636 """Return the Z3 expression `self[arg]`.
4637
4638 >>> a = Array('a', IntSort(), BoolSort())
4639 >>> i = Int('i')
4640 >>> a[i]
4641 a[i]
4642 >>> a[i].sexpr()
4643 '(select a i)'
4644 """
4645 return _array_select(self, arg)
4646
4647 def default(self):
4648 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)
4649
4650
4651def _array_select(ar, arg):
4652 if isinstance(arg, tuple):
4653 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4654 _args, sz = _to_ast_array(args)
4655 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4656 arg = ar.sort().domain().cast(arg)
4657 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4658
4659
4661 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4662
4663
4665 """Return `True` if `a` is a Z3 array expression.
4666
4667 >>> a = Array('a', IntSort(), IntSort())
4668 >>> is_array(a)
4669 True
4670 >>> is_array(Store(a, 0, 1))
4671 True
4672 >>> is_array(a[0])
4673 False
4674 """
4675 return isinstance(a, ArrayRef)
4676
4677
4679 """Return `True` if `a` is a Z3 constant array.
4680
4681 >>> a = K(IntSort(), 10)
4682 >>> is_const_array(a)
4683 True
4684 >>> a = Array('a', IntSort(), IntSort())
4685 >>> is_const_array(a)
4686 False
4687 """
4688 return is_app_of(a, Z3_OP_CONST_ARRAY)
4689
4690
4691def is_K(a):
4692 """Return `True` if `a` is a Z3 constant array.
4693
4694 >>> a = K(IntSort(), 10)
4695 >>> is_K(a)
4696 True
4697 >>> a = Array('a', IntSort(), IntSort())
4698 >>> is_K(a)
4699 False
4700 """
4701 return is_app_of(a, Z3_OP_CONST_ARRAY)
4702
4703
4704def is_map(a):
4705 """Return `True` if `a` is a Z3 map array expression.
4706
4707 >>> f = Function('f', IntSort(), IntSort())
4708 >>> b = Array('b', IntSort(), IntSort())
4709 >>> a = Map(f, b)
4710 >>> a
4711 Map(f, b)
4712 >>> is_map(a)
4713 True
4714 >>> is_map(b)
4715 False
4716 """
4717 return is_app_of(a, Z3_OP_ARRAY_MAP)
4718
4719
4721 """Return `True` if `a` is a Z3 default array expression.
4722 >>> d = Default(K(IntSort(), 10))
4723 >>> is_default(d)
4724 True
4725 """
4726 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4727
4728
4730 """Return the function declaration associated with a Z3 map array expression.
4731
4732 >>> f = Function('f', IntSort(), IntSort())
4733 >>> b = Array('b', IntSort(), IntSort())
4734 >>> a = Map(f, b)
4735 >>> eq(f, get_map_func(a))
4736 True
4737 >>> get_map_func(a)
4738 f
4739 >>> get_map_func(a)(0)
4740 f(0)
4741 """
4742 if z3_debug():
4743 _z3_assert(is_map(a), "Z3 array map expression expected.")
4744 return FuncDeclRef(
4746 a.ctx_ref(),
4747 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4748 ),
4749 ctx=a.ctx,
4750 )
4751
4752
4753def ArraySort(*sig):
4754 """Return the Z3 array sort with the given domain and range sorts.
4755
4756 >>> A = ArraySort(IntSort(), BoolSort())
4757 >>> A
4758 Array(Int, Bool)
4759 >>> A.domain()
4760 Int
4761 >>> A.range()
4762 Bool
4763 >>> AA = ArraySort(IntSort(), A)
4764 >>> AA
4765 Array(Int, Array(Int, Bool))
4766 """
4767 sig = _get_args(sig)
4768 if z3_debug():
4769 _z3_assert(len(sig) > 1, "At least two arguments expected")
4770 arity = len(sig) - 1
4771 r = sig[arity]
4772 d = sig[0]
4773 if z3_debug():
4774 for s in sig:
4775 _z3_assert(is_sort(s), "Z3 sort expected")
4776 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4777 ctx = d.ctx
4778 if len(sig) == 2:
4779 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4780 dom = (Sort * arity)()
4781 for i in range(arity):
4782 dom[i] = sig[i].ast
4783 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4784
4785
4786def Array(name, *sorts):
4787 """Return an array constant named `name` with the given domain and range sorts.
4788
4789 >>> a = Array('a', IntSort(), IntSort())
4790 >>> a.sort()
4791 Array(Int, Int)
4792 >>> a[0]
4793 a[0]
4794 """
4795 s = ArraySort(sorts)
4796 ctx = s.ctx
4797 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4798
4799
4800def Update(a, *args):
4801 """Return a Z3 store array expression.
4802
4803 >>> a = Array('a', IntSort(), IntSort())
4804 >>> i, v = Ints('i v')
4805 >>> s = Update(a, i, v)
4806 >>> s.sort()
4807 Array(Int, Int)
4808 >>> prove(s[i] == v)
4809 proved
4810 >>> j = Int('j')
4811 >>> prove(Implies(i != j, s[j] == a[j]))
4812 proved
4813 """
4814 if z3_debug():
4815 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4816 args = _get_args(args)
4817 ctx = a.ctx
4818 if len(args) <= 1:
4819 raise Z3Exception("array update requires index and value arguments")
4820 if len(args) == 2:
4821 i = args[0]
4822 v = args[1]
4823 i = a.sort().domain().cast(i)
4824 v = a.sort().range().cast(v)
4825 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4826 v = a.sort().range().cast(args[-1])
4827 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4828 _args, sz = _to_ast_array(idxs)
4829 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4830
4831
4832def Default(a):
4833 """ Return a default value for array expression.
4834 >>> b = K(IntSort(), 1)
4835 >>> prove(Default(b) == 1)
4836 proved
4837 """
4838 if z3_debug():
4839 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4840 return a.default()
4841
4842
4843def Store(a, *args):
4844 """Return a Z3 store array expression.
4845
4846 >>> a = Array('a', IntSort(), IntSort())
4847 >>> i, v = Ints('i v')
4848 >>> s = Store(a, i, v)
4849 >>> s.sort()
4850 Array(Int, Int)
4851 >>> prove(s[i] == v)
4852 proved
4853 >>> j = Int('j')
4854 >>> prove(Implies(i != j, s[j] == a[j]))
4855 proved
4856 """
4857 return Update(a, args)
4858
4859
4860def Select(a, *args):
4861 """Return a Z3 select array expression.
4862
4863 >>> a = Array('a', IntSort(), IntSort())
4864 >>> i = Int('i')
4865 >>> Select(a, i)
4866 a[i]
4867 >>> eq(Select(a, i), a[i])
4868 True
4869 """
4870 args = _get_args(args)
4871 if z3_debug():
4872 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4873 return a[args]
4874
4875
4876def Map(f, *args):
4877 """Return a Z3 map array expression.
4878
4879 >>> f = Function('f', IntSort(), IntSort(), IntSort())
4880 >>> a1 = Array('a1', IntSort(), IntSort())
4881 >>> a2 = Array('a2', IntSort(), IntSort())
4882 >>> b = Map(f, a1, a2)
4883 >>> b
4884 Map(f, a1, a2)
4885 >>> prove(b[0] == f(a1[0], a2[0]))
4886 proved
4887 """
4888 args = _get_args(args)
4889 if z3_debug():
4890 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
4891 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
4892 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
4893 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
4894 _args, sz = _to_ast_array(args)
4895 ctx = f.ctx
4896 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
4897
4898
4899def K(dom, v):
4900 """Return a Z3 constant array expression.
4901
4902 >>> a = K(IntSort(), 10)
4903 >>> a
4904 K(Int, 10)
4905 >>> a.sort()
4906 Array(Int, Int)
4907 >>> i = Int('i')
4908 >>> a[i]
4909 K(Int, 10)[i]
4910 >>> simplify(a[i])
4911 10
4912 """
4913 if z3_debug():
4914 _z3_assert(is_sort(dom), "Z3 sort expected")
4915 ctx = dom.ctx
4916 if not is_expr(v):
4917 v = _py2expr(v, ctx)
4918 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
4919
4920
4921def Ext(a, b):
4922 """Return extensionality index for one-dimensional arrays.
4923 >> a, b = Consts('a b', SetSort(IntSort()))
4924 >> Ext(a, b)
4925 Ext(a, b)
4926 """
4927 ctx = a.ctx
4928 if z3_debug():
4929 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
4930 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4931
4932
4933def SetHasSize(a, k):
4934 ctx = a.ctx
4935 k = _py2expr(k, ctx)
4936 return _to_expr_ref(Z3_mk_set_has_size(ctx.ref(), a.as_ast(), k.as_ast()), ctx)
4937
4938
4940 """Return `True` if `a` is a Z3 array select application.
4941
4942 >>> a = Array('a', IntSort(), IntSort())
4943 >>> is_select(a)
4944 False
4945 >>> i = Int('i')
4946 >>> is_select(a[i])
4947 True
4948 """
4949 return is_app_of(a, Z3_OP_SELECT)
4950
4951
4953 """Return `True` if `a` is a Z3 array store application.
4954
4955 >>> a = Array('a', IntSort(), IntSort())
4956 >>> is_store(a)
4957 False
4958 >>> is_store(Store(a, 0, 1))
4959 True
4960 """
4961 return is_app_of(a, Z3_OP_STORE)
4962
4963
4968
4969
4970def SetSort(s):
4971 """ Create a set sort over element sort s"""
4972 return ArraySort(s, BoolSort())
4973
4974
4976 """Create the empty set
4977 >>> EmptySet(IntSort())
4978 K(Int, False)
4979 """
4980 ctx = s.ctx
4981 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
4982
4983
4984def FullSet(s):
4985 """Create the full set
4986 >>> FullSet(IntSort())
4987 K(Int, True)
4988 """
4989 ctx = s.ctx
4990 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
4991
4992
4993def SetUnion(*args):
4994 """ Take the union of sets
4995 >>> a = Const('a', SetSort(IntSort()))
4996 >>> b = Const('b', SetSort(IntSort()))
4997 >>> SetUnion(a, b)
4998 union(a, b)
4999 """
5000 args = _get_args(args)
5001 ctx = _ctx_from_ast_arg_list(args)
5002 _args, sz = _to_ast_array(args)
5003 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5004
5005
5006def SetIntersect(*args):
5007 """ Take the union of sets
5008 >>> a = Const('a', SetSort(IntSort()))
5009 >>> b = Const('b', SetSort(IntSort()))
5010 >>> SetIntersect(a, b)
5011 intersection(a, b)
5012 """
5013 args = _get_args(args)
5014 ctx = _ctx_from_ast_arg_list(args)
5015 _args, sz = _to_ast_array(args)
5016 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5017
5018
5019def SetAdd(s, e):
5020 """ Add element e to set s
5021 >>> a = Const('a', SetSort(IntSort()))
5022 >>> SetAdd(a, 1)
5023 Store(a, 1, True)
5024 """
5025 ctx = _ctx_from_ast_arg_list([s, e])
5026 e = _py2expr(e, ctx)
5027 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5028
5029
5030def SetDel(s, e):
5031 """ Remove element e to set s
5032 >>> a = Const('a', SetSort(IntSort()))
5033 >>> SetDel(a, 1)
5034 Store(a, 1, False)
5035 """
5036 ctx = _ctx_from_ast_arg_list([s, e])
5037 e = _py2expr(e, ctx)
5038 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5039
5040
5042 """ The complement of set s
5043 >>> a = Const('a', SetSort(IntSort()))
5044 >>> SetComplement(a)
5045 complement(a)
5046 """
5047 ctx = s.ctx
5048 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5049
5050
5052 """ The set difference of a and b
5053 >>> a = Const('a', SetSort(IntSort()))
5054 >>> b = Const('b', SetSort(IntSort()))
5055 >>> SetDifference(a, b)
5056 setminus(a, b)
5057 """
5058 ctx = _ctx_from_ast_arg_list([a, b])
5059 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5060
5061
5062def IsMember(e, s):
5063 """ Check if e is a member of set s
5064 >>> a = Const('a', SetSort(IntSort()))
5065 >>> IsMember(1, a)
5066 a[1]
5067 """
5068 ctx = _ctx_from_ast_arg_list([s, e])
5069 e = _py2expr(e, ctx)
5070 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5071
5072
5073def IsSubset(a, b):
5074 """ Check if a is a subset of b
5075 >>> a = Const('a', SetSort(IntSort()))
5076 >>> b = Const('b', SetSort(IntSort()))
5077 >>> IsSubset(a, b)
5078 subset(a, b)
5079 """
5080 ctx = _ctx_from_ast_arg_list([a, b])
5081 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5082
5083
5084
5089
5091 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5092 if not isinstance(acc, tuple):
5093 return False
5094 if len(acc) != 2:
5095 return False
5096 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5097
5098
5100 """Helper class for declaring Z3 datatypes.
5101
5102 >>> List = Datatype('List')
5103 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5104 >>> List.declare('nil')
5105 >>> List = List.create()
5106 >>> # List is now a Z3 declaration
5107 >>> List.nil
5108 nil
5109 >>> List.cons(10, List.nil)
5110 cons(10, nil)
5111 >>> List.cons(10, List.nil).sort()
5112 List
5113 >>> cons = List.cons
5114 >>> nil = List.nil
5115 >>> car = List.car
5116 >>> cdr = List.cdr
5117 >>> n = cons(1, cons(0, nil))
5118 >>> n
5119 cons(1, cons(0, nil))
5120 >>> simplify(cdr(n))
5121 cons(0, nil)
5122 >>> simplify(car(n))
5123 1
5124 """
5125
5126 def __init__(self, name, ctx=None):
5127 self.ctx = _get_ctx(ctx)
5128 self.name = name
5130
5131 def __deepcopy__(self, memo={}):
5132 r = Datatype(self.name, self.ctx)
5133 r.constructors = copy.deepcopy(self.constructors)
5134 return r
5135
5136 def declare_core(self, name, rec_name, *args):
5137 if z3_debug():
5138 _z3_assert(isinstance(name, str), "String expected")
5139 _z3_assert(isinstance(rec_name, str), "String expected")
5140 _z3_assert(
5141 all([_valid_accessor(a) for a in args]),
5142 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5143 )
5144 self.constructors.append((name, rec_name, args))
5145
5146 def declare(self, name, *args):
5147 """Declare constructor named `name` with the given accessors `args`.
5148 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5149 or a reference to the datatypes being declared.
5150
5151 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5152 declares the constructor named `cons` that builds a new List using an integer and a List.
5153 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5154 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5155 we use the method create() to create the actual datatype in Z3.
5156
5157 >>> List = Datatype('List')
5158 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5159 >>> List.declare('nil')
5160 >>> List = List.create()
5161 """
5162 if z3_debug():
5163 _z3_assert(isinstance(name, str), "String expected")
5164 _z3_assert(name != "", "Constructor name cannot be empty")
5165 return self.declare_core(name, "is-" + name, *args)
5166
5167 def __repr__(self):
5168 return "Datatype(%s, %s)" % (self.name, self.constructors)
5169
5170 def create(self):
5171 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5172
5173 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5174
5175 >>> List = Datatype('List')
5176 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5177 >>> List.declare('nil')
5178 >>> List = List.create()
5179 >>> List.nil
5180 nil
5181 >>> List.cons(10, List.nil)
5182 cons(10, nil)
5183 """
5184 return CreateDatatypes([self])[0]
5185
5186
5188 """Auxiliary object used to create Z3 datatypes."""
5189
5190 def __init__(self, c, ctx):
5191 self.c = c
5192 self.ctx = ctx
5193
5194 def __del__(self):
5195 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5196 Z3_del_constructor(self.ctx.ref(), self.c)
5197
5198
5200 """Auxiliary object used to create Z3 datatypes."""
5201
5202 def __init__(self, c, ctx):
5203 self.c = c
5204 self.ctx = ctx
5205
5206 def __del__(self):
5207 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5208 Z3_del_constructor_list(self.ctx.ref(), self.c)
5209
5210
5212 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5213
5214 In the following example we define a Tree-List using two mutually recursive datatypes.
5215
5216 >>> TreeList = Datatype('TreeList')
5217 >>> Tree = Datatype('Tree')
5218 >>> # Tree has two constructors: leaf and node
5219 >>> Tree.declare('leaf', ('val', IntSort()))
5220 >>> # a node contains a list of trees
5221 >>> Tree.declare('node', ('children', TreeList))
5222 >>> TreeList.declare('nil')
5223 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5224 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5225 >>> Tree.val(Tree.leaf(10))
5226 val(leaf(10))
5227 >>> simplify(Tree.val(Tree.leaf(10)))
5228 10
5229 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5230 >>> n1
5231 node(cons(leaf(10), cons(leaf(20), nil)))
5232 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5233 >>> simplify(n2 == n1)
5234 False
5235 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5236 True
5237 """
5238 ds = _get_args(ds)
5239 if z3_debug():
5240 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5241 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5242 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5243 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5244 ctx = ds[0].ctx
5245 num = len(ds)
5246 names = (Symbol * num)()
5247 out = (Sort * num)()
5248 clists = (ConstructorList * num)()
5249 to_delete = []
5250 for i in range(num):
5251 d = ds[i]
5252 names[i] = to_symbol(d.name, ctx)
5253 num_cs = len(d.constructors)
5254 cs = (Constructor * num_cs)()
5255 for j in range(num_cs):
5256 c = d.constructors[j]
5257 cname = to_symbol(c[0], ctx)
5258 rname = to_symbol(c[1], ctx)
5259 fs = c[2]
5260 num_fs = len(fs)
5261 fnames = (Symbol * num_fs)()
5262 sorts = (Sort * num_fs)()
5263 refs = (ctypes.c_uint * num_fs)()
5264 for k in range(num_fs):
5265 fname = fs[k][0]
5266 ftype = fs[k][1]
5267 fnames[k] = to_symbol(fname, ctx)
5268 if isinstance(ftype, Datatype):
5269 if z3_debug():
5270 _z3_assert(
5271 ds.count(ftype) == 1,
5272 "One and only one occurrence of each datatype is expected",
5273 )
5274 sorts[k] = None
5275 refs[k] = ds.index(ftype)
5276 else:
5277 if z3_debug():
5278 _z3_assert(is_sort(ftype), "Z3 sort expected")
5279 sorts[k] = ftype.ast
5280 refs[k] = 0
5281 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5282 to_delete.append(ScopedConstructor(cs[j], ctx))
5283 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5284 to_delete.append(ScopedConstructorList(clists[i], ctx))
5285 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5286 result = []
5287 # Create a field for every constructor, recognizer and accessor
5288 for i in range(num):
5289 dref = DatatypeSortRef(out[i], ctx)
5290 num_cs = dref.num_constructors()
5291 for j in range(num_cs):
5292 cref = dref.constructor(j)
5293 cref_name = cref.name()
5294 cref_arity = cref.arity()
5295 if cref.arity() == 0:
5296 cref = cref()
5297 setattr(dref, cref_name, cref)
5298 rref = dref.recognizer(j)
5299 setattr(dref, "is_" + cref_name, rref)
5300 for k in range(cref_arity):
5301 aref = dref.accessor(j, k)
5302 setattr(dref, aref.name(), aref)
5303 result.append(dref)
5304 return tuple(result)
5305
5306
5308 """Datatype sorts."""
5309
5311 """Return the number of constructors in the given Z3 datatype.
5312
5313 >>> List = Datatype('List')
5314 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5315 >>> List.declare('nil')
5316 >>> List = List.create()
5317 >>> # List is now a Z3 declaration
5318 >>> List.num_constructors()
5319 2
5320 """
5322
5323 def constructor(self, idx):
5324 """Return a constructor of the datatype `self`.
5325
5326 >>> List = Datatype('List')
5327 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5328 >>> List.declare('nil')
5329 >>> List = List.create()
5330 >>> # List is now a Z3 declaration
5331 >>> List.num_constructors()
5332 2
5333 >>> List.constructor(0)
5334 cons
5335 >>> List.constructor(1)
5336 nil
5337 """
5338 if z3_debug():
5339 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5341
5342 def recognizer(self, idx):
5343 """In Z3, each constructor has an associated recognizer predicate.
5344
5345 If the constructor is named `name`, then the recognizer `is_name`.
5346
5347 >>> List = Datatype('List')
5348 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5349 >>> List.declare('nil')
5350 >>> List = List.create()
5351 >>> # List is now a Z3 declaration
5352 >>> List.num_constructors()
5353 2
5354 >>> List.recognizer(0)
5355 is(cons)
5356 >>> List.recognizer(1)
5357 is(nil)
5358 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5359 False
5360 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5361 True
5362 >>> l = Const('l', List)
5363 >>> simplify(List.is_cons(l))
5364 is(cons, l)
5365 """
5366 if z3_debug():
5367 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5368 return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
5369
5370 def accessor(self, i, j):
5371 """In Z3, each constructor has 0 or more accessor.
5372 The number of accessors is equal to the arity of the constructor.
5373
5374 >>> List = Datatype('List')
5375 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5376 >>> List.declare('nil')
5377 >>> List = List.create()
5378 >>> List.num_constructors()
5379 2
5380 >>> List.constructor(0)
5381 cons
5382 >>> num_accs = List.constructor(0).arity()
5383 >>> num_accs
5384 2
5385 >>> List.accessor(0, 0)
5386 car
5387 >>> List.accessor(0, 1)
5388 cdr
5389 >>> List.constructor(1)
5390 nil
5391 >>> num_accs = List.constructor(1).arity()
5392 >>> num_accs
5393 0
5394 """
5395 if z3_debug():
5396 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5397 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5398 return FuncDeclRef(
5400 ctx=self.ctx,
5401 )
5402
5403
5405 """Datatype expressions."""
5406
5407 def sort(self):
5408 """Return the datatype sort of the datatype expression `self`."""
5409 return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5410
5411def DatatypeSort(name, ctx = None):
5412 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype"""
5413 ctx = _get_ctx(ctx)
5414 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
5415
5416def TupleSort(name, sorts, ctx=None):
5417 """Create a named tuple sort base on a set of underlying sorts
5418 Example:
5419 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5420 """
5421 tuple = Datatype(name, ctx)
5422 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5423 tuple.declare(name, *projects)
5424 tuple = tuple.create()
5425 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5426
5427
5428def DisjointSum(name, sorts, ctx=None):
5429 """Create a named tagged union sort base on a set of underlying sorts
5430 Example:
5431 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5432 """
5433 sum = Datatype(name, ctx)
5434 for i in range(len(sorts)):
5435 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5436 sum = sum.create()
5437 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5438
5439
5440def EnumSort(name, values, ctx=None):
5441 """Return a new enumeration sort named `name` containing the given values.
5442
5443 The result is a pair (sort, list of constants).
5444 Example:
5445 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5446 """
5447 if z3_debug():
5448 _z3_assert(isinstance(name, str), "Name must be a string")
5449 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5450 _z3_assert(len(values) > 0, "At least one value expected")
5451 ctx = _get_ctx(ctx)
5452 num = len(values)
5453 _val_names = (Symbol * num)()
5454 for i in range(num):
5455 _val_names[i] = to_symbol(values[i], ctx)
5456 _values = (FuncDecl * num)()
5457 _testers = (FuncDecl * num)()
5458 name = to_symbol(name, ctx)
5459 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5460 V = []
5461 for i in range(num):
5462 V.append(FuncDeclRef(_values[i], ctx))
5463 V = [a() for a in V]
5464 return S, V
5465
5466
5471
5472
5474 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5475
5476 Consider using the function `args2params` to create instances of this object.
5477 """
5478
5479 def __init__(self, ctx=None, params=None):
5480 self.ctx = _get_ctx(ctx)
5481 if params is None:
5482 self.params = Z3_mk_params(self.ctx.ref())
5483 else:
5484 self.params = params
5485 Z3_params_inc_ref(self.ctx.ref(), self.params)
5486
5487 def __deepcopy__(self, memo={}):
5488 return ParamsRef(self.ctx, self.params)
5489
5490 def __del__(self):
5491 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5492 Z3_params_dec_ref(self.ctx.ref(), self.params)
5493
5494 def set(self, name, val):
5495 """Set parameter name with value val."""
5496 if z3_debug():
5497 _z3_assert(isinstance(name, str), "parameter name must be a string")
5498 name_sym = to_symbol(name, self.ctx)
5499 if isinstance(val, bool):
5500 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5501 elif _is_int(val):
5502 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5503 elif isinstance(val, float):
5504 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5505 elif isinstance(val, str):
5506 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5507 else:
5508 if z3_debug():
5509 _z3_assert(False, "invalid parameter value")
5510
5511 def __repr__(self):
5512 return Z3_params_to_string(self.ctx.ref(), self.params)
5513
5514 def validate(self, ds):
5515 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5516 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5517
5518
5519def args2params(arguments, keywords, ctx=None):
5520 """Convert python arguments into a Z3_params object.
5521 A ':' is added to the keywords, and '_' is replaced with '-'
5522
5523 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5524 (params model true relevancy 2 elim_and true)
5525 """
5526 if z3_debug():
5527 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5528 prev = None
5529 r = ParamsRef(ctx)
5530 for a in arguments:
5531 if prev is None:
5532 prev = a
5533 else:
5534 r.set(prev, a)
5535 prev = None
5536 for k in keywords:
5537 v = keywords[k]
5538 r.set(k, v)
5539 return r
5540
5541
5543 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5544 """
5545
5546 def __init__(self, descr, ctx=None):
5547 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5548 self.ctx = _get_ctx(ctx)
5549 self.descr = descr
5550 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5551
5552 def __deepcopy__(self, memo={}):
5553 return ParamsDescrsRef(self.descr, self.ctx)
5554
5555 def __del__(self):
5556 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5557 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5558
5559 def size(self):
5560 """Return the size of in the parameter description `self`.
5561 """
5562 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5563
5564 def __len__(self):
5565 """Return the size of in the parameter description `self`.
5566 """
5567 return self.size()
5568
5569 def get_name(self, i):
5570 """Return the i-th parameter name in the parameter description `self`.
5571 """
5572 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5573
5574 def get_kind(self, n):
5575 """Return the kind of the parameter named `n`.
5576 """
5577 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5578
5579 def get_documentation(self, n):
5580 """Return the documentation string of the parameter named `n`.
5581 """
5582 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5583
5584 def __getitem__(self, arg):
5585 if _is_int(arg):
5586 return self.get_name(arg)
5587 else:
5588 return self.get_kind(arg)
5589
5590 def __repr__(self):
5591 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5592
5593
5598
5599
5601 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5602
5603 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5604 A goal has a solution if one of its subgoals has a solution.
5605 A goal is unsatisfiable if all subgoals are unsatisfiable.
5606 """
5607
5608 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5609 if z3_debug():
5610 _z3_assert(goal is None or ctx is not None,
5611 "If goal is different from None, then ctx must be also different from None")
5612 self.ctx = _get_ctx(ctx)
5613 self.goal = goal
5614 if self.goal is None:
5615 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5616 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5617
5618 def __del__(self):
5619 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5620 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5621
5622 def depth(self):
5623 """Return the depth of the goal `self`.
5624 The depth corresponds to the number of tactics applied to `self`.
5625
5626 >>> x, y = Ints('x y')
5627 >>> g = Goal()
5628 >>> g.add(x == 0, y >= x + 1)
5629 >>> g.depth()
5630 0
5631 >>> r = Then('simplify', 'solve-eqs')(g)
5632 >>> # r has 1 subgoal
5633 >>> len(r)
5634 1
5635 >>> r[0].depth()
5636 2
5637 """
5638 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5639
5640 def inconsistent(self):
5641 """Return `True` if `self` contains the `False` constraints.
5642
5643 >>> x, y = Ints('x y')
5644 >>> g = Goal()
5645 >>> g.inconsistent()
5646 False
5647 >>> g.add(x == 0, x == 1)
5648 >>> g
5649 [x == 0, x == 1]
5650 >>> g.inconsistent()
5651 False
5652 >>> g2 = Tactic('propagate-values')(g)[0]
5653 >>> g2.inconsistent()
5654 True
5655 """
5656 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5657
5658 def prec(self):
5659 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5660
5661 >>> g = Goal()
5662 >>> g.prec() == Z3_GOAL_PRECISE
5663 True
5664 >>> x, y = Ints('x y')
5665 >>> g.add(x == y + 1)
5666 >>> g.prec() == Z3_GOAL_PRECISE
5667 True
5668 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5669 >>> g2 = t(g)[0]
5670 >>> g2
5671 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5672 >>> g2.prec() == Z3_GOAL_PRECISE
5673 False
5674 >>> g2.prec() == Z3_GOAL_UNDER
5675 True
5676 """
5677 return Z3_goal_precision(self.ctx.ref(), self.goal)
5678
5679 def precision(self):
5680 """Alias for `prec()`.
5681
5682 >>> g = Goal()
5683 >>> g.precision() == Z3_GOAL_PRECISE
5684 True
5685 """
5686 return self.prec()
5687
5688 def size(self):
5689 """Return the number of constraints in the goal `self`.
5690
5691 >>> g = Goal()
5692 >>> g.size()
5693 0
5694 >>> x, y = Ints('x y')
5695 >>> g.add(x == 0, y > x)
5696 >>> g.size()
5697 2
5698 """
5699 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5700
5701 def __len__(self):
5702 """Return the number of constraints in the goal `self`.
5703
5704 >>> g = Goal()
5705 >>> len(g)
5706 0
5707 >>> x, y = Ints('x y')
5708 >>> g.add(x == 0, y > x)
5709 >>> len(g)
5710 2
5711 """
5712 return self.size()
5713
5714 def get(self, i):
5715 """Return a constraint in the goal `self`.
5716
5717 >>> g = Goal()
5718 >>> x, y = Ints('x y')
5719 >>> g.add(x == 0, y > x)
5720 >>> g.get(0)
5721 x == 0
5722 >>> g.get(1)
5723 y > x
5724 """
5725 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5726
5727 def __getitem__(self, arg):
5728 """Return a constraint in the goal `self`.
5729
5730 >>> g = Goal()
5731 >>> x, y = Ints('x y')
5732 >>> g.add(x == 0, y > x)
5733 >>> g[0]
5734 x == 0
5735 >>> g[1]
5736 y > x
5737 """
5738 if arg >= len(self):
5739 raise IndexError
5740 return self.get(arg)
5741
5742 def assert_exprs(self, *args):
5743 """Assert constraints into the goal.
5744
5745 >>> x = Int('x')
5746 >>> g = Goal()
5747 >>> g.assert_exprs(x > 0, x < 2)
5748 >>> g
5749 [x > 0, x < 2]
5750 """
5751 args = _get_args(args)
5752 s = BoolSort(self.ctx)
5753 for arg in args:
5754 arg = s.cast(arg)
5755 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5756
5757 def append(self, *args):
5758 """Add constraints.
5759
5760 >>> x = Int('x')
5761 >>> g = Goal()
5762 >>> g.append(x > 0, x < 2)
5763 >>> g
5764 [x > 0, x < 2]
5765 """
5766 self.assert_exprs(*args)
5767
5768 def insert(self, *args):
5769 """Add constraints.
5770
5771 >>> x = Int('x')
5772 >>> g = Goal()
5773 >>> g.insert(x > 0, x < 2)
5774 >>> g
5775 [x > 0, x < 2]
5776 """
5777 self.assert_exprs(*args)
5778
5779 def add(self, *args):
5780 """Add constraints.
5781
5782 >>> x = Int('x')
5783 >>> g = Goal()
5784 >>> g.add(x > 0, x < 2)
5785 >>> g
5786 [x > 0, x < 2]
5787 """
5788 self.assert_exprs(*args)
5789
5790 def convert_model(self, model):
5791 """Retrieve model from a satisfiable goal
5792 >>> a, b = Ints('a b')
5793 >>> g = Goal()
5794 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5795 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5796 >>> r = t(g)
5797 >>> r[0]
5798 [Or(b == 0, b == 1), Not(0 <= b)]
5799 >>> r[1]
5800 [Or(b == 0, b == 1), Not(1 <= b)]
5801 >>> # Remark: the subgoal r[0] is unsatisfiable
5802 >>> # Creating a solver for solving the second subgoal
5803 >>> s = Solver()
5804 >>> s.add(r[1])
5805 >>> s.check()
5806 sat
5807 >>> s.model()
5808 [b = 0]
5809 >>> # Model s.model() does not assign a value to `a`
5810 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5811 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5812 >>> r[1].convert_model(s.model())
5813 [b = 0, a = 1]
5814 """
5815 if z3_debug():
5816 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5817 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5818
5819 def __repr__(self):
5820 return obj_to_string(self)
5821
5822 def sexpr(self):
5823 """Return a textual representation of the s-expression representing the goal."""
5824 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5825
5826 def dimacs(self, include_names=True):
5827 """Return a textual representation of the goal in DIMACS format."""
5828 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5829
5830 def translate(self, target):
5831 """Copy goal `self` to context `target`.
5832
5833 >>> x = Int('x')
5834 >>> g = Goal()
5835 >>> g.add(x > 10)
5836 >>> g
5837 [x > 10]
5838 >>> c2 = Context()
5839 >>> g2 = g.translate(c2)
5840 >>> g2
5841 [x > 10]
5842 >>> g.ctx == main_ctx()
5843 True
5844 >>> g2.ctx == c2
5845 True
5846 >>> g2.ctx == main_ctx()
5847 False
5848 """
5849 if z3_debug():
5850 _z3_assert(isinstance(target, Context), "target must be a context")
5851 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5852
5853 def __copy__(self):
5854 return self.translate(self.ctx)
5855
5856 def __deepcopy__(self, memo={}):
5857 return self.translate(self.ctx)
5858
5859 def simplify(self, *arguments, **keywords):
5860 """Return a new simplified goal.
5861
5862 This method is essentially invoking the simplify tactic.
5863
5864 >>> g = Goal()
5865 >>> x = Int('x')
5866 >>> g.add(x + 1 >= 2)
5867 >>> g
5868 [x + 1 >= 2]
5869 >>> g2 = g.simplify()
5870 >>> g2
5871 [x >= 1]
5872 >>> # g was not modified
5873 >>> g
5874 [x + 1 >= 2]
5875 """
5876 t = Tactic("simplify")
5877 return t.apply(self, *arguments, **keywords)[0]
5878
5879 def as_expr(self):
5880 """Return goal `self` as a single Z3 expression.
5881
5882 >>> x = Int('x')
5883 >>> g = Goal()
5884 >>> g.as_expr()
5885 True
5886 >>> g.add(x > 1)
5887 >>> g.as_expr()
5888 x > 1
5889 >>> g.add(x < 10)
5890 >>> g.as_expr()
5891 And(x > 1, x < 10)
5892 """
5893 sz = len(self)
5894 if sz == 0:
5895 return BoolVal(True, self.ctx)
5896 elif sz == 1:
5897 return self.get(0)
5898 else:
5899 return And([self.get(i) for i in range(len(self))], self.ctx)
5900
5901
5906
5907
5909 """A collection (vector) of ASTs."""
5910
5911 def __init__(self, v=None, ctx=None):
5912 self.vector = None
5913 if v is None:
5914 self.ctx = _get_ctx(ctx)
5915 self.vector = Z3_mk_ast_vector(self.ctx.ref())
5916 else:
5917 self.vector = v
5918 assert ctx is not None
5919 self.ctx = ctx
5920 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
5921
5922 def __del__(self):
5923 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
5924 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
5925
5926 def __len__(self):
5927 """Return the size of the vector `self`.
5928
5929 >>> A = AstVector()
5930 >>> len(A)
5931 0
5932 >>> A.push(Int('x'))
5933 >>> A.push(Int('x'))
5934 >>> len(A)
5935 2
5936 """
5937 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
5938
5939 def __getitem__(self, i):
5940 """Return the AST at position `i`.
5941
5942 >>> A = AstVector()
5943 >>> A.push(Int('x') + 1)
5944 >>> A.push(Int('y'))
5945 >>> A[0]
5946 x + 1
5947 >>> A[1]
5948 y
5949 """
5950
5951 if isinstance(i, int):
5952 if i < 0:
5953 i += self.__len__()
5954
5955 if i >= self.__len__():
5956 raise IndexError
5957 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
5958
5959 elif isinstance(i, slice):
5960 result = []
5961 for ii in range(*i.indices(self.__len__())):
5962 result.append(_to_ast_ref(
5963 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
5964 self.ctx,
5965 ))
5966 return result
5967
5968 def __setitem__(self, i, v):
5969 """Update AST at position `i`.
5970
5971 >>> A = AstVector()
5972 >>> A.push(Int('x') + 1)
5973 >>> A.push(Int('y'))
5974 >>> A[0]
5975 x + 1
5976 >>> A[0] = Int('x')
5977 >>> A[0]
5978 x
5979 """
5980 if i >= self.__len__():
5981 raise IndexError
5982 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
5983
5984 def push(self, v):
5985 """Add `v` in the end of the vector.
5986
5987 >>> A = AstVector()
5988 >>> len(A)
5989 0
5990 >>> A.push(Int('x'))
5991 >>> len(A)
5992 1
5993 """
5994 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
5995
5996 def resize(self, sz):
5997 """Resize the vector to `sz` elements.
5998
5999 >>> A = AstVector()
6000 >>> A.resize(10)
6001 >>> len(A)
6002 10
6003 >>> for i in range(10): A[i] = Int('x')
6004 >>> A[5]
6005 x
6006 """
6007 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6008
6009 def __contains__(self, item):
6010 """Return `True` if the vector contains `item`.
6011
6012 >>> x = Int('x')
6013 >>> A = AstVector()
6014 >>> x in A
6015 False
6016 >>> A.push(x)
6017 >>> x in A
6018 True
6019 >>> (x+1) in A
6020 False
6021 >>> A.push(x+1)
6022 >>> (x+1) in A
6023 True
6024 >>> A
6025 [x, x + 1]
6026 """
6027 for elem in self:
6028 if elem.eq(item):
6029 return True
6030 return False
6031
6032 def translate(self, other_ctx):
6033 """Copy vector `self` to context `other_ctx`.
6034
6035 >>> x = Int('x')
6036 >>> A = AstVector()
6037 >>> A.push(x)
6038 >>> c2 = Context()
6039 >>> B = A.translate(c2)
6040 >>> B
6041 [x]
6042 """
6043 return AstVector(
6044 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6045 ctx=other_ctx,
6046 )
6047
6048 def __copy__(self):
6049 return self.translate(self.ctx)
6050
6051 def __deepcopy__(self, memo={}):
6052 return self.translate(self.ctx)
6053
6054 def __repr__(self):
6055 return obj_to_string(self)
6056
6057 def sexpr(self):
6058 """Return a textual representation of the s-expression representing the vector."""
6059 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6060
6061
6066
6067
6069 """A mapping from ASTs to ASTs."""
6070
6071 def __init__(self, m=None, ctx=None):
6072 self.map = None
6073 if m is None:
6074 self.ctx = _get_ctx(ctx)
6075 self.map = Z3_mk_ast_map(self.ctx.ref())
6076 else:
6077 self.map = m
6078 assert ctx is not None
6079 self.ctx = ctx
6080 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6081
6082 def __deepcopy__(self, memo={}):
6083 return AstMap(self.map, self.ctx)
6084
6085 def __del__(self):
6086 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6087 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6088
6089 def __len__(self):
6090 """Return the size of the map.
6091
6092 >>> M = AstMap()
6093 >>> len(M)
6094 0
6095 >>> x = Int('x')
6096 >>> M[x] = IntVal(1)
6097 >>> len(M)
6098 1
6099 """
6100 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6101
6102 def __contains__(self, key):
6103 """Return `True` if the map contains key `key`.
6104
6105 >>> M = AstMap()
6106 >>> x = Int('x')
6107 >>> M[x] = x + 1
6108 >>> x in M
6109 True
6110 >>> x+1 in M
6111 False
6112 """
6113 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6114
6115 def __getitem__(self, key):
6116 """Retrieve the value associated with key `key`.
6117
6118 >>> M = AstMap()
6119 >>> x = Int('x')
6120 >>> M[x] = x + 1
6121 >>> M[x]
6122 x + 1
6123 """
6124 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6125
6126 def __setitem__(self, k, v):
6127 """Add/Update key `k` with value `v`.
6128
6129 >>> M = AstMap()
6130 >>> x = Int('x')
6131 >>> M[x] = x + 1
6132 >>> len(M)
6133 1
6134 >>> M[x]
6135 x + 1
6136 >>> M[x] = IntVal(1)
6137 >>> M[x]
6138 1
6139 """
6140 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6141
6142 def __repr__(self):
6143 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6144
6145 def erase(self, k):
6146 """Remove the entry associated with key `k`.
6147
6148 >>> M = AstMap()
6149 >>> x = Int('x')
6150 >>> M[x] = x + 1
6151 >>> len(M)
6152 1
6153 >>> M.erase(x)
6154 >>> len(M)
6155 0
6156 """
6157 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6158
6159 def reset(self):
6160 """Remove all entries from the map.
6161
6162 >>> M = AstMap()
6163 >>> x = Int('x')
6164 >>> M[x] = x + 1
6165 >>> M[x+x] = IntVal(1)
6166 >>> len(M)
6167 2
6168 >>> M.reset()
6169 >>> len(M)
6170 0
6171 """
6172 Z3_ast_map_reset(self.ctx.ref(), self.map)
6173
6174 def keys(self):
6175 """Return an AstVector containing all keys in the map.
6176
6177 >>> M = AstMap()
6178 >>> x = Int('x')
6179 >>> M[x] = x + 1
6180 >>> M[x+x] = IntVal(1)
6181 >>> M.keys()
6182 [x, x + x]
6183 """
6184 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6185
6186
6191
6192
6194 """Store the value of the interpretation of a function in a particular point."""
6195
6196 def __init__(self, entry, ctx):
6197 self.entry = entry
6198 self.ctx = ctx
6199 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6200
6201 def __deepcopy__(self, memo={}):
6202 return FuncEntry(self.entry, self.ctx)
6203
6204 def __del__(self):
6205 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6206 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6207
6208 def num_args(self):
6209 """Return the number of arguments in the given entry.
6210
6211 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6212 >>> s = Solver()
6213 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6214 >>> s.check()
6215 sat
6216 >>> m = s.model()
6217 >>> f_i = m[f]
6218 >>> f_i.num_entries()
6219 1
6220 >>> e = f_i.entry(0)
6221 >>> e.num_args()
6222 2
6223 """
6224 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6225
6226 def arg_value(self, idx):
6227 """Return the value of argument `idx`.
6228
6229 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6230 >>> s = Solver()
6231 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6232 >>> s.check()
6233 sat
6234 >>> m = s.model()
6235 >>> f_i = m[f]
6236 >>> f_i.num_entries()
6237 1
6238 >>> e = f_i.entry(0)
6239 >>> e
6240 [1, 2, 20]
6241 >>> e.num_args()
6242 2
6243 >>> e.arg_value(0)
6244 1
6245 >>> e.arg_value(1)
6246 2
6247 >>> try:
6248 ... e.arg_value(2)
6249 ... except IndexError:
6250 ... print("index error")
6251 index error
6252 """
6253 if idx >= self.num_args():
6254 raise IndexError
6255 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6256
6257 def value(self):
6258 """Return the value of the function at point `self`.
6259
6260 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6261 >>> s = Solver()
6262 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6263 >>> s.check()
6264 sat
6265 >>> m = s.model()
6266 >>> f_i = m[f]
6267 >>> f_i.num_entries()
6268 1
6269 >>> e = f_i.entry(0)
6270 >>> e
6271 [1, 2, 20]
6272 >>> e.num_args()
6273 2
6274 >>> e.value()
6275 20
6276 """
6277 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6278
6279 def as_list(self):
6280 """Return entry `self` as a Python list.
6281 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6282 >>> s = Solver()
6283 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6284 >>> s.check()
6285 sat
6286 >>> m = s.model()
6287 >>> f_i = m[f]
6288 >>> f_i.num_entries()
6289 1
6290 >>> e = f_i.entry(0)
6291 >>> e.as_list()
6292 [1, 2, 20]
6293 """
6294 args = [self.arg_value(i) for i in range(self.num_args())]
6295 args.append(self.value())
6296 return args
6297
6298 def __repr__(self):
6299 return repr(self.as_list())
6300
6301
6303 """Stores the interpretation of a function in a Z3 model."""
6304
6305 def __init__(self, f, ctx):
6306 self.f = f
6307 self.ctx = ctx
6308 if self.f is not None:
6309 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6310
6311 def __del__(self):
6312 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6313 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6314
6315 def else_value(self):
6316 """
6317 Return the `else` value for a function interpretation.
6318 Return None if Z3 did not specify the `else` value for
6319 this object.
6320
6321 >>> f = Function('f', IntSort(), IntSort())
6322 >>> s = Solver()
6323 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6324 >>> s.check()
6325 sat
6326 >>> m = s.model()
6327 >>> m[f]
6328 [2 -> 0, else -> 1]
6329 >>> m[f].else_value()
6330 1
6331 """
6332 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6333 if r:
6334 return _to_expr_ref(r, self.ctx)
6335 else:
6336 return None
6337
6338 def num_entries(self):
6339 """Return the number of entries/points in the function interpretation `self`.
6340
6341 >>> f = Function('f', IntSort(), IntSort())
6342 >>> s = Solver()
6343 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6344 >>> s.check()
6345 sat
6346 >>> m = s.model()
6347 >>> m[f]
6348 [2 -> 0, else -> 1]
6349 >>> m[f].num_entries()
6350 1
6351 """
6352 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6353
6354 def arity(self):
6355 """Return the number of arguments for each entry in the function interpretation `self`.
6356
6357 >>> f = Function('f', IntSort(), IntSort())
6358 >>> s = Solver()
6359 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6360 >>> s.check()
6361 sat
6362 >>> m = s.model()
6363 >>> m[f].arity()
6364 1
6365 """
6366 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6367
6368 def entry(self, idx):
6369 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6370
6371 >>> f = Function('f', IntSort(), IntSort())
6372 >>> s = Solver()
6373 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6374 >>> s.check()
6375 sat
6376 >>> m = s.model()
6377 >>> m[f]
6378 [2 -> 0, else -> 1]
6379 >>> m[f].num_entries()
6380 1
6381 >>> m[f].entry(0)
6382 [2, 0]
6383 """
6384 if idx >= self.num_entries():
6385 raise IndexError
6386 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6387
6388 def translate(self, other_ctx):
6389 """Copy model 'self' to context 'other_ctx'.
6390 """
6391 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6392
6393 def __copy__(self):
6394 return self.translate(self.ctx)
6395
6396 def __deepcopy__(self, memo={}):
6397 return self.translate(self.ctx)
6398
6399 def as_list(self):
6400 """Return the function interpretation as a Python list.
6401 >>> f = Function('f', IntSort(), IntSort())
6402 >>> s = Solver()
6403 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6404 >>> s.check()
6405 sat
6406 >>> m = s.model()
6407 >>> m[f]
6408 [2 -> 0, else -> 1]
6409 >>> m[f].as_list()
6410 [[2, 0], 1]
6411 """
6412 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6413 r.append(self.else_value())
6414 return r
6415
6416 def __repr__(self):
6417 return obj_to_string(self)
6418
6419
6421 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6422
6423 def __init__(self, m, ctx):
6424 assert ctx is not None
6425 self.model = m
6426 self.ctx = ctx
6427 Z3_model_inc_ref(self.ctx.ref(), self.model)
6428
6429 def __del__(self):
6430 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6431 Z3_model_dec_ref(self.ctx.ref(), self.model)
6432
6433 def __repr__(self):
6434 return obj_to_string(self)
6435
6436 def sexpr(self):
6437 """Return a textual representation of the s-expression representing the model."""
6438 return Z3_model_to_string(self.ctx.ref(), self.model)
6439
6440 def eval(self, t, model_completion=False):
6441 """Evaluate the expression `t` in the model `self`.
6442 If `model_completion` is enabled, then a default interpretation is automatically added
6443 for symbols that do not have an interpretation in the model `self`.
6444
6445 >>> x = Int('x')
6446 >>> s = Solver()
6447 >>> s.add(x > 0, x < 2)
6448 >>> s.check()
6449 sat
6450 >>> m = s.model()
6451 >>> m.eval(x + 1)
6452 2
6453 >>> m.eval(x == 1)
6454 True
6455 >>> y = Int('y')
6456 >>> m.eval(y + x)
6457 1 + y
6458 >>> m.eval(y)
6459 y
6460 >>> m.eval(y, model_completion=True)
6461 0
6462 >>> # Now, m contains an interpretation for y
6463 >>> m.eval(y + x)
6464 1
6465 """
6466 r = (Ast * 1)()
6467 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6468 return _to_expr_ref(r[0], self.ctx)
6469 raise Z3Exception("failed to evaluate expression in the model")
6470
6471 def evaluate(self, t, model_completion=False):
6472 """Alias for `eval`.
6473
6474 >>> x = Int('x')
6475 >>> s = Solver()
6476 >>> s.add(x > 0, x < 2)
6477 >>> s.check()
6478 sat
6479 >>> m = s.model()
6480 >>> m.evaluate(x + 1)
6481 2
6482 >>> m.evaluate(x == 1)
6483 True
6484 >>> y = Int('y')
6485 >>> m.evaluate(y + x)
6486 1 + y
6487 >>> m.evaluate(y)
6488 y
6489 >>> m.evaluate(y, model_completion=True)
6490 0
6491 >>> # Now, m contains an interpretation for y
6492 >>> m.evaluate(y + x)
6493 1
6494 """
6495 return self.eval(t, model_completion)
6496
6497 def __len__(self):
6498 """Return the number of constant and function declarations in the model `self`.
6499
6500 >>> f = Function('f', IntSort(), IntSort())
6501 >>> x = Int('x')
6502 >>> s = Solver()
6503 >>> s.add(x > 0, f(x) != x)
6504 >>> s.check()
6505 sat
6506 >>> m = s.model()
6507 >>> len(m)
6508 2
6509 """
6510 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6511 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6512 return num_consts + num_funcs
6513
6514 def get_interp(self, decl):
6515 """Return the interpretation for a given declaration or constant.
6516
6517 >>> f = Function('f', IntSort(), IntSort())
6518 >>> x = Int('x')
6519 >>> s = Solver()
6520 >>> s.add(x > 0, x < 2, f(x) == 0)
6521 >>> s.check()
6522 sat
6523 >>> m = s.model()
6524 >>> m[x]
6525 1
6526 >>> m[f]
6527 [else -> 0]
6528 """
6529 if z3_debug():
6530 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6531 if is_const(decl):
6532 decl = decl.decl()
6533 try:
6534 if decl.arity() == 0:
6535 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6536 if _r.value is None:
6537 return None
6538 r = _to_expr_ref(_r, self.ctx)
6539 if is_as_array(r):
6540 fi = self.get_interp(get_as_array_func(r))
6541 if fi is None:
6542 return fi
6543 e = fi.else_value()
6544 if e is None:
6545 return fi
6546 if fi.arity() != 1:
6547 return fi
6548 srt = decl.range()
6549 dom = srt.domain()
6550 e = K(dom, e)
6551 i = 0
6552 sz = fi.num_entries()
6553 n = fi.arity()
6554 while i < sz:
6555 fe = fi.entry(i)
6556 e = Store(e, fe.arg_value(0), fe.value())
6557 i += 1
6558 return e
6559 else:
6560 return r
6561 else:
6562 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6563 except Z3Exception:
6564 return None
6565
6566 def num_sorts(self):
6567 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6568
6569 >>> A = DeclareSort('A')
6570 >>> a, b = Consts('a b', A)
6571 >>> s = Solver()
6572 >>> s.add(a != b)
6573 >>> s.check()
6574 sat
6575 >>> m = s.model()
6576 >>> m.num_sorts()
6577 1
6578 """
6579 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6580
6581 def get_sort(self, idx):
6582 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6583
6584 >>> A = DeclareSort('A')
6585 >>> B = DeclareSort('B')
6586 >>> a1, a2 = Consts('a1 a2', A)
6587 >>> b1, b2 = Consts('b1 b2', B)
6588 >>> s = Solver()
6589 >>> s.add(a1 != a2, b1 != b2)
6590 >>> s.check()
6591 sat
6592 >>> m = s.model()
6593 >>> m.num_sorts()
6594 2
6595 >>> m.get_sort(0)
6596 A
6597 >>> m.get_sort(1)
6598 B
6599 """
6600 if idx >= self.num_sorts():
6601 raise IndexError
6602 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6603
6604 def sorts(self):
6605 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6606
6607 >>> A = DeclareSort('A')
6608 >>> B = DeclareSort('B')
6609 >>> a1, a2 = Consts('a1 a2', A)
6610 >>> b1, b2 = Consts('b1 b2', B)
6611 >>> s = Solver()
6612 >>> s.add(a1 != a2, b1 != b2)
6613 >>> s.check()
6614 sat
6615 >>> m = s.model()
6616 >>> m.sorts()
6617 [A, B]
6618 """
6619 return [self.get_sort(i) for i in range(self.num_sorts())]
6620
6621 def get_universe(self, s):
6622 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6623
6624 >>> A = DeclareSort('A')
6625 >>> a, b = Consts('a b', A)
6626 >>> s = Solver()
6627 >>> s.add(a != b)
6628 >>> s.check()
6629 sat
6630 >>> m = s.model()
6631 >>> m.get_universe(A)
6632 [A!val!1, A!val!0]
6633 """
6634 if z3_debug():
6635 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6636 try:
6637 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6638 except Z3Exception:
6639 return None
6640
6641 def __getitem__(self, idx):
6642 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6643 If `idx` is a declaration, then the actual interpretation is returned.
6644
6645 The elements can be retrieved using position or the actual declaration.
6646
6647 >>> f = Function('f', IntSort(), IntSort())
6648 >>> x = Int('x')
6649 >>> s = Solver()
6650 >>> s.add(x > 0, x < 2, f(x) == 0)
6651 >>> s.check()
6652 sat
6653 >>> m = s.model()
6654 >>> len(m)
6655 2
6656 >>> m[0]
6657 x
6658 >>> m[1]
6659 f
6660 >>> m[x]
6661 1
6662 >>> m[f]
6663 [else -> 0]
6664 >>> for d in m: print("%s -> %s" % (d, m[d]))
6665 x -> 1
6666 f -> [else -> 0]
6667 """
6668 if _is_int(idx):
6669 if idx >= len(self):
6670 raise IndexError
6671 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6672 if (idx < num_consts):
6673 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6674 else:
6675 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6676 if isinstance(idx, FuncDeclRef):
6677 return self.get_interp(idx)
6678 if is_const(idx):
6679 return self.get_interp(idx.decl())
6680 if isinstance(idx, SortRef):
6681 return self.get_universe(idx)
6682 if z3_debug():
6683 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6684 return None
6685
6686 def decls(self):
6687 """Return a list with all symbols that have an interpretation in the model `self`.
6688 >>> f = Function('f', IntSort(), IntSort())
6689 >>> x = Int('x')
6690 >>> s = Solver()
6691 >>> s.add(x > 0, x < 2, f(x) == 0)
6692 >>> s.check()
6693 sat
6694 >>> m = s.model()
6695 >>> m.decls()
6696 [x, f]
6697 """
6698 r = []
6699 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6700 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6701 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6702 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6703 return r
6704
6705 def update_value(self, x, value):
6706 """Update the interpretation of a constant"""
6707 if is_expr(x):
6708 x = x.decl()
6709 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6710 fi1 = value.f
6711 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6712 fi2 = FuncInterp(fi2, x.ctx)
6713 for i in range(value.num_entries()):
6714 e = value.entry(i)
6715 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6716 v = AstVector()
6717 for j in range(n):
6718 v.push(e.arg_value(j))
6719 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6720 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6721 return
6722 if not is_func_decl(x) or x.arity() != 0:
6723 raise Z3Exception("Expecting 0-ary function or constant expression")
6724 value = _py2expr(value)
6725 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6726
6727 def translate(self, target):
6728 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6729 """
6730 if z3_debug():
6731 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6732 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6733 return ModelRef(model, target)
6734
6735 def project(self, vars, fml):
6736 """Perform model-based projection on fml with respect to vars.
6737 Assume that the model satisfies fml. Then compute a projection fml_p, such
6738 that vars do not occur free in fml_p, fml_p is true in the model and
6739 fml_p => exists vars . fml
6740 """
6741 ctx = self.ctx.ref()
6742 _vars = (Ast * len(vars))()
6743 for i in range(len(vars)):
6744 _vars[i] = vars[i].as_ast()
6745 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6746
6747 def project_with_witness(self, vars, fml):
6748 """Perform model-based projection, but also include realizer terms for the projected variables"""
6749 ctx = self.ctx.ref()
6750 _vars = (Ast * len(vars))()
6751 for i in range(len(vars)):
6752 _vars[i] = vars[i].as_ast()
6753 defs = AstMap()
6754 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6755 result = _to_expr_ref(result, self.ctx)
6756 return result, defs
6757
6758
6759 def __copy__(self):
6760 return self.translate(self.ctx)
6761
6762 def __deepcopy__(self, memo={}):
6763 return self.translate(self.ctx)
6764
6765
6766def Model(ctx=None, eval = {}):
6767 ctx = _get_ctx(ctx)
6768 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6769 for k, v in eval.items():
6770 mdl.update_value(k, v)
6771 return mdl
6772
6773
6775 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6776 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6777
6778
6780 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6781 if z3_debug():
6782 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6783 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6784
6785
6790
6791
6793 """Statistics for `Solver.check()`."""
6794
6795 def __init__(self, stats, ctx):
6796 self.stats = stats
6797 self.ctx = ctx
6798 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6799
6800 def __deepcopy__(self, memo={}):
6801 return Statistics(self.stats, self.ctx)
6802
6803 def __del__(self):
6804 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6805 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6806
6807 def __repr__(self):
6808 if in_html_mode():
6809 out = io.StringIO()
6810 even = True
6811 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6812 for k, v in self:
6813 if even:
6814 out.write(u('<tr style="background-color:#CFCFCF">'))
6815 even = False
6816 else:
6817 out.write(u("<tr>"))
6818 even = True
6819 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6820 out.write(u("</table>"))
6821 return out.getvalue()
6822 else:
6823 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6824
6825 def __len__(self):
6826 """Return the number of statistical counters.
6827
6828 >>> x = Int('x')
6829 >>> s = Then('simplify', 'nlsat').solver()
6830 >>> s.add(x > 0)
6831 >>> s.check()
6832 sat
6833 >>> st = s.statistics()
6834 >>> len(st)
6835 7
6836 """
6837 return int(Z3_stats_size(self.ctx.ref(), self.stats))
6838
6839 def __getitem__(self, idx):
6840 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6841
6842 >>> x = Int('x')
6843 >>> s = Then('simplify', 'nlsat').solver()
6844 >>> s.add(x > 0)
6845 >>> s.check()
6846 sat
6847 >>> st = s.statistics()
6848 >>> len(st)
6849 7
6850 >>> st[0]
6851 ('nlsat propagations', 2)
6852 >>> st[1]
6853 ('nlsat restarts', 1)
6854 """
6855 if idx >= len(self):
6856 raise IndexError
6857 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6858 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6859 else:
6860 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6861 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
6862
6863 def keys(self):
6864 """Return the list of statistical counters.
6865
6866 >>> x = Int('x')
6867 >>> s = Then('simplify', 'nlsat').solver()
6868 >>> s.add(x > 0)
6869 >>> s.check()
6870 sat
6871 >>> st = s.statistics()
6872 """
6873 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
6874
6875 def get_key_value(self, key):
6876 """Return the value of a particular statistical counter.
6877
6878 >>> x = Int('x')
6879 >>> s = Then('simplify', 'nlsat').solver()
6880 >>> s.add(x > 0)
6881 >>> s.check()
6882 sat
6883 >>> st = s.statistics()
6884 >>> st.get_key_value('nlsat propagations')
6885 2
6886 """
6887 for idx in range(len(self)):
6888 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
6889 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6890 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6891 else:
6892 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6893 raise Z3Exception("unknown key")
6894
6895 def __getattr__(self, name):
6896 """Access the value of statistical using attributes.
6897
6898 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
6899 we should use '_' (e.g., 'nlsat_propagations').
6900
6901 >>> x = Int('x')
6902 >>> s = Then('simplify', 'nlsat').solver()
6903 >>> s.add(x > 0)
6904 >>> s.check()
6905 sat
6906 >>> st = s.statistics()
6907 >>> st.nlsat_propagations
6908 2
6909 >>> st.nlsat_stages
6910 2
6911 """
6912 key = name.replace("_", " ")
6913 try:
6914 return self.get_key_value(key)
6915 except Z3Exception:
6916 raise AttributeError
6917
6918
6923
6924
6926 """Represents the result of a satisfiability check: sat, unsat, unknown.
6927
6928 >>> s = Solver()
6929 >>> s.check()
6930 sat
6931 >>> r = s.check()
6932 >>> isinstance(r, CheckSatResult)
6933 True
6934 """
6935
6936 def __init__(self, r):
6937 self.r = r
6938
6939 def __deepcopy__(self, memo={}):
6940 return CheckSatResult(self.r)
6941
6942 def __eq__(self, other):
6943 return isinstance(other, CheckSatResult) and self.r == other.r
6944
6945 def __ne__(self, other):
6946 return not self.__eq__(other)
6947
6948 def __repr__(self):
6949 if in_html_mode():
6950 if self.r == Z3_L_TRUE:
6951 return "<b>sat</b>"
6952 elif self.r == Z3_L_FALSE:
6953 return "<b>unsat</b>"
6954 else:
6955 return "<b>unknown</b>"
6956 else:
6957 if self.r == Z3_L_TRUE:
6958 return "sat"
6959 elif self.r == Z3_L_FALSE:
6960 return "unsat"
6961 else:
6962 return "unknown"
6963
6964 def _repr_html_(self):
6965 in_html = in_html_mode()
6966 set_html_mode(True)
6967 res = repr(self)
6968 set_html_mode(in_html)
6969 return res
6970
6971
6972sat = CheckSatResult(Z3_L_TRUE)
6973unsat = CheckSatResult(Z3_L_FALSE)
6974unknown = CheckSatResult(Z3_L_UNDEF)
6975
6976
6978 """
6979 Solver API provides methods for implementing the main SMT 2.0 commands:
6980 push, pop, check, get-model, etc.
6981 """
6982
6983 def __init__(self, solver=None, ctx=None, logFile=None):
6984 assert solver is None or ctx is not None
6985 self.ctx = _get_ctx(ctx)
6986 self.backtrack_level = 4000000000
6987 self.solver = None
6988 if solver is None:
6989 self.solver = Z3_mk_solver(self.ctx.ref())
6990 else:
6991 self.solver = solver
6992 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
6993 if logFile is not None:
6994 self.set("smtlib2_log", logFile)
6995
6996 def __del__(self):
6997 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
6998 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
6999
7000 def __enter__(self):
7001 self.push()
7002 return self
7003
7004 def __exit__(self, *exc_info):
7005 self.pop()
7006
7007 def set(self, *args, **keys):
7008 """Set a configuration option.
7009 The method `help()` return a string containing all available options.
7010
7011 >>> s = Solver()
7012 >>> # The option MBQI can be set using three different approaches.
7013 >>> s.set(mbqi=True)
7014 >>> s.set('MBQI', True)
7015 >>> s.set(':mbqi', True)
7016 """
7017 p = args2params(args, keys, self.ctx)
7018 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7019
7020 def push(self):
7021 """Create a backtracking point.
7022
7023 >>> x = Int('x')
7024 >>> s = Solver()
7025 >>> s.add(x > 0)
7026 >>> s
7027 [x > 0]
7028 >>> s.push()
7029 >>> s.add(x < 1)
7030 >>> s
7031 [x > 0, x < 1]
7032 >>> s.check()
7033 unsat
7034 >>> s.pop()
7035 >>> s.check()
7036 sat
7037 >>> s
7038 [x > 0]
7039 """
7040 Z3_solver_push(self.ctx.ref(), self.solver)
7041
7042 def pop(self, num=1):
7043 """Backtrack \\c num backtracking points.
7044
7045 >>> x = Int('x')
7046 >>> s = Solver()
7047 >>> s.add(x > 0)
7048 >>> s
7049 [x > 0]
7050 >>> s.push()
7051 >>> s.add(x < 1)
7052 >>> s
7053 [x > 0, x < 1]
7054 >>> s.check()
7055 unsat
7056 >>> s.pop()
7057 >>> s.check()
7058 sat
7059 >>> s
7060 [x > 0]
7061 """
7062 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7063
7064 def num_scopes(self):
7065 """Return the current number of backtracking points.
7066
7067 >>> s = Solver()
7068 >>> s.num_scopes()
7069 0
7070 >>> s.push()
7071 >>> s.num_scopes()
7072 1
7073 >>> s.push()
7074 >>> s.num_scopes()
7075 2
7076 >>> s.pop()
7077 >>> s.num_scopes()
7078 1
7079 """
7080 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7081
7082 def reset(self):
7083 """Remove all asserted constraints and backtracking points created using `push()`.
7084
7085 >>> x = Int('x')
7086 >>> s = Solver()
7087 >>> s.add(x > 0)
7088 >>> s
7089 [x > 0]
7090 >>> s.reset()
7091 >>> s
7092 []
7093 """
7094 Z3_solver_reset(self.ctx.ref(), self.solver)
7095
7096 def assert_exprs(self, *args):
7097 """Assert constraints into the solver.
7098
7099 >>> x = Int('x')
7100 >>> s = Solver()
7101 >>> s.assert_exprs(x > 0, x < 2)
7102 >>> s
7103 [x > 0, x < 2]
7104 """
7105 args = _get_args(args)
7106 s = BoolSort(self.ctx)
7107 for arg in args:
7108 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7109 for f in arg:
7110 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7111 else:
7112 arg = s.cast(arg)
7113 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7114
7115 def add(self, *args):
7116 """Assert constraints into the solver.
7117
7118 >>> x = Int('x')
7119 >>> s = Solver()
7120 >>> s.add(x > 0, x < 2)
7121 >>> s
7122 [x > 0, x < 2]
7123 """
7124 self.assert_exprs(*args)
7125
7126 def __iadd__(self, fml):
7127 self.add(fml)
7128 return self
7129
7130 def append(self, *args):
7131 """Assert constraints into the solver.
7132
7133 >>> x = Int('x')
7134 >>> s = Solver()
7135 >>> s.append(x > 0, x < 2)
7136 >>> s
7137 [x > 0, x < 2]
7138 """
7139 self.assert_exprs(*args)
7140
7141 def insert(self, *args):
7142 """Assert constraints into the solver.
7143
7144 >>> x = Int('x')
7145 >>> s = Solver()
7146 >>> s.insert(x > 0, x < 2)
7147 >>> s
7148 [x > 0, x < 2]
7149 """
7150 self.assert_exprs(*args)
7151
7152 def assert_and_track(self, a, p):
7153 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7154
7155 If `p` is a string, it will be automatically converted into a Boolean constant.
7156
7157 >>> x = Int('x')
7158 >>> p3 = Bool('p3')
7159 >>> s = Solver()
7160 >>> s.set(unsat_core=True)
7161 >>> s.assert_and_track(x > 0, 'p1')
7162 >>> s.assert_and_track(x != 1, 'p2')
7163 >>> s.assert_and_track(x < 0, p3)
7164 >>> print(s.check())
7165 unsat
7166 >>> c = s.unsat_core()
7167 >>> len(c)
7168 2
7169 >>> Bool('p1') in c
7170 True
7171 >>> Bool('p2') in c
7172 False
7173 >>> p3 in c
7174 True
7175 """
7176 if isinstance(p, str):
7177 p = Bool(p, self.ctx)
7178 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7179 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7180 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7181
7182 def check(self, *assumptions):
7183 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7184
7185 >>> x = Int('x')
7186 >>> s = Solver()
7187 >>> s.check()
7188 sat
7189 >>> s.add(x > 0, x < 2)
7190 >>> s.check()
7191 sat
7192 >>> s.model().eval(x)
7193 1
7194 >>> s.add(x < 1)
7195 >>> s.check()
7196 unsat
7197 >>> s.reset()
7198 >>> s.add(2**x == 4)
7199 >>> s.check()
7200 unknown
7201 """
7202 s = BoolSort(self.ctx)
7203 assumptions = _get_args(assumptions)
7204 num = len(assumptions)
7205 _assumptions = (Ast * num)()
7206 for i in range(num):
7207 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7208 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7209 return CheckSatResult(r)
7210
7211 def model(self):
7212 """Return a model for the last `check()`.
7213
7214 This function raises an exception if
7215 a model is not available (e.g., last `check()` returned unsat).
7216
7217 >>> s = Solver()
7218 >>> a = Int('a')
7219 >>> s.add(a + 2 == 0)
7220 >>> s.check()
7221 sat
7222 >>> s.model()
7223 [a = -2]
7224 """
7225 try:
7226 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7227 except Z3Exception:
7228 raise Z3Exception("model is not available")
7229
7230 def import_model_converter(self, other):
7231 """Import model converter from other into the current solver"""
7232 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7233
7234 def interrupt(self):
7235 """Interrupt the execution of the solver object.
7236 Remarks: This ensures that the interrupt applies only
7237 to the given solver object and it applies only if it is running.
7238 """
7239 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7240
7241 def unsat_core(self):
7242 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7243
7244 These are the assumptions Z3 used in the unsatisfiability proof.
7245 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7246 They may be also used to "retract" assumptions. Note that, assumptions are not really
7247 "soft constraints", but they can be used to implement them.
7248
7249 >>> p1, p2, p3 = Bools('p1 p2 p3')
7250 >>> x, y = Ints('x y')
7251 >>> s = Solver()
7252 >>> s.add(Implies(p1, x > 0))
7253 >>> s.add(Implies(p2, y > x))
7254 >>> s.add(Implies(p2, y < 1))
7255 >>> s.add(Implies(p3, y > -3))
7256 >>> s.check(p1, p2, p3)
7257 unsat
7258 >>> core = s.unsat_core()
7259 >>> len(core)
7260 2
7261 >>> p1 in core
7262 True
7263 >>> p2 in core
7264 True
7265 >>> p3 in core
7266 False
7267 >>> # "Retracting" p2
7268 >>> s.check(p1, p3)
7269 sat
7270 """
7271 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7272
7273 def consequences(self, assumptions, variables):
7274 """Determine fixed values for the variables based on the solver state and assumptions.
7275 >>> s = Solver()
7276 >>> a, b, c, d = Bools('a b c d')
7277 >>> s.add(Implies(a,b), Implies(b, c))
7278 >>> s.consequences([a],[b,c,d])
7279 (sat, [Implies(a, b), Implies(a, c)])
7280 >>> s.consequences([Not(c),d],[a,b,c,d])
7281 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7282 """
7283 if isinstance(assumptions, list):
7284 _asms = AstVector(None, self.ctx)
7285 for a in assumptions:
7286 _asms.push(a)
7287 assumptions = _asms
7288 if isinstance(variables, list):
7289 _vars = AstVector(None, self.ctx)
7290 for a in variables:
7291 _vars.push(a)
7292 variables = _vars
7293 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7294 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7295 consequences = AstVector(None, self.ctx)
7296 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7297 variables.vector, consequences.vector)
7298 sz = len(consequences)
7299 consequences = [consequences[i] for i in range(sz)]
7300 return CheckSatResult(r), consequences
7301
7302 def from_file(self, filename):
7303 """Parse assertions from a file"""
7304 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7305
7306 def from_string(self, s):
7307 """Parse assertions from a string"""
7308 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7309
7310 def cube(self, vars=None):
7311 """Get set of cubes
7312 The method takes an optional set of variables that restrict which
7313 variables may be used as a starting point for cubing.
7314 If vars is not None, then the first case split is based on a variable in
7315 this set.
7316 """
7317 self.cube_vs = AstVector(None, self.ctx)
7318 if vars is not None:
7319 for v in vars:
7320 self.cube_vs.push(v)
7321 while True:
7322 lvl = self.backtrack_level
7323 self.backtrack_level = 4000000000
7324 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7325 if (len(r) == 1 and is_false(r[0])):
7326 return
7327 yield r
7328 if (len(r) == 0):
7329 return
7330
7331 def cube_vars(self):
7332 """Access the set of variables that were touched by the most recently generated cube.
7333 This set of variables can be used as a starting point for additional cubes.
7334 The idea is that variables that appear in clauses that are reduced by the most recent
7335 cube are likely more useful to cube on."""
7336 return self.cube_vs
7337
7338 def root(self, t):
7339 t = _py2expr(t, self.ctx)
7340 """Retrieve congruence closure root of the term t relative to the current search state
7341 The function primarily works for SimpleSolver. Terms and variables that are
7342 eliminated during pre-processing are not visible to the congruence closure.
7343 """
7344 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7345
7346 def next(self, t):
7347 t = _py2expr(t, self.ctx)
7348 """Retrieve congruence closure sibling of the term t relative to the current search state
7349 The function primarily works for SimpleSolver. Terms and variables that are
7350 eliminated during pre-processing are not visible to the congruence closure.
7351 """
7352 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7353
7354 def solve_for(self, t):
7355 t = _py2expr(t, self.ctx)
7356 """Retrieve a solution for t relative to linear equations maintained in the current state.
7357 The function primarily works for SimpleSolver and when there is a solution using linear arithmetic."""
7358 return _to_expr_ref(Z3_solver_solve_for(self.ctx.ref(), self.solver, t.ast), self.ctx)
7359
7360 def proof(self):
7361 """Return a proof for the last `check()`. Proof construction must be enabled."""
7362 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7363
7364 def assertions(self):
7365 """Return an AST vector containing all added constraints.
7366
7367 >>> s = Solver()
7368 >>> s.assertions()
7369 []
7370 >>> a = Int('a')
7371 >>> s.add(a > 0)
7372 >>> s.add(a < 10)
7373 >>> s.assertions()
7374 [a > 0, a < 10]
7375 """
7376 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7377
7378 def units(self):
7379 """Return an AST vector containing all currently inferred units.
7380 """
7381 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7382
7383 def non_units(self):
7384 """Return an AST vector containing all atomic formulas in solver state that are not units.
7385 """
7386 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7387
7388 def trail_levels(self):
7389 """Return trail and decision levels of the solver state after a check() call.
7390 """
7391 trail = self.trail()
7392 levels = (ctypes.c_uint * len(trail))()
7393 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7394 return trail, levels
7395
7396 def set_initial_value(self, var, value):
7397 """initialize the solver's state by setting the initial value of var to value
7398 """
7399 s = var.sort()
7400 value = s.cast(value)
7401 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7402
7403 def trail(self):
7404 """Return trail of the solver state after a check() call.
7405 """
7406 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7407
7408 def statistics(self):
7409 """Return statistics for the last `check()`.
7410
7411 >>> s = SimpleSolver()
7412 >>> x = Int('x')
7413 >>> s.add(x > 0)
7414 >>> s.check()
7415 sat
7416 >>> st = s.statistics()
7417 >>> st.get_key_value('final checks')
7418 1
7419 >>> len(st) > 0
7420 True
7421 >>> st[0] != 0
7422 True
7423 """
7424 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7425
7426 def reason_unknown(self):
7427 """Return a string describing why the last `check()` returned `unknown`.
7428
7429 >>> x = Int('x')
7430 >>> s = SimpleSolver()
7431 >>> s.add(2**x == 4)
7432 >>> s.check()
7433 unknown
7434 >>> s.reason_unknown()
7435 '(incomplete (theory arithmetic))'
7436 """
7437 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7438
7439 def help(self):
7440 """Display a string describing all available options."""
7441 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7442
7443 def param_descrs(self):
7444 """Return the parameter description set."""
7445 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7446
7447 def __repr__(self):
7448 """Return a formatted string with all added constraints."""
7449 return obj_to_string(self)
7450
7451 def translate(self, target):
7452 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7453
7454 >>> c1 = Context()
7455 >>> c2 = Context()
7456 >>> s1 = Solver(ctx=c1)
7457 >>> s2 = s1.translate(c2)
7458 """
7459 if z3_debug():
7460 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7461 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7462 return Solver(solver, target)
7463
7464 def __copy__(self):
7465 return self.translate(self.ctx)
7466
7467 def __deepcopy__(self, memo={}):
7468 return self.translate(self.ctx)
7469
7470 def sexpr(self):
7471 """Return a formatted string (in Lisp-like format) with all added constraints.
7472 We say the string is in s-expression format.
7473
7474 >>> x = Int('x')
7475 >>> s = Solver()
7476 >>> s.add(x > 0)
7477 >>> s.add(x < 2)
7478 >>> r = s.sexpr()
7479 """
7480 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7481
7482 def dimacs(self, include_names=True):
7483 """Return a textual representation of the solver in DIMACS format."""
7484 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7485
7486 def to_smt2(self):
7487 """return SMTLIB2 formatted benchmark for solver's assertions"""
7488 es = self.assertions()
7489 sz = len(es)
7490 sz1 = sz
7491 if sz1 > 0:
7492 sz1 -= 1
7493 v = (Ast * sz1)()
7494 for i in range(sz1):
7495 v[i] = es[i].as_ast()
7496 if sz > 0:
7497 e = es[sz1].as_ast()
7498 else:
7499 e = BoolVal(True, self.ctx).as_ast()
7500 return Z3_benchmark_to_smtlib_string(
7501 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7502 )
7503
7504
7505def SolverFor(logic, ctx=None, logFile=None):
7506 """Create a solver customized for the given logic.
7507
7508 The parameter `logic` is a string. It should be contains
7509 the name of a SMT-LIB logic.
7510 See http://www.smtlib.org/ for the name of all available logics.
7511
7512 >>> s = SolverFor("QF_LIA")
7513 >>> x = Int('x')
7514 >>> s.add(x > 0)
7515 >>> s.add(x < 2)
7516 >>> s.check()
7517 sat
7518 >>> s.model()
7519 [x = 1]
7520 """
7521 ctx = _get_ctx(ctx)
7522 logic = to_symbol(logic)
7523 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7524
7525
7526def SimpleSolver(ctx=None, logFile=None):
7527 """Return a simple general purpose solver with limited amount of preprocessing.
7528
7529 >>> s = SimpleSolver()
7530 >>> x = Int('x')
7531 >>> s.add(x > 0)
7532 >>> s.check()
7533 sat
7534 """
7535 ctx = _get_ctx(ctx)
7536 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7537
7538#########################################
7539#
7540# Fixedpoint
7541#
7542#########################################
7543
7544
7545class Fixedpoint(Z3PPObject):
7546 """Fixedpoint API provides methods for solving with recursive predicates"""
7547
7548 def __init__(self, fixedpoint=None, ctx=None):
7549 assert fixedpoint is None or ctx is not None
7550 self.ctx = _get_ctx(ctx)
7551 self.fixedpoint = None
7552 if fixedpoint is None:
7553 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7554 else:
7555 self.fixedpoint = fixedpoint
7556 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7557 self.vars = []
7558
7559 def __deepcopy__(self, memo={}):
7560 return FixedPoint(self.fixedpoint, self.ctx)
7561
7562 def __del__(self):
7563 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7564 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7565
7566 def set(self, *args, **keys):
7567 """Set a configuration option. The method `help()` return a string containing all available options.
7568 """
7569 p = args2params(args, keys, self.ctx)
7570 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7571
7572 def help(self):
7573 """Display a string describing all available options."""
7574 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7575
7576 def param_descrs(self):
7577 """Return the parameter description set."""
7578 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7579
7580 def assert_exprs(self, *args):
7581 """Assert constraints as background axioms for the fixedpoint solver."""
7582 args = _get_args(args)
7583 s = BoolSort(self.ctx)
7584 for arg in args:
7585 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7586 for f in arg:
7587 f = self.abstract(f)
7588 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7589 else:
7590 arg = s.cast(arg)
7591 arg = self.abstract(arg)
7592 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7593
7594 def add(self, *args):
7595 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7596 self.assert_exprs(*args)
7597
7598 def __iadd__(self, fml):
7599 self.add(fml)
7600 return self
7601
7602 def append(self, *args):
7603 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7604 self.assert_exprs(*args)
7605
7606 def insert(self, *args):
7607 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7608 self.assert_exprs(*args)
7609
7610 def add_rule(self, head, body=None, name=None):
7611 """Assert rules defining recursive predicates to the fixedpoint solver.
7612 >>> a = Bool('a')
7613 >>> b = Bool('b')
7614 >>> s = Fixedpoint()
7615 >>> s.register_relation(a.decl())
7616 >>> s.register_relation(b.decl())
7617 >>> s.fact(a)
7618 >>> s.rule(b, a)
7619 >>> s.query(b)
7620 sat
7621 """
7622 if name is None:
7623 name = ""
7624 name = to_symbol(name, self.ctx)
7625 if body is None:
7626 head = self.abstract(head)
7627 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7628 else:
7629 body = _get_args(body)
7630 f = self.abstract(Implies(And(body, self.ctx), head))
7631 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7632
7633 def rule(self, head, body=None, name=None):
7634 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7635 self.add_rule(head, body, name)
7636
7637 def fact(self, head, name=None):
7638 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7639 self.add_rule(head, None, name)
7640
7641 def query(self, *query):
7642 """Query the fixedpoint engine whether formula is derivable.
7643 You can also pass an tuple or list of recursive predicates.
7644 """
7645 query = _get_args(query)
7646 sz = len(query)
7647 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7648 _decls = (FuncDecl * sz)()
7649 i = 0
7650 for q in query:
7651 _decls[i] = q.ast
7652 i = i + 1
7653 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7654 else:
7655 if sz == 1:
7656 query = query[0]
7657 else:
7658 query = And(query, self.ctx)
7659 query = self.abstract(query, False)
7660 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7661 return CheckSatResult(r)
7662
7663 def query_from_lvl(self, lvl, *query):
7664 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7665 """
7666 query = _get_args(query)
7667 sz = len(query)
7668 if sz >= 1 and isinstance(query[0], FuncDecl):
7669 _z3_assert(False, "unsupported")
7670 else:
7671 if sz == 1:
7672 query = query[0]
7673 else:
7674 query = And(query)
7675 query = self.abstract(query, False)
7676 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7677 return CheckSatResult(r)
7678
7679 def update_rule(self, head, body, name):
7680 """update rule"""
7681 if name is None:
7682 name = ""
7683 name = to_symbol(name, self.ctx)
7684 body = _get_args(body)
7685 f = self.abstract(Implies(And(body, self.ctx), head))
7686 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7687
7688 def get_answer(self):
7689 """Retrieve answer from last query call."""
7690 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7691 return _to_expr_ref(r, self.ctx)
7692
7693 def get_ground_sat_answer(self):
7694 """Retrieve a ground cex from last query call."""
7695 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7696 return _to_expr_ref(r, self.ctx)
7697
7698 def get_rules_along_trace(self):
7699 """retrieve rules along the counterexample trace"""
7700 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7701
7702 def get_rule_names_along_trace(self):
7703 """retrieve rule names along the counterexample trace"""
7704 # this is a hack as I don't know how to return a list of symbols from C++;
7705 # obtain names as a single string separated by semicolons
7706 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7707 # split into individual names
7708 return names.split(";")
7709
7710 def get_num_levels(self, predicate):
7711 """Retrieve number of levels used for predicate in PDR engine"""
7712 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7713
7714 def get_cover_delta(self, level, predicate):
7715 """Retrieve properties known about predicate for the level'th unfolding.
7716 -1 is treated as the limit (infinity)
7717 """
7718 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7719 return _to_expr_ref(r, self.ctx)
7720
7721 def add_cover(self, level, predicate, property):
7722 """Add property to predicate for the level'th unfolding.
7723 -1 is treated as infinity (infinity)
7724 """
7725 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7726
7727 def register_relation(self, *relations):
7728 """Register relation as recursive"""
7729 relations = _get_args(relations)
7730 for f in relations:
7731 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7732
7733 def set_predicate_representation(self, f, *representations):
7734 """Control how relation is represented"""
7735 representations = _get_args(representations)
7736 representations = [to_symbol(s) for s in representations]
7737 sz = len(representations)
7738 args = (Symbol * sz)()
7739 for i in range(sz):
7740 args[i] = representations[i]
7741 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7742
7743 def parse_string(self, s):
7744 """Parse rules and queries from a string"""
7745 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7746
7747 def parse_file(self, f):
7748 """Parse rules and queries from a file"""
7749 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7750
7751 def get_rules(self):
7752 """retrieve rules that have been added to fixedpoint context"""
7753 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7754
7755 def get_assertions(self):
7756 """retrieve assertions that have been added to fixedpoint context"""
7757 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7758
7759 def __repr__(self):
7760 """Return a formatted string with all added rules and constraints."""
7761 return self.sexpr()
7762
7763 def sexpr(self):
7764 """Return a formatted string (in Lisp-like format) with all added constraints.
7765 We say the string is in s-expression format.
7766 """
7767 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7768
7769 def to_string(self, queries):
7770 """Return a formatted string (in Lisp-like format) with all added constraints.
7771 We say the string is in s-expression format.
7772 Include also queries.
7773 """
7774 args, len = _to_ast_array(queries)
7775 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7776
7777 def statistics(self):
7778 """Return statistics for the last `query()`.
7779 """
7780 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7781
7782 def reason_unknown(self):
7783 """Return a string describing why the last `query()` returned `unknown`.
7784 """
7785 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7786
7787 def declare_var(self, *vars):
7788 """Add variable or several variables.
7789 The added variable or variables will be bound in the rules
7790 and queries
7791 """
7792 vars = _get_args(vars)
7793 for v in vars:
7794 self.vars += [v]
7795
7796 def abstract(self, fml, is_forall=True):
7797 if self.vars == []:
7798 return fml
7799 if is_forall:
7800 return ForAll(self.vars, fml)
7801 else:
7802 return Exists(self.vars, fml)
7803
7804
7805#########################################
7806#
7807# Finite domains
7808#
7809#########################################
7810
7811class FiniteDomainSortRef(SortRef):
7812 """Finite domain sort."""
7813
7814 def size(self):
7815 """Return the size of the finite domain sort"""
7816 r = (ctypes.c_ulonglong * 1)()
7817 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7818 return r[0]
7819 else:
7820 raise Z3Exception("Failed to retrieve finite domain sort size")
7821
7822
7823def FiniteDomainSort(name, sz, ctx=None):
7824 """Create a named finite domain sort of a given size sz"""
7825 if not isinstance(name, Symbol):
7826 name = to_symbol(name)
7827 ctx = _get_ctx(ctx)
7828 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7829
7830
7831def is_finite_domain_sort(s):
7832 """Return True if `s` is a Z3 finite-domain sort.
7833
7834 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7835 True
7836 >>> is_finite_domain_sort(IntSort())
7837 False
7838 """
7839 return isinstance(s, FiniteDomainSortRef)
7840
7841
7842class FiniteDomainRef(ExprRef):
7843 """Finite-domain expressions."""
7844
7845 def sort(self):
7846 """Return the sort of the finite-domain expression `self`."""
7847 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7848
7849 def as_string(self):
7850 """Return a Z3 floating point expression as a Python string."""
7851 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7852
7853
7854def is_finite_domain(a):
7855 """Return `True` if `a` is a Z3 finite-domain expression.
7856
7857 >>> s = FiniteDomainSort('S', 100)
7858 >>> b = Const('b', s)
7859 >>> is_finite_domain(b)
7860 True
7861 >>> is_finite_domain(Int('x'))
7862 False
7863 """
7864 return isinstance(a, FiniteDomainRef)
7865
7866
7867class FiniteDomainNumRef(FiniteDomainRef):
7868 """Integer values."""
7869
7870 def as_long(self):
7871 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7872
7873 >>> s = FiniteDomainSort('S', 100)
7874 >>> v = FiniteDomainVal(3, s)
7875 >>> v
7876 3
7877 >>> v.as_long() + 1
7878 4
7879 """
7880 return int(self.as_string())
7881
7882 def as_string(self):
7883 """Return a Z3 finite-domain numeral as a Python string.
7884
7885 >>> s = FiniteDomainSort('S', 100)
7886 >>> v = FiniteDomainVal(42, s)
7887 >>> v.as_string()
7888 '42'
7889 """
7890 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
7891
7892
7893def FiniteDomainVal(val, sort, ctx=None):
7894 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
7895
7896 >>> s = FiniteDomainSort('S', 256)
7897 >>> FiniteDomainVal(255, s)
7898 255
7899 >>> FiniteDomainVal('100', s)
7900 100
7901 """
7902 if z3_debug():
7903 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
7904 ctx = sort.ctx
7905 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
7906
7907
7908def is_finite_domain_value(a):
7909 """Return `True` if `a` is a Z3 finite-domain value.
7910
7911 >>> s = FiniteDomainSort('S', 100)
7912 >>> b = Const('b', s)
7913 >>> is_finite_domain_value(b)
7914 False
7915 >>> b = FiniteDomainVal(10, s)
7916 >>> b
7917 10
7918 >>> is_finite_domain_value(b)
7919 True
7920 """
7921 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
7922
7923
7924#########################################
7925#
7926# Optimize
7927#
7928#########################################
7929
7930class OptimizeObjective:
7931 def __init__(self, opt, value, is_max):
7932 self._opt = opt
7933 self._value = value
7934 self._is_max = is_max
7935
7936 def lower(self):
7937 opt = self._opt
7938 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7939
7940 def upper(self):
7941 opt = self._opt
7942 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7943
7944 def lower_values(self):
7945 opt = self._opt
7946 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7947
7948 def upper_values(self):
7949 opt = self._opt
7950 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7951
7952 def value(self):
7953 if self._is_max:
7954 return self.upper()
7955 else:
7956 return self.lower()
7957
7958 def __str__(self):
7959 return "%s:%s" % (self._value, self._is_max)
7960
7961
7962_on_models = {}
7963
7964
7965def _global_on_model(ctx):
7966 (fn, mdl) = _on_models[ctx]
7967 fn(mdl)
7968
7969
7970_on_model_eh = on_model_eh_type(_global_on_model)
7971
7972
7973class Optimize(Z3PPObject):
7974 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
7975
7976 def __init__(self, optimize=None, ctx=None):
7977 self.ctx = _get_ctx(ctx)
7978 if optimize is None:
7979 self.optimize = Z3_mk_optimize(self.ctx.ref())
7980 else:
7981 self.optimize = optimize
7982 self._on_models_id = None
7983 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
7984
7985 def __deepcopy__(self, memo={}):
7986 return Optimize(self.optimize, self.ctx)
7987
7988 def __del__(self):
7989 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
7990 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
7991 if self._on_models_id is not None:
7992 del _on_models[self._on_models_id]
7993
7994 def __enter__(self):
7995 self.push()
7996 return self
7997
7998 def __exit__(self, *exc_info):
7999 self.pop()
8000
8001 def set(self, *args, **keys):
8002 """Set a configuration option.
8003 The method `help()` return a string containing all available options.
8004 """
8005 p = args2params(args, keys, self.ctx)
8006 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8007
8008 def help(self):
8009 """Display a string describing all available options."""
8010 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8011
8012 def param_descrs(self):
8013 """Return the parameter description set."""
8014 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8015
8016 def assert_exprs(self, *args):
8017 """Assert constraints as background axioms for the optimize solver."""
8018 args = _get_args(args)
8019 s = BoolSort(self.ctx)
8020 for arg in args:
8021 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8022 for f in arg:
8023 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8024 else:
8025 arg = s.cast(arg)
8026 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8027
8028 def add(self, *args):
8029 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8030 self.assert_exprs(*args)
8031
8032 def __iadd__(self, fml):
8033 self.add(fml)
8034 return self
8035
8036 def assert_and_track(self, a, p):
8037 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8038
8039 If `p` is a string, it will be automatically converted into a Boolean constant.
8040
8041 >>> x = Int('x')
8042 >>> p3 = Bool('p3')
8043 >>> s = Optimize()
8044 >>> s.assert_and_track(x > 0, 'p1')
8045 >>> s.assert_and_track(x != 1, 'p2')
8046 >>> s.assert_and_track(x < 0, p3)
8047 >>> print(s.check())
8048 unsat
8049 >>> c = s.unsat_core()
8050 >>> len(c)
8051 2
8052 >>> Bool('p1') in c
8053 True
8054 >>> Bool('p2') in c
8055 False
8056 >>> p3 in c
8057 True
8058 """
8059 if isinstance(p, str):
8060 p = Bool(p, self.ctx)
8061 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8062 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8063 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8064
8065 def add_soft(self, arg, weight="1", id=None):
8066 """Add soft constraint with optional weight and optional identifier.
8067 If no weight is supplied, then the penalty for violating the soft constraint
8068 is 1.
8069 Soft constraints are grouped by identifiers. Soft constraints that are
8070 added without identifiers are grouped by default.
8071 """
8072 if _is_int(weight):
8073 weight = "%d" % weight
8074 elif isinstance(weight, float):
8075 weight = "%f" % weight
8076 if not isinstance(weight, str):
8077 raise Z3Exception("weight should be a string or an integer")
8078 if id is None:
8079 id = ""
8080 id = to_symbol(id, self.ctx)
8081
8082 def asoft(a):
8083 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8084 return OptimizeObjective(self, v, False)
8085 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8086 return [asoft(a) for a in arg]
8087 return asoft(arg)
8088
8089 def set_initial_value(self, var, value):
8090 """initialize the solver's state by setting the initial value of var to value
8091 """
8092 s = var.sort()
8093 value = s.cast(value)
8094 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8095
8096 def maximize(self, arg):
8097 """Add objective function to maximize."""
8098 return OptimizeObjective(
8099 self,
8100 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8101 is_max=True,
8102 )
8103
8104 def minimize(self, arg):
8105 """Add objective function to minimize."""
8106 return OptimizeObjective(
8107 self,
8108 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8109 is_max=False,
8110 )
8111
8112 def push(self):
8113 """create a backtracking point for added rules, facts and assertions"""
8114 Z3_optimize_push(self.ctx.ref(), self.optimize)
8115
8116 def pop(self):
8117 """restore to previously created backtracking point"""
8118 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8119
8120 def check(self, *assumptions):
8121 """Check consistency and produce optimal values."""
8122 assumptions = _get_args(assumptions)
8123 num = len(assumptions)
8124 _assumptions = (Ast * num)()
8125 for i in range(num):
8126 _assumptions[i] = assumptions[i].as_ast()
8127 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8128
8129 def reason_unknown(self):
8130 """Return a string that describes why the last `check()` returned `unknown`."""
8131 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8132
8133 def model(self):
8134 """Return a model for the last check()."""
8135 try:
8136 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8137 except Z3Exception:
8138 raise Z3Exception("model is not available")
8139
8140 def unsat_core(self):
8141 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8142
8143 def lower(self, obj):
8144 if not isinstance(obj, OptimizeObjective):
8145 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8146 return obj.lower()
8147
8148 def upper(self, obj):
8149 if not isinstance(obj, OptimizeObjective):
8150 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8151 return obj.upper()
8152
8153 def lower_values(self, obj):
8154 if not isinstance(obj, OptimizeObjective):
8155 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8156 return obj.lower_values()
8157
8158 def upper_values(self, obj):
8159 if not isinstance(obj, OptimizeObjective):
8160 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8161 return obj.upper_values()
8162
8163 def from_file(self, filename):
8164 """Parse assertions and objectives from a file"""
8165 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8166
8167 def from_string(self, s):
8168 """Parse assertions and objectives from a string"""
8169 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8170
8171 def assertions(self):
8172 """Return an AST vector containing all added constraints."""
8173 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8174
8175 def objectives(self):
8176 """returns set of objective functions"""
8177 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8178
8179 def __repr__(self):
8180 """Return a formatted string with all added rules and constraints."""
8181 return self.sexpr()
8182
8183 def sexpr(self):
8184 """Return a formatted string (in Lisp-like format) with all added constraints.
8185 We say the string is in s-expression format.
8186 """
8187 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8188
8189 def statistics(self):
8190 """Return statistics for the last check`.
8191 """
8192 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8193
8194 def set_on_model(self, on_model):
8195 """Register a callback that is invoked with every incremental improvement to
8196 objective values. The callback takes a model as argument.
8197 The life-time of the model is limited to the callback so the
8198 model has to be (deep) copied if it is to be used after the callback
8199 """
8200 id = len(_on_models) + 41
8201 mdl = Model(self.ctx)
8202 _on_models[id] = (on_model, mdl)
8203 self._on_models_id = id
8204 Z3_optimize_register_model_eh(
8205 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8206 )
8207
8208
8209#########################################
8210#
8211# ApplyResult
8212#
8213#########################################
8214class ApplyResult(Z3PPObject):
8215 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8216 It also contains model and proof converters.
8217 """
8218
8219 def __init__(self, result, ctx):
8220 self.result = result
8221 self.ctx = ctx
8222 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8223
8224 def __deepcopy__(self, memo={}):
8225 return ApplyResult(self.result, self.ctx)
8226
8227 def __del__(self):
8228 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8229 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8230
8231 def __len__(self):
8232 """Return the number of subgoals in `self`.
8233
8234 >>> a, b = Ints('a b')
8235 >>> g = Goal()
8236 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8237 >>> t = Tactic('split-clause')
8238 >>> r = t(g)
8239 >>> len(r)
8240 2
8241 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8242 >>> len(t(g))
8243 4
8244 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8245 >>> len(t(g))
8246 1
8247 """
8248 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8249
8250 def __getitem__(self, idx):
8251 """Return one of the subgoals stored in ApplyResult object `self`.
8252
8253 >>> a, b = Ints('a b')
8254 >>> g = Goal()
8255 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8256 >>> t = Tactic('split-clause')
8257 >>> r = t(g)
8258 >>> r[0]
8259 [a == 0, Or(b == 0, b == 1), a > b]
8260 >>> r[1]
8261 [a == 1, Or(b == 0, b == 1), a > b]
8262 """
8263 if idx >= len(self):
8264 raise IndexError
8265 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8266
8267 def __repr__(self):
8268 return obj_to_string(self)
8269
8270 def sexpr(self):
8271 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8272 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8273
8274 def as_expr(self):
8275 """Return a Z3 expression consisting of all subgoals.
8276
8277 >>> x = Int('x')
8278 >>> g = Goal()
8279 >>> g.add(x > 1)
8280 >>> g.add(Or(x == 2, x == 3))
8281 >>> r = Tactic('simplify')(g)
8282 >>> r
8283 [[Not(x <= 1), Or(x == 2, x == 3)]]
8284 >>> r.as_expr()
8285 And(Not(x <= 1), Or(x == 2, x == 3))
8286 >>> r = Tactic('split-clause')(g)
8287 >>> r
8288 [[x > 1, x == 2], [x > 1, x == 3]]
8289 >>> r.as_expr()
8290 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8291 """
8292 sz = len(self)
8293 if sz == 0:
8294 return BoolVal(False, self.ctx)
8295 elif sz == 1:
8296 return self[0].as_expr()
8297 else:
8298 return Or([self[i].as_expr() for i in range(len(self))])
8299
8300#########################################
8301#
8302# Simplifiers
8303#
8304#########################################
8305
8306class Simplifier:
8307 """Simplifiers act as pre-processing utilities for solvers.
8308 Build a custom simplifier and add it to a solver"""
8309
8310 def __init__(self, simplifier, ctx=None):
8311 self.ctx = _get_ctx(ctx)
8312 self.simplifier = None
8313 if isinstance(simplifier, SimplifierObj):
8314 self.simplifier = simplifier
8315 elif isinstance(simplifier, list):
8316 simps = [Simplifier(s, ctx) for s in simplifier]
8317 self.simplifier = simps[0].simplifier
8318 for i in range(1, len(simps)):
8319 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8320 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8321 return
8322 else:
8323 if z3_debug():
8324 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8325 try:
8326 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8327 except Z3Exception:
8328 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8329 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8330
8331 def __deepcopy__(self, memo={}):
8332 return Simplifier(self.simplifier, self.ctx)
8333
8334 def __del__(self):
8335 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8336 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8337
8338 def using_params(self, *args, **keys):
8339 """Return a simplifier that uses the given configuration options"""
8340 p = args2params(args, keys, self.ctx)
8341 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8342
8343 def add(self, solver):
8344 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8345 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8346
8347 def help(self):
8348 """Display a string containing a description of the available options for the `self` simplifier."""
8349 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8350
8351 def param_descrs(self):
8352 """Return the parameter description set."""
8353 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8354
8355
8356#########################################
8357#
8358# Tactics
8359#
8360#########################################
8361
8362
8363class Tactic:
8364 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8365 A Tactic can be converted into a Solver using the method solver().
8366
8367 Several combinators are available for creating new tactics using the built-in ones:
8368 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8369 """
8370
8371 def __init__(self, tactic, ctx=None):
8372 self.ctx = _get_ctx(ctx)
8373 self.tactic = None
8374 if isinstance(tactic, TacticObj):
8375 self.tactic = tactic
8376 else:
8377 if z3_debug():
8378 _z3_assert(isinstance(tactic, str), "tactic name expected")
8379 try:
8380 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8381 except Z3Exception:
8382 raise Z3Exception("unknown tactic '%s'" % tactic)
8383 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8384
8385 def __deepcopy__(self, memo={}):
8386 return Tactic(self.tactic, self.ctx)
8387
8388 def __del__(self):
8389 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8390 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8391
8392 def solver(self, logFile=None):
8393 """Create a solver using the tactic `self`.
8394
8395 The solver supports the methods `push()` and `pop()`, but it
8396 will always solve each `check()` from scratch.
8397
8398 >>> t = Then('simplify', 'nlsat')
8399 >>> s = t.solver()
8400 >>> x = Real('x')
8401 >>> s.add(x**2 == 2, x > 0)
8402 >>> s.check()
8403 sat
8404 >>> s.model()
8405 [x = 1.4142135623?]
8406 """
8407 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8408
8409 def apply(self, goal, *arguments, **keywords):
8410 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8411
8412 >>> x, y = Ints('x y')
8413 >>> t = Tactic('solve-eqs')
8414 >>> t.apply(And(x == 0, y >= x + 1))
8415 [[y >= 1]]
8416 """
8417 if z3_debug():
8418 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8419 goal = _to_goal(goal)
8420 if len(arguments) > 0 or len(keywords) > 0:
8421 p = args2params(arguments, keywords, self.ctx)
8422 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8423 else:
8424 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8425
8426 def __call__(self, goal, *arguments, **keywords):
8427 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8428
8429 >>> x, y = Ints('x y')
8430 >>> t = Tactic('solve-eqs')
8431 >>> t(And(x == 0, y >= x + 1))
8432 [[y >= 1]]
8433 """
8434 return self.apply(goal, *arguments, **keywords)
8435
8436 def help(self):
8437 """Display a string containing a description of the available options for the `self` tactic."""
8438 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8439
8440 def param_descrs(self):
8441 """Return the parameter description set."""
8442 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8443
8444
8445def _to_goal(a):
8446 if isinstance(a, BoolRef):
8447 goal = Goal(ctx=a.ctx)
8448 goal.add(a)
8449 return goal
8450 else:
8451 return a
8452
8453
8454def _to_tactic(t, ctx=None):
8455 if isinstance(t, Tactic):
8456 return t
8457 else:
8458 return Tactic(t, ctx)
8459
8460
8461def _and_then(t1, t2, ctx=None):
8462 t1 = _to_tactic(t1, ctx)
8463 t2 = _to_tactic(t2, ctx)
8464 if z3_debug():
8465 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8466 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8467
8468
8469def _or_else(t1, t2, ctx=None):
8470 t1 = _to_tactic(t1, ctx)
8471 t2 = _to_tactic(t2, ctx)
8472 if z3_debug():
8473 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8474 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8475
8476
8477def AndThen(*ts, **ks):
8478 """Return a tactic that applies the tactics in `*ts` in sequence.
8479
8480 >>> x, y = Ints('x y')
8481 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8482 >>> t(And(x == 0, y > x + 1))
8483 [[Not(y <= 1)]]
8484 >>> t(And(x == 0, y > x + 1)).as_expr()
8485 Not(y <= 1)
8486 """
8487 if z3_debug():
8488 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8489 ctx = ks.get("ctx", None)
8490 num = len(ts)
8491 r = ts[0]
8492 for i in range(num - 1):
8493 r = _and_then(r, ts[i + 1], ctx)
8494 return r
8495
8496
8497def Then(*ts, **ks):
8498 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8499
8500 >>> x, y = Ints('x y')
8501 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8502 >>> t(And(x == 0, y > x + 1))
8503 [[Not(y <= 1)]]
8504 >>> t(And(x == 0, y > x + 1)).as_expr()
8505 Not(y <= 1)
8506 """
8507 return AndThen(*ts, **ks)
8508
8509
8510def OrElse(*ts, **ks):
8511 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8512
8513 >>> x = Int('x')
8514 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8515 >>> # Tactic split-clause fails if there is no clause in the given goal.
8516 >>> t(x == 0)
8517 [[x == 0]]
8518 >>> t(Or(x == 0, x == 1))
8519 [[x == 0], [x == 1]]
8520 """
8521 if z3_debug():
8522 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8523 ctx = ks.get("ctx", None)
8524 num = len(ts)
8525 r = ts[0]
8526 for i in range(num - 1):
8527 r = _or_else(r, ts[i + 1], ctx)
8528 return r
8529
8530
8531def ParOr(*ts, **ks):
8532 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8533
8534 >>> x = Int('x')
8535 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8536 >>> t(x + 1 == 2)
8537 [[x == 1]]
8538 """
8539 if z3_debug():
8540 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8541 ctx = _get_ctx(ks.get("ctx", None))
8542 ts = [_to_tactic(t, ctx) for t in ts]
8543 sz = len(ts)
8544 _args = (TacticObj * sz)()
8545 for i in range(sz):
8546 _args[i] = ts[i].tactic
8547 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8548
8549
8550def ParThen(t1, t2, ctx=None):
8551 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8552 The subgoals are processed in parallel.
8553
8554 >>> x, y = Ints('x y')
8555 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8556 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8557 [[x == 1, y == 2], [x == 2, y == 3]]
8558 """
8559 t1 = _to_tactic(t1, ctx)
8560 t2 = _to_tactic(t2, ctx)
8561 if z3_debug():
8562 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8563 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8564
8565
8566def ParAndThen(t1, t2, ctx=None):
8567 """Alias for ParThen(t1, t2, ctx)."""
8568 return ParThen(t1, t2, ctx)
8569
8570
8571def With(t, *args, **keys):
8572 """Return a tactic that applies tactic `t` using the given configuration options.
8573
8574 >>> x, y = Ints('x y')
8575 >>> t = With(Tactic('simplify'), som=True)
8576 >>> t((x + 1)*(y + 2) == 0)
8577 [[2*x + y + x*y == -2]]
8578 """
8579 ctx = keys.pop("ctx", None)
8580 t = _to_tactic(t, ctx)
8581 p = args2params(args, keys, t.ctx)
8582 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8583
8584
8585def WithParams(t, p):
8586 """Return a tactic that applies tactic `t` using the given configuration options.
8587
8588 >>> x, y = Ints('x y')
8589 >>> p = ParamsRef()
8590 >>> p.set("som", True)
8591 >>> t = WithParams(Tactic('simplify'), p)
8592 >>> t((x + 1)*(y + 2) == 0)
8593 [[2*x + y + x*y == -2]]
8594 """
8595 t = _to_tactic(t, None)
8596 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8597
8598
8599def Repeat(t, max=4294967295, ctx=None):
8600 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8601 or the maximum number of iterations `max` is reached.
8602
8603 >>> x, y = Ints('x y')
8604 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8605 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8606 >>> r = t(c)
8607 >>> for subgoal in r: print(subgoal)
8608 [x == 0, y == 0, x > y]
8609 [x == 0, y == 1, x > y]
8610 [x == 1, y == 0, x > y]
8611 [x == 1, y == 1, x > y]
8612 >>> t = Then(t, Tactic('propagate-values'))
8613 >>> t(c)
8614 [[x == 1, y == 0]]
8615 """
8616 t = _to_tactic(t, ctx)
8617 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8618
8619
8620def TryFor(t, ms, ctx=None):
8621 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8622
8623 If `t` does not terminate in `ms` milliseconds, then it fails.
8624 """
8625 t = _to_tactic(t, ctx)
8626 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8627
8628
8629def tactics(ctx=None):
8630 """Return a list of all available tactics in Z3.
8631
8632 >>> l = tactics()
8633 >>> l.count('simplify') == 1
8634 True
8635 """
8636 ctx = _get_ctx(ctx)
8637 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8638
8639
8640def tactic_description(name, ctx=None):
8641 """Return a short description for the tactic named `name`.
8642
8643 >>> d = tactic_description('simplify')
8644 """
8645 ctx = _get_ctx(ctx)
8646 return Z3_tactic_get_descr(ctx.ref(), name)
8647
8648
8649def describe_tactics():
8650 """Display a (tabular) description of all available tactics in Z3."""
8651 if in_html_mode():
8652 even = True
8653 print('<table border="1" cellpadding="2" cellspacing="0">')
8654 for t in tactics():
8655 if even:
8656 print('<tr style="background-color:#CFCFCF">')
8657 even = False
8658 else:
8659 print("<tr>")
8660 even = True
8661 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8662 print("</table>")
8663 else:
8664 for t in tactics():
8665 print("%s : %s" % (t, tactic_description(t)))
8666
8667
8668class Probe:
8669 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8670 to decide which solver and/or preprocessing step will be used.
8671 """
8672
8673 def __init__(self, probe, ctx=None):
8674 self.ctx = _get_ctx(ctx)
8675 self.probe = None
8676 if isinstance(probe, ProbeObj):
8677 self.probe = probe
8678 elif isinstance(probe, float):
8679 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8680 elif _is_int(probe):
8681 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8682 elif isinstance(probe, bool):
8683 if probe:
8684 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8685 else:
8686 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8687 else:
8688 if z3_debug():
8689 _z3_assert(isinstance(probe, str), "probe name expected")
8690 try:
8691 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8692 except Z3Exception:
8693 raise Z3Exception("unknown probe '%s'" % probe)
8694 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8695
8696 def __deepcopy__(self, memo={}):
8697 return Probe(self.probe, self.ctx)
8698
8699 def __del__(self):
8700 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8701 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8702
8703 def __lt__(self, other):
8704 """Return a probe that evaluates to "true" when the value returned by `self`
8705 is less than the value returned by `other`.
8706
8707 >>> p = Probe('size') < 10
8708 >>> x = Int('x')
8709 >>> g = Goal()
8710 >>> g.add(x > 0)
8711 >>> g.add(x < 10)
8712 >>> p(g)
8713 1.0
8714 """
8715 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8716
8717 def __gt__(self, other):
8718 """Return a probe that evaluates to "true" when the value returned by `self`
8719 is greater than the value returned by `other`.
8720
8721 >>> p = Probe('size') > 10
8722 >>> x = Int('x')
8723 >>> g = Goal()
8724 >>> g.add(x > 0)
8725 >>> g.add(x < 10)
8726 >>> p(g)
8727 0.0
8728 """
8729 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8730
8731 def __le__(self, other):
8732 """Return a probe that evaluates to "true" when the value returned by `self`
8733 is less than or equal to the value returned by `other`.
8734
8735 >>> p = Probe('size') <= 2
8736 >>> x = Int('x')
8737 >>> g = Goal()
8738 >>> g.add(x > 0)
8739 >>> g.add(x < 10)
8740 >>> p(g)
8741 1.0
8742 """
8743 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8744
8745 def __ge__(self, other):
8746 """Return a probe that evaluates to "true" when the value returned by `self`
8747 is greater than or equal to the value returned by `other`.
8748
8749 >>> p = Probe('size') >= 2
8750 >>> x = Int('x')
8751 >>> g = Goal()
8752 >>> g.add(x > 0)
8753 >>> g.add(x < 10)
8754 >>> p(g)
8755 1.0
8756 """
8757 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8758
8759 def __eq__(self, other):
8760 """Return a probe that evaluates to "true" when the value returned by `self`
8761 is equal to the value returned by `other`.
8762
8763 >>> p = Probe('size') == 2
8764 >>> x = Int('x')
8765 >>> g = Goal()
8766 >>> g.add(x > 0)
8767 >>> g.add(x < 10)
8768 >>> p(g)
8769 1.0
8770 """
8771 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8772
8773 def __ne__(self, other):
8774 """Return a probe that evaluates to "true" when the value returned by `self`
8775 is not equal to the value returned by `other`.
8776
8777 >>> p = Probe('size') != 2
8778 >>> x = Int('x')
8779 >>> g = Goal()
8780 >>> g.add(x > 0)
8781 >>> g.add(x < 10)
8782 >>> p(g)
8783 0.0
8784 """
8785 p = self.__eq__(other)
8786 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8787
8788 def __call__(self, goal):
8789 """Evaluate the probe `self` in the given goal.
8790
8791 >>> p = Probe('size')
8792 >>> x = Int('x')
8793 >>> g = Goal()
8794 >>> g.add(x > 0)
8795 >>> g.add(x < 10)
8796 >>> p(g)
8797 2.0
8798 >>> g.add(x < 20)
8799 >>> p(g)
8800 3.0
8801 >>> p = Probe('num-consts')
8802 >>> p(g)
8803 1.0
8804 >>> p = Probe('is-propositional')
8805 >>> p(g)
8806 0.0
8807 >>> p = Probe('is-qflia')
8808 >>> p(g)
8809 1.0
8810 """
8811 if z3_debug():
8812 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8813 goal = _to_goal(goal)
8814 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8815
8816
8817def is_probe(p):
8818 """Return `True` if `p` is a Z3 probe.
8819
8820 >>> is_probe(Int('x'))
8821 False
8822 >>> is_probe(Probe('memory'))
8823 True
8824 """
8825 return isinstance(p, Probe)
8826
8827
8828def _to_probe(p, ctx=None):
8829 if is_probe(p):
8830 return p
8831 else:
8832 return Probe(p, ctx)
8833
8834
8835def probes(ctx=None):
8836 """Return a list of all available probes in Z3.
8837
8838 >>> l = probes()
8839 >>> l.count('memory') == 1
8840 True
8841 """
8842 ctx = _get_ctx(ctx)
8843 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8844
8845
8846def probe_description(name, ctx=None):
8847 """Return a short description for the probe named `name`.
8848
8849 >>> d = probe_description('memory')
8850 """
8851 ctx = _get_ctx(ctx)
8852 return Z3_probe_get_descr(ctx.ref(), name)
8853
8854
8855def describe_probes():
8856 """Display a (tabular) description of all available probes in Z3."""
8857 if in_html_mode():
8858 even = True
8859 print('<table border="1" cellpadding="2" cellspacing="0">')
8860 for p in probes():
8861 if even:
8862 print('<tr style="background-color:#CFCFCF">')
8863 even = False
8864 else:
8865 print("<tr>")
8866 even = True
8867 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
8868 print("</table>")
8869 else:
8870 for p in probes():
8871 print("%s : %s" % (p, probe_description(p)))
8872
8873
8874def _probe_nary(f, args, ctx):
8875 if z3_debug():
8876 _z3_assert(len(args) > 0, "At least one argument expected")
8877 num = len(args)
8878 r = _to_probe(args[0], ctx)
8879 for i in range(num - 1):
8880 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
8881 return r
8882
8883
8884def _probe_and(args, ctx):
8885 return _probe_nary(Z3_probe_and, args, ctx)
8886
8887
8888def _probe_or(args, ctx):
8889 return _probe_nary(Z3_probe_or, args, ctx)
8890
8891
8892def FailIf(p, ctx=None):
8893 """Return a tactic that fails if the probe `p` evaluates to true.
8894 Otherwise, it returns the input goal unmodified.
8895
8896 In the following example, the tactic applies 'simplify' if and only if there are
8897 more than 2 constraints in the goal.
8898
8899 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
8900 >>> x, y = Ints('x y')
8901 >>> g = Goal()
8902 >>> g.add(x > 0)
8903 >>> g.add(y > 0)
8904 >>> t(g)
8905 [[x > 0, y > 0]]
8906 >>> g.add(x == y + 1)
8907 >>> t(g)
8908 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8909 """
8910 p = _to_probe(p, ctx)
8911 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
8912
8913
8914def When(p, t, ctx=None):
8915 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
8916 Otherwise, it returns the input goal unmodified.
8917
8918 >>> t = When(Probe('size') > 2, Tactic('simplify'))
8919 >>> x, y = Ints('x y')
8920 >>> g = Goal()
8921 >>> g.add(x > 0)
8922 >>> g.add(y > 0)
8923 >>> t(g)
8924 [[x > 0, y > 0]]
8925 >>> g.add(x == y + 1)
8926 >>> t(g)
8927 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8928 """
8929 p = _to_probe(p, ctx)
8930 t = _to_tactic(t, ctx)
8931 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
8932
8933
8934def Cond(p, t1, t2, ctx=None):
8935 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
8936
8937 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
8938 """
8939 p = _to_probe(p, ctx)
8940 t1 = _to_tactic(t1, ctx)
8941 t2 = _to_tactic(t2, ctx)
8942 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
8943
8944#########################################
8945#
8946# Utils
8947#
8948#########################################
8949
8950
8951def simplify(a, *arguments, **keywords):
8952 """Simplify the expression `a` using the given options.
8953
8954 This function has many options. Use `help_simplify` to obtain the complete list.
8955
8956 >>> x = Int('x')
8957 >>> y = Int('y')
8958 >>> simplify(x + 1 + y + x + 1)
8959 2 + 2*x + y
8960 >>> simplify((x + 1)*(y + 1), som=True)
8961 1 + x + y + x*y
8962 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
8963 And(Not(x == y), Not(x == 1), Not(y == 1))
8964 >>> simplify(And(x == 0, y == 1), elim_and=True)
8965 Not(Or(Not(x == 0), Not(y == 1)))
8966 """
8967 if z3_debug():
8968 _z3_assert(is_expr(a), "Z3 expression expected")
8969 if len(arguments) > 0 or len(keywords) > 0:
8970 p = args2params(arguments, keywords, a.ctx)
8971 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
8972 else:
8973 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
8974
8975
8976def help_simplify():
8977 """Return a string describing all options available for Z3 `simplify` procedure."""
8978 print(Z3_simplify_get_help(main_ctx().ref()))
8979
8980
8981def simplify_param_descrs():
8982 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
8983 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
8984
8985
8986def substitute(t, *m):
8987 """Apply substitution m on t, m is a list of pairs of the form (from, to).
8988 Every occurrence in t of from is replaced with to.
8989
8990 >>> x = Int('x')
8991 >>> y = Int('y')
8992 >>> substitute(x + 1, (x, y + 1))
8993 y + 1 + 1
8994 >>> f = Function('f', IntSort(), IntSort())
8995 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
8996 1 + 1
8997 """
8998 if isinstance(m, tuple):
8999 m1 = _get_args(m)
9000 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9001 m = m1
9002 if z3_debug():
9003 _z3_assert(is_expr(t), "Z3 expression expected")
9004 _z3_assert(
9005 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9006 "Z3 invalid substitution, expression pairs expected.")
9007 _z3_assert(
9008 all([p[0].sort().eq(p[1].sort()) for p in m]),
9009 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9010 num = len(m)
9011 _from = (Ast * num)()
9012 _to = (Ast * num)()
9013 for i in range(num):
9014 _from[i] = m[i][0].as_ast()
9015 _to[i] = m[i][1].as_ast()
9016 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9017
9018
9019def substitute_vars(t, *m):
9020 """Substitute the free variables in t with the expression in m.
9021
9022 >>> v0 = Var(0, IntSort())
9023 >>> v1 = Var(1, IntSort())
9024 >>> x = Int('x')
9025 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9026 >>> # replace v0 with x+1 and v1 with x
9027 >>> substitute_vars(f(v0, v1), x + 1, x)
9028 f(x + 1, x)
9029 """
9030 if z3_debug():
9031 _z3_assert(is_expr(t), "Z3 expression expected")
9032 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9033 num = len(m)
9034 _to = (Ast * num)()
9035 for i in range(num):
9036 _to[i] = m[i].as_ast()
9037 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9038
9039def substitute_funs(t, *m):
9040 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9041 Every occurrence in to of the function from is replaced with the expression to.
9042 The expression to can have free variables, that refer to the arguments of from.
9043 For examples, see
9044 """
9045 if isinstance(m, tuple):
9046 m1 = _get_args(m)
9047 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9048 m = m1
9049 if z3_debug():
9050 _z3_assert(is_expr(t), "Z3 expression expected")
9051 _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.")
9052 num = len(m)
9053 _from = (FuncDecl * num)()
9054 _to = (Ast * num)()
9055 for i in range(num):
9056 _from[i] = m[i][0].as_func_decl()
9057 _to[i] = m[i][1].as_ast()
9058 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9059
9060
9061def Sum(*args):
9062 """Create the sum of the Z3 expressions.
9063
9064 >>> a, b, c = Ints('a b c')
9065 >>> Sum(a, b, c)
9066 a + b + c
9067 >>> Sum([a, b, c])
9068 a + b + c
9069 >>> A = IntVector('a', 5)
9070 >>> Sum(A)
9071 a__0 + a__1 + a__2 + a__3 + a__4
9072 """
9073 args = _get_args(args)
9074 if len(args) == 0:
9075 return 0
9076 ctx = _ctx_from_ast_arg_list(args)
9077 if ctx is None:
9078 return _reduce(lambda a, b: a + b, args, 0)
9079 args = _coerce_expr_list(args, ctx)
9080 if is_bv(args[0]):
9081 return _reduce(lambda a, b: a + b, args, 0)
9082 else:
9083 _args, sz = _to_ast_array(args)
9084 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9085
9086
9087def Product(*args):
9088 """Create the product of the Z3 expressions.
9089
9090 >>> a, b, c = Ints('a b c')
9091 >>> Product(a, b, c)
9092 a*b*c
9093 >>> Product([a, b, c])
9094 a*b*c
9095 >>> A = IntVector('a', 5)
9096 >>> Product(A)
9097 a__0*a__1*a__2*a__3*a__4
9098 """
9099 args = _get_args(args)
9100 if len(args) == 0:
9101 return 1
9102 ctx = _ctx_from_ast_arg_list(args)
9103 if ctx is None:
9104 return _reduce(lambda a, b: a * b, args, 1)
9105 args = _coerce_expr_list(args, ctx)
9106 if is_bv(args[0]):
9107 return _reduce(lambda a, b: a * b, args, 1)
9108 else:
9109 _args, sz = _to_ast_array(args)
9110 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9111
9112def Abs(arg):
9113 """Create the absolute value of an arithmetic expression"""
9114 return If(arg > 0, arg, -arg)
9115
9116
9117def AtMost(*args):
9118 """Create an at-most Pseudo-Boolean k constraint.
9119
9120 >>> a, b, c = Bools('a b c')
9121 >>> f = AtMost(a, b, c, 2)
9122 """
9123 args = _get_args(args)
9124 if z3_debug():
9125 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9126 ctx = _ctx_from_ast_arg_list(args)
9127 if z3_debug():
9128 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9129 args1 = _coerce_expr_list(args[:-1], ctx)
9130 k = args[-1]
9131 _args, sz = _to_ast_array(args1)
9132 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9133
9134
9135def AtLeast(*args):
9136 """Create an at-least Pseudo-Boolean k constraint.
9137
9138 >>> a, b, c = Bools('a b c')
9139 >>> f = AtLeast(a, b, c, 2)
9140 """
9141 args = _get_args(args)
9142 if z3_debug():
9143 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9144 ctx = _ctx_from_ast_arg_list(args)
9145 if z3_debug():
9146 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9147 args1 = _coerce_expr_list(args[:-1], ctx)
9148 k = args[-1]
9149 _args, sz = _to_ast_array(args1)
9150 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9151
9152
9153def _reorder_pb_arg(arg):
9154 a, b = arg
9155 if not _is_int(b) and _is_int(a):
9156 return b, a
9157 return arg
9158
9159
9160def _pb_args_coeffs(args, default_ctx=None):
9161 args = _get_args_ast_list(args)
9162 if len(args) == 0:
9163 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9164 args = [_reorder_pb_arg(arg) for arg in args]
9165 args, coeffs = zip(*args)
9166 if z3_debug():
9167 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9168 ctx = _ctx_from_ast_arg_list(args)
9169 if z3_debug():
9170 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9171 args = _coerce_expr_list(args, ctx)
9172 _args, sz = _to_ast_array(args)
9173 _coeffs = (ctypes.c_int * len(coeffs))()
9174 for i in range(len(coeffs)):
9175 _z3_check_cint_overflow(coeffs[i], "coefficient")
9176 _coeffs[i] = coeffs[i]
9177 return ctx, sz, _args, _coeffs, args
9178
9179
9180def PbLe(args, k):
9181 """Create a Pseudo-Boolean inequality k constraint.
9182
9183 >>> a, b, c = Bools('a b c')
9184 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9185 """
9186 _z3_check_cint_overflow(k, "k")
9187 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9188 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9189
9190
9191def PbGe(args, k):
9192 """Create a Pseudo-Boolean inequality k constraint.
9193
9194 >>> a, b, c = Bools('a b c')
9195 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9196 """
9197 _z3_check_cint_overflow(k, "k")
9198 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9199 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9200
9201
9202def PbEq(args, k, ctx=None):
9203 """Create a Pseudo-Boolean equality k constraint.
9204
9205 >>> a, b, c = Bools('a b c')
9206 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9207 """
9208 _z3_check_cint_overflow(k, "k")
9209 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9210 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9211
9212
9213def solve(*args, **keywords):
9214 """Solve the constraints `*args`.
9215
9216 This is a simple function for creating demonstrations. It creates a solver,
9217 configure it using the options in `keywords`, adds the constraints
9218 in `args`, and invokes check.
9219
9220 >>> a = Int('a')
9221 >>> solve(a > 0, a < 2)
9222 [a = 1]
9223 """
9224 show = keywords.pop("show", False)
9225 s = Solver()
9226 s.set(**keywords)
9227 s.add(*args)
9228 if show:
9229 print(s)
9230 r = s.check()
9231 if r == unsat:
9232 print("no solution")
9233 elif r == unknown:
9234 print("failed to solve")
9235 try:
9236 print(s.model())
9237 except Z3Exception:
9238 return
9239 else:
9240 print(s.model())
9241
9242
9243def solve_using(s, *args, **keywords):
9244 """Solve the constraints `*args` using solver `s`.
9245
9246 This is a simple function for creating demonstrations. It is similar to `solve`,
9247 but it uses the given solver `s`.
9248 It configures solver `s` using the options in `keywords`, adds the constraints
9249 in `args`, and invokes check.
9250 """
9251 show = keywords.pop("show", False)
9252 if z3_debug():
9253 _z3_assert(isinstance(s, Solver), "Solver object expected")
9254 s.set(**keywords)
9255 s.add(*args)
9256 if show:
9257 print("Problem:")
9258 print(s)
9259 r = s.check()
9260 if r == unsat:
9261 print("no solution")
9262 elif r == unknown:
9263 print("failed to solve")
9264 try:
9265 print(s.model())
9266 except Z3Exception:
9267 return
9268 else:
9269 if show:
9270 print("Solution:")
9271 print(s.model())
9272
9273
9274def prove(claim, show=False, **keywords):
9275 """Try to prove the given claim.
9276
9277 This is a simple function for creating demonstrations. It tries to prove
9278 `claim` by showing the negation is unsatisfiable.
9279
9280 >>> p, q = Bools('p q')
9281 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9282 proved
9283 """
9284 if z3_debug():
9285 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9286 s = Solver()
9287 s.set(**keywords)
9288 s.add(Not(claim))
9289 if show:
9290 print(s)
9291 r = s.check()
9292 if r == unsat:
9293 print("proved")
9294 elif r == unknown:
9295 print("failed to prove")
9296 print(s.model())
9297 else:
9298 print("counterexample")
9299 print(s.model())
9300
9301
9302def _solve_html(*args, **keywords):
9303 """Version of function `solve` that renders HTML output."""
9304 show = keywords.pop("show", False)
9305 s = Solver()
9306 s.set(**keywords)
9307 s.add(*args)
9308 if show:
9309 print("<b>Problem:</b>")
9310 print(s)
9311 r = s.check()
9312 if r == unsat:
9313 print("<b>no solution</b>")
9314 elif r == unknown:
9315 print("<b>failed to solve</b>")
9316 try:
9317 print(s.model())
9318 except Z3Exception:
9319 return
9320 else:
9321 if show:
9322 print("<b>Solution:</b>")
9323 print(s.model())
9324
9325
9326def _solve_using_html(s, *args, **keywords):
9327 """Version of function `solve_using` that renders HTML."""
9328 show = keywords.pop("show", False)
9329 if z3_debug():
9330 _z3_assert(isinstance(s, Solver), "Solver object expected")
9331 s.set(**keywords)
9332 s.add(*args)
9333 if show:
9334 print("<b>Problem:</b>")
9335 print(s)
9336 r = s.check()
9337 if r == unsat:
9338 print("<b>no solution</b>")
9339 elif r == unknown:
9340 print("<b>failed to solve</b>")
9341 try:
9342 print(s.model())
9343 except Z3Exception:
9344 return
9345 else:
9346 if show:
9347 print("<b>Solution:</b>")
9348 print(s.model())
9349
9350
9351def _prove_html(claim, show=False, **keywords):
9352 """Version of function `prove` that renders HTML."""
9353 if z3_debug():
9354 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9355 s = Solver()
9356 s.set(**keywords)
9357 s.add(Not(claim))
9358 if show:
9359 print(s)
9360 r = s.check()
9361 if r == unsat:
9362 print("<b>proved</b>")
9363 elif r == unknown:
9364 print("<b>failed to prove</b>")
9365 print(s.model())
9366 else:
9367 print("<b>counterexample</b>")
9368 print(s.model())
9369
9370
9371def _dict2sarray(sorts, ctx):
9372 sz = len(sorts)
9373 _names = (Symbol * sz)()
9374 _sorts = (Sort * sz)()
9375 i = 0
9376 for k in sorts:
9377 v = sorts[k]
9378 if z3_debug():
9379 _z3_assert(isinstance(k, str), "String expected")
9380 _z3_assert(is_sort(v), "Z3 sort expected")
9381 _names[i] = to_symbol(k, ctx)
9382 _sorts[i] = v.ast
9383 i = i + 1
9384 return sz, _names, _sorts
9385
9386
9387def _dict2darray(decls, ctx):
9388 sz = len(decls)
9389 _names = (Symbol * sz)()
9390 _decls = (FuncDecl * sz)()
9391 i = 0
9392 for k in decls:
9393 v = decls[k]
9394 if z3_debug():
9395 _z3_assert(isinstance(k, str), "String expected")
9396 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9397 _names[i] = to_symbol(k, ctx)
9398 if is_const(v):
9399 _decls[i] = v.decl().ast
9400 else:
9401 _decls[i] = v.ast
9402 i = i + 1
9403 return sz, _names, _decls
9404
9405class ParserContext:
9406 def __init__(self, ctx= None):
9407 self.ctx = _get_ctx(ctx)
9408 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9409 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9410
9411 def __del__(self):
9412 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9413 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9414 self.pctx = None
9415
9416 def add_sort(self, sort):
9417 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9418
9419 def add_decl(self, decl):
9420 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9421
9422 def from_string(self, s):
9423 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9424
9425def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9426 """Parse a string in SMT 2.0 format using the given sorts and decls.
9427
9428 The arguments sorts and decls are Python dictionaries used to initialize
9429 the symbol table used for the SMT 2.0 parser.
9430
9431 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9432 [x > 0, x < 10]
9433 >>> x, y = Ints('x y')
9434 >>> f = Function('f', IntSort(), IntSort())
9435 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9436 [x + f(y) > 0]
9437 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9438 [a > 0]
9439 """
9440 ctx = _get_ctx(ctx)
9441 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9442 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9443 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9444
9445
9446def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9447 """Parse a file in SMT 2.0 format using the given sorts and decls.
9448
9449 This function is similar to parse_smt2_string().
9450 """
9451 ctx = _get_ctx(ctx)
9452 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9453 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9454 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9455
9456
9457#########################################
9458#
9459# Floating-Point Arithmetic
9460#
9461#########################################
9462
9463
9464# Global default rounding mode
9465_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9466_dflt_fpsort_ebits = 11
9467_dflt_fpsort_sbits = 53
9468
9469
9470def get_default_rounding_mode(ctx=None):
9471 """Retrieves the global default rounding mode."""
9472 global _dflt_rounding_mode
9473 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9474 return RTZ(ctx)
9475 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9476 return RTN(ctx)
9477 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9478 return RTP(ctx)
9479 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9480 return RNE(ctx)
9481 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9482 return RNA(ctx)
9483
9484
9485_ROUNDING_MODES = frozenset({
9486 Z3_OP_FPA_RM_TOWARD_ZERO,
9487 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9488 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9489 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9490 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9491})
9492
9493
9494def set_default_rounding_mode(rm, ctx=None):
9495 global _dflt_rounding_mode
9496 if is_fprm_value(rm):
9497 _dflt_rounding_mode = rm.kind()
9498 else:
9499 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9500 _dflt_rounding_mode = rm
9501
9502
9503def get_default_fp_sort(ctx=None):
9504 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9505
9506
9507def set_default_fp_sort(ebits, sbits, ctx=None):
9508 global _dflt_fpsort_ebits
9509 global _dflt_fpsort_sbits
9510 _dflt_fpsort_ebits = ebits
9511 _dflt_fpsort_sbits = sbits
9512
9513
9514def _dflt_rm(ctx=None):
9515 return get_default_rounding_mode(ctx)
9516
9517
9518def _dflt_fps(ctx=None):
9519 return get_default_fp_sort(ctx)
9520
9521
9522def _coerce_fp_expr_list(alist, ctx):
9523 first_fp_sort = None
9524 for a in alist:
9525 if is_fp(a):
9526 if first_fp_sort is None:
9527 first_fp_sort = a.sort()
9528 elif first_fp_sort == a.sort():
9529 pass # OK, same as before
9530 else:
9531 # we saw at least 2 different float sorts; something will
9532 # throw a sort mismatch later, for now assume None.
9533 first_fp_sort = None
9534 break
9535
9536 r = []
9537 for i in range(len(alist)):
9538 a = alist[i]
9539 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9540 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9541 r.append(FPVal(a, None, first_fp_sort, ctx))
9542 else:
9543 r.append(a)
9544 return _coerce_expr_list(r, ctx)
9545
9546
9547# FP Sorts
9548
9549class FPSortRef(SortRef):
9550 """Floating-point sort."""
9551
9552 def ebits(self):
9553 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9554 >>> b = FPSort(8, 24)
9555 >>> b.ebits()
9556 8
9557 """
9558 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9559
9560 def sbits(self):
9561 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9562 >>> b = FPSort(8, 24)
9563 >>> b.sbits()
9564 24
9565 """
9566 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9567
9568 def cast(self, val):
9569 """Try to cast `val` as a floating-point expression.
9570 >>> b = FPSort(8, 24)
9571 >>> b.cast(1.0)
9572 1
9573 >>> b.cast(1.0).sexpr()
9574 '(fp #b0 #x7f #b00000000000000000000000)'
9575 """
9576 if is_expr(val):
9577 if z3_debug():
9578 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9579 return val
9580 else:
9581 return FPVal(val, None, self, self.ctx)
9582
9583
9584def Float16(ctx=None):
9585 """Floating-point 16-bit (half) sort."""
9586 ctx = _get_ctx(ctx)
9587 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9588
9589
9590def FloatHalf(ctx=None):
9591 """Floating-point 16-bit (half) sort."""
9592 ctx = _get_ctx(ctx)
9593 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9594
9595
9596def Float32(ctx=None):
9597 """Floating-point 32-bit (single) sort."""
9598 ctx = _get_ctx(ctx)
9599 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9600
9601
9602def FloatSingle(ctx=None):
9603 """Floating-point 32-bit (single) sort."""
9604 ctx = _get_ctx(ctx)
9605 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9606
9607
9608def Float64(ctx=None):
9609 """Floating-point 64-bit (double) sort."""
9610 ctx = _get_ctx(ctx)
9611 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9612
9613
9614def FloatDouble(ctx=None):
9615 """Floating-point 64-bit (double) sort."""
9616 ctx = _get_ctx(ctx)
9617 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9618
9619
9620def Float128(ctx=None):
9621 """Floating-point 128-bit (quadruple) sort."""
9622 ctx = _get_ctx(ctx)
9623 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9624
9625
9626def FloatQuadruple(ctx=None):
9627 """Floating-point 128-bit (quadruple) sort."""
9628 ctx = _get_ctx(ctx)
9629 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9630
9631
9632class FPRMSortRef(SortRef):
9633 """"Floating-point rounding mode sort."""
9634
9635
9636def is_fp_sort(s):
9637 """Return True if `s` is a Z3 floating-point sort.
9638
9639 >>> is_fp_sort(FPSort(8, 24))
9640 True
9641 >>> is_fp_sort(IntSort())
9642 False
9643 """
9644 return isinstance(s, FPSortRef)
9645
9646
9647def is_fprm_sort(s):
9648 """Return True if `s` is a Z3 floating-point rounding mode sort.
9649
9650 >>> is_fprm_sort(FPSort(8, 24))
9651 False
9652 >>> is_fprm_sort(RNE().sort())
9653 True
9654 """
9655 return isinstance(s, FPRMSortRef)
9656
9657# FP Expressions
9658
9659
9660class FPRef(ExprRef):
9661 """Floating-point expressions."""
9662
9663 def sort(self):
9664 """Return the sort of the floating-point expression `self`.
9665
9666 >>> x = FP('1.0', FPSort(8, 24))
9667 >>> x.sort()
9668 FPSort(8, 24)
9669 >>> x.sort() == FPSort(8, 24)
9670 True
9671 """
9672 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9673
9674 def ebits(self):
9675 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9676 >>> b = FPSort(8, 24)
9677 >>> b.ebits()
9678 8
9679 """
9680 return self.sort().ebits()
9681
9682 def sbits(self):
9683 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9684 >>> b = FPSort(8, 24)
9685 >>> b.sbits()
9686 24
9687 """
9688 return self.sort().sbits()
9689
9690 def as_string(self):
9691 """Return a Z3 floating point expression as a Python string."""
9692 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9693
9694 def __le__(self, other):
9695 return fpLEQ(self, other, self.ctx)
9696
9697 def __lt__(self, other):
9698 return fpLT(self, other, self.ctx)
9699
9700 def __ge__(self, other):
9701 return fpGEQ(self, other, self.ctx)
9702
9703 def __gt__(self, other):
9704 return fpGT(self, other, self.ctx)
9705
9706 def __add__(self, other):
9707 """Create the Z3 expression `self + other`.
9708
9709 >>> x = FP('x', FPSort(8, 24))
9710 >>> y = FP('y', FPSort(8, 24))
9711 >>> x + y
9712 x + y
9713 >>> (x + y).sort()
9714 FPSort(8, 24)
9715 """
9716 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9717 return fpAdd(_dflt_rm(), a, b, self.ctx)
9718
9719 def __radd__(self, other):
9720 """Create the Z3 expression `other + self`.
9721
9722 >>> x = FP('x', FPSort(8, 24))
9723 >>> 10 + x
9724 1.25*(2**3) + x
9725 """
9726 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9727 return fpAdd(_dflt_rm(), a, b, self.ctx)
9728
9729 def __sub__(self, other):
9730 """Create the Z3 expression `self - other`.
9731
9732 >>> x = FP('x', FPSort(8, 24))
9733 >>> y = FP('y', FPSort(8, 24))
9734 >>> x - y
9735 x - y
9736 >>> (x - y).sort()
9737 FPSort(8, 24)
9738 """
9739 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9740 return fpSub(_dflt_rm(), a, b, self.ctx)
9741
9742 def __rsub__(self, other):
9743 """Create the Z3 expression `other - self`.
9744
9745 >>> x = FP('x', FPSort(8, 24))
9746 >>> 10 - x
9747 1.25*(2**3) - x
9748 """
9749 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9750 return fpSub(_dflt_rm(), a, b, self.ctx)
9751
9752 def __mul__(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 >>> 10 * y
9762 1.25*(2**3) * y
9763 """
9764 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9765 return fpMul(_dflt_rm(), a, b, self.ctx)
9766
9767 def __rmul__(self, other):
9768 """Create the Z3 expression `other * self`.
9769
9770 >>> x = FP('x', FPSort(8, 24))
9771 >>> y = FP('y', FPSort(8, 24))
9772 >>> x * y
9773 x * y
9774 >>> x * 10
9775 x * 1.25*(2**3)
9776 """
9777 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9778 return fpMul(_dflt_rm(), a, b, self.ctx)
9779
9780 def __pos__(self):
9781 """Create the Z3 expression `+self`."""
9782 return self
9783
9784 def __neg__(self):
9785 """Create the Z3 expression `-self`.
9786
9787 >>> x = FP('x', Float32())
9788 >>> -x
9789 -x
9790 """
9791 return fpNeg(self)
9792
9793 def __div__(self, other):
9794 """Create the Z3 expression `self / other`.
9795
9796 >>> x = FP('x', FPSort(8, 24))
9797 >>> y = FP('y', FPSort(8, 24))
9798 >>> x / y
9799 x / y
9800 >>> (x / y).sort()
9801 FPSort(8, 24)
9802 >>> 10 / y
9803 1.25*(2**3) / y
9804 """
9805 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9806 return fpDiv(_dflt_rm(), a, b, self.ctx)
9807
9808 def __rdiv__(self, other):
9809 """Create the Z3 expression `other / self`.
9810
9811 >>> x = FP('x', FPSort(8, 24))
9812 >>> y = FP('y', FPSort(8, 24))
9813 >>> x / y
9814 x / y
9815 >>> x / 10
9816 x / 1.25*(2**3)
9817 """
9818 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9819 return fpDiv(_dflt_rm(), a, b, self.ctx)
9820
9821 def __truediv__(self, other):
9822 """Create the Z3 expression division `self / other`."""
9823 return self.__div__(other)
9824
9825 def __rtruediv__(self, other):
9826 """Create the Z3 expression division `other / self`."""
9827 return self.__rdiv__(other)
9828
9829 def __mod__(self, other):
9830 """Create the Z3 expression mod `self % other`."""
9831 return fpRem(self, other)
9832
9833 def __rmod__(self, other):
9834 """Create the Z3 expression mod `other % self`."""
9835 return fpRem(other, self)
9836
9837
9838class FPRMRef(ExprRef):
9839 """Floating-point rounding mode expressions"""
9840
9841 def as_string(self):
9842 """Return a Z3 floating point expression as a Python string."""
9843 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9844
9845
9846def RoundNearestTiesToEven(ctx=None):
9847 ctx = _get_ctx(ctx)
9848 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9849
9850
9851def RNE(ctx=None):
9852 ctx = _get_ctx(ctx)
9853 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9854
9855
9856def RoundNearestTiesToAway(ctx=None):
9857 ctx = _get_ctx(ctx)
9858 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9859
9860
9861def RNA(ctx=None):
9862 ctx = _get_ctx(ctx)
9863 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9864
9865
9866def RoundTowardPositive(ctx=None):
9867 ctx = _get_ctx(ctx)
9868 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9869
9870
9871def RTP(ctx=None):
9872 ctx = _get_ctx(ctx)
9873 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9874
9875
9876def RoundTowardNegative(ctx=None):
9877 ctx = _get_ctx(ctx)
9878 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9879
9880
9881def RTN(ctx=None):
9882 ctx = _get_ctx(ctx)
9883 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9884
9885
9886def RoundTowardZero(ctx=None):
9887 ctx = _get_ctx(ctx)
9888 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9889
9890
9891def RTZ(ctx=None):
9892 ctx = _get_ctx(ctx)
9893 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9894
9895
9896def is_fprm(a):
9897 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
9898
9899 >>> rm = RNE()
9900 >>> is_fprm(rm)
9901 True
9902 >>> rm = 1.0
9903 >>> is_fprm(rm)
9904 False
9905 """
9906 return isinstance(a, FPRMRef)
9907
9908
9909def is_fprm_value(a):
9910 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
9911 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
9912
9913# FP Numerals
9914
9915
9916class FPNumRef(FPRef):
9917 """The sign of the numeral.
9918
9919 >>> x = FPVal(+1.0, FPSort(8, 24))
9920 >>> x.sign()
9921 False
9922 >>> x = FPVal(-1.0, FPSort(8, 24))
9923 >>> x.sign()
9924 True
9925 """
9926
9927 def sign(self):
9928 num = (ctypes.c_int)()
9929 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
9930 if nsign is False:
9931 raise Z3Exception("error retrieving the sign of a numeral.")
9932 return num.value != 0
9933
9934 """The sign of a floating-point numeral as a bit-vector expression.
9935
9936 Remark: NaN's are invalid arguments.
9937 """
9938
9939 def sign_as_bv(self):
9940 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9941
9942 """The significand of the numeral.
9943
9944 >>> x = FPVal(2.5, FPSort(8, 24))
9945 >>> x.significand()
9946 1.25
9947 """
9948
9949 def significand(self):
9950 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
9951
9952 """The significand of the numeral as a long.
9953
9954 >>> x = FPVal(2.5, FPSort(8, 24))
9955 >>> x.significand_as_long()
9956 1.25
9957 """
9958
9959 def significand_as_long(self):
9960 ptr = (ctypes.c_ulonglong * 1)()
9961 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
9962 raise Z3Exception("error retrieving the significand of a numeral.")
9963 return ptr[0]
9964
9965 """The significand of the numeral as a bit-vector expression.
9966
9967 Remark: NaN are invalid arguments.
9968 """
9969
9970 def significand_as_bv(self):
9971 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9972
9973 """The exponent of the numeral.
9974
9975 >>> x = FPVal(2.5, FPSort(8, 24))
9976 >>> x.exponent()
9977 1
9978 """
9979
9980 def exponent(self, biased=True):
9981 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
9982
9983 """The exponent of the numeral as a long.
9984
9985 >>> x = FPVal(2.5, FPSort(8, 24))
9986 >>> x.exponent_as_long()
9987 1
9988 """
9989
9990 def exponent_as_long(self, biased=True):
9991 ptr = (ctypes.c_longlong * 1)()
9992 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
9993 raise Z3Exception("error retrieving the exponent of a numeral.")
9994 return ptr[0]
9995
9996 """The exponent of the numeral as a bit-vector expression.
9997
9998 Remark: NaNs are invalid arguments.
9999 """
10000
10001 def exponent_as_bv(self, biased=True):
10002 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10003
10004 """Indicates whether the numeral is a NaN."""
10005
10006 def isNaN(self):
10007 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10008
10009 """Indicates whether the numeral is +oo or -oo."""
10010
10011 def isInf(self):
10012 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10013
10014 """Indicates whether the numeral is +zero or -zero."""
10015
10016 def isZero(self):
10017 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10018
10019 """Indicates whether the numeral is normal."""
10020
10021 def isNormal(self):
10022 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10023
10024 """Indicates whether the numeral is subnormal."""
10025
10026 def isSubnormal(self):
10027 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10028
10029 """Indicates whether the numeral is positive."""
10030
10031 def isPositive(self):
10032 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10033
10034 """Indicates whether the numeral is negative."""
10035
10036 def isNegative(self):
10037 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10038
10039 """
10040 The string representation of the numeral.
10041
10042 >>> x = FPVal(20, FPSort(8, 24))
10043 >>> x.as_string()
10044 1.25*(2**4)
10045 """
10046
10047 def as_string(self):
10048 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10049 return ("FPVal(%s, %s)" % (s, self.sort()))
10050
10051
10052def is_fp(a):
10053 """Return `True` if `a` is a Z3 floating-point expression.
10054
10055 >>> b = FP('b', FPSort(8, 24))
10056 >>> is_fp(b)
10057 True
10058 >>> is_fp(b + 1.0)
10059 True
10060 >>> is_fp(Int('x'))
10061 False
10062 """
10063 return isinstance(a, FPRef)
10064
10065
10066def is_fp_value(a):
10067 """Return `True` if `a` is a Z3 floating-point numeral value.
10068
10069 >>> b = FP('b', FPSort(8, 24))
10070 >>> is_fp_value(b)
10071 False
10072 >>> b = FPVal(1.0, FPSort(8, 24))
10073 >>> b
10074 1
10075 >>> is_fp_value(b)
10076 True
10077 """
10078 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10079
10080
10081def FPSort(ebits, sbits, ctx=None):
10082 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10083
10084 >>> Single = FPSort(8, 24)
10085 >>> Double = FPSort(11, 53)
10086 >>> Single
10087 FPSort(8, 24)
10088 >>> x = Const('x', Single)
10089 >>> eq(x, FP('x', FPSort(8, 24)))
10090 True
10091 """
10092 ctx = _get_ctx(ctx)
10093 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10094
10095
10096def _to_float_str(val, exp=0):
10097 if isinstance(val, float):
10098 if math.isnan(val):
10099 res = "NaN"
10100 elif val == 0.0:
10101 sone = math.copysign(1.0, val)
10102 if sone < 0.0:
10103 return "-0.0"
10104 else:
10105 return "+0.0"
10106 elif val == float("+inf"):
10107 res = "+oo"
10108 elif val == float("-inf"):
10109 res = "-oo"
10110 else:
10111 v = val.as_integer_ratio()
10112 num = v[0]
10113 den = v[1]
10114 rvs = str(num) + "/" + str(den)
10115 res = rvs + "p" + _to_int_str(exp)
10116 elif isinstance(val, bool):
10117 if val:
10118 res = "1.0"
10119 else:
10120 res = "0.0"
10121 elif _is_int(val):
10122 res = str(val)
10123 elif isinstance(val, str):
10124 inx = val.find("*(2**")
10125 if inx == -1:
10126 res = val
10127 elif val[-1] == ")":
10128 res = val[0:inx]
10129 exp = str(int(val[inx + 5:-1]) + int(exp))
10130 else:
10131 _z3_assert(False, "String does not have floating-point numeral form.")
10132 elif z3_debug():
10133 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10134 if exp == 0:
10135 return res
10136 else:
10137 return res + "p" + exp
10138
10139
10140def fpNaN(s):
10141 """Create a Z3 floating-point NaN term.
10142
10143 >>> s = FPSort(8, 24)
10144 >>> set_fpa_pretty(True)
10145 >>> fpNaN(s)
10146 NaN
10147 >>> pb = get_fpa_pretty()
10148 >>> set_fpa_pretty(False)
10149 >>> fpNaN(s)
10150 fpNaN(FPSort(8, 24))
10151 >>> set_fpa_pretty(pb)
10152 """
10153 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10154 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10155
10156
10157def fpPlusInfinity(s):
10158 """Create a Z3 floating-point +oo term.
10159
10160 >>> s = FPSort(8, 24)
10161 >>> pb = get_fpa_pretty()
10162 >>> set_fpa_pretty(True)
10163 >>> fpPlusInfinity(s)
10164 +oo
10165 >>> set_fpa_pretty(False)
10166 >>> fpPlusInfinity(s)
10167 fpPlusInfinity(FPSort(8, 24))
10168 >>> set_fpa_pretty(pb)
10169 """
10170 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10171 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10172
10173
10174def fpMinusInfinity(s):
10175 """Create a Z3 floating-point -oo term."""
10176 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10177 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10178
10179
10180def fpInfinity(s, negative):
10181 """Create a Z3 floating-point +oo or -oo term."""
10182 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10183 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10184 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10185
10186
10187def fpPlusZero(s):
10188 """Create a Z3 floating-point +0.0 term."""
10189 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10190 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10191
10192
10193def fpMinusZero(s):
10194 """Create a Z3 floating-point -0.0 term."""
10195 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10196 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10197
10198
10199def fpZero(s, negative):
10200 """Create a Z3 floating-point +0.0 or -0.0 term."""
10201 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10202 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10203 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10204
10205
10206def FPVal(sig, exp=None, fps=None, ctx=None):
10207 """Return a floating-point value of value `val` and sort `fps`.
10208 If `ctx=None`, then the global context is used.
10209
10210 >>> v = FPVal(20.0, FPSort(8, 24))
10211 >>> v
10212 1.25*(2**4)
10213 >>> print("0x%.8x" % v.exponent_as_long(False))
10214 0x00000004
10215 >>> v = FPVal(2.25, FPSort(8, 24))
10216 >>> v
10217 1.125*(2**1)
10218 >>> v = FPVal(-2.25, FPSort(8, 24))
10219 >>> v
10220 -1.125*(2**1)
10221 >>> FPVal(-0.0, FPSort(8, 24))
10222 -0.0
10223 >>> FPVal(0.0, FPSort(8, 24))
10224 +0.0
10225 >>> FPVal(+0.0, FPSort(8, 24))
10226 +0.0
10227 """
10228 ctx = _get_ctx(ctx)
10229 if is_fp_sort(exp):
10230 fps = exp
10231 exp = None
10232 elif fps is None:
10233 fps = _dflt_fps(ctx)
10234 _z3_assert(is_fp_sort(fps), "sort mismatch")
10235 if exp is None:
10236 exp = 0
10237 val = _to_float_str(sig)
10238 if val == "NaN" or val == "nan":
10239 return fpNaN(fps)
10240 elif val == "-0.0":
10241 return fpMinusZero(fps)
10242 elif val == "0.0" or val == "+0.0":
10243 return fpPlusZero(fps)
10244 elif val == "+oo" or val == "+inf" or val == "+Inf":
10245 return fpPlusInfinity(fps)
10246 elif val == "-oo" or val == "-inf" or val == "-Inf":
10247 return fpMinusInfinity(fps)
10248 else:
10249 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10250
10251
10252def FP(name, fpsort, ctx=None):
10253 """Return a floating-point constant named `name`.
10254 `fpsort` is the floating-point sort.
10255 If `ctx=None`, then the global context is used.
10256
10257 >>> x = FP('x', FPSort(8, 24))
10258 >>> is_fp(x)
10259 True
10260 >>> x.ebits()
10261 8
10262 >>> x.sort()
10263 FPSort(8, 24)
10264 >>> word = FPSort(8, 24)
10265 >>> x2 = FP('x', word)
10266 >>> eq(x, x2)
10267 True
10268 """
10269 if isinstance(fpsort, FPSortRef) and ctx is None:
10270 ctx = fpsort.ctx
10271 else:
10272 ctx = _get_ctx(ctx)
10273 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10274
10275
10276def FPs(names, fpsort, ctx=None):
10277 """Return an array of floating-point constants.
10278
10279 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10280 >>> x.sort()
10281 FPSort(8, 24)
10282 >>> x.sbits()
10283 24
10284 >>> x.ebits()
10285 8
10286 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10287 (x + y) * z
10288 """
10289 ctx = _get_ctx(ctx)
10290 if isinstance(names, str):
10291 names = names.split(" ")
10292 return [FP(name, fpsort, ctx) for name in names]
10293
10294
10295def fpAbs(a, ctx=None):
10296 """Create a Z3 floating-point absolute value expression.
10297
10298 >>> s = FPSort(8, 24)
10299 >>> rm = RNE()
10300 >>> x = FPVal(1.0, s)
10301 >>> fpAbs(x)
10302 fpAbs(1)
10303 >>> y = FPVal(-20.0, s)
10304 >>> y
10305 -1.25*(2**4)
10306 >>> fpAbs(y)
10307 fpAbs(-1.25*(2**4))
10308 >>> fpAbs(-1.25*(2**4))
10309 fpAbs(-1.25*(2**4))
10310 >>> fpAbs(x).sort()
10311 FPSort(8, 24)
10312 """
10313 ctx = _get_ctx(ctx)
10314 [a] = _coerce_fp_expr_list([a], ctx)
10315 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10316
10317
10318def fpNeg(a, ctx=None):
10319 """Create a Z3 floating-point addition expression.
10320
10321 >>> s = FPSort(8, 24)
10322 >>> rm = RNE()
10323 >>> x = FP('x', s)
10324 >>> fpNeg(x)
10325 -x
10326 >>> fpNeg(x).sort()
10327 FPSort(8, 24)
10328 """
10329 ctx = _get_ctx(ctx)
10330 [a] = _coerce_fp_expr_list([a], ctx)
10331 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10332
10333
10334def _mk_fp_unary(f, rm, a, ctx):
10335 ctx = _get_ctx(ctx)
10336 [a] = _coerce_fp_expr_list([a], ctx)
10337 if z3_debug():
10338 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10339 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10340 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10341
10342
10343def _mk_fp_unary_pred(f, a, ctx):
10344 ctx = _get_ctx(ctx)
10345 [a] = _coerce_fp_expr_list([a], ctx)
10346 if z3_debug():
10347 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10348 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10349
10350
10351def _mk_fp_bin(f, rm, a, b, ctx):
10352 ctx = _get_ctx(ctx)
10353 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10354 if z3_debug():
10355 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10356 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10357 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10358
10359
10360def _mk_fp_bin_norm(f, a, b, ctx):
10361 ctx = _get_ctx(ctx)
10362 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10363 if z3_debug():
10364 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10365 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10366
10367
10368def _mk_fp_bin_pred(f, a, b, ctx):
10369 ctx = _get_ctx(ctx)
10370 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10371 if z3_debug():
10372 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10373 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10374
10375
10376def _mk_fp_tern(f, rm, a, b, c, ctx):
10377 ctx = _get_ctx(ctx)
10378 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10379 if z3_debug():
10380 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10381 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10382 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10383 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10384
10385
10386def fpAdd(rm, a, b, ctx=None):
10387 """Create a Z3 floating-point addition expression.
10388
10389 >>> s = FPSort(8, 24)
10390 >>> rm = RNE()
10391 >>> x = FP('x', s)
10392 >>> y = FP('y', s)
10393 >>> fpAdd(rm, x, y)
10394 x + y
10395 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10396 fpAdd(RTZ(), x, y)
10397 >>> fpAdd(rm, x, y).sort()
10398 FPSort(8, 24)
10399 """
10400 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10401
10402
10403def fpSub(rm, a, b, ctx=None):
10404 """Create a Z3 floating-point subtraction expression.
10405
10406 >>> s = FPSort(8, 24)
10407 >>> rm = RNE()
10408 >>> x = FP('x', s)
10409 >>> y = FP('y', s)
10410 >>> fpSub(rm, x, y)
10411 x - y
10412 >>> fpSub(rm, x, y).sort()
10413 FPSort(8, 24)
10414 """
10415 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10416
10417
10418def fpMul(rm, a, b, ctx=None):
10419 """Create a Z3 floating-point multiplication expression.
10420
10421 >>> s = FPSort(8, 24)
10422 >>> rm = RNE()
10423 >>> x = FP('x', s)
10424 >>> y = FP('y', s)
10425 >>> fpMul(rm, x, y)
10426 x * y
10427 >>> fpMul(rm, x, y).sort()
10428 FPSort(8, 24)
10429 """
10430 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10431
10432
10433def fpDiv(rm, a, b, ctx=None):
10434 """Create a Z3 floating-point division expression.
10435
10436 >>> s = FPSort(8, 24)
10437 >>> rm = RNE()
10438 >>> x = FP('x', s)
10439 >>> y = FP('y', s)
10440 >>> fpDiv(rm, x, y)
10441 x / y
10442 >>> fpDiv(rm, x, y).sort()
10443 FPSort(8, 24)
10444 """
10445 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10446
10447
10448def fpRem(a, b, ctx=None):
10449 """Create a Z3 floating-point remainder expression.
10450
10451 >>> s = FPSort(8, 24)
10452 >>> x = FP('x', s)
10453 >>> y = FP('y', s)
10454 >>> fpRem(x, y)
10455 fpRem(x, y)
10456 >>> fpRem(x, y).sort()
10457 FPSort(8, 24)
10458 """
10459 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10460
10461
10462def fpMin(a, b, ctx=None):
10463 """Create a Z3 floating-point minimum expression.
10464
10465 >>> s = FPSort(8, 24)
10466 >>> rm = RNE()
10467 >>> x = FP('x', s)
10468 >>> y = FP('y', s)
10469 >>> fpMin(x, y)
10470 fpMin(x, y)
10471 >>> fpMin(x, y).sort()
10472 FPSort(8, 24)
10473 """
10474 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10475
10476
10477def fpMax(a, b, ctx=None):
10478 """Create a Z3 floating-point maximum expression.
10479
10480 >>> s = FPSort(8, 24)
10481 >>> rm = RNE()
10482 >>> x = FP('x', s)
10483 >>> y = FP('y', s)
10484 >>> fpMax(x, y)
10485 fpMax(x, y)
10486 >>> fpMax(x, y).sort()
10487 FPSort(8, 24)
10488 """
10489 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10490
10491
10492def fpFMA(rm, a, b, c, ctx=None):
10493 """Create a Z3 floating-point fused multiply-add expression.
10494 """
10495 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10496
10497
10498def fpSqrt(rm, a, ctx=None):
10499 """Create a Z3 floating-point square root expression.
10500 """
10501 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10502
10503
10504def fpRoundToIntegral(rm, a, ctx=None):
10505 """Create a Z3 floating-point roundToIntegral expression.
10506 """
10507 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10508
10509
10510def fpIsNaN(a, ctx=None):
10511 """Create a Z3 floating-point isNaN expression.
10512
10513 >>> s = FPSort(8, 24)
10514 >>> x = FP('x', s)
10515 >>> y = FP('y', s)
10516 >>> fpIsNaN(x)
10517 fpIsNaN(x)
10518 """
10519 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10520
10521
10522def fpIsInf(a, ctx=None):
10523 """Create a Z3 floating-point isInfinite expression.
10524
10525 >>> s = FPSort(8, 24)
10526 >>> x = FP('x', s)
10527 >>> fpIsInf(x)
10528 fpIsInf(x)
10529 """
10530 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10531
10532
10533def fpIsZero(a, ctx=None):
10534 """Create a Z3 floating-point isZero expression.
10535 """
10536 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10537
10538
10539def fpIsNormal(a, ctx=None):
10540 """Create a Z3 floating-point isNormal expression.
10541 """
10542 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10543
10544
10545def fpIsSubnormal(a, ctx=None):
10546 """Create a Z3 floating-point isSubnormal expression.
10547 """
10548 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10549
10550
10551def fpIsNegative(a, ctx=None):
10552 """Create a Z3 floating-point isNegative expression.
10553 """
10554 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10555
10556
10557def fpIsPositive(a, ctx=None):
10558 """Create a Z3 floating-point isPositive expression.
10559 """
10560 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10561
10562
10563def _check_fp_args(a, b):
10564 if z3_debug():
10565 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10566
10567
10568def fpLT(a, b, ctx=None):
10569 """Create the Z3 floating-point expression `other < self`.
10570
10571 >>> x, y = FPs('x y', FPSort(8, 24))
10572 >>> fpLT(x, y)
10573 x < y
10574 >>> (x < y).sexpr()
10575 '(fp.lt x y)'
10576 """
10577 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10578
10579
10580def fpLEQ(a, b, ctx=None):
10581 """Create the Z3 floating-point expression `other <= self`.
10582
10583 >>> x, y = FPs('x y', FPSort(8, 24))
10584 >>> fpLEQ(x, y)
10585 x <= y
10586 >>> (x <= y).sexpr()
10587 '(fp.leq x y)'
10588 """
10589 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10590
10591
10592def fpGT(a, b, ctx=None):
10593 """Create the Z3 floating-point expression `other > self`.
10594
10595 >>> x, y = FPs('x y', FPSort(8, 24))
10596 >>> fpGT(x, y)
10597 x > y
10598 >>> (x > y).sexpr()
10599 '(fp.gt x y)'
10600 """
10601 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10602
10603
10604def fpGEQ(a, b, ctx=None):
10605 """Create the Z3 floating-point expression `other >= self`.
10606
10607 >>> x, y = FPs('x y', FPSort(8, 24))
10608 >>> fpGEQ(x, y)
10609 x >= y
10610 >>> (x >= y).sexpr()
10611 '(fp.geq x y)'
10612 """
10613 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10614
10615
10616def fpEQ(a, b, ctx=None):
10617 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10618
10619 >>> x, y = FPs('x y', FPSort(8, 24))
10620 >>> fpEQ(x, y)
10621 fpEQ(x, y)
10622 >>> fpEQ(x, y).sexpr()
10623 '(fp.eq x y)'
10624 """
10625 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10626
10627
10628def fpNEQ(a, b, ctx=None):
10629 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10630
10631 >>> x, y = FPs('x y', FPSort(8, 24))
10632 >>> fpNEQ(x, y)
10633 Not(fpEQ(x, y))
10634 >>> (x != y).sexpr()
10635 '(distinct x y)'
10636 """
10637 return Not(fpEQ(a, b, ctx))
10638
10639
10640def fpFP(sgn, exp, sig, ctx=None):
10641 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10642
10643 >>> s = FPSort(8, 24)
10644 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10645 >>> print(x)
10646 fpFP(1, 127, 4194304)
10647 >>> xv = FPVal(-1.5, s)
10648 >>> print(xv)
10649 -1.5
10650 >>> slvr = Solver()
10651 >>> slvr.add(fpEQ(x, xv))
10652 >>> slvr.check()
10653 sat
10654 >>> xv = FPVal(+1.5, s)
10655 >>> print(xv)
10656 1.5
10657 >>> slvr = Solver()
10658 >>> slvr.add(fpEQ(x, xv))
10659 >>> slvr.check()
10660 unsat
10661 """
10662 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10663 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10664 ctx = _get_ctx(ctx)
10665 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10666 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10667
10668
10669def fpToFP(a1, a2=None, a3=None, ctx=None):
10670 """Create a Z3 floating-point conversion expression from other term sorts
10671 to floating-point.
10672
10673 From a bit-vector term in IEEE 754-2008 format:
10674 >>> x = FPVal(1.0, Float32())
10675 >>> x_bv = fpToIEEEBV(x)
10676 >>> simplify(fpToFP(x_bv, Float32()))
10677 1
10678
10679 From a floating-point term with different precision:
10680 >>> x = FPVal(1.0, Float32())
10681 >>> x_db = fpToFP(RNE(), x, Float64())
10682 >>> x_db.sort()
10683 FPSort(11, 53)
10684
10685 From a real term:
10686 >>> x_r = RealVal(1.5)
10687 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10688 1.5
10689
10690 From a signed bit-vector term:
10691 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10692 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10693 -1.25*(2**2)
10694 """
10695 ctx = _get_ctx(ctx)
10696 if is_bv(a1) and is_fp_sort(a2):
10697 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10698 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10699 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10700 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10701 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10702 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10703 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10704 else:
10705 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10706
10707
10708def fpBVToFP(v, sort, ctx=None):
10709 """Create a Z3 floating-point conversion expression that represents the
10710 conversion from a bit-vector term to a floating-point term.
10711
10712 >>> x_bv = BitVecVal(0x3F800000, 32)
10713 >>> x_fp = fpBVToFP(x_bv, Float32())
10714 >>> x_fp
10715 fpToFP(1065353216)
10716 >>> simplify(x_fp)
10717 1
10718 """
10719 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10720 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10721 ctx = _get_ctx(ctx)
10722 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10723
10724
10725def fpFPToFP(rm, v, sort, ctx=None):
10726 """Create a Z3 floating-point conversion expression that represents the
10727 conversion from a floating-point term to a floating-point term of different precision.
10728
10729 >>> x_sgl = FPVal(1.0, Float32())
10730 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10731 >>> x_dbl
10732 fpToFP(RNE(), 1)
10733 >>> simplify(x_dbl)
10734 1
10735 >>> x_dbl.sort()
10736 FPSort(11, 53)
10737 """
10738 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10739 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10740 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10741 ctx = _get_ctx(ctx)
10742 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10743
10744
10745def fpRealToFP(rm, v, sort, ctx=None):
10746 """Create a Z3 floating-point conversion expression that represents the
10747 conversion from a real term to a floating-point term.
10748
10749 >>> x_r = RealVal(1.5)
10750 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10751 >>> x_fp
10752 fpToFP(RNE(), 3/2)
10753 >>> simplify(x_fp)
10754 1.5
10755 """
10756 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10757 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10758 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10759 ctx = _get_ctx(ctx)
10760 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10761
10762
10763def fpSignedToFP(rm, v, sort, ctx=None):
10764 """Create a Z3 floating-point conversion expression that represents the
10765 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10766
10767 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10768 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10769 >>> x_fp
10770 fpToFP(RNE(), 4294967291)
10771 >>> simplify(x_fp)
10772 -1.25*(2**2)
10773 """
10774 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10775 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10776 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10777 ctx = _get_ctx(ctx)
10778 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10779
10780
10781def fpUnsignedToFP(rm, v, sort, ctx=None):
10782 """Create a Z3 floating-point conversion expression that represents the
10783 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10784
10785 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10786 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10787 >>> x_fp
10788 fpToFPUnsigned(RNE(), 4294967291)
10789 >>> simplify(x_fp)
10790 1*(2**32)
10791 """
10792 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10793 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10794 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10795 ctx = _get_ctx(ctx)
10796 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10797
10798
10799def fpToFPUnsigned(rm, x, s, ctx=None):
10800 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10801 if z3_debug():
10802 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10803 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10804 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10805 ctx = _get_ctx(ctx)
10806 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10807
10808
10809def fpToSBV(rm, x, s, ctx=None):
10810 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10811
10812 >>> x = FP('x', FPSort(8, 24))
10813 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10814 >>> print(is_fp(x))
10815 True
10816 >>> print(is_bv(y))
10817 True
10818 >>> print(is_fp(y))
10819 False
10820 >>> print(is_bv(x))
10821 False
10822 """
10823 if z3_debug():
10824 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10825 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10826 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10827 ctx = _get_ctx(ctx)
10828 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10829
10830
10831def fpToUBV(rm, x, s, ctx=None):
10832 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10833
10834 >>> x = FP('x', FPSort(8, 24))
10835 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10836 >>> print(is_fp(x))
10837 True
10838 >>> print(is_bv(y))
10839 True
10840 >>> print(is_fp(y))
10841 False
10842 >>> print(is_bv(x))
10843 False
10844 """
10845 if z3_debug():
10846 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10847 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10848 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10849 ctx = _get_ctx(ctx)
10850 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10851
10852
10853def fpToReal(x, ctx=None):
10854 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
10855
10856 >>> x = FP('x', FPSort(8, 24))
10857 >>> y = fpToReal(x)
10858 >>> print(is_fp(x))
10859 True
10860 >>> print(is_real(y))
10861 True
10862 >>> print(is_fp(y))
10863 False
10864 >>> print(is_real(x))
10865 False
10866 """
10867 if z3_debug():
10868 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10869 ctx = _get_ctx(ctx)
10870 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
10871
10872
10873def fpToIEEEBV(x, ctx=None):
10874 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
10875
10876 The size of the resulting bit-vector is automatically determined.
10877
10878 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
10879 knows only one NaN and it will always produce the same bit-vector representation of
10880 that NaN.
10881
10882 >>> x = FP('x', FPSort(8, 24))
10883 >>> y = fpToIEEEBV(x)
10884 >>> print(is_fp(x))
10885 True
10886 >>> print(is_bv(y))
10887 True
10888 >>> print(is_fp(y))
10889 False
10890 >>> print(is_bv(x))
10891 False
10892 """
10893 if z3_debug():
10894 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10895 ctx = _get_ctx(ctx)
10896 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
10897
10898
10899#########################################
10900#
10901# Strings, Sequences and Regular expressions
10902#
10903#########################################
10904
10905class SeqSortRef(SortRef):
10906 """Sequence sort."""
10907
10908 def is_string(self):
10909 """Determine if sort is a string
10910 >>> s = StringSort()
10911 >>> s.is_string()
10912 True
10913 >>> s = SeqSort(IntSort())
10914 >>> s.is_string()
10915 False
10916 """
10917 return Z3_is_string_sort(self.ctx_ref(), self.ast)
10918
10919 def basis(self):
10920 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10921
10922class CharSortRef(SortRef):
10923 """Character sort."""
10924
10925
10926def StringSort(ctx=None):
10927 """Create a string sort
10928 >>> s = StringSort()
10929 >>> print(s)
10930 String
10931 """
10932 ctx = _get_ctx(ctx)
10933 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
10934
10935def CharSort(ctx=None):
10936 """Create a character sort
10937 >>> ch = CharSort()
10938 >>> print(ch)
10939 Char
10940 """
10941 ctx = _get_ctx(ctx)
10942 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
10943
10944
10945def SeqSort(s):
10946 """Create a sequence sort over elements provided in the argument
10947 >>> s = SeqSort(IntSort())
10948 >>> s == Unit(IntVal(1)).sort()
10949 True
10950 """
10951 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
10952
10953
10954class SeqRef(ExprRef):
10955 """Sequence expression."""
10956
10957 def sort(self):
10958 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
10959
10960 def __add__(self, other):
10961 return Concat(self, other)
10962
10963 def __radd__(self, other):
10964 return Concat(other, self)
10965
10966 def __getitem__(self, i):
10967 if _is_int(i):
10968 i = IntVal(i, self.ctx)
10969 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
10970
10971 def at(self, i):
10972 if _is_int(i):
10973 i = IntVal(i, self.ctx)
10974 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
10975
10976 def is_string(self):
10977 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
10978
10979 def is_string_value(self):
10980 return Z3_is_string(self.ctx_ref(), self.as_ast())
10981
10982 def as_string(self):
10983 """Return a string representation of sequence expression."""
10984 if self.is_string_value():
10985 string_length = ctypes.c_uint()
10986 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
10987 return string_at(chars, size=string_length.value).decode("latin-1")
10988 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10989
10990 def __le__(self, other):
10991 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10992
10993 def __lt__(self, other):
10994 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
10995
10996 def __ge__(self, other):
10997 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
10998
10999 def __gt__(self, other):
11000 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11001
11002
11003def _coerce_char(ch, ctx=None):
11004 if isinstance(ch, str):
11005 ctx = _get_ctx(ctx)
11006 ch = CharVal(ch, ctx)
11007 if not is_expr(ch):
11008 raise Z3Exception("Character expression expected")
11009 return ch
11010
11011class CharRef(ExprRef):
11012 """Character expression."""
11013
11014 def __le__(self, other):
11015 other = _coerce_char(other, self.ctx)
11016 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11017
11018 def to_int(self):
11019 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11020
11021 def to_bv(self):
11022 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11023
11024 def is_digit(self):
11025 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11026
11027
11028def CharVal(ch, ctx=None):
11029 ctx = _get_ctx(ctx)
11030 if isinstance(ch, str):
11031 ch = ord(ch)
11032 if not isinstance(ch, int):
11033 raise Z3Exception("character value should be an ordinal")
11034 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11035
11036def CharFromBv(bv):
11037 if not is_expr(bv):
11038 raise Z3Exception("Bit-vector expression needed")
11039 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11040
11041def CharToBv(ch, ctx=None):
11042 ch = _coerce_char(ch, ctx)
11043 return ch.to_bv()
11044
11045def CharToInt(ch, ctx=None):
11046 ch = _coerce_char(ch, ctx)
11047 return ch.to_int()
11048
11049def CharIsDigit(ch, ctx=None):
11050 ch = _coerce_char(ch, ctx)
11051 return ch.is_digit()
11052
11053def _coerce_seq(s, ctx=None):
11054 if isinstance(s, str):
11055 ctx = _get_ctx(ctx)
11056 s = StringVal(s, ctx)
11057 if not is_expr(s):
11058 raise Z3Exception("Non-expression passed as a sequence")
11059 if not is_seq(s):
11060 raise Z3Exception("Non-sequence passed as a sequence")
11061 return s
11062
11063
11064def _get_ctx2(a, b, ctx=None):
11065 if is_expr(a):
11066 return a.ctx
11067 if is_expr(b):
11068 return b.ctx
11069 if ctx is None:
11070 ctx = main_ctx()
11071 return ctx
11072
11073
11074def is_seq(a):
11075 """Return `True` if `a` is a Z3 sequence expression.
11076 >>> print (is_seq(Unit(IntVal(0))))
11077 True
11078 >>> print (is_seq(StringVal("abc")))
11079 True
11080 """
11081 return isinstance(a, SeqRef)
11082
11083
11084def is_string(a):
11085 """Return `True` if `a` is a Z3 string expression.
11086 >>> print (is_string(StringVal("ab")))
11087 True
11088 """
11089 return isinstance(a, SeqRef) and a.is_string()
11090
11091
11092def is_string_value(a):
11093 """return 'True' if 'a' is a Z3 string constant expression.
11094 >>> print (is_string_value(StringVal("a")))
11095 True
11096 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11097 False
11098 """
11099 return isinstance(a, SeqRef) and a.is_string_value()
11100
11101def StringVal(s, ctx=None):
11102 """create a string expression"""
11103 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11104 ctx = _get_ctx(ctx)
11105 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11106
11107
11108def String(name, ctx=None):
11109 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11110
11111 >>> x = String('x')
11112 """
11113 ctx = _get_ctx(ctx)
11114 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11115
11116
11117def Strings(names, ctx=None):
11118 """Return a tuple of String constants. """
11119 ctx = _get_ctx(ctx)
11120 if isinstance(names, str):
11121 names = names.split(" ")
11122 return [String(name, ctx) for name in names]
11123
11124
11125def SubString(s, offset, length):
11126 """Extract substring or subsequence starting at offset"""
11127 return Extract(s, offset, length)
11128
11129
11130def SubSeq(s, offset, length):
11131 """Extract substring or subsequence starting at offset"""
11132 return Extract(s, offset, length)
11133
11134
11135def Empty(s):
11136 """Create the empty sequence of the given sort
11137 >>> e = Empty(StringSort())
11138 >>> e2 = StringVal("")
11139 >>> print(e.eq(e2))
11140 True
11141 >>> e3 = Empty(SeqSort(IntSort()))
11142 >>> print(e3)
11143 Empty(Seq(Int))
11144 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11145 >>> print(e4)
11146 Empty(ReSort(Seq(Int)))
11147 """
11148 if isinstance(s, SeqSortRef):
11149 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11150 if isinstance(s, ReSortRef):
11151 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11152 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11153
11154
11155def Full(s):
11156 """Create the regular expression that accepts the universal language
11157 >>> e = Full(ReSort(SeqSort(IntSort())))
11158 >>> print(e)
11159 Full(ReSort(Seq(Int)))
11160 >>> e1 = Full(ReSort(StringSort()))
11161 >>> print(e1)
11162 Full(ReSort(String))
11163 """
11164 if isinstance(s, ReSortRef):
11165 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11166 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11167
11168
11169
11170def Unit(a):
11171 """Create a singleton sequence"""
11172 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11173
11174
11175def PrefixOf(a, b):
11176 """Check if 'a' is a prefix of 'b'
11177 >>> s1 = PrefixOf("ab", "abc")
11178 >>> simplify(s1)
11179 True
11180 >>> s2 = PrefixOf("bc", "abc")
11181 >>> simplify(s2)
11182 False
11183 """
11184 ctx = _get_ctx2(a, b)
11185 a = _coerce_seq(a, ctx)
11186 b = _coerce_seq(b, ctx)
11187 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11188
11189
11190def SuffixOf(a, b):
11191 """Check if 'a' is a suffix of 'b'
11192 >>> s1 = SuffixOf("ab", "abc")
11193 >>> simplify(s1)
11194 False
11195 >>> s2 = SuffixOf("bc", "abc")
11196 >>> simplify(s2)
11197 True
11198 """
11199 ctx = _get_ctx2(a, b)
11200 a = _coerce_seq(a, ctx)
11201 b = _coerce_seq(b, ctx)
11202 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11203
11204
11205def Contains(a, b):
11206 """Check if 'a' contains 'b'
11207 >>> s1 = Contains("abc", "ab")
11208 >>> simplify(s1)
11209 True
11210 >>> s2 = Contains("abc", "bc")
11211 >>> simplify(s2)
11212 True
11213 >>> x, y, z = Strings('x y z')
11214 >>> s3 = Contains(Concat(x,y,z), y)
11215 >>> simplify(s3)
11216 True
11217 """
11218 ctx = _get_ctx2(a, b)
11219 a = _coerce_seq(a, ctx)
11220 b = _coerce_seq(b, ctx)
11221 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11222
11223
11224def Replace(s, src, dst):
11225 """Replace the first occurrence of 'src' by 'dst' in 's'
11226 >>> r = Replace("aaa", "a", "b")
11227 >>> simplify(r)
11228 "baa"
11229 """
11230 ctx = _get_ctx2(dst, s)
11231 if ctx is None and is_expr(src):
11232 ctx = src.ctx
11233 src = _coerce_seq(src, ctx)
11234 dst = _coerce_seq(dst, ctx)
11235 s = _coerce_seq(s, ctx)
11236 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11237
11238
11239def IndexOf(s, substr, offset=None):
11240 """Retrieve the index of substring within a string starting at a specified offset.
11241 >>> simplify(IndexOf("abcabc", "bc", 0))
11242 1
11243 >>> simplify(IndexOf("abcabc", "bc", 2))
11244 4
11245 """
11246 if offset is None:
11247 offset = IntVal(0)
11248 ctx = None
11249 if is_expr(offset):
11250 ctx = offset.ctx
11251 ctx = _get_ctx2(s, substr, ctx)
11252 s = _coerce_seq(s, ctx)
11253 substr = _coerce_seq(substr, ctx)
11254 if _is_int(offset):
11255 offset = IntVal(offset, ctx)
11256 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11257
11258
11259def LastIndexOf(s, substr):
11260 """Retrieve the last index of substring within a string"""
11261 ctx = None
11262 ctx = _get_ctx2(s, substr, ctx)
11263 s = _coerce_seq(s, ctx)
11264 substr = _coerce_seq(substr, ctx)
11265 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11266
11267
11268def Length(s):
11269 """Obtain the length of a sequence 's'
11270 >>> l = Length(StringVal("abc"))
11271 >>> simplify(l)
11272 3
11273 """
11274 s = _coerce_seq(s)
11275 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11276
11277def SeqMap(f, s):
11278 """Map function 'f' over sequence 's'"""
11279 ctx = _get_ctx2(f, s)
11280 s = _coerce_seq(s, ctx)
11281 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11282
11283def SeqMapI(f, i, s):
11284 """Map function 'f' over sequence 's' at index 'i'"""
11285 ctx = _get_ctx(f, s)
11286 s = _coerce_seq(s, ctx)
11287 if not is_expr(i):
11288 i = _py2expr(i)
11289 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11290
11291def SeqFoldLeft(f, a, s):
11292 ctx = _get_ctx2(f, s)
11293 s = _coerce_seq(s, ctx)
11294 a = _py2expr(a)
11295 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11296
11297def SeqFoldLeftI(f, i, a, s):
11298 ctx = _get_ctx2(f, s)
11299 s = _coerce_seq(s, ctx)
11300 a = _py2expr(a)
11301 i = _py2epxr(i)
11302 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11303
11304def StrToInt(s):
11305 """Convert string expression to integer
11306 >>> a = StrToInt("1")
11307 >>> simplify(1 == a)
11308 True
11309 >>> b = StrToInt("2")
11310 >>> simplify(1 == b)
11311 False
11312 >>> c = StrToInt(IntToStr(2))
11313 >>> simplify(1 == c)
11314 False
11315 """
11316 s = _coerce_seq(s)
11317 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11318
11319
11320def IntToStr(s):
11321 """Convert integer expression to string"""
11322 if not is_expr(s):
11323 s = _py2expr(s)
11324 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11325
11326
11327def StrToCode(s):
11328 """Convert a unit length string to integer code"""
11329 if not is_expr(s):
11330 s = _py2expr(s)
11331 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11332
11333def StrFromCode(c):
11334 """Convert code to a string"""
11335 if not is_expr(c):
11336 c = _py2expr(c)
11337 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11338
11339def Re(s, ctx=None):
11340 """The regular expression that accepts sequence 's'
11341 >>> s1 = Re("ab")
11342 >>> s2 = Re(StringVal("ab"))
11343 >>> s3 = Re(Unit(BoolVal(True)))
11344 """
11345 s = _coerce_seq(s, ctx)
11346 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11347
11348
11349# Regular expressions
11350
11351class ReSortRef(SortRef):
11352 """Regular expression sort."""
11353
11354 def basis(self):
11355 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11356
11357
11358def ReSort(s):
11359 if is_ast(s):
11360 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11361 if s is None or isinstance(s, Context):
11362 ctx = _get_ctx(s)
11363 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11364 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11365
11366
11367class ReRef(ExprRef):
11368 """Regular expressions."""
11369
11370 def __add__(self, other):
11371 return Union(self, other)
11372
11373
11374def is_re(s):
11375 return isinstance(s, ReRef)
11376
11377
11378def InRe(s, re):
11379 """Create regular expression membership test
11380 >>> re = Union(Re("a"),Re("b"))
11381 >>> print (simplify(InRe("a", re)))
11382 True
11383 >>> print (simplify(InRe("b", re)))
11384 True
11385 >>> print (simplify(InRe("c", re)))
11386 False
11387 """
11388 s = _coerce_seq(s, re.ctx)
11389 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11390
11391
11392def Union(*args):
11393 """Create union of regular expressions.
11394 >>> re = Union(Re("a"), Re("b"), Re("c"))
11395 >>> print (simplify(InRe("d", re)))
11396 False
11397 """
11398 args = _get_args(args)
11399 sz = len(args)
11400 if z3_debug():
11401 _z3_assert(sz > 0, "At least one argument expected.")
11402 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11403 if sz == 1:
11404 return args[0]
11405 ctx = args[0].ctx
11406 v = (Ast * sz)()
11407 for i in range(sz):
11408 v[i] = args[i].as_ast()
11409 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11410
11411
11412def Intersect(*args):
11413 """Create intersection of regular expressions.
11414 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11415 """
11416 args = _get_args(args)
11417 sz = len(args)
11418 if z3_debug():
11419 _z3_assert(sz > 0, "At least one argument expected.")
11420 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11421 if sz == 1:
11422 return args[0]
11423 ctx = args[0].ctx
11424 v = (Ast * sz)()
11425 for i in range(sz):
11426 v[i] = args[i].as_ast()
11427 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11428
11429
11430def Plus(re):
11431 """Create the regular expression accepting one or more repetitions of argument.
11432 >>> re = Plus(Re("a"))
11433 >>> print(simplify(InRe("aa", re)))
11434 True
11435 >>> print(simplify(InRe("ab", re)))
11436 False
11437 >>> print(simplify(InRe("", re)))
11438 False
11439 """
11440 if z3_debug():
11441 _z3_assert(is_expr(re), "expression expected")
11442 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11443
11444
11445def Option(re):
11446 """Create the regular expression that optionally accepts the argument.
11447 >>> re = Option(Re("a"))
11448 >>> print(simplify(InRe("a", re)))
11449 True
11450 >>> print(simplify(InRe("", re)))
11451 True
11452 >>> print(simplify(InRe("aa", re)))
11453 False
11454 """
11455 if z3_debug():
11456 _z3_assert(is_expr(re), "expression expected")
11457 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11458
11459
11460def Complement(re):
11461 """Create the complement regular expression."""
11462 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11463
11464
11465def Star(re):
11466 """Create the regular expression accepting zero or more repetitions of argument.
11467 >>> re = Star(Re("a"))
11468 >>> print(simplify(InRe("aa", re)))
11469 True
11470 >>> print(simplify(InRe("ab", re)))
11471 False
11472 >>> print(simplify(InRe("", re)))
11473 True
11474 """
11475 if z3_debug():
11476 _z3_assert(is_expr(re), "expression expected")
11477 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11478
11479
11480def Loop(re, lo, hi=0):
11481 """Create the regular expression accepting between a lower and upper bound repetitions
11482 >>> re = Loop(Re("a"), 1, 3)
11483 >>> print(simplify(InRe("aa", re)))
11484 True
11485 >>> print(simplify(InRe("aaaa", re)))
11486 False
11487 >>> print(simplify(InRe("", re)))
11488 False
11489 """
11490 if z3_debug():
11491 _z3_assert(is_expr(re), "expression expected")
11492 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11493
11494
11495def Range(lo, hi, ctx=None):
11496 """Create the range regular expression over two sequences of length 1
11497 >>> range = Range("a","z")
11498 >>> print(simplify(InRe("b", range)))
11499 True
11500 >>> print(simplify(InRe("bb", range)))
11501 False
11502 """
11503 lo = _coerce_seq(lo, ctx)
11504 hi = _coerce_seq(hi, ctx)
11505 if z3_debug():
11506 _z3_assert(is_expr(lo), "expression expected")
11507 _z3_assert(is_expr(hi), "expression expected")
11508 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11509
11510def Diff(a, b, ctx=None):
11511 """Create the difference regular expression
11512 """
11513 if z3_debug():
11514 _z3_assert(is_expr(a), "expression expected")
11515 _z3_assert(is_expr(b), "expression expected")
11516 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11517
11518def AllChar(regex_sort, ctx=None):
11519 """Create a regular expression that accepts all single character strings
11520 """
11521 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11522
11523# Special Relations
11524
11525
11526def PartialOrder(a, index):
11527 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11528
11529
11530def LinearOrder(a, index):
11531 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11532
11533
11534def TreeOrder(a, index):
11535 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11536
11537
11538def PiecewiseLinearOrder(a, index):
11539 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11540
11541
11542def TransitiveClosure(f):
11543 """Given a binary relation R, such that the two arguments have the same sort
11544 create the transitive closure relation R+.
11545 The transitive closure R+ is a new relation.
11546 """
11547 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11548
11549def to_Ast(ptr,):
11550 ast = Ast(ptr)
11551 super(ctypes.c_void_p, ast).__init__(ptr)
11552 return ast
11553
11554def to_ContextObj(ptr,):
11555 ctx = ContextObj(ptr)
11556 super(ctypes.c_void_p, ctx).__init__(ptr)
11557 return ctx
11558
11559def to_AstVectorObj(ptr,):
11560 v = AstVectorObj(ptr)
11561 super(ctypes.c_void_p, v).__init__(ptr)
11562 return v
11563
11564# NB. my-hacky-class only works for a single instance of OnClause
11565# it should be replaced with a proper correlation between OnClause
11566# and object references that can be passed over the FFI.
11567# for UserPropagator we use a global dictionary, which isn't great code.
11568
11569_my_hacky_class = None
11570def on_clause_eh(ctx, p, n, dep, clause):
11571 onc = _my_hacky_class
11572 p = _to_expr_ref(to_Ast(p), onc.ctx)
11573 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11574 deps = [dep[i] for i in range(n)]
11575 onc.on_clause(p, deps, clause)
11576
11577_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11578
11579class OnClause:
11580 def __init__(self, s, on_clause):
11581 self.s = s
11582 self.ctx = s.ctx
11583 self.on_clause = on_clause
11584 self.idx = 22
11585 global _my_hacky_class
11586 _my_hacky_class = self
11587 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11588
11589
11590class PropClosures:
11591 def __init__(self):
11592 self.bases = {}
11593 self.lock = None
11594
11595 def set_threaded(self):
11596 if self.lock is None:
11597 import threading
11598 self.lock = threading.Lock()
11599
11600 def get(self, ctx):
11601 if self.lock:
11602 with self.lock:
11603 r = self.bases[ctx]
11604 else:
11605 r = self.bases[ctx]
11606 return r
11607
11608 def set(self, ctx, r):
11609 if self.lock:
11610 with self.lock:
11611 self.bases[ctx] = r
11612 else:
11613 self.bases[ctx] = r
11614
11615 def insert(self, r):
11616 if self.lock:
11617 with self.lock:
11618 id = len(self.bases) + 3
11619 self.bases[id] = r
11620 else:
11621 id = len(self.bases) + 3
11622 self.bases[id] = r
11623 return id
11624
11625
11626_prop_closures = None
11627
11628
11629def ensure_prop_closures():
11630 global _prop_closures
11631 if _prop_closures is None:
11632 _prop_closures = PropClosures()
11633
11634
11635def user_prop_push(ctx, cb):
11636 prop = _prop_closures.get(ctx)
11637 prop.cb = cb
11638 prop.push()
11639
11640
11641def user_prop_pop(ctx, cb, num_scopes):
11642 prop = _prop_closures.get(ctx)
11643 prop.cb = cb
11644 prop.pop(num_scopes)
11645
11646
11647def user_prop_fresh(ctx, _new_ctx):
11648 _prop_closures.set_threaded()
11649 prop = _prop_closures.get(ctx)
11650 nctx = Context()
11651 Z3_del_context(nctx.ctx)
11652 new_ctx = to_ContextObj(_new_ctx)
11653 nctx.ctx = new_ctx
11654 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11655 nctx.owner = False
11656 new_prop = prop.fresh(nctx)
11657 _prop_closures.set(new_prop.id, new_prop)
11658 return new_prop.id
11659
11660
11661def user_prop_fixed(ctx, cb, id, value):
11662 prop = _prop_closures.get(ctx)
11663 old_cb = prop.cb
11664 prop.cb = cb
11665 id = _to_expr_ref(to_Ast(id), prop.ctx())
11666 value = _to_expr_ref(to_Ast(value), prop.ctx())
11667 prop.fixed(id, value)
11668 prop.cb = old_cb
11669
11670def user_prop_created(ctx, cb, id):
11671 prop = _prop_closures.get(ctx)
11672 old_cb = prop.cb
11673 prop.cb = cb
11674 id = _to_expr_ref(to_Ast(id), prop.ctx())
11675 prop.created(id)
11676 prop.cb = old_cb
11677
11678
11679def user_prop_final(ctx, cb):
11680 prop = _prop_closures.get(ctx)
11681 old_cb = prop.cb
11682 prop.cb = cb
11683 prop.final()
11684 prop.cb = old_cb
11685
11686def user_prop_eq(ctx, cb, x, y):
11687 prop = _prop_closures.get(ctx)
11688 old_cb = prop.cb
11689 prop.cb = cb
11690 x = _to_expr_ref(to_Ast(x), prop.ctx())
11691 y = _to_expr_ref(to_Ast(y), prop.ctx())
11692 prop.eq(x, y)
11693 prop.cb = old_cb
11694
11695def user_prop_diseq(ctx, cb, x, y):
11696 prop = _prop_closures.get(ctx)
11697 old_cb = prop.cb
11698 prop.cb = cb
11699 x = _to_expr_ref(to_Ast(x), prop.ctx())
11700 y = _to_expr_ref(to_Ast(y), prop.ctx())
11701 prop.diseq(x, y)
11702 prop.cb = old_cb
11703
11704def user_prop_decide(ctx, cb, t_ref, idx, phase):
11705 prop = _prop_closures.get(ctx)
11706 old_cb = prop.cb
11707 prop.cb = cb
11708 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11709 prop.decide(t, idx, phase)
11710 prop.cb = old_cb
11711
11712
11713_user_prop_push = Z3_push_eh(user_prop_push)
11714_user_prop_pop = Z3_pop_eh(user_prop_pop)
11715_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11716_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11717_user_prop_created = Z3_created_eh(user_prop_created)
11718_user_prop_final = Z3_final_eh(user_prop_final)
11719_user_prop_eq = Z3_eq_eh(user_prop_eq)
11720_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11721_user_prop_decide = Z3_decide_eh(user_prop_decide)
11722
11723
11724def PropagateFunction(name, *sig):
11725 """Create a function that gets tracked by user propagator.
11726 Every term headed by this function symbol is tracked.
11727 If a term is fixed and the fixed callback is registered a
11728 callback is invoked that the term headed by this function is fixed.
11729 """
11730 sig = _get_args(sig)
11731 if z3_debug():
11732 _z3_assert(len(sig) > 0, "At least two arguments expected")
11733 arity = len(sig) - 1
11734 rng = sig[arity]
11735 if z3_debug():
11736 _z3_assert(is_sort(rng), "Z3 sort expected")
11737 dom = (Sort * arity)()
11738 for i in range(arity):
11739 if z3_debug():
11740 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11741 dom[i] = sig[i].ast
11742 ctx = rng.ctx
11743 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11744
11745
11746
11747class UserPropagateBase:
11748
11749 #
11750 # Either solver is set or ctx is set.
11751 # Propagators that are created through callbacks
11752 # to "fresh" inherit the context of that is supplied
11753 # as argument to the callback.
11754 # This context should not be deleted. It is owned by the solver.
11755 #
11756 def __init__(self, s, ctx=None):
11757 assert s is None or ctx is None
11758 ensure_prop_closures()
11759 self.solver = s
11760 self._ctx = None
11761 self.fresh_ctx = None
11762 self.cb = None
11763 self.id = _prop_closures.insert(self)
11764 self.fixed = None
11765 self.final = None
11766 self.eq = None
11767 self.diseq = None
11768 self.decide = None
11769 self.created = None
11770 if ctx:
11771 self.fresh_ctx = ctx
11772 if s:
11773 Z3_solver_propagate_init(self.ctx_ref(),
11774 s.solver,
11775 ctypes.c_void_p(self.id),
11776 _user_prop_push,
11777 _user_prop_pop,
11778 _user_prop_fresh)
11779
11780 def __del__(self):
11781 if self._ctx:
11782 self._ctx.ctx = None
11783
11784 def ctx(self):
11785 if self.fresh_ctx:
11786 return self.fresh_ctx
11787 else:
11788 return self.solver.ctx
11789
11790 def ctx_ref(self):
11791 return self.ctx().ref()
11792
11793 def add_fixed(self, fixed):
11794 assert not self.fixed
11795 assert not self._ctx
11796 if self.solver:
11797 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11798 self.fixed = fixed
11799
11800 def add_created(self, created):
11801 assert not self.created
11802 assert not self._ctx
11803 if self.solver:
11804 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
11805 self.created = created
11806
11807 def add_final(self, final):
11808 assert not self.final
11809 assert not self._ctx
11810 if self.solver:
11811 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
11812 self.final = final
11813
11814 def add_eq(self, eq):
11815 assert not self.eq
11816 assert not self._ctx
11817 if self.solver:
11818 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
11819 self.eq = eq
11820
11821 def add_diseq(self, diseq):
11822 assert not self.diseq
11823 assert not self._ctx
11824 if self.solver:
11825 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
11826 self.diseq = diseq
11827
11828 def add_decide(self, decide):
11829 assert not self.decide
11830 assert not self._ctx
11831 if self.solver:
11832 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
11833 self.decide = decide
11834
11835 def push(self):
11836 raise Z3Exception("push needs to be overwritten")
11837
11838 def pop(self, num_scopes):
11839 raise Z3Exception("pop needs to be overwritten")
11840
11841 def fresh(self, new_ctx):
11842 raise Z3Exception("fresh needs to be overwritten")
11843
11844 def add(self, e):
11845 assert not self._ctx
11846 if self.solver:
11847 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
11848 else:
11849 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
11850
11851 #
11852 # Tell the solver to perform the next split on a given term
11853 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
11854 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
11855 #
11856 def next_split(self, t, idx, phase):
11857 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
11858
11859 #
11860 # Propagation can only be invoked as during a fixed or final callback.
11861 #
11862 def propagate(self, e, ids, eqs=[]):
11863 _ids, num_fixed = _to_ast_array(ids)
11864 num_eqs = len(eqs)
11865 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
11866 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
11867 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
11868 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
11869
11870 def conflict(self, deps = [], eqs = []):
11871 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3149
as_decimal(self, prec)
Definition z3py.py:3161
__rmod__(self, other)
Definition z3py.py:2637
__mod__(self, other)
Definition z3py.py:2622
__pow__(self, other)
Definition z3py.py:2546
__gt__(self, other)
Definition z3py.py:2695
__lt__(self, other)
Definition z3py.py:2682
__rtruediv__(self, other)
Definition z3py.py:2618
__rmul__(self, other)
Definition z3py.py:2513
__rsub__(self, other)
Definition z3py.py:2536
__add__(self, other)
Definition z3py.py:2475
__sub__(self, other)
Definition z3py.py:2523
is_real(self)
Definition z3py.py:2464
is_int(self)
Definition z3py.py:2450
__radd__(self, other)
Definition z3py.py:2488
__truediv__(self, other)
Definition z3py.py:2597
__le__(self, other)
Definition z3py.py:2669
__rpow__(self, other)
Definition z3py.py:2560
__pos__(self)
Definition z3py.py:2660
sort(self)
Definition z3py.py:2440
__mul__(self, other)
Definition z3py.py:2498
__rdiv__(self, other)
Definition z3py.py:2601
__ge__(self, other)
Definition z3py.py:2708
__neg__(self)
Definition z3py.py:2649
__div__(self, other)
Definition z3py.py:2574
Arithmetic.
Definition z3py.py:2345
subsort(self, other)
Definition z3py.py:2379
cast(self, val)
Definition z3py.py:2383
domain(self)
Definition z3py.py:4613
domain_n(self, i)
Definition z3py.py:4622
__getitem__(self, arg)
Definition z3py.py:4635
range(self)
Definition z3py.py:4626
sort(self)
Definition z3py.py:4604
default(self)
Definition z3py.py:4647
domain_n(self, i)
Definition z3py.py:4586
erase(self, k)
Definition z3py.py:6145
__deepcopy__(self, memo={})
Definition z3py.py:6082
__init__(self, m=None, ctx=None)
Definition z3py.py:6071
__repr__(self)
Definition z3py.py:6142
__len__(self)
Definition z3py.py:6089
keys(self)
Definition z3py.py:6174
__setitem__(self, k, v)
Definition z3py.py:6126
__contains__(self, key)
Definition z3py.py:6102
__del__(self)
Definition z3py.py:6085
__getitem__(self, key)
Definition z3py.py:6115
reset(self)
Definition z3py.py:6159
__deepcopy__(self, memo={})
Definition z3py.py:355
__nonzero__(self)
Definition z3py.py:370
as_ast(self)
Definition z3py.py:392
translate(self, target)
Definition z3py.py:421
__hash__(self)
Definition z3py.py:367
__init__(self, ast, ctx=None)
Definition z3py.py:345
__str__(self)
Definition z3py.py:358
ctx_ref(self)
Definition z3py.py:400
__repr__(self)
Definition z3py.py:361
get_id(self)
Definition z3py.py:396
hash(self)
Definition z3py.py:440
__eq__(self, other)
Definition z3py.py:364
eq(self, other)
Definition z3py.py:404
sexpr(self)
Definition z3py.py:383
__del__(self)
Definition z3py.py:350
__bool__(self)
Definition z3py.py:373
__copy__(self)
Definition z3py.py:437
__deepcopy__(self, memo={})
Definition z3py.py:6051
translate(self, other_ctx)
Definition z3py.py:6032
__repr__(self)
Definition z3py.py:6054
__len__(self)
Definition z3py.py:5926
__init__(self, v=None, ctx=None)
Definition z3py.py:5911
push(self, v)
Definition z3py.py:5984
__getitem__(self, i)
Definition z3py.py:5939
sexpr(self)
Definition z3py.py:6057
__del__(self)
Definition z3py.py:5922
__setitem__(self, i, v)
Definition z3py.py:5968
__contains__(self, item)
Definition z3py.py:6009
__copy__(self)
Definition z3py.py:6048
resize(self, sz)
Definition z3py.py:5996
as_binary_string(self)
Definition z3py.py:3993
as_signed_long(self)
Definition z3py.py:3967
as_string(self)
Definition z3py.py:3990
__and__(self, other)
Definition z3py.py:3657
__rmod__(self, other)
Definition z3py.py:3798
__rrshift__(self, other)
Definition z3py.py:3924
__mod__(self, other)
Definition z3py.py:3777
__or__(self, other)
Definition z3py.py:3634
__rlshift__(self, other)
Definition z3py.py:3938
__gt__(self, other)
Definition z3py.py:3848
__lt__(self, other)
Definition z3py.py:3832
__invert__(self)
Definition z3py.py:3723
__rtruediv__(self, other)
Definition z3py.py:3773
__rmul__(self, other)
Definition z3py.py:3601
__rxor__(self, other)
Definition z3py.py:3693
__ror__(self, other)
Definition z3py.py:3647
__rsub__(self, other)
Definition z3py.py:3624
__add__(self, other)
Definition z3py.py:3565
__sub__(self, other)
Definition z3py.py:3611
__radd__(self, other)
Definition z3py.py:3578
size(self)
Definition z3py.py:3554
__rand__(self, other)
Definition z3py.py:3670
__truediv__(self, other)
Definition z3py.py:3753
__le__(self, other)
Definition z3py.py:3816
__xor__(self, other)
Definition z3py.py:3680
__lshift__(self, other)
Definition z3py.py:3910
__pos__(self)
Definition z3py.py:3703
sort(self)
Definition z3py.py:3543
__mul__(self, other)
Definition z3py.py:3588
__rdiv__(self, other)
Definition z3py.py:3757
__ge__(self, other)
Definition z3py.py:3864
__neg__(self)
Definition z3py.py:3712
__rshift__(self, other)
Definition z3py.py:3880
__div__(self, other)
Definition z3py.py:3734
Bit-Vectors.
Definition z3py.py:3496
subsort(self, other)
Definition z3py.py:3508
cast(self, val)
Definition z3py.py:3511
__and__(self, other)
Definition z3py.py:1603
__or__(self, other)
Definition z3py.py:1606
__invert__(self)
Definition z3py.py:1612
__rmul__(self, other)
Definition z3py.py:1589
__add__(self, other)
Definition z3py.py:1581
__radd__(self, other)
Definition z3py.py:1586
__xor__(self, other)
Definition z3py.py:1609
sort(self)
Definition z3py.py:1578
__mul__(self, other)
Definition z3py.py:1592
Booleans.
Definition z3py.py:1539
subsort(self, other)
Definition z3py.py:1565
is_bool(self)
Definition z3py.py:1571
cast(self, val)
Definition z3py.py:1542
__deepcopy__(self, memo={})
Definition z3py.py:6939
__eq__(self, other)
Definition z3py.py:6942
__ne__(self, other)
Definition z3py.py:6945
__init__(self, r)
Definition z3py.py:6936
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:5131
create(self)
Definition z3py.py:5170
__init__(self, name, ctx=None)
Definition z3py.py:5126
__repr__(self)
Definition z3py.py:5167
list constructors
Definition z3py.py:5129
declare(self, name, *args)
Definition z3py.py:5146
declare_core(self, name, rec_name, *args)
Definition z3py.py:5136
constructor(self, idx)
Definition z3py.py:5323
accessor(self, i, j)
Definition z3py.py:5370
num_constructors(self)
Definition z3py.py:5310
recognizer(self, idx)
Definition z3py.py:5342
Expressions.
Definition z3py.py:979
as_ast(self)
Definition z3py.py:990
__hash__(self)
Definition z3py.py:1036
kind(self)
Definition z3py.py:1076
children(self)
Definition z3py.py:1120
serialize(self)
Definition z3py.py:1138
get_id(self)
Definition z3py.py:993
num_args(self)
Definition z3py.py:1083
__eq__(self, other)
Definition z3py.py:1019
__ne__(self, other)
Definition z3py.py:1040
from_string(self, s)
Definition z3py.py:1135
sort_kind(self)
Definition z3py.py:1008
arg(self, idx)
Definition z3py.py:1099
sort(self)
Definition z3py.py:996
params(self)
Definition z3py.py:1058
decl(self)
Definition z3py.py:1061
Function Declarations.
Definition z3py.py:740
as_func_decl(self)
Definition z3py.py:754
domain(self, i)
Definition z3py.py:778
as_ast(self)
Definition z3py.py:748
__call__(self, *args)
Definition z3py.py:837
arity(self)
Definition z3py.py:768
get_id(self)
Definition z3py.py:751
range(self)
Definition z3py.py:790
params(self)
Definition z3py.py:813
Definition z3py.py:6193
__deepcopy__(self, memo={})
Definition z3py.py:6201
ctx
Definition z3py.py:6198
__repr__(self)
Definition z3py.py:6298
num_args(self)
Definition z3py.py:6208
entry
Definition z3py.py:6197
value(self)
Definition z3py.py:6257
__init__(self, entry, ctx)
Definition z3py.py:6196
__del__(self)
Definition z3py.py:6204
as_list(self)
Definition z3py.py:6279
arg_value(self, idx)
Definition z3py.py:6226
__deepcopy__(self, memo={})
Definition z3py.py:6396
translate(self, other_ctx)
Definition z3py.py:6388
arity(self)
Definition z3py.py:6354
__repr__(self)
Definition z3py.py:6416
num_entries(self)
Definition z3py.py:6338
__init__(self, f, ctx)
Definition z3py.py:6305
__del__(self)
Definition z3py.py:6311
as_list(self)
Definition z3py.py:6399
else_value(self)
Definition z3py.py:6315
entry(self, idx)
Definition z3py.py:6368
__copy__(self)
Definition z3py.py:6393
__deepcopy__(self, memo={})
Definition z3py.py:5856
get(self, i)
Definition z3py.py:5714
prec(self)
Definition z3py.py:5658
translate(self, target)
Definition z3py.py:5830
append(self, *args)
Definition z3py.py:5757
as_expr(self)
Definition z3py.py:5879
assert_exprs(self, *args)
Definition z3py.py:5742
__repr__(self)
Definition z3py.py:5819
__len__(self)
Definition z3py.py:5701
inconsistent(self)
Definition z3py.py:5640
dimacs(self, include_names=True)
Definition z3py.py:5826
__getitem__(self, arg)
Definition z3py.py:5727
size(self)
Definition z3py.py:5688
precision(self)
Definition z3py.py:5679
simplify(self, *arguments, **keywords)
Definition z3py.py:5859
sexpr(self)
Definition z3py.py:5822
add(self, *args)
Definition z3py.py:5779
__del__(self)
Definition z3py.py:5618
convert_model(self, model)
Definition z3py.py:5790
insert(self, *args)
Definition z3py.py:5768
depth(self)
Definition z3py.py:5622
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5608
__copy__(self)
Definition z3py.py:5853
as_binary_string(self)
Definition z3py.py:3040
as_long(self)
Definition z3py.py:3019
as_string(self)
Definition z3py.py:3032
__deepcopy__(self, memo={})
Definition z3py.py:6762
eval(self, t, model_completion=False)
Definition z3py.py:6440
translate(self, target)
Definition z3py.py:6727
__getitem__(self, idx)
Definition z3py.py:6641
num_sorts(self)
Definition z3py.py:6566
get_universe(self, s)
Definition z3py.py:6621
get_sort(self, idx)
Definition z3py.py:6581
project(self, vars, fml)
Definition z3py.py:6735
__repr__(self)
Definition z3py.py:6433
__len__(self)
Definition z3py.py:6497
get_interp(self, decl)
Definition z3py.py:6514
__init__(self, m, ctx)
Definition z3py.py:6423
sexpr(self)
Definition z3py.py:6436
sorts(self)
Definition z3py.py:6604
__del__(self)
Definition z3py.py:6429
decls(self)
Definition z3py.py:6686
project_with_witness(self, vars, fml)
Definition z3py.py:6747
update_value(self, x, value)
Definition z3py.py:6705
evaluate(self, t, model_completion=False)
Definition z3py.py:6471
__copy__(self)
Definition z3py.py:6759
__deepcopy__(self, memo={})
Definition z3py.py:5552
__init__(self, descr, ctx=None)
Definition z3py.py:5546
get_kind(self, n)
Definition z3py.py:5574
get_documentation(self, n)
Definition z3py.py:5579
__getitem__(self, arg)
Definition z3py.py:5584
get_name(self, i)
Definition z3py.py:5569
Parameter Sets.
Definition z3py.py:5473
__deepcopy__(self, memo={})
Definition z3py.py:5487
validate(self, ds)
Definition z3py.py:5514
__repr__(self)
Definition z3py.py:5511
__init__(self, ctx=None, params=None)
Definition z3py.py:5479
set(self, name, val)
Definition z3py.py:5494
__del__(self)
Definition z3py.py:5490
Patterns.
Definition z3py.py:1968
as_ast(self)
Definition z3py.py:1973
get_id(self)
Definition z3py.py:1976
Quantifiers.
Definition z3py.py:2035
num_no_patterns(self)
Definition z3py.py:2153
no_pattern(self, idx)
Definition z3py.py:2157
num_patterns(self)
Definition z3py.py:2123
var_name(self, idx)
Definition z3py.py:2186
__getitem__(self, arg)
Definition z3py.py:2092
var_sort(self, idx)
Definition z3py.py:2202
pattern(self, idx)
Definition z3py.py:2135
numerator_as_long(self)
Definition z3py.py:3078
is_int_value(self)
Definition z3py.py:3108
as_fraction(self)
Definition z3py.py:3136
numerator(self)
Definition z3py.py:3052
is_real(self)
Definition z3py.py:3105
as_long(self)
Definition z3py.py:3111
is_int(self)
Definition z3py.py:3102
denominator_as_long(self)
Definition z3py.py:3091
as_string(self)
Definition z3py.py:3127
denominator(self)
Definition z3py.py:3067
as_decimal(self, prec)
Definition z3py.py:3115
__init__(self, c, ctx)
Definition z3py.py:5190
__init__(self, c, ctx)
Definition z3py.py:5202
Strings, Sequences and Regular expressions.
Definition z3py.py:10905
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:6983
assert_and_track(self, a, p)
Definition z3py.py:7152
num_scopes(self)
Definition z3py.py:7064
append(self, *args)
Definition z3py.py:7130
__iadd__(self, fml)
Definition z3py.py:7126
pop(self, num=1)
Definition z3py.py:7042
import_model_converter(self, other)
Definition z3py.py:7230
assert_exprs(self, *args)
Definition z3py.py:7096
model(self)
Definition z3py.py:7211
set(self, *args, **keys)
Definition z3py.py:7007
__enter__(self)
Definition z3py.py:7000
add(self, *args)
Definition z3py.py:7115
__del__(self)
Definition z3py.py:6996
int backtrack_level
Definition z3py.py:6986
insert(self, *args)
Definition z3py.py:7141
check(self, *assumptions)
Definition z3py.py:7182
push(self)
Definition z3py.py:7020
__exit__(self, *exc_info)
Definition z3py.py:7004
reset(self)
Definition z3py.py:7082
subsort(self, other)
Definition z3py.py:585
as_ast(self)
Definition z3py.py:562
__hash__(self)
Definition z3py.py:642
kind(self)
Definition z3py.py:568
get_id(self)
Definition z3py.py:565
__eq__(self, other)
Definition z3py.py:618
__ne__(self, other)
Definition z3py.py:631
cast(self, val)
Definition z3py.py:593
name(self)
Definition z3py.py:608
Statistics.
Definition z3py.py:6792
__deepcopy__(self, memo={})
Definition z3py.py:6800
__getattr__(self, name)
Definition z3py.py:6895
__getitem__(self, idx)
Definition z3py.py:6839
__init__(self, stats, ctx)
Definition z3py.py:6795
__repr__(self)
Definition z3py.py:6807
__len__(self)
Definition z3py.py:6825
__del__(self)
Definition z3py.py:6803
get_key_value(self, key)
Definition z3py.py:6875
subsort(self, other)
Definition z3py.py:716
cast(self, val)
Definition z3py.py:719
ASTs base class.
Definition z3py.py:328
_repr_html_(self)
Definition z3py.py:334
use_pp(self)
Definition z3py.py:331
Z3_ast Z3_API Z3_model_get_const_interp(Z3_context c, Z3_model m, Z3_func_decl a)
Return the interpretation (i.e., assignment) of constant a in the model m. Return NULL,...
Z3_sort Z3_API Z3_mk_int_sort(Z3_context c)
Create the integer type.
Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const *domain, Z3_sort range)
Create an array type with N arguments.
bool Z3_API Z3_open_log(Z3_string filename)
Log interaction to a file.
Z3_parameter_kind Z3_API Z3_get_decl_parameter_kind(Z3_context c, Z3_func_decl d, unsigned idx)
Return the parameter type associated with a declaration.
Z3_ast Z3_API Z3_get_denominator(Z3_context c, Z3_ast a)
Return the denominator (as a numeral AST) of a numeral AST of sort Real.
Z3_probe Z3_API Z3_probe_not(Z3_context x, Z3_probe p)
Return a probe that evaluates to "true" when p does not evaluate to true.
Z3_decl_kind Z3_API Z3_get_decl_kind(Z3_context c, Z3_func_decl d)
Return declaration kind corresponding to declaration.
void Z3_API Z3_solver_assert_and_track(Z3_context c, Z3_solver s, Z3_ast a, Z3_ast p)
Assert a constraint a into the solver, and track it (in the unsat) core using the Boolean constant p.
Z3_ast Z3_API Z3_func_interp_get_else(Z3_context c, Z3_func_interp f)
Return the 'else' value of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsge(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than or equal to.
void Z3_API Z3_ast_map_inc_ref(Z3_context c, Z3_ast_map m)
Increment the reference counter of the given AST map.
Z3_ast Z3_API Z3_mk_const_array(Z3_context c, Z3_sort domain, Z3_ast v)
Create the constant array.
Z3_ast Z3_API Z3_mk_bvsle(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than or equal to.
Z3_func_decl Z3_API Z3_get_app_decl(Z3_context c, Z3_app a)
Return the declaration of a constant or function application.
void Z3_API Z3_del_context(Z3_context c)
Delete the given logical context.
Z3_func_decl Z3_API Z3_get_decl_func_decl_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_ast Z3_API Z3_ast_map_find(Z3_context c, Z3_ast_map m, Z3_ast k)
Return the value associated with the key k.
Z3_string Z3_API Z3_ast_map_to_string(Z3_context c, Z3_ast_map m)
Convert the given map into a string.
Z3_string Z3_API Z3_param_descrs_to_string(Z3_context c, Z3_param_descrs p)
Convert a parameter description set into a string. This function is mainly used for printing the cont...
Z3_ast Z3_API Z3_mk_zero_ext(Z3_context c, unsigned i, Z3_ast t1)
Extend the given bit-vector with zeros to the (unsigned) equivalent bit-vector of size m+i,...
void Z3_API Z3_solver_set_params(Z3_context c, Z3_solver s, Z3_params p)
Set the given solver using the given parameters.
Z3_ast Z3_API Z3_mk_set_intersect(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the intersection of a list of sets.
Z3_params Z3_API Z3_mk_params(Z3_context c)
Create a Z3 (empty) parameter set. Starting at Z3 4.0, parameter sets are used to configure many comp...
unsigned Z3_API Z3_get_decl_num_parameters(Z3_context c, Z3_func_decl d)
Return the number of parameters associated with a declaration.
Z3_ast Z3_API Z3_mk_set_subset(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Check for subsetness of sets.
Z3_ast Z3_API Z3_mk_bvule(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than or equal to.
Z3_ast Z3_API Z3_mk_full_set(Z3_context c, Z3_sort domain)
Create the full set.
Z3_param_kind Z3_API Z3_param_descrs_get_kind(Z3_context c, Z3_param_descrs p, Z3_symbol n)
Return the kind associated with the given parameter name n.
void Z3_API Z3_add_rec_def(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast args[], Z3_ast body)
Define the body of a recursive function.
Z3_ast Z3_API Z3_mk_true(Z3_context c)
Create an AST node representing true.
Z3_ast Z3_API Z3_mk_set_union(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the union of a list of sets.
Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast default_value)
Create a fresh func_interp object, add it to a model for a specified function. It has reference count...
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed division of t1 and t2 does not overflow.
unsigned Z3_API Z3_get_arity(Z3_context c, Z3_func_decl d)
Alias for Z3_get_domain_size.
void Z3_API Z3_ast_vector_set(Z3_context c, Z3_ast_vector v, unsigned i, Z3_ast a)
Update position i of the AST vector v with the AST a.
Z3_ast Z3_API Z3_mk_bvxor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise exclusive-or.
Z3_string Z3_API Z3_stats_to_string(Z3_context c, Z3_stats s)
Convert a statistics into a string.
Z3_sort Z3_API Z3_mk_real_sort(Z3_context c)
Create the real type.
Z3_ast Z3_API Z3_mk_le(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than or equal to.
bool Z3_API Z3_global_param_get(Z3_string param_id, Z3_string_ptr param_value)
Get a global (or module) parameter.
bool Z3_API Z3_goal_inconsistent(Z3_context c, Z3_goal g)
Return true if the given goal contains the formula false.
Z3_ast Z3_API Z3_mk_lambda_const(Z3_context c, unsigned num_bound, Z3_app const bound[], Z3_ast body)
Create a lambda expression using a list of constants that form the set of bound variables.
void Z3_API Z3_solver_dec_ref(Z3_context c, Z3_solver s)
Decrement the reference counter of the given solver.
Z3_ast Z3_API Z3_mk_bvslt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than.
Z3_func_decl Z3_API Z3_model_get_func_decl(Z3_context c, Z3_model m, unsigned i)
Return the declaration of the i-th function in the given model.
bool Z3_API Z3_ast_map_contains(Z3_context c, Z3_ast_map m, Z3_ast k)
Return true if the map m contains the AST key k.
Z3_ast Z3_API Z3_mk_numeral(Z3_context c, Z3_string numeral, Z3_sort ty)
Create a numeral of a given sort.
unsigned Z3_API Z3_func_entry_get_num_args(Z3_context c, Z3_func_entry e)
Return the number of arguments in a Z3_func_entry object.
Z3_symbol Z3_API Z3_get_decl_symbol_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the double value associated with an double parameter.
Z3_symbol Z3_API Z3_get_quantifier_skolem_id(Z3_context c, Z3_ast a)
Obtain skolem id of quantifier.
Z3_ast Z3_API Z3_get_numerator(Z3_context c, Z3_ast a)
Return the numerator (as a numeral AST) of a numeral AST of sort Real.
Z3_ast Z3_API Z3_mk_unary_minus(Z3_context c, Z3_ast arg)
Create an AST node representing - arg.
Z3_ast Z3_API Z3_mk_and(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] and ... and args[num_args-1].
void Z3_API Z3_interrupt(Z3_context c)
Interrupt the execution of a Z3 procedure. This procedure can be used to interrupt: solvers,...
void Z3_API Z3_goal_assert(Z3_context c, Z3_goal g, Z3_ast a)
Add a new formula a to the given goal. The formula is split according to the following procedure that...
Z3_symbol Z3_API Z3_param_descrs_get_name(Z3_context c, Z3_param_descrs p, unsigned i)
Return the name of the parameter at given index i.
Z3_ast Z3_API Z3_func_entry_get_value(Z3_context c, Z3_func_entry e)
Return the value of this point.
bool Z3_API Z3_is_quantifier_exists(Z3_context c, Z3_ast a)
Determine if ast is an existential quantifier.
Z3_sort Z3_API Z3_mk_uninterpreted_sort(Z3_context c, Z3_symbol s)
Create a free (uninterpreted) type using the given name (symbol).
Z3_ast Z3_API Z3_mk_false(Z3_context c)
Create an AST node representing false.
Z3_ast_vector Z3_API Z3_ast_map_keys(Z3_context c, Z3_ast_map m)
Return the keys stored in the given map.
Z3_ast Z3_API Z3_mk_bvmul(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement multiplication.
Z3_model Z3_API Z3_goal_convert_model(Z3_context c, Z3_goal g, Z3_model m)
Convert a model of the formulas of a goal to a model of an original goal. The model may be null,...
void Z3_API Z3_del_constructor(Z3_context c, Z3_constructor constr)
Reclaim memory allocated to constructor.
Z3_ast Z3_API Z3_mk_bvsgt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than.
Z3_string Z3_API Z3_ast_to_string(Z3_context c, Z3_ast a)
Convert the given AST node into a string.
Z3_context Z3_API Z3_mk_context_rc(Z3_config c)
Create a context using the given configuration. This function is similar to Z3_mk_context....
Z3_string Z3_API Z3_get_full_version(void)
Return a string that fully describes the version of Z3 in use.
void Z3_API Z3_enable_trace(Z3_string tag)
Enable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_mk_set_complement(Z3_context c, Z3_ast arg)
Take the complement of a set.
unsigned Z3_API Z3_get_quantifier_num_patterns(Z3_context c, Z3_ast a)
Return number of patterns used in quantifier.
Z3_symbol Z3_API Z3_get_quantifier_bound_name(Z3_context c, Z3_ast a, unsigned i)
Return symbol of the i'th bound variable.
bool Z3_API Z3_stats_is_uint(Z3_context c, Z3_stats s, unsigned idx)
Return true if the given statistical data is a unsigned integer.
unsigned Z3_API Z3_model_get_num_consts(Z3_context c, Z3_model m)
Return the number of constants assigned by the given model.
Z3_ast Z3_API Z3_mk_extract(Z3_context c, unsigned high, unsigned low, Z3_ast t1)
Extract the bits high down to low from a bit-vector of size m to yield a new bit-vector of size n,...
Z3_ast Z3_API Z3_mk_mod(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 mod arg2.
Z3_ast Z3_API Z3_mk_bvredand(Z3_context c, Z3_ast t1)
Take conjunction of bits in vector, return vector of length 1.
Z3_ast Z3_API Z3_mk_set_add(Z3_context c, Z3_ast set, Z3_ast elem)
Add an element to a set.
Z3_ast Z3_API Z3_mk_ge(Z3_context c, Z3_ast t1, Z3_ast t2)
Create greater than or equal to.
Z3_ast Z3_API Z3_mk_bvadd_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed addition of t1 and t2 does not underflow.
Z3_ast Z3_API Z3_mk_bvadd_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise addition of t1 and t2 does not overflow.
void Z3_API Z3_set_ast_print_mode(Z3_context c, Z3_ast_print_mode mode)
Select mode for the format used for pretty-printing AST nodes.
Z3_ast Z3_API Z3_mk_array_default(Z3_context c, Z3_ast array)
Access the array default value. Produces the default range value, for arrays that can be represented ...
unsigned Z3_API Z3_model_get_num_sorts(Z3_context c, Z3_model m)
Return the number of uninterpreted sorts that m assigns an interpretation to.
Z3_constructor Z3_API Z3_mk_constructor(Z3_context c, Z3_symbol name, Z3_symbol recognizer, unsigned num_fields, Z3_symbol const field_names[], Z3_sort_opt const sorts[], unsigned sort_refs[])
Create a constructor.
Z3_ast_vector Z3_API Z3_ast_vector_translate(Z3_context s, Z3_ast_vector v, Z3_context t)
Translate the AST vector v from context s into an AST vector in context t.
void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e)
Increment the reference counter of the given Z3_func_entry object.
Z3_ast Z3_API Z3_mk_fresh_const(Z3_context c, Z3_string prefix, Z3_sort ty)
Declare and create a fresh constant.
Z3_ast Z3_API Z3_mk_bvsub_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed subtraction of t1 and t2 does not overflow.
void Z3_API Z3_solver_push(Z3_context c, Z3_solver s)
Create a backtracking point.
Z3_ast Z3_API Z3_mk_bvsub_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise subtraction of t1 and t2 does not underflow.
Z3_goal Z3_API Z3_goal_translate(Z3_context source, Z3_goal g, Z3_context target)
Copy a goal g from the context source to the context target.
Z3_ast Z3_API Z3_mk_bvudiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned division.
Z3_string Z3_API Z3_ast_vector_to_string(Z3_context c, Z3_ast_vector v)
Convert AST vector into a string.
Z3_ast Z3_API Z3_mk_bvshl(Z3_context c, Z3_ast t1, Z3_ast t2)
Shift left.
bool Z3_API Z3_is_numeral_ast(Z3_context c, Z3_ast a)
Z3_ast Z3_API Z3_mk_bvsrem(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed remainder (sign follows dividend).
bool Z3_API Z3_is_as_array(Z3_context c, Z3_ast a)
The (_ as-array f) AST node is a construct for assigning interpretations for arrays in Z3....
Z3_func_decl Z3_API Z3_mk_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a constant or function.
Z3_ast Z3_API Z3_mk_is_int(Z3_context c, Z3_ast t1)
Check if a real number is an integer.
void Z3_API Z3_params_set_bool(Z3_context c, Z3_params p, Z3_symbol k, bool v)
Add a Boolean parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_mk_ite(Z3_context c, Z3_ast t1, Z3_ast t2, Z3_ast t3)
Create an AST node representing an if-then-else: ite(t1, t2, t3).
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i)
Array read. The argument a is the array and i is the index of the array that gets read.
Z3_ast Z3_API Z3_mk_sign_ext(Z3_context c, unsigned i, Z3_ast t1)
Sign-extend of the given bit-vector to the (signed) equivalent bit-vector of size m+i,...
unsigned Z3_API Z3_goal_size(Z3_context c, Z3_goal g)
Return the number of formulas in the given goal.
void Z3_API Z3_stats_inc_ref(Z3_context c, Z3_stats s)
Increment the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs)
n-ary Array read. The argument a is the array and idxs are the indices of the array that gets read.
Z3_ast_vector Z3_API Z3_algebraic_get_poly(Z3_context c, Z3_ast a)
Return the coefficients of the defining polynomial.
Z3_ast Z3_API Z3_mk_div(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 div arg2.
void Z3_API Z3_model_dec_ref(Z3_context c, Z3_model m)
Decrement the reference counter of the given model.
void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f)
Increment the reference counter of the given Z3_func_interp object.
void Z3_API Z3_params_set_double(Z3_context c, Z3_params p, Z3_symbol k, double v)
Add a double parameter k with value v to the parameter set p.
Z3_string Z3_API Z3_param_descrs_get_documentation(Z3_context c, Z3_param_descrs p, Z3_symbol s)
Retrieve documentation string corresponding to parameter name s.
Z3_sort Z3_API Z3_mk_datatype_sort(Z3_context c, Z3_symbol name)
create a forward reference to a recursive datatype being declared. The forward reference can be used ...
Z3_solver Z3_API Z3_mk_solver(Z3_context c)
Create a new solver. This solver is a "combined solver" (see combined_solver module) that internally ...
Z3_model Z3_API Z3_solver_get_model(Z3_context c, Z3_solver s)
Retrieve the model for the last Z3_solver_check or Z3_solver_check_assumptions.
int Z3_API Z3_get_symbol_int(Z3_context c, Z3_symbol s)
Return the symbol int value.
Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a)
Return the function declaration f associated with a (_ as_array f) node.
Z3_ast Z3_API Z3_mk_ext_rotate_left(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the left t2 times.
void Z3_API Z3_goal_inc_ref(Z3_context c, Z3_goal g)
Increment the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_implies(Z3_context c, Z3_ast t1, Z3_ast t2)
Create an AST node representing t1 implies t2.
unsigned Z3_API Z3_get_datatype_sort_num_constructors(Z3_context c, Z3_sort t)
Return number of constructors for datatype.
void Z3_API Z3_params_set_uint(Z3_context c, Z3_params p, Z3_symbol k, unsigned v)
Add a unsigned parameter k with value v to the parameter set p.
Z3_lbool Z3_API Z3_solver_check_assumptions(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[])
Check whether the assertions in the given solver and optional assumptions are consistent or not.
Z3_sort Z3_API Z3_model_get_sort(Z3_context c, Z3_model m, unsigned i)
Return a uninterpreted sort that m assigns an interpretation.
Z3_ast Z3_API Z3_mk_bvashr(Z3_context c, Z3_ast t1, Z3_ast t2)
Arithmetic shift right.
Z3_ast Z3_API Z3_mk_bv2int(Z3_context c, Z3_ast t1, bool is_signed)
Create an integer from the bit-vector argument t1. If is_signed is false, then the bit-vector t1 is t...
Z3_sort Z3_API Z3_get_array_sort_domain_n(Z3_context c, Z3_sort t, unsigned idx)
Return the i'th domain sort of an n-dimensional array.
Z3_ast Z3_API Z3_mk_set_del(Z3_context c, Z3_ast set, Z3_ast elem)
Remove an element to a set.
Z3_ast Z3_API Z3_mk_bvmul_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise multiplication of t1 and t2 does not overflow.
Z3_ast Z3_API Z3_mk_bvor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise or.
int Z3_API Z3_get_decl_int_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the integer value associated with an integer parameter.
unsigned Z3_API Z3_get_quantifier_num_no_patterns(Z3_context c, Z3_ast a)
Return number of no_patterns used in quantifier.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor(Z3_context c, Z3_sort t, unsigned idx)
Return idx'th constructor.
void Z3_API Z3_ast_vector_resize(Z3_context c, Z3_ast_vector v, unsigned n)
Resize the AST vector v.
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c, bool is_forall, unsigned weight, Z3_symbol quantifier_id, Z3_symbol skolem_id, unsigned num_bound, Z3_app const bound[], unsigned num_patterns, Z3_pattern const patterns[], unsigned num_no_patterns, Z3_ast const no_patterns[], Z3_ast body)
Create a universal or existential quantifier using a list of constants that will form the set of boun...
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[])
Create a pattern for quantifier instantiation.
Z3_symbol_kind Z3_API Z3_get_symbol_kind(Z3_context c, Z3_symbol s)
Return Z3_INT_SYMBOL if the symbol was constructed using Z3_mk_int_symbol, and Z3_STRING_SYMBOL if th...
bool Z3_API Z3_is_lambda(Z3_context c, Z3_ast a)
Determine if ast is a lambda expression.
unsigned Z3_API Z3_stats_get_uint_value(Z3_context c, Z3_stats s, unsigned idx)
Return the unsigned value of the given statistical data.
Z3_sort Z3_API Z3_get_array_sort_domain(Z3_context c, Z3_sort t)
Return the domain of the given array sort. In the case of a multi-dimensional array,...
Z3_ast Z3_API Z3_mk_bvmul_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed multiplication of t1 and t2 does not underflo...
Z3_ast Z3_API Z3_func_decl_to_ast(Z3_context c, Z3_func_decl f)
Convert a Z3_func_decl into Z3_ast. This is just type casting.
void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a)
Add a constant interpretation.
Z3_ast Z3_API Z3_mk_bvadd(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement addition.
unsigned Z3_API Z3_algebraic_get_i(Z3_context c, Z3_ast a)
Return which root of the polynomial the algebraic number represents.
void Z3_API Z3_params_dec_ref(Z3_context c, Z3_params p)
Decrement the reference counter of the given parameter set.
Z3_ast Z3_API Z3_get_app_arg(Z3_context c, Z3_app a, unsigned i)
Return the i-th argument of the given application.
Z3_string Z3_API Z3_model_to_string(Z3_context c, Z3_model m)
Convert the given model into a string.
Z3_func_decl Z3_API Z3_mk_fresh_func_decl(Z3_context c, Z3_string prefix, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a fresh constant or function.
unsigned Z3_API Z3_ast_map_size(Z3_context c, Z3_ast_map m)
Return the size of the given map.
unsigned Z3_API Z3_param_descrs_size(Z3_context c, Z3_param_descrs p)
Return the number of parameters in the given parameter description set.
Z3_string Z3_API Z3_goal_to_dimacs_string(Z3_context c, Z3_goal g, bool include_names)
Convert a goal into a DIMACS formatted string. The goal must be in CNF. You can convert a goal to CNF...
Z3_ast Z3_API Z3_mk_lt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than.
Z3_ast Z3_API Z3_get_quantifier_no_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th no_pattern.
double Z3_API Z3_stats_get_double_value(Z3_context c, Z3_stats s, unsigned idx)
Return the double value of the given statistical data.
Z3_ast Z3_API Z3_mk_bvugt(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than.
unsigned Z3_API Z3_goal_depth(Z3_context c, Z3_goal g)
Return the depth of the given goal. It tracks how many transformations were applied to it.
Z3_string Z3_API Z3_get_symbol_string(Z3_context c, Z3_symbol s)
Return the symbol name.
Z3_ast Z3_API Z3_pattern_to_ast(Z3_context c, Z3_pattern p)
Convert a Z3_pattern into Z3_ast. This is just type casting.
Z3_ast Z3_API Z3_mk_bvnot(Z3_context c, Z3_ast t1)
Bitwise negation.
Z3_ast Z3_API Z3_mk_bvurem(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned remainder.
void Z3_API Z3_mk_datatypes(Z3_context c, unsigned num_sorts, Z3_symbol const sort_names[], Z3_sort sorts[], Z3_constructor_list constructor_lists[])
Create mutually recursive datatypes.
unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f)
Return the arity (number of arguments) of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsub(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement subtraction.
Z3_ast Z3_API Z3_get_algebraic_number_upper(Z3_context c, Z3_ast a, unsigned precision)
Return a upper bound for the given real algebraic number. The interval isolating the number is smalle...
Z3_ast Z3_API Z3_mk_power(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 ^ arg2.
Z3_ast Z3_API Z3_mk_seq_concat(Z3_context c, unsigned n, Z3_ast const args[])
Concatenate sequences.
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c, Z3_symbol name, unsigned n, Z3_symbol const enum_names[], Z3_func_decl enum_consts[], Z3_func_decl enum_testers[])
Create a enumeration sort.
unsigned Z3_API Z3_get_bv_sort_size(Z3_context c, Z3_sort t)
Return the size of the given bit-vector sort.
Z3_ast Z3_API Z3_mk_set_member(Z3_context c, Z3_ast elem, Z3_ast set)
Check for set membership.
void Z3_API Z3_ast_vector_dec_ref(Z3_context c, Z3_ast_vector v)
Decrement the reference counter of the given AST vector.
void Z3_API Z3_func_interp_dec_ref(Z3_context c, Z3_func_interp f)
Decrement the reference counter of the given Z3_func_interp object.
void Z3_API Z3_params_inc_ref(Z3_context c, Z3_params p)
Increment the reference counter of the given parameter set.
void Z3_API Z3_set_error_handler(Z3_context c, Z3_error_handler h)
Register a Z3 error handler.
Z3_ast Z3_API Z3_mk_distinct(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing distinct(args[0], ..., args[num_args-1]).
Z3_config Z3_API Z3_mk_config(void)
Create a configuration object for the Z3 context object.
void Z3_API Z3_set_param_value(Z3_config c, Z3_string param_id, Z3_string param_value)
Set a configuration parameter.
Z3_sort Z3_API Z3_mk_bv_sort(Z3_context c, unsigned sz)
Create a bit-vector type of the given size.
Z3_ast Z3_API Z3_mk_bvult(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than.
void Z3_API Z3_ast_map_dec_ref(Z3_context c, Z3_ast_map m)
Decrement the reference counter of the given AST map.
Z3_string Z3_API Z3_params_to_string(Z3_context c, Z3_params p)
Convert a parameter set into a string. This function is mainly used for printing the contents of a pa...
Z3_param_descrs Z3_API Z3_get_global_param_descrs(Z3_context c)
Retrieve description of global parameters.
Z3_func_decl Z3_API Z3_model_get_const_decl(Z3_context c, Z3_model m, unsigned i)
Return the i-th constant in the given model.
Z3_ast Z3_API Z3_translate(Z3_context source, Z3_ast a, Z3_context target)
Translate/Copy the AST a from context source to context target. AST a must have been created using co...
Z3_sort Z3_API Z3_get_range(Z3_context c, Z3_func_decl d)
Return the range of the given declaration.
void Z3_API Z3_global_param_set(Z3_string param_id, Z3_string param_value)
Set a global (or module) parameter. This setting is shared by all Z3 contexts.
Z3_ast_vector Z3_API Z3_model_get_sort_universe(Z3_context c, Z3_model m, Z3_sort s)
Return the finite set of distinct values that represent the interpretation for sort s.
void Z3_API Z3_func_entry_dec_ref(Z3_context c, Z3_func_entry e)
Decrement the reference counter of the given Z3_func_entry object.
unsigned Z3_API Z3_stats_size(Z3_context c, Z3_stats s)
Return the number of statistical data in s.
void Z3_API Z3_append_log(Z3_string string)
Append user-defined string to interaction log.
Z3_ast Z3_API Z3_get_quantifier_body(Z3_context c, Z3_ast a)
Return body of quantifier.
void Z3_API Z3_param_descrs_dec_ref(Z3_context c, Z3_param_descrs p)
Decrement the reference counter of the given parameter description set.
Z3_model Z3_API Z3_mk_model(Z3_context c)
Create a fresh model object. It has reference count 0.
Z3_symbol Z3_API Z3_get_decl_name(Z3_context c, Z3_func_decl d)
Return the constant declaration name as a symbol.
Z3_ast Z3_API Z3_mk_bvneg_no_overflow(Z3_context c, Z3_ast t1)
Check that bit-wise negation does not overflow when t1 is interpreted as a signed bit-vector.
Z3_string Z3_API Z3_stats_get_key(Z3_context c, Z3_stats s, unsigned idx)
Return the key (a string) for a particular statistical data.
Z3_ast Z3_API Z3_mk_bvand(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise and.
Z3_ast_kind Z3_API Z3_get_ast_kind(Z3_context c, Z3_ast a)
Return the kind of the given AST.
Z3_ast Z3_API Z3_mk_bvsmod(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed remainder (sign follows divisor).
Z3_model Z3_API Z3_model_translate(Z3_context c, Z3_model m, Z3_context dst)
translate model from context c to context dst.
void Z3_API Z3_get_version(unsigned *major, unsigned *minor, unsigned *build_number, unsigned *revision_number)
Return Z3 version number information.
Z3_ast Z3_API Z3_mk_int2bv(Z3_context c, unsigned n, Z3_ast t1)
Create an n bit bit-vector from the integer argument t1.
void Z3_API Z3_solver_assert(Z3_context c, Z3_solver s, Z3_ast a)
Assert a constraint into the solver.
unsigned Z3_API Z3_ast_vector_size(Z3_context c, Z3_ast_vector v)
Return the size of the given AST vector.
unsigned Z3_API Z3_get_quantifier_weight(Z3_context c, Z3_ast a)
Obtain weight of quantifier.
bool Z3_API Z3_model_eval(Z3_context c, Z3_model m, Z3_ast t, bool model_completion, Z3_ast *v)
Evaluate the AST node t in the given model. Return true if succeeded, and store the result in v.
unsigned Z3_API Z3_solver_get_num_scopes(Z3_context c, Z3_solver s)
Return the number of backtracking points.
Z3_sort Z3_API Z3_get_array_sort_range(Z3_context c, Z3_sort t)
Return the range of the given array sort.
void Z3_API Z3_del_constructor_list(Z3_context c, Z3_constructor_list clist)
Reclaim memory allocated for constructor list.
Z3_ast Z3_API Z3_mk_bound(Z3_context c, unsigned index, Z3_sort ty)
Create a variable.
unsigned Z3_API Z3_get_app_num_args(Z3_context c, Z3_app a)
Return the number of argument of an application. If t is an constant, then the number of arguments is...
Z3_ast Z3_API Z3_func_entry_get_arg(Z3_context c, Z3_func_entry e, unsigned i)
Return an argument of a Z3_func_entry object.
Z3_ast Z3_API Z3_mk_eq(Z3_context c, Z3_ast l, Z3_ast r)
Create an AST node representing l = r.
void Z3_API Z3_ast_vector_inc_ref(Z3_context c, Z3_ast_vector v)
Increment the reference counter of the given AST vector.
unsigned Z3_API Z3_model_get_num_funcs(Z3_context c, Z3_model m)
Return the number of function interpretations in the given model.
void Z3_API Z3_dec_ref(Z3_context c, Z3_ast a)
Decrement the reference counter of the given AST. The context c should have been created using Z3_mk_...
Z3_ast_vector Z3_API Z3_mk_ast_vector(Z3_context c)
Return an empty AST vector.
Z3_ast Z3_API Z3_mk_empty_set(Z3_context c, Z3_sort domain)
Create the empty set.
Z3_ast Z3_API Z3_mk_set_has_size(Z3_context c, Z3_ast set, Z3_ast k)
Create predicate that holds if Boolean array set has k elements set to true.
Z3_ast Z3_API Z3_mk_repeat(Z3_context c, unsigned i, Z3_ast t1)
Repeat the given bit-vector up length i.
Z3_goal_prec Z3_API Z3_goal_precision(Z3_context c, Z3_goal g)
Return the "precision" of the given goal. Goals can be transformed using over and under approximation...
void Z3_API Z3_solver_pop(Z3_context c, Z3_solver s, unsigned n)
Backtrack n backtracking points.
void Z3_API Z3_ast_map_erase(Z3_context c, Z3_ast_map m, Z3_ast k)
Erase a key from the map.
Z3_ast Z3_API Z3_mk_int2real(Z3_context c, Z3_ast t1)
Coerce an integer to a real.
unsigned Z3_API Z3_get_index_value(Z3_context c, Z3_ast a)
Return index of de-Bruijn bound variable.
Z3_goal Z3_API Z3_mk_goal(Z3_context c, bool models, bool unsat_cores, bool proofs)
Create a goal (aka problem). A goal is essentially a set of formulas, that can be solved and/or trans...
double Z3_API Z3_get_decl_double_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the double value associated with an double parameter.
unsigned Z3_API Z3_get_ast_hash(Z3_context c, Z3_ast a)
Return a hash code for the given AST. The hash code is structural but two different AST objects can m...
Z3_symbol Z3_API Z3_get_sort_name(Z3_context c, Z3_sort d)
Return the sort name as a symbol.
void Z3_API Z3_params_validate(Z3_context c, Z3_params p, Z3_param_descrs d)
Validate the parameter set p against the parameter description set d.
Z3_func_decl Z3_API Z3_get_datatype_sort_recognizer(Z3_context c, Z3_sort t, unsigned idx)
Return idx'th recognizer.
void Z3_API Z3_global_param_reset_all(void)
Restore the value of all global (and module) parameters. This command will not affect already created...
Z3_ast Z3_API Z3_mk_gt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create greater than.
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v)
Array update.
Z3_string Z3_API Z3_get_decl_rational_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the rational value, as a string, associated with a rational parameter.
void Z3_API Z3_ast_vector_push(Z3_context c, Z3_ast_vector v, Z3_ast a)
Add the AST a in the end of the AST vector v. The size of v is increased by one.
bool Z3_API Z3_is_eq_ast(Z3_context c, Z3_ast t1, Z3_ast t2)
Compare terms.
bool Z3_API Z3_is_quantifier_forall(Z3_context c, Z3_ast a)
Determine if an ast is a universal quantifier.
Z3_ast_map Z3_API Z3_mk_ast_map(Z3_context c)
Return an empty mapping from AST to AST.
Z3_ast Z3_API Z3_mk_xor(Z3_context c, Z3_ast t1, Z3_ast t2)
Create an AST node representing t1 xor t2.
Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const *args)
Map f on the argument arrays.
Z3_ast Z3_API Z3_mk_const(Z3_context c, Z3_symbol s, Z3_sort ty)
Declare and create a constant.
Z3_symbol Z3_API Z3_mk_string_symbol(Z3_context c, Z3_string s)
Create a Z3 symbol using a C string.
void Z3_API Z3_param_descrs_inc_ref(Z3_context c, Z3_param_descrs p)
Increment the reference counter of the given parameter description set.
void Z3_API Z3_stats_dec_ref(Z3_context c, Z3_stats s)
Decrement the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_array_ext(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create array extensionality index given two arrays with the same sort. The meaning is given by the ax...
Z3_ast Z3_API Z3_mk_re_concat(Z3_context c, unsigned n, Z3_ast const args[])
Create the concatenation of the regular languages.
Z3_ast Z3_API Z3_sort_to_ast(Z3_context c, Z3_sort s)
Convert a Z3_sort into Z3_ast. This is just type casting.
Z3_func_entry Z3_API Z3_func_interp_get_entry(Z3_context c, Z3_func_interp f, unsigned i)
Return a "point" of the given function interpretation. It represents the value of f in a particular p...
Z3_func_decl Z3_API Z3_mk_rec_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a recursive function.
unsigned Z3_API Z3_get_ast_id(Z3_context c, Z3_ast t)
Return a unique identifier for t. The identifier is unique up to structural equality....
Z3_ast Z3_API Z3_mk_concat(Z3_context c, Z3_ast t1, Z3_ast t2)
Concatenate the given bit-vectors.
unsigned Z3_API Z3_get_quantifier_num_bound(Z3_context c, Z3_ast a)
Return number of bound variables of quantifier.
Z3_sort Z3_API Z3_get_decl_sort_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the sort value associated with a sort parameter.
Z3_constructor_list Z3_API Z3_mk_constructor_list(Z3_context c, unsigned num_constructors, Z3_constructor const constructors[])
Create list of constructors.
Z3_ast Z3_API Z3_mk_app(Z3_context c, Z3_func_decl d, unsigned num_args, Z3_ast const args[])
Create a constant or function application.
Z3_sort_kind Z3_API Z3_get_sort_kind(Z3_context c, Z3_sort t)
Return the sort kind (e.g., array, tuple, int, bool, etc).
Z3_ast Z3_API Z3_mk_bvneg(Z3_context c, Z3_ast t1)
Standard two's complement unary minus.
Z3_ast Z3_API Z3_mk_store_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs, Z3_ast v)
n-ary Array update.
Z3_sort Z3_API Z3_get_domain(Z3_context c, Z3_func_decl d, unsigned i)
Return the sort of the i-th parameter of the given function declaration.
Z3_sort Z3_API Z3_mk_bool_sort(Z3_context c)
Create the Boolean type.
void Z3_API Z3_params_set_symbol(Z3_context c, Z3_params p, Z3_symbol k, Z3_symbol v)
Add a symbol parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_ast_vector_get(Z3_context c, Z3_ast_vector v, unsigned i)
Return the AST at position i in the AST vector v.
Z3_func_decl Z3_API Z3_to_func_decl(Z3_context c, Z3_ast a)
Convert an AST into a FUNC_DECL_AST. This is just type casting.
Z3_ast Z3_API Z3_mk_set_difference(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Take the set difference between two sets.
Z3_ast Z3_API Z3_mk_bvsdiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed division.
Z3_ast Z3_API Z3_mk_bvlshr(Z3_context c, Z3_ast t1, Z3_ast t2)
Logical shift right.
Z3_ast Z3_API Z3_get_decl_ast_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_pattern Z3_API Z3_get_quantifier_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th pattern.
void Z3_API Z3_goal_dec_ref(Z3_context c, Z3_goal g)
Decrement the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_not(Z3_context c, Z3_ast a)
Create an AST node representing not(a).
Z3_ast Z3_API Z3_mk_or(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] or ... or args[num_args-1].
Z3_sort Z3_API Z3_mk_array_sort(Z3_context c, Z3_sort domain, Z3_sort range)
Create an array type.
void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m)
Increment the reference counter of the given model.
Z3_ast Z3_API Z3_mk_seq_extract(Z3_context c, Z3_ast s, Z3_ast offset, Z3_ast length)
Extract subsequence starting at offset of length.
Z3_sort Z3_API Z3_mk_type_variable(Z3_context c, Z3_symbol s)
Create a type variable.
Z3_string Z3_API Z3_get_numeral_string(Z3_context c, Z3_ast a)
Return numeral value, as a decimal string of a numeric constant term.
void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value)
add a function entry to a function interpretation.
Z3_ast Z3_API Z3_mk_bvuge(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than or equal to.
Z3_string Z3_API Z3_get_numeral_binary_string(Z3_context c, Z3_ast a)
Return numeral value, as a binary string of a numeric constant term.
Z3_sort Z3_API Z3_get_quantifier_bound_sort(Z3_context c, Z3_ast a, unsigned i)
Return sort of the i'th bound variable.
void Z3_API Z3_disable_trace(Z3_string tag)
Disable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_goal_formula(Z3_context c, Z3_goal g, unsigned idx)
Return a formula from the given goal.
Z3_symbol Z3_API Z3_mk_int_symbol(Z3_context c, int i)
Create a Z3 symbol using an integer.
unsigned Z3_API Z3_func_interp_get_num_entries(Z3_context c, Z3_func_interp f)
Return the number of entries in the given function interpretation.
void Z3_API Z3_ast_map_insert(Z3_context c, Z3_ast_map m, Z3_ast k, Z3_ast v)
Store/Replace a new key, value pair in the given map.
Z3_string Z3_API Z3_goal_to_string(Z3_context c, Z3_goal g)
Convert a goal into a string.
bool Z3_API Z3_is_eq_sort(Z3_context c, Z3_sort s1, Z3_sort s2)
compare sorts.
void Z3_API Z3_del_config(Z3_config c)
Delete the given configuration object.
void Z3_API Z3_inc_ref(Z3_context c, Z3_ast a)
Increment the reference counter of the given AST. The context c should have been created using Z3_mk_...
Z3_ast Z3_API Z3_mk_real2int(Z3_context c, Z3_ast t1)
Coerce a real to an integer.
Z3_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f)
Return the interpretation of the function f in the model m. Return NULL, if the model does not assign...
void Z3_API Z3_solver_inc_ref(Z3_context c, Z3_solver s)
Increment the reference counter of the given solver.
Z3_symbol Z3_API Z3_get_quantifier_id(Z3_context c, Z3_ast a)
Obtain id of quantifier.
Z3_ast Z3_API Z3_mk_ext_rotate_right(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the right t2 times.
Z3_string Z3_API Z3_get_numeral_decimal_string(Z3_context c, Z3_ast a, unsigned precision)
Return numeral as a string in decimal notation. The result has at most precision decimal places.
Z3_sort Z3_API Z3_get_sort(Z3_context c, Z3_ast a)
Return the sort of an AST node.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(Z3_context c, Z3_sort t, unsigned idx_c, unsigned idx_a)
Return idx_a'th accessor for the idx_c'th constructor.
Z3_ast Z3_API Z3_mk_bvredor(Z3_context c, Z3_ast t1)
Take disjunction of bits in vector, return vector of length 1.
void Z3_API Z3_ast_map_reset(Z3_context c, Z3_ast_map m)
Remove all keys from the given map.
void Z3_API Z3_solver_reset(Z3_context c, Z3_solver s)
Remove all assertions from the solver.
bool Z3_API Z3_is_algebraic_number(Z3_context c, Z3_ast a)
Return true if the given AST is a real algebraic number.
_py2expr(a, ctx=None)
Definition z3py.py:3180
RotateRight(a, b)
Definition z3py.py:4400
_symbol2py(ctx, s)
Definition z3py.py:132
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4073
BVSNegNoOverflow(a)
Definition z3py.py:4547
SetAdd(s, e)
Definition z3py.py:5019
SetSort(s)
Sets.
Definition z3py.py:4970
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1227
UGT(a, b)
Definition z3py.py:4271
is_probe(p)
Definition z3py.py:8817
is_lt(a)
Definition z3py.py:2938
Var(idx, s)
Definition z3py.py:1495
SetDel(s, e)
Definition z3py.py:5030
BoolSort(ctx=None)
Definition z3py.py:1738
is_bv_sort(s)
Definition z3py.py:3529
_ctx_from_ast_args(*args)
Definition z3py.py:511
RatVal(a, b, ctx=None)
Definition z3py.py:3272
_to_func_decl_ref(a, ctx)
Definition z3py.py:923
SetUnion(*args)
Definition z3py.py:4993
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5090
BitVec(name, bv, ctx=None)
Definition z3py.py:4090
DeclareSort(name, ctx=None)
Definition z3py.py:695
EmptySet(s)
Definition z3py.py:4975
BVMulNoUnderflow(a, b)
Definition z3py.py:4561
CreateDatatypes(*ds)
Definition z3py.py:5211
is_func_decl(a)
Definition z3py.py:868
get_as_array_func(n)
Definition z3py.py:6779
Distinct(*args)
Definition z3py.py:1429
is_distinct(a)
Definition z3py.py:1726
RecAddDefinition(f, args, body)
Definition z3py.py:945
ToInt(a)
Definition z3py.py:3429
Implies(a, b, ctx=None)
Definition z3py.py:1832
UGE(a, b)
Definition z3py.py:4253
Ext(a, b)
Definition z3py.py:4921
_to_ast_array(args)
Definition z3py.py:523
_check_bv_args(a, b)
Definition z3py.py:4212
RealSort(ctx=None)
Definition z3py.py:3212
IsSubset(a, b)
Definition z3py.py:5073
DeclareTypeVar(name, ctx=None)
Definition z3py.py:723
_get_args_ast_list(args)
Definition z3py.py:158
_to_ref_array(ref, args)
Definition z3py.py:531
get_map_func(a)
Definition z3py.py:4729
_z3_check_cint_overflow(n, name)
Definition z3py.py:110
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5416
is_sort(s)
Definition z3py.py:647
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1255
is_select(a)
Definition z3py.py:4939
SignExt(n, a)
Definition z3py.py:4416
Int(name, ctx=None)
Definition z3py.py:3301
Bools(names, ctx=None)
Definition z3py.py:1787
_probe_and(args, ctx)
Definition z3py.py:8884
Int2BV(a, num_bits)
Definition z3py.py:4049
Lambda(vs, body)
Definition z3py.py:2318
_to_param_value(val)
Definition z3py.py:168
FreshFunction(*sig)
Definition z3py.py:904
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3382
BVRedOr(a)
Definition z3py.py:4505
is_true(a)
Definition z3py.py:1636
SRem(a, b)
Definition z3py.py:4331
is_le(a)
Definition z3py.py:2926
is_idiv(a)
Definition z3py.py:2902
set_option(*args, **kws)
Definition z3py.py:301
_ast_kind(ctx, a)
Definition z3py.py:491
is_bv(a)
Definition z3py.py:3997
SetDifference(a, b)
Definition z3py.py:5051
_get_ctx(ctx)
Definition z3py.py:260
BitVecs(names, bv, ctx=None)
Definition z3py.py:4114
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1803
is_mul(a)
Definition z3py.py:2861
_has_probe(args)
Definition z3py.py:1888
IsMember(e, s)
Definition z3py.py:5062
get_param(name)
Definition z3py.py:307
BVAddNoUnderflow(a, b)
Definition z3py.py:4519
deserialize(st)
Definition z3py.py:1144
Extract(high, low, a)
Definition z3py.py:4181
Function(name, *sig)
Definition z3py.py:881
get_version()
Definition z3py.py:92
FreshConst(sort, prefix="c")
Definition z3py.py:1489
ULT(a, b)
Definition z3py.py:4235
EnumSort(name, values, ctx=None)
Definition z3py.py:5440
_to_int_str(val)
Definition z3py.py:3229
is_algebraic_value(a)
Definition z3py.py:2835
is_bv_value(a)
Definition z3py.py:4011
BVSDivNoOverflow(a, b)
Definition z3py.py:4540
SetIntersect(*args)
Definition z3py.py:5006
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:8951
BV2Int(a, is_signed=False)
Definition z3py.py:4026
RealVar(idx, ctx=None)
Definition z3py.py:1510
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3340
is_div(a)
Definition z3py.py:2885
_to_ast_ref(a, ctx)
Definition z3py.py:539
_to_func_decl_array(args)
Definition z3py.py:515
disable_trace(msg)
Definition z3py.py:79
is_map(a)
Definition z3py.py:4704
is_not(a)
Definition z3py.py:1704
Or(*args)
Definition z3py.py:1929
is_re(s)
Definition z3py.py:11374
is_bool(a)
Definition z3py.py:1618
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5519
Consts(names, sort)
Definition z3py.py:1474
Cond(p, t1, t2, ctx=None)
Definition z3py.py:8934
is_mod(a)
Definition z3py.py:2914
_to_pattern(arg)
Definition z3py.py:2022
is_arith(a)
Definition z3py.py:2722
If(a, b, c, ctx=None)
Definition z3py.py:1406
is_app_of(a, k)
Definition z3py.py:1393
is_app(a)
Definition z3py.py:1290
_sort(ctx, a)
Definition z3py.py:691
z3_error_handler(c, e)
Definition z3py.py:174
Reals(names, ctx=None)
Definition z3py.py:3367
is_int_value(a)
Definition z3py.py:2789
set_param(*args, **kws)
Definition z3py.py:271
is_pattern(a)
Definition z3py.py:1980
is_add(a)
Definition z3py.py:2849
is_to_int(a)
Definition z3py.py:3001
_coerce_seq(s, ctx=None)
Definition z3py.py:11053
is_ge(a)
Definition z3py.py:2950
is_sub(a)
Definition z3py.py:2873
is_implies(a)
Definition z3py.py:1692
ULE(a, b)
Definition z3py.py:4217
is_real(a)
Definition z3py.py:2762
is_arith_sort(s)
Definition z3py.py:2421
FullSet(s)
Definition z3py.py:4984
to_symbol(s, ctx=None)
Definition z3py.py:124
is_array(a)
Definition z3py.py:4664
_get_args(args)
Definition z3py.py:144
And(*args)
Definition z3py.py:1896
RepeatBitVec(n, a)
Definition z3py.py:4474
SetHasSize(a, k)
Definition z3py.py:4933
is_to_real(a)
Definition z3py.py:2986
get_version_string()
Definition z3py.py:83
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3397
Array(name, *sorts)
Definition z3py.py:4786
Concat(*args)
Definition z3py.py:4135
_reduce(func, sequence, initial)
Definition z3py.py:1248
is_false(a)
Definition z3py.py:1654
_is_algebraic(ctx, a)
Definition z3py.py:2785
Ints(names, ctx=None)
Definition z3py.py:3314
Select(a, *args)
Definition z3py.py:4860
Const(name, sort)
Definition z3py.py:1462
is_array_sort(a)
Definition z3py.py:4660
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4512
is_int(a)
Definition z3py.py:2743
Real(name, ctx=None)
Definition z3py.py:3354
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1818
BitVecSort(sz, ctx=None)
Definition z3py.py:4058
open_log(fname)
Definition z3py.py:114
is_and(a)
Definition z3py.py:1668
RecFunction(name, *sig)
Definition z3py.py:927
get_ctx(ctx)
Definition z3py.py:267
Model(ctx=None, eval={})
Definition z3py.py:6766
BVSubNoOverflow(a, b)
Definition z3py.py:4526
is_default(a)
Definition z3py.py:4720
is_K(a)
Definition z3py.py:4691
Bool(name, ctx=None)
Definition z3py.py:1775
_is_int(v)
Definition z3py.py:68
is_const_array(a)
Definition z3py.py:4678
Sqrt(a, ctx=None)
Definition z3py.py:3464
main_ctx()
Definition z3py.py:239
Default(a)
Definition z3py.py:4832
is_is_int(a)
Definition z3py.py:2974
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:497
SetComplement(s)
Definition z3py.py:5041
is_as_array(n)
Definition z3py.py:6774
is_store(a)
Definition z3py.py:4952
eq(a, b)
Definition z3py.py:472
is_quantifier(a)
Definition z3py.py:2230
is_eq(a)
Definition z3py.py:1716
reset_params()
Definition z3py.py:295
_mk_bin(f, a, b)
Definition z3py.py:1453
K(dom, v)
Definition z3py.py:4899
Xor(a, b, ctx=None)
Definition z3py.py:1846
Store(a, *args)
Definition z3py.py:4843
mk_not(a)
Definition z3py.py:1881
is_expr(a)
Definition z3py.py:1267
_array_select(ar, arg)
Definition z3py.py:4651
is_or(a)
Definition z3py.py:1680
is_const(a)
Definition z3py.py:1316
BoolVal(val, ctx=None)
Definition z3py.py:1756
RealVal(val, ctx=None)
Definition z3py.py:3253
z3_debug()
Definition z3py.py:62
get_full_version()
Definition z3py.py:101
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3327
_coerce_expr_merge(s, a)
Definition z3py.py:1208
LShR(a, b)
Definition z3py.py:4352
RealVarVector(n, ctx=None)
Definition z3py.py:1521
ArraySort(*sig)
Definition z3py.py:4753
Map(f, *args)
Definition z3py.py:4876
is_rational_value(a)
Definition z3py.py:2813
_probe_or(args, ctx)
Definition z3py.py:8888
is_gt(a)
Definition z3py.py:2962
BVRedAnd(a)
Definition z3py.py:4498
Cbrt(a, ctx=None)
Definition z3py.py:3477
_to_expr_ref(a, ctx)
Definition z3py.py:1158
is_ast(a)
Definition z3py.py:451
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5428
IntSort(ctx=None)
Definition z3py.py:3195
is_seq(a)
Definition z3py.py:11074
Not(a, ctx=None)
Definition z3py.py:1862
_to_sort_ref(s, ctx)
Definition z3py.py:660
enable_trace(msg)
Definition z3py.py:75
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2297
ToReal(a)
Definition z3py.py:3411
URem(a, b)
Definition z3py.py:4310
StringVal(s, ctx=None)
Definition z3py.py:11101
IsInt(a)
Definition z3py.py:3447
_is_numeral(ctx, a)
Definition z3py.py:2781
MultiPattern(*args)
Definition z3py.py:1998
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2279
ZeroExt(n, a)
Definition z3py.py:4446
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:555
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4533
UDiv(a, b)
Definition z3py.py:4289
DatatypeSort(name, ctx=None)
Definition z3py.py:5411
Q(a, b, ctx=None)
Definition z3py.py:3288
Update(a, *args)
Definition z3py.py:4800
get_var_index(a)
Definition z3py.py:1360
append_log(s)
Definition z3py.py:119
is_var(a)
Definition z3py.py:1335
IntVal(val, ctx=None)
Definition z3py.py:3241
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4554
RotateLeft(a, b)
Definition z3py.py:4384
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2244
_z3_assert(cond, msg)
Definition z3py.py:105