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, Iterator
58
59from collections.abc import Callable
60from typing import (
61 Any,
62 Iterable,
63 Sequence
64)
65
66
67Z3_DEBUG = __debug__
68
69
71 global Z3_DEBUG
72 return Z3_DEBUG
73
74
75if sys.version_info.major < 3:
76 def _is_int(v):
77 return isinstance(v, (int, long))
78else:
79 def _is_int(v):
80 return isinstance(v, int)
81
82
83def enable_trace(msg):
85
86
89
90
92 major = ctypes.c_uint(0)
93 minor = ctypes.c_uint(0)
94 build = ctypes.c_uint(0)
95 rev = ctypes.c_uint(0)
96 Z3_get_version(major, minor, build, rev)
97 return "%s.%s.%s" % (major.value, minor.value, build.value)
98
99
101 major = ctypes.c_uint(0)
102 minor = ctypes.c_uint(0)
103 build = ctypes.c_uint(0)
104 rev = ctypes.c_uint(0)
105 Z3_get_version(major, minor, build, rev)
106 return (major.value, minor.value, build.value, rev.value)
107
108
110 return Z3_get_full_version()
111
112
113def _z3_assert(cond, msg):
114 if not cond:
115 raise Z3Exception(msg)
116
117
119 _z3_assert(ctypes.c_int(n).value == n, name + " is too large")
120
121
122def open_log(fname):
123 """Log interaction to a file. This function must be invoked immediately after init(). """
124 Z3_open_log(fname)
125
126
128 """Append user-defined string to interaction log. """
130
131
132def to_symbol(s, ctx = None):
133 """Convert an integer or string into a Z3 symbol."""
134 if _is_int(s):
135 return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
136 else:
137 return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
138
139
140def _symbol2py(ctx, s):
141 """Convert a Z3 symbol back into a Python object. """
142 if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
143 return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
144 else:
145 return Z3_get_symbol_string(ctx.ref(), s)
146
147# Hack for having nary functions that can receive one argument that is the
148# list of arguments.
149# Use this when function takes a single list of arguments
150
151
152def _get_args(args):
153 try:
154 if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
155 return args[0]
156 elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)):
157 return [arg for arg in args[0]]
158 elif len(args) == 1 and isinstance(args[0], Iterator):
159 return list(args[0])
160 else:
161 return args
162 except TypeError: # len is not necessarily defined when args is not a sequence (use reflection?)
163 return args
164
165# Use this when function takes multiple arguments
166
167
169 try:
170 if isinstance(args, (set, AstVector, tuple)):
171 return [arg for arg in args]
172 else:
173 return args
174 except Exception:
175 return args
176
177
179 if isinstance(val, bool):
180 return "true" if val else "false"
181 return str(val)
182
183
185 # Do nothing error handler, just avoid exit(0)
186 # The wrappers in z3core.py will raise a Z3Exception if an error is detected
187 return
188
189
190class Context:
191 """A Context manages all other Z3 objects, global configuration options, etc.
192
193 Z3Py uses a default global context. For most applications this is sufficient.
194 An application may use multiple Z3 contexts. Objects created in one context
195 cannot be used in another one. However, several objects may be "translated" from
196 one context to another. It is not safe to access Z3 objects from multiple threads.
197 The only exception is the method `interrupt()` that can be used to interrupt() a long
198 computation.
199 The initialization method receives global configuration options for the new context.
200 """
201
202 def __init__(self, *args, **kws):
203 if z3_debug():
204 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
205 conf = Z3_mk_config()
206 for key in kws:
207 value = kws[key]
208 Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
209 prev = None
210 for a in args:
211 if prev is None:
212 prev = a
213 else:
214 Z3_set_param_value(conf, str(prev), _to_param_value(a))
215 prev = None
217 self.owner = True
218 self.eh = Z3_set_error_handler(self.ctx, z3_error_handler)
219 Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
220 Z3_del_config(conf)
221
222 def __del__(self):
223 if Z3_del_context is not None and self.owner:
224 Z3_del_context(self.ctx)
225 self.ctx = None
226 self.eh = None
227
228 def ref(self):
229 """Return a reference to the actual C pointer to the Z3 context."""
230 return self.ctx
231
232 def interrupt(self):
233 """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
234
235 This method can be invoked from a thread different from the one executing the
236 interruptible procedure.
237 """
238 Z3_interrupt(self.ref())
239
240 def param_descrs(self):
241 """Return the global parameter description set."""
242 return ParamDescrsRef(Z3_get_global_param_descrs(self.ref()), self)
243
244
245# Global Z3 context
246_main_ctx = None
247
248
249def main_ctx() -> Context:
250 """Return a reference to the global Z3 context.
251
252 >>> x = Real('x')
253 >>> x.ctx == main_ctx()
254 True
255 >>> c = Context()
256 >>> c == main_ctx()
257 False
258 >>> x2 = Real('x', c)
259 >>> x2.ctx == c
260 True
261 >>> eq(x, x2)
262 False
263 """
264 global _main_ctx
265 if _main_ctx is None:
266 _main_ctx = Context()
267 return _main_ctx
268
269
270def _get_ctx(ctx) -> Context:
271 if ctx is None:
272 return main_ctx()
273 else:
274 return ctx
275
276
277def get_ctx(ctx) -> Context:
278 return _get_ctx(ctx)
279
280
281def set_param(*args, **kws):
282 """Set Z3 global (or module) parameters.
283
284 >>> set_param(precision=10)
285 """
286 if z3_debug():
287 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
288 new_kws = {}
289 for k in kws:
290 v = kws[k]
291 if not set_pp_option(k, v):
292 new_kws[k] = v
293 for key in new_kws:
294 value = new_kws[key]
295 Z3_global_param_set(str(key).upper(), _to_param_value(value))
296 prev = None
297 for a in args:
298 if prev is None:
299 prev = a
300 else:
302 prev = None
303
304
305def reset_params() -> None:
306 """Reset all global (or module) parameters.
307 """
309
310
311def set_option(*args, **kws):
312 """Alias for 'set_param' for backward compatibility.
313 """
314 return set_param(*args, **kws)
315
316
317def get_param(name):
318 """Return the value of a Z3 global (or module) parameter
319
320 >>> get_param('nlsat.reorder')
321 'true'
322 """
323 ptr = (ctypes.c_char_p * 1)()
324 if Z3_global_param_get(str(name), ptr):
325 r = z3core._to_pystr(ptr[0])
326 return r
327 raise Z3Exception("failed to retrieve value for '%s'" % name)
328
329
334
335# Mark objects that use pretty printer
336
337
339 """Superclass for all Z3 objects that have support for pretty printing."""
340
341 def use_pp(self):
342 return True
343
344 def _repr_html_(self):
345 in_html = in_html_mode()
346 set_html_mode(True)
347 res = repr(self)
348 set_html_mode(in_html)
349 return res
350
351
353 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
354
355 def __init__(self, ast, ctx=None):
356 self.ast = ast
357 self.ctx = _get_ctx(ctx)
358 Z3_inc_ref(self.ctx.ref(), self.as_ast())
359
360 def __del__(self):
361 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
362 Z3_dec_ref(self.ctx.ref(), self.as_ast())
363 self.ast = None
364
365 def __deepcopy__(self, memo={}):
366 return _to_ast_ref(self.ast, self.ctx)
367
368 def __str__(self):
369 return obj_to_string(self)
370
371 def __repr__(self):
372 return obj_to_string(self)
373
374 def __eq__(self, other):
375 return self.eq(other)
376
377 def __hash__(self):
378 return self.hash()
379
380 def __nonzero__(self):
381 return self.__bool__()
382
383 def __bool__(self):
384 if is_true(self):
385 return True
386 elif is_false(self):
387 return False
388 elif is_eq(self) and self.num_args() == 2:
389 return self.arg(0).eq(self.arg(1))
390 else:
391 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
392
393 def sexpr(self):
394 """Return a string representing the AST node in s-expression notation.
395
396 >>> x = Int('x')
397 >>> ((x + 1)*x).sexpr()
398 '(* (+ x 1) x)'
399 """
400 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
401
402 def as_ast(self):
403 """Return a pointer to the corresponding C Z3_ast object."""
404 return self.ast
405
406 def get_id(self):
407 """Return unique identifier for object. It can be used for hash-tables and maps."""
408 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
409
410 def ctx_ref(self):
411 """Return a reference to the C context where this AST node is stored."""
412 return self.ctx.ref()
413
414 def eq(self, other):
415 """Return `True` if `self` and `other` are structurally identical.
416
417 >>> x = Int('x')
418 >>> n1 = x + 1
419 >>> n2 = 1 + x
420 >>> n1.eq(n2)
421 False
422 >>> n1 = simplify(n1)
423 >>> n2 = simplify(n2)
424 >>> n1.eq(n2)
425 True
426 """
427 if z3_debug():
428 _z3_assert(is_ast(other), "Z3 AST expected")
429 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
430
431 def translate(self, target):
432 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
433
434 >>> c1 = Context()
435 >>> c2 = Context()
436 >>> x = Int('x', c1)
437 >>> y = Int('y', c2)
438 >>> # Nodes in different contexts can't be mixed.
439 >>> # However, we can translate nodes from one context to another.
440 >>> x.translate(c2) + y
441 x + y
442 """
443 if z3_debug():
444 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
445 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
446
447 def __copy__(self):
448 return self.translate(self.ctx)
449
450 def hash(self):
451 """Return a hashcode for the `self`.
452
453 >>> n1 = simplify(Int('x') + 1)
454 >>> n2 = simplify(2 + Int('x') - 1)
455 >>> n1.hash() == n2.hash()
456 True
457 """
458 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
459
460 def py_value(self):
461 """Return a Python value that is equivalent to `self`."""
462 return None
463
464
465def is_ast(a : Any) -> bool:
466 """Return `True` if `a` is an AST node.
467
468 >>> is_ast(10)
469 False
470 >>> is_ast(IntVal(10))
471 True
472 >>> is_ast(Int('x'))
473 True
474 >>> is_ast(BoolSort())
475 True
476 >>> is_ast(Function('f', IntSort(), IntSort()))
477 True
478 >>> is_ast("x")
479 False
480 >>> is_ast(Solver())
481 False
482 """
483 return isinstance(a, AstRef)
484
485
486def eq(a : AstRef, b : AstRef) -> bool:
487 """Return `True` if `a` and `b` are structurally identical AST nodes.
488
489 >>> x = Int('x')
490 >>> y = Int('y')
491 >>> eq(x, y)
492 False
493 >>> eq(x + 1, x + 1)
494 True
495 >>> eq(x + 1, 1 + x)
496 False
497 >>> eq(simplify(x + 1), simplify(1 + x))
498 True
499 """
500 if z3_debug():
501 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
502 return a.eq(b)
503
504
505def _ast_kind(ctx : Context, a : Any) -> int:
506 if is_ast(a):
507 a = a.as_ast()
508 return Z3_get_ast_kind(ctx.ref(), a)
509
510
511def _ctx_from_ast_arg_list(args, default_ctx=None):
512 ctx = None
513 for a in args:
514 if is_ast(a) or is_probe(a):
515 if ctx is None:
516 ctx = a.ctx
517 else:
518 if z3_debug():
519 _z3_assert(ctx == a.ctx, "Context mismatch")
520 if ctx is None:
521 ctx = default_ctx
522 return ctx
523
524
526 return _ctx_from_ast_arg_list(args)
527
528
530 sz = len(args)
531 _args = (FuncDecl * sz)()
532 for i in range(sz):
533 _args[i] = args[i].as_func_decl()
534 return _args, sz
535
536
538 sz = len(args)
539 _args = (Ast * sz)()
540 for i in range(sz):
541 _args[i] = args[i].as_ast()
542 return _args, sz
543
544
545def _to_ref_array(ref, args):
546 sz = len(args)
547 _args = (ref * sz)()
548 for i in range(sz):
549 _args[i] = args[i].as_ast()
550 return _args, sz
551
552
553def _to_ast_ref(a, ctx):
554 k = _ast_kind(ctx, a)
555 if k == Z3_SORT_AST:
556 return _to_sort_ref(a, ctx)
557 elif k == Z3_FUNC_DECL_AST:
558 return _to_func_decl_ref(a, ctx)
559 else:
560 return _to_expr_ref(a, ctx)
561
562
563
568
569def _sort_kind(ctx, s):
570 return Z3_get_sort_kind(ctx.ref(), s)
571
572
574 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
575
576 def as_ast(self):
577 return Z3_sort_to_ast(self.ctx_ref(), self.ast)
578
579 def get_id(self):
580 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
581
582 def kind(self):
583 """Return the Z3 internal kind of a sort.
584 This method can be used to test if `self` is one of the Z3 builtin sorts.
585
586 >>> b = BoolSort()
587 >>> b.kind() == Z3_BOOL_SORT
588 True
589 >>> b.kind() == Z3_INT_SORT
590 False
591 >>> A = ArraySort(IntSort(), IntSort())
592 >>> A.kind() == Z3_ARRAY_SORT
593 True
594 >>> A.kind() == Z3_INT_SORT
595 False
596 """
597 return _sort_kind(self.ctx, self.ast)
598
599 def subsort(self, other):
600 """Return `True` if `self` is a subsort of `other`.
601
602 >>> IntSort().subsort(RealSort())
603 True
604 """
605 return False
606
607 def cast(self, val):
608 """Try to cast `val` as an element of sort `self`.
609
610 This method is used in Z3Py to convert Python objects such as integers,
611 floats, longs and strings into Z3 expressions.
612
613 >>> x = Int('x')
614 >>> RealSort().cast(x)
615 ToReal(x)
616 """
617 if z3_debug():
618 _z3_assert(is_expr(val), "Z3 expression expected")
619 _z3_assert(self.eq(val.sort()), "Sort mismatch")
620 return val
621
622 def name(self):
623 """Return the name (string) of sort `self`.
624
625 >>> BoolSort().name()
626 'Bool'
627 >>> ArraySort(IntSort(), IntSort()).name()
628 'Array'
629 """
630 return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
631
632 def __eq__(self, other):
633 """Return `True` if `self` and `other` are the same Z3 sort.
634
635 >>> p = Bool('p')
636 >>> p.sort() == BoolSort()
637 True
638 >>> p.sort() == IntSort()
639 False
640 """
641 if other is None:
642 return False
643 return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
644
645 def __ne__(self, other):
646 """Return `True` if `self` and `other` are not the same Z3 sort.
647
648 >>> p = Bool('p')
649 >>> p.sort() != BoolSort()
650 False
651 >>> p.sort() != IntSort()
652 True
653 """
654 return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
655
656 def __hash__(self):
657 """ Hash code. """
658 return AstRef.__hash__(self)
659
660
661def is_sort(s : Any) -> bool:
662 """Return `True` if `s` is a Z3 sort.
663
664 >>> is_sort(IntSort())
665 True
666 >>> is_sort(Int('x'))
667 False
668 >>> is_expr(Int('x'))
669 True
670 """
671 return isinstance(s, SortRef)
672
673
674def _to_sort_ref(s, ctx):
675 if z3_debug():
676 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
677 k = _sort_kind(ctx, s)
678 if k == Z3_BOOL_SORT:
679 return BoolSortRef(s, ctx)
680 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
681 return ArithSortRef(s, ctx)
682 elif k == Z3_BV_SORT:
683 return BitVecSortRef(s, ctx)
684 elif k == Z3_ARRAY_SORT:
685 return ArraySortRef(s, ctx)
686 elif k == Z3_DATATYPE_SORT:
687 return DatatypeSortRef(s, ctx)
688 elif k == Z3_FINITE_DOMAIN_SORT:
689 return FiniteDomainSortRef(s, ctx)
690 elif k == Z3_FLOATING_POINT_SORT:
691 return FPSortRef(s, ctx)
692 elif k == Z3_ROUNDING_MODE_SORT:
693 return FPRMSortRef(s, ctx)
694 elif k == Z3_RE_SORT:
695 return ReSortRef(s, ctx)
696 elif k == Z3_SEQ_SORT:
697 return SeqSortRef(s, ctx)
698 elif k == Z3_CHAR_SORT:
699 return CharSortRef(s, ctx)
700 elif k == Z3_TYPE_VAR:
701 return TypeVarRef(s, ctx)
702 return SortRef(s, ctx)
703
704
705def _sort(ctx : Context, a : Any) -> SortRef:
706 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
707
708
709def DeclareSort(name, ctx= None) -> SortRef:
710 """Create a new uninterpreted sort named `name`.
711
712 If `ctx=None`, then the new sort is declared in the global Z3Py context.
713
714 >>> A = DeclareSort('A')
715 >>> a = Const('a', A)
716 >>> b = Const('b', A)
717 >>> a.sort() == A
718 True
719 >>> b.sort() == A
720 True
721 >>> a == b
722 a == b
723 """
724 ctx = _get_ctx(ctx)
725 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
726
728 """Type variable reference"""
729
730 def subsort(self, other):
731 return True
732
733 def cast(self, val):
734 return val
735
736
737def DeclareTypeVar(name, ctx=None):
738 """Create a new type variable named `name`.
739
740 If `ctx=None`, then the new sort is declared in the global Z3Py context.
741
742 """
743 ctx = _get_ctx(ctx)
744 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
745
746
747
752
753
755 """Function declaration. Every constant and function have an associated declaration.
756
757 The declaration assigns a name, a sort (i.e., type), and for function
758 the sort (i.e., type) of each of its arguments. Note that, in Z3,
759 a constant is a function with 0 arguments.
760 """
761
762 def as_ast(self):
763 return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
764
765 def get_id(self):
766 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
767
768 def as_func_decl(self):
769 return self.ast
770
771 def name(self):
772 """Return the name of the function declaration `self`.
773
774 >>> f = Function('f', IntSort(), IntSort())
775 >>> f.name()
776 'f'
777 >>> isinstance(f.name(), str)
778 True
779 """
780 return _symbol2py(self.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
781
782 def arity(self):
783 """Return the number of arguments of a function declaration.
784 If `self` is a constant, then `self.arity()` is 0.
785
786 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
787 >>> f.arity()
788 2
789 """
790 return int(Z3_get_arity(self.ctx_ref(), self.ast))
791
792 def domain(self, i):
793 """Return the sort of the argument `i` of a function declaration.
794 This method assumes that `0 <= i < self.arity()`.
795
796 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
797 >>> f.domain(0)
798 Int
799 >>> f.domain(1)
800 Real
801 """
802 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
803
804 def range(self):
805 """Return the sort of the range of a function declaration.
806 For constants, this is the sort of the constant.
807
808 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
809 >>> f.range()
810 Bool
811 """
812 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.ast), self.ctx)
813
814 def kind(self):
815 """Return the internal kind of a function declaration.
816 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
817
818 >>> x = Int('x')
819 >>> d = (x + 1).decl()
820 >>> d.kind() == Z3_OP_ADD
821 True
822 >>> d.kind() == Z3_OP_MUL
823 False
824 """
825 return Z3_get_decl_kind(self.ctx_ref(), self.ast)
826
827 def params(self):
828 ctx = self.ctx
829 n = Z3_get_decl_num_parameters(self.ctx_ref(), self.ast)
830 result = [None for i in range(n)]
831 for i in range(n):
832 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.ast, i)
833 if k == Z3_PARAMETER_INT:
834 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.ast, i)
835 elif k == Z3_PARAMETER_DOUBLE:
836 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.ast, i)
837 elif k == Z3_PARAMETER_RATIONAL:
838 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.ast, i)
839 elif k == Z3_PARAMETER_SYMBOL:
840 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.ast, i)
841 elif k == Z3_PARAMETER_SORT:
842 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.ast, i), ctx)
843 elif k == Z3_PARAMETER_AST:
844 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.ast, i), ctx)
845 elif k == Z3_PARAMETER_FUNC_DECL:
846 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.ast, i), ctx)
847 elif k == Z3_PARAMETER_INTERNAL:
848 result[i] = "internal parameter"
849 elif k == Z3_PARAMETER_ZSTRING:
850 result[i] = "internal string"
851 else:
852 assert(False)
853 return result
854
855 def __call__(self, *args):
856 """Create a Z3 application expression using the function `self`, and the given arguments.
857
858 The arguments must be Z3 expressions. This method assumes that
859 the sorts of the elements in `args` match the sorts of the
860 domain. Limited coercion is supported. For example, if
861 args[0] is a Python integer, and the function expects a Z3
862 integer, then the argument is automatically converted into a
863 Z3 integer.
864
865 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
866 >>> x = Int('x')
867 >>> y = Real('y')
868 >>> f(x, y)
869 f(x, y)
870 >>> f(x, x)
871 f(x, ToReal(x))
872 """
873 args = _get_args(args)
874 num = len(args)
875 _args = (Ast * num)()
876 saved = []
877 for i in range(num):
878 # self.domain(i).cast(args[i]) may create a new Z3 expression,
879 # then we must save in 'saved' to prevent it from being garbage collected.
880 tmp = self.domain(i).cast(args[i])
881 saved.append(tmp)
882 _args[i] = tmp.as_ast()
883 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
884
885
887 """Return `True` if `a` is a Z3 function declaration.
888
889 >>> f = Function('f', IntSort(), IntSort())
890 >>> is_func_decl(f)
891 True
892 >>> x = Real('x')
893 >>> is_func_decl(x)
894 False
895 """
896 return isinstance(a, FuncDeclRef)
897
898
899def Function(name, *sig):
900 """Create a new Z3 uninterpreted function with the given sorts.
901
902 >>> f = Function('f', IntSort(), IntSort())
903 >>> f(f(0))
904 f(f(0))
905 """
906 sig = _get_args(sig)
907 if z3_debug():
908 _z3_assert(len(sig) > 0, "At least two arguments expected")
909 arity = len(sig) - 1
910 rng = sig[arity]
911 if z3_debug():
912 _z3_assert(is_sort(rng), "Z3 sort expected")
913 dom = (Sort * arity)()
914 for i in range(arity):
915 if z3_debug():
916 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
917 dom[i] = sig[i].ast
918 ctx = rng.ctx
919 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
920
921
923 """Create a new fresh Z3 uninterpreted function with the given sorts.
924 """
925 sig = _get_args(sig)
926 if z3_debug():
927 _z3_assert(len(sig) > 0, "At least two arguments expected")
928 arity = len(sig) - 1
929 rng = sig[arity]
930 if z3_debug():
931 _z3_assert(is_sort(rng), "Z3 sort expected")
932 dom = (z3.Sort * arity)()
933 for i in range(arity):
934 if z3_debug():
935 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
936 dom[i] = sig[i].ast
937 ctx = rng.ctx
938 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
939
940
942 return FuncDeclRef(a, ctx)
943
944
945def RecFunction(name, *sig):
946 """Create a new Z3 recursive with the given sorts."""
947 sig = _get_args(sig)
948 if z3_debug():
949 _z3_assert(len(sig) > 0, "At least two arguments expected")
950 arity = len(sig) - 1
951 rng = sig[arity]
952 if z3_debug():
953 _z3_assert(is_sort(rng), "Z3 sort expected")
954 dom = (Sort * arity)()
955 for i in range(arity):
956 if z3_debug():
957 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
958 dom[i] = sig[i].ast
959 ctx = rng.ctx
960 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
961
962
963def RecAddDefinition(f, args, body):
964 """Set the body of a recursive function.
965 Recursive definitions can be simplified if they are applied to ground
966 arguments.
967 >>> ctx = Context()
968 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
969 >>> n = Int('n', ctx)
970 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
971 >>> simplify(fac(5))
972 120
973 >>> s = Solver(ctx=ctx)
974 >>> s.add(fac(n) < 3)
975 >>> s.check()
976 sat
977 >>> s.model().eval(fac(5))
978 120
979 """
980 if is_app(args):
981 args = [args]
982 ctx = body.ctx
983 args = _get_args(args)
984 n = len(args)
985 _args = (Ast * n)()
986 for i in range(n):
987 _args[i] = args[i].ast
988 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
989
990
995
996
998 """Constraints, formulas and terms are expressions in Z3.
999
1000 Expressions are ASTs. Every expression has a sort.
1001 There are three main kinds of expressions:
1002 function applications, quantifiers and bounded variables.
1003 A constant is a function application with 0 arguments.
1004 For quantifier free problems, all expressions are
1005 function applications.
1006 """
1007
1008 def as_ast(self):
1009 return self.ast
1010
1011 def get_id(self):
1012 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1013
1014 def sort(self):
1015 """Return the sort of expression `self`.
1016
1017 >>> x = Int('x')
1018 >>> (x + 1).sort()
1019 Int
1020 >>> y = Real('y')
1021 >>> (x + y).sort()
1022 Real
1023 """
1024 return _sort(self.ctx, self.as_ast())
1025
1026 def sort_kind(self):
1027 """Shorthand for `self.sort().kind()`.
1028
1029 >>> a = Array('a', IntSort(), IntSort())
1030 >>> a.sort_kind() == Z3_ARRAY_SORT
1031 True
1032 >>> a.sort_kind() == Z3_INT_SORT
1033 False
1034 """
1035 return self.sort().kind()
1036
1037 def __eq__(self, other):
1038 """Return a Z3 expression that represents the constraint `self == other`.
1039
1040 If `other` is `None`, then this method simply returns `False`.
1041
1042 >>> a = Int('a')
1043 >>> b = Int('b')
1044 >>> a == b
1045 a == b
1046 >>> a is None
1047 False
1048 """
1049 if other is None:
1050 return False
1051 a, b = _coerce_exprs(self, other)
1052 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
1053
1054 def __hash__(self):
1055 """ Hash code. """
1056 return AstRef.__hash__(self)
1057
1058 def __ne__(self, other):
1059 """Return a Z3 expression that represents the constraint `self != other`.
1060
1061 If `other` is `None`, then this method simply returns `True`.
1062
1063 >>> a = Int('a')
1064 >>> b = Int('b')
1065 >>> a != b
1066 a != b
1067 >>> a is not None
1068 True
1069 """
1070 if other is None:
1071 return True
1072 a, b = _coerce_exprs(self, other)
1073 _args, sz = _to_ast_array((a, b))
1074 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
1075
1076 def params(self):
1077 return self.decl().params()
1078
1079 def decl(self):
1080 """Return the Z3 function declaration associated with a Z3 application.
1081
1082 >>> f = Function('f', IntSort(), IntSort())
1083 >>> a = Int('a')
1084 >>> t = f(a)
1085 >>> eq(t.decl(), f)
1086 True
1087 >>> (a + 1).decl()
1088 +
1089 """
1090 if z3_debug():
1091 _z3_assert(is_app(self), "Z3 application expected")
1092 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_ast()), self.ctx)
1093
1094 def kind(self):
1095 """Return the Z3 internal kind of a function application."""
1096 if z3_debug():
1097 _z3_assert(is_app(self), "Z3 application expected")
1099
1100
1101 def num_args(self):
1102 """Return the number of arguments of a Z3 application.
1103
1104 >>> a = Int('a')
1105 >>> b = Int('b')
1106 >>> (a + b).num_args()
1107 2
1108 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1109 >>> t = f(a, b, 0)
1110 >>> t.num_args()
1111 3
1112 """
1113 if z3_debug():
1114 _z3_assert(is_app(self), "Z3 application expected")
1115 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_ast()))
1116
1117 def arg(self, idx):
1118 """Return argument `idx` of the application `self`.
1119
1120 This method assumes that `self` is a function application with at least `idx+1` arguments.
1121
1122 >>> a = Int('a')
1123 >>> b = Int('b')
1124 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1125 >>> t = f(a, b, 0)
1126 >>> t.arg(0)
1127 a
1128 >>> t.arg(1)
1129 b
1130 >>> t.arg(2)
1131 0
1132 """
1133 if z3_debug():
1134 _z3_assert(is_app(self), "Z3 application expected")
1135 _z3_assert(idx < self.num_args(), "Invalid argument index")
1136 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_ast(), idx), self.ctx)
1137
1138 def children(self):
1139 """Return a list containing the children of the given expression
1140
1141 >>> a = Int('a')
1142 >>> b = Int('b')
1143 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1144 >>> t = f(a, b, 0)
1145 >>> t.children()
1146 [a, b, 0]
1147 """
1148 if is_app(self):
1149 return [self.arg(i) for i in range(self.num_args())]
1150 else:
1151 return []
1152
1153 def from_string(self, s):
1154 pass
1155
1156 def serialize(self):
1157 s = Solver()
1158 f = Function('F', self.sort(), BoolSort(self.ctx))
1159 s.add(f(self))
1160 return s.sexpr()
1161
1163 """inverse function to the serialize method on ExprRef.
1164 It is made available to make it easier for users to serialize expressions back and forth between
1165 strings. Solvers can be serialized using the 'sexpr()' method.
1166 """
1167 s = Solver()
1168 s.from_string(st)
1169 if len(s.assertions()) != 1:
1170 raise Z3Exception("single assertion expected")
1171 fml = s.assertions()[0]
1172 if fml.num_args() != 1:
1173 raise Z3Exception("dummy function 'F' expected")
1174 return fml.arg(0)
1175
1176def _to_expr_ref(a, ctx):
1177 if isinstance(a, Pattern):
1178 return PatternRef(a, ctx)
1179 ctx_ref = ctx.ref()
1180 k = Z3_get_ast_kind(ctx_ref, a)
1181 if k == Z3_QUANTIFIER_AST:
1182 return QuantifierRef(a, ctx)
1183 sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1184 if sk == Z3_BOOL_SORT:
1185 return BoolRef(a, ctx)
1186 if sk == Z3_INT_SORT:
1187 if k == Z3_NUMERAL_AST:
1188 return IntNumRef(a, ctx)
1189 return ArithRef(a, ctx)
1190 if sk == Z3_REAL_SORT:
1191 if k == Z3_NUMERAL_AST:
1192 return RatNumRef(a, ctx)
1193 if _is_algebraic(ctx, a):
1194 return AlgebraicNumRef(a, ctx)
1195 return ArithRef(a, ctx)
1196 if sk == Z3_BV_SORT:
1197 if k == Z3_NUMERAL_AST:
1198 return BitVecNumRef(a, ctx)
1199 else:
1200 return BitVecRef(a, ctx)
1201 if sk == Z3_ARRAY_SORT:
1202 return ArrayRef(a, ctx)
1203 if sk == Z3_DATATYPE_SORT:
1204 return DatatypeRef(a, ctx)
1205 if sk == Z3_FLOATING_POINT_SORT:
1206 if k == Z3_APP_AST and _is_numeral(ctx, a):
1207 return FPNumRef(a, ctx)
1208 else:
1209 return FPRef(a, ctx)
1210 if sk == Z3_FINITE_DOMAIN_SORT:
1211 if k == Z3_NUMERAL_AST:
1212 return FiniteDomainNumRef(a, ctx)
1213 else:
1214 return FiniteDomainRef(a, ctx)
1215 if sk == Z3_ROUNDING_MODE_SORT:
1216 return FPRMRef(a, ctx)
1217 if sk == Z3_SEQ_SORT:
1218 return SeqRef(a, ctx)
1219 if sk == Z3_CHAR_SORT:
1220 return CharRef(a, ctx)
1221 if sk == Z3_RE_SORT:
1222 return ReRef(a, ctx)
1223 return ExprRef(a, ctx)
1224
1225
1227 if is_expr(a):
1228 s1 = a.sort()
1229 if s is None:
1230 return s1
1231 if s1.eq(s):
1232 return s
1233 elif s.subsort(s1):
1234 return s1
1235 elif s1.subsort(s):
1236 return s
1237 else:
1238 if z3_debug():
1239 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1240 _z3_assert(False, "sort mismatch")
1241 else:
1242 return s
1243
1244
1245def _coerce_exprs(a, b, ctx=None):
1246 if not is_expr(a) and not is_expr(b):
1247 a = _py2expr(a, ctx)
1248 b = _py2expr(b, ctx)
1249 if isinstance(a, str) and isinstance(b, SeqRef):
1250 a = StringVal(a, b.ctx)
1251 if isinstance(b, str) and isinstance(a, SeqRef):
1252 b = StringVal(b, a.ctx)
1253 if isinstance(a, float) and isinstance(b, ArithRef):
1254 a = RealVal(a, b.ctx)
1255 if isinstance(b, float) and isinstance(a, ArithRef):
1256 b = RealVal(b, a.ctx)
1257
1258 s = None
1259 s = _coerce_expr_merge(s, a)
1260 s = _coerce_expr_merge(s, b)
1261 a = s.cast(a)
1262 b = s.cast(b)
1263 return (a, b)
1264
1265
1266def _reduce(func, sequence, initial):
1267 result = initial
1268 for element in sequence:
1269 result = func(result, element)
1270 return result
1271
1272
1273def _coerce_expr_list(alist, ctx=None):
1274 has_expr = False
1275 for a in alist:
1276 if is_expr(a):
1277 has_expr = True
1278 break
1279 if not has_expr:
1280 alist = [_py2expr(a, ctx) for a in alist]
1281 s = _reduce(_coerce_expr_merge, alist, None)
1282 return [s.cast(a) for a in alist]
1283
1284
1285def is_expr(a):
1286 """Return `True` if `a` is a Z3 expression.
1287
1288 >>> a = Int('a')
1289 >>> is_expr(a)
1290 True
1291 >>> is_expr(a + 1)
1292 True
1293 >>> is_expr(IntSort())
1294 False
1295 >>> is_expr(1)
1296 False
1297 >>> is_expr(IntVal(1))
1298 True
1299 >>> x = Int('x')
1300 >>> is_expr(ForAll(x, x >= 0))
1301 True
1302 >>> is_expr(FPVal(1.0))
1303 True
1304 """
1305 return isinstance(a, ExprRef)
1306
1307
1308def is_app(a):
1309 """Return `True` if `a` is a Z3 function application.
1310
1311 Note that, constants are function applications with 0 arguments.
1312
1313 >>> a = Int('a')
1314 >>> is_app(a)
1315 True
1316 >>> is_app(a + 1)
1317 True
1318 >>> is_app(IntSort())
1319 False
1320 >>> is_app(1)
1321 False
1322 >>> is_app(IntVal(1))
1323 True
1324 >>> x = Int('x')
1325 >>> is_app(ForAll(x, x >= 0))
1326 False
1327 """
1328 if not isinstance(a, ExprRef):
1329 return False
1330 k = _ast_kind(a.ctx, a)
1331 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1332
1333
1335 """Return `True` if `a` is Z3 constant/variable expression.
1336
1337 >>> a = Int('a')
1338 >>> is_const(a)
1339 True
1340 >>> is_const(a + 1)
1341 False
1342 >>> is_const(1)
1343 False
1344 >>> is_const(IntVal(1))
1345 True
1346 >>> x = Int('x')
1347 >>> is_const(ForAll(x, x >= 0))
1348 False
1349 """
1350 return is_app(a) and a.num_args() == 0
1351
1352
1353def is_var(a):
1354 """Return `True` if `a` is variable.
1355
1356 Z3 uses de-Bruijn indices for representing bound variables in
1357 quantifiers.
1358
1359 >>> x = Int('x')
1360 >>> is_var(x)
1361 False
1362 >>> is_const(x)
1363 True
1364 >>> f = Function('f', IntSort(), IntSort())
1365 >>> # Z3 replaces x with bound variables when ForAll is executed.
1366 >>> q = ForAll(x, f(x) == x)
1367 >>> b = q.body()
1368 >>> b
1369 f(Var(0)) == Var(0)
1370 >>> b.arg(1)
1371 Var(0)
1372 >>> is_var(b.arg(1))
1373 True
1374 """
1375 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1376
1377
1379 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1380
1381 >>> x = Int('x')
1382 >>> y = Int('y')
1383 >>> is_var(x)
1384 False
1385 >>> is_const(x)
1386 True
1387 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1388 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1389 >>> q = ForAll([x, y], f(x, y) == x + y)
1390 >>> q.body()
1391 f(Var(1), Var(0)) == Var(1) + Var(0)
1392 >>> b = q.body()
1393 >>> b.arg(0)
1394 f(Var(1), Var(0))
1395 >>> v1 = b.arg(0).arg(0)
1396 >>> v2 = b.arg(0).arg(1)
1397 >>> v1
1398 Var(1)
1399 >>> v2
1400 Var(0)
1401 >>> get_var_index(v1)
1402 1
1403 >>> get_var_index(v2)
1404 0
1405 """
1406 if z3_debug():
1407 _z3_assert(is_var(a), "Z3 bound variable expected")
1408 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1409
1410
1411def is_app_of(a, k):
1412 """Return `True` if `a` is an application of the given kind `k`.
1413
1414 >>> x = Int('x')
1415 >>> n = x + 1
1416 >>> is_app_of(n, Z3_OP_ADD)
1417 True
1418 >>> is_app_of(n, Z3_OP_MUL)
1419 False
1420 """
1421 return is_app(a) and a.kind() == k
1422
1423
1424def If(a, b, c, ctx=None):
1425 """Create a Z3 if-then-else expression.
1426
1427 >>> x = Int('x')
1428 >>> y = Int('y')
1429 >>> max = If(x > y, x, y)
1430 >>> max
1431 If(x > y, x, y)
1432 >>> simplify(max)
1433 If(x <= y, y, x)
1434 """
1435 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1436 return Cond(a, b, c, ctx)
1437 else:
1438 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1439 s = BoolSort(ctx)
1440 a = s.cast(a)
1441 b, c = _coerce_exprs(b, c, ctx)
1442 if z3_debug():
1443 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1444 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1445
1446
1447def Distinct(*args):
1448 """Create a Z3 distinct expression.
1449
1450 >>> x = Int('x')
1451 >>> y = Int('y')
1452 >>> Distinct(x, y)
1453 x != y
1454 >>> z = Int('z')
1455 >>> Distinct(x, y, z)
1456 Distinct(x, y, z)
1457 >>> simplify(Distinct(x, y, z))
1458 Distinct(x, y, z)
1459 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1460 And(Not(x == y), Not(x == z), Not(y == z))
1461 """
1462 args = _get_args(args)
1463 ctx = _ctx_from_ast_arg_list(args)
1464 if z3_debug():
1465 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1466 args = _coerce_expr_list(args, ctx)
1467 _args, sz = _to_ast_array(args)
1468 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1469
1470
1471def _mk_bin(f, a, b):
1472 args = (Ast * 2)()
1473 if z3_debug():
1474 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1475 args[0] = a.as_ast()
1476 args[1] = b.as_ast()
1477 return f(a.ctx.ref(), 2, args)
1478
1479
1480def Const(name, sort):
1481 """Create a constant of the given sort.
1482
1483 >>> Const('x', IntSort())
1484 x
1485 """
1486 if z3_debug():
1487 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1488 ctx = sort.ctx
1489 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1490
1491
1492def Consts(names, sort):
1493 """Create several constants of the given sort.
1494
1495 `names` is a string containing the names of all constants to be created.
1496 Blank spaces separate the names of different constants.
1497
1498 >>> x, y, z = Consts('x y z', IntSort())
1499 >>> x + y + z
1500 x + y + z
1501 """
1502 if isinstance(names, str):
1503 names = names.split(" ")
1504 return [Const(name, sort) for name in names]
1505
1506
1507def FreshConst(sort, prefix="c"):
1508 """Create a fresh constant of a specified sort"""
1509 ctx = _get_ctx(sort.ctx)
1510 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1511
1512
1513def Var(idx : int, s : SortRef) -> ExprRef:
1514 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1515 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1516 declarations.
1517
1518 >>> Var(0, IntSort())
1519 Var(0)
1520 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1521 False
1522 """
1523 if z3_debug():
1524 _z3_assert(is_sort(s), "Z3 sort expected")
1525 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1526
1527
1528def RealVar(idx: int, ctx=None) -> ExprRef:
1529 """
1530 Create a real free variable. Free variables are used to create quantified formulas.
1531 They are also used to create polynomials.
1532
1533 >>> RealVar(0)
1534 Var(0)
1535 """
1536 return Var(idx, RealSort(ctx))
1537
1538def RealVarVector(n: int, ctx= None):
1539 """
1540 Create a list of Real free variables.
1541 The variables have ids: 0, 1, ..., n-1
1542
1543 >>> x0, x1, x2, x3 = RealVarVector(4)
1544 >>> x2
1545 Var(2)
1546 """
1547 return [RealVar(i, ctx) for i in range(n)]
1548
1549
1554
1555
1557 """Boolean sort."""
1558
1559 def cast(self, val):
1560 """Try to cast `val` as a Boolean.
1561
1562 >>> x = BoolSort().cast(True)
1563 >>> x
1564 True
1565 >>> is_expr(x)
1566 True
1567 >>> is_expr(True)
1568 False
1569 >>> x.sort()
1570 Bool
1571 """
1572 if isinstance(val, bool):
1573 return BoolVal(val, self.ctx)
1574 if z3_debug():
1575 if not is_expr(val):
1576 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1577 _z3_assert(is_expr(val), msg % (val, type(val)))
1578 if not self.eq(val.sort()):
1579 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1580 return val
1581
1582 def subsort(self, other):
1583 return isinstance(other, ArithSortRef)
1584
1585 def is_int(self):
1586 return True
1587
1588 def is_bool(self):
1589 return True
1590
1591
1593 """All Boolean expressions are instances of this class."""
1594
1595 def sort(self):
1596 return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
1597
1598 def __add__(self, other):
1599 if isinstance(other, BoolRef):
1600 other = If(other, 1, 0)
1601 return If(self, 1, 0) + other
1602
1603 def __radd__(self, other):
1604 return self + other
1605
1606 def __rmul__(self, other):
1607 return self * other
1608
1609 def __mul__(self, other):
1610 """Create the Z3 expression `self * other`.
1611 """
1612 if isinstance(other, int) and other == 1:
1613 return If(self, 1, 0)
1614 if isinstance(other, int) and other == 0:
1615 return IntVal(0, self.ctx)
1616 if isinstance(other, BoolRef):
1617 other = If(other, 1, 0)
1618 return If(self, other, 0)
1619
1620 def __and__(self, other):
1621 return And(self, other)
1622
1623 def __or__(self, other):
1624 return Or(self, other)
1625
1626 def __xor__(self, other):
1627 return Xor(self, other)
1628
1629 def __invert__(self):
1630 return Not(self)
1631
1632 def py_value(self):
1633 if is_true(self):
1634 return True
1635 if is_false(self):
1636 return False
1637 return None
1638
1639
1640
1641
1642def is_bool(a : Any) -> bool:
1643 """Return `True` if `a` is a Z3 Boolean expression.
1644
1645 >>> p = Bool('p')
1646 >>> is_bool(p)
1647 True
1648 >>> q = Bool('q')
1649 >>> is_bool(And(p, q))
1650 True
1651 >>> x = Real('x')
1652 >>> is_bool(x)
1653 False
1654 >>> is_bool(x == 0)
1655 True
1656 """
1657 return isinstance(a, BoolRef)
1658
1659
1660def is_true(a : Any) -> bool:
1661 """Return `True` if `a` is the Z3 true expression.
1662
1663 >>> p = Bool('p')
1664 >>> is_true(p)
1665 False
1666 >>> is_true(simplify(p == p))
1667 True
1668 >>> x = Real('x')
1669 >>> is_true(x == 0)
1670 False
1671 >>> # True is a Python Boolean expression
1672 >>> is_true(True)
1673 False
1674 """
1675 return is_app_of(a, Z3_OP_TRUE)
1676
1677
1678def is_false(a : Any) -> bool:
1679 """Return `True` if `a` is the Z3 false expression.
1680
1681 >>> p = Bool('p')
1682 >>> is_false(p)
1683 False
1684 >>> is_false(False)
1685 False
1686 >>> is_false(BoolVal(False))
1687 True
1688 """
1689 return is_app_of(a, Z3_OP_FALSE)
1690
1691
1692def is_and(a : Any) -> bool:
1693 """Return `True` if `a` is a Z3 and expression.
1694
1695 >>> p, q = Bools('p q')
1696 >>> is_and(And(p, q))
1697 True
1698 >>> is_and(Or(p, q))
1699 False
1700 """
1701 return is_app_of(a, Z3_OP_AND)
1702
1703
1704def is_or(a : Any) -> bool:
1705 """Return `True` if `a` is a Z3 or expression.
1706
1707 >>> p, q = Bools('p q')
1708 >>> is_or(Or(p, q))
1709 True
1710 >>> is_or(And(p, q))
1711 False
1712 """
1713 return is_app_of(a, Z3_OP_OR)
1714
1715
1716def is_implies(a : Any) -> bool:
1717 """Return `True` if `a` is a Z3 implication expression.
1718
1719 >>> p, q = Bools('p q')
1720 >>> is_implies(Implies(p, q))
1721 True
1722 >>> is_implies(And(p, q))
1723 False
1724 """
1725 return is_app_of(a, Z3_OP_IMPLIES)
1726
1727
1728def is_not(a : Any) -> bool:
1729 """Return `True` if `a` is a Z3 not expression.
1730
1731 >>> p = Bool('p')
1732 >>> is_not(p)
1733 False
1734 >>> is_not(Not(p))
1735 True
1736 """
1737 return is_app_of(a, Z3_OP_NOT)
1738
1739
1740def is_eq(a : Any) -> bool:
1741 """Return `True` if `a` is a Z3 equality expression.
1742
1743 >>> x, y = Ints('x y')
1744 >>> is_eq(x == y)
1745 True
1746 """
1747 return is_app_of(a, Z3_OP_EQ)
1748
1749
1750def is_distinct(a : Any) -> bool:
1751 """Return `True` if `a` is a Z3 distinct expression.
1752
1753 >>> x, y, z = Ints('x y z')
1754 >>> is_distinct(x == y)
1755 False
1756 >>> is_distinct(Distinct(x, y, z))
1757 True
1758 """
1759 return is_app_of(a, Z3_OP_DISTINCT)
1760
1761
1762def BoolSort(ctx=None):
1763 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1764
1765 >>> BoolSort()
1766 Bool
1767 >>> p = Const('p', BoolSort())
1768 >>> is_bool(p)
1769 True
1770 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1771 >>> r(0, 1)
1772 r(0, 1)
1773 >>> is_bool(r(0, 1))
1774 True
1775 """
1776 ctx = _get_ctx(ctx)
1777 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1778
1779
1780def BoolVal(val, ctx=None):
1781 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1782
1783 >>> BoolVal(True)
1784 True
1785 >>> is_true(BoolVal(True))
1786 True
1787 >>> is_true(True)
1788 False
1789 >>> is_false(BoolVal(False))
1790 True
1791 """
1792 ctx = _get_ctx(ctx)
1793 if val:
1794 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1795 else:
1796 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1797
1798
1799def Bool(name, ctx=None):
1800 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1801
1802 >>> p = Bool('p')
1803 >>> q = Bool('q')
1804 >>> And(p, q)
1805 And(p, q)
1806 """
1807 ctx = _get_ctx(ctx)
1808 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1809
1810
1811def Bools(names, ctx=None):
1812 """Return a tuple of Boolean constants.
1813
1814 `names` is a single string containing all names separated by blank spaces.
1815 If `ctx=None`, then the global context is used.
1816
1817 >>> p, q, r = Bools('p q r')
1818 >>> And(p, Or(q, r))
1819 And(p, Or(q, r))
1820 """
1821 ctx = _get_ctx(ctx)
1822 if isinstance(names, str):
1823 names = names.split(" ")
1824 return [Bool(name, ctx) for name in names]
1825
1826
1827def BoolVector(prefix, sz, ctx=None):
1828 """Return a list of Boolean constants of size `sz`.
1829
1830 The constants are named using the given prefix.
1831 If `ctx=None`, then the global context is used.
1832
1833 >>> P = BoolVector('p', 3)
1834 >>> P
1835 [p__0, p__1, p__2]
1836 >>> And(P)
1837 And(p__0, p__1, p__2)
1838 """
1839 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1840
1841
1842def FreshBool(prefix="b", ctx=None):
1843 """Return a fresh Boolean constant in the given context using the given prefix.
1844
1845 If `ctx=None`, then the global context is used.
1846
1847 >>> b1 = FreshBool()
1848 >>> b2 = FreshBool()
1849 >>> eq(b1, b2)
1850 False
1851 """
1852 ctx = _get_ctx(ctx)
1853 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1854
1855
1856def Implies(a, b, ctx=None):
1857 """Create a Z3 implies expression.
1858
1859 >>> p, q = Bools('p q')
1860 >>> Implies(p, q)
1861 Implies(p, q)
1862 """
1863 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1864 s = BoolSort(ctx)
1865 a = s.cast(a)
1866 b = s.cast(b)
1867 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1868
1869
1870def Xor(a, b, ctx=None):
1871 """Create a Z3 Xor expression.
1872
1873 >>> p, q = Bools('p q')
1874 >>> Xor(p, q)
1875 Xor(p, q)
1876 >>> simplify(Xor(p, q))
1877 Not(p == q)
1878 """
1879 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1880 s = BoolSort(ctx)
1881 a = s.cast(a)
1882 b = s.cast(b)
1883 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1884
1885
1886def Not(a, ctx=None):
1887 """Create a Z3 not expression or probe.
1888
1889 >>> p = Bool('p')
1890 >>> Not(Not(p))
1891 Not(Not(p))
1892 >>> simplify(Not(Not(p)))
1893 p
1894 """
1895 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1896 if is_probe(a):
1897 # Not is also used to build probes
1898 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1899 else:
1900 s = BoolSort(ctx)
1901 a = s.cast(a)
1902 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1903
1904
1905def mk_not(a):
1906 if is_not(a):
1907 return a.arg(0)
1908 else:
1909 return Not(a)
1910
1911
1912def _has_probe(args):
1913 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1914 for arg in args:
1915 if is_probe(arg):
1916 return True
1917 return False
1918
1919
1920def And(*args):
1921 """Create a Z3 and-expression or and-probe.
1922
1923 >>> p, q, r = Bools('p q r')
1924 >>> And(p, q, r)
1925 And(p, q, r)
1926 >>> P = BoolVector('p', 5)
1927 >>> And(P)
1928 And(p__0, p__1, p__2, p__3, p__4)
1929 """
1930 last_arg = None
1931 if len(args) > 0:
1932 last_arg = args[len(args) - 1]
1933 if isinstance(last_arg, Context):
1934 ctx = args[len(args) - 1]
1935 args = args[:len(args) - 1]
1936 elif len(args) == 1 and isinstance(args[0], AstVector):
1937 ctx = args[0].ctx
1938 args = [a for a in args[0]]
1939 else:
1940 ctx = None
1941 args = _get_args(args)
1942 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1943 if z3_debug():
1944 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1945 if _has_probe(args):
1946 return _probe_and(args, ctx)
1947 else:
1948 args = _coerce_expr_list(args, ctx)
1949 _args, sz = _to_ast_array(args)
1950 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
1951
1952
1953def Or(*args):
1954 """Create a Z3 or-expression or or-probe.
1955
1956 >>> p, q, r = Bools('p q r')
1957 >>> Or(p, q, r)
1958 Or(p, q, r)
1959 >>> P = BoolVector('p', 5)
1960 >>> Or(P)
1961 Or(p__0, p__1, p__2, p__3, p__4)
1962 """
1963 last_arg = None
1964 if len(args) > 0:
1965 last_arg = args[len(args) - 1]
1966 if isinstance(last_arg, Context):
1967 ctx = args[len(args) - 1]
1968 args = args[:len(args) - 1]
1969 elif len(args) == 1 and isinstance(args[0], AstVector):
1970 ctx = args[0].ctx
1971 args = [a for a in args[0]]
1972 else:
1973 ctx = None
1974 args = _get_args(args)
1975 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1976 if z3_debug():
1977 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1978 if _has_probe(args):
1979 return _probe_or(args, ctx)
1980 else:
1981 args = _coerce_expr_list(args, ctx)
1982 _args, sz = _to_ast_array(args)
1983 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
1984
1985
1990
1991
1993 """Patterns are hints for quantifier instantiation.
1994
1995 """
1996
1997 def as_ast(self):
1998 return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
1999
2000 def get_id(self):
2001 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2002
2003
2005 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
2006
2007 >>> f = Function('f', IntSort(), IntSort())
2008 >>> x = Int('x')
2009 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
2010 >>> q
2011 ForAll(x, f(x) == 0)
2012 >>> q.num_patterns()
2013 1
2014 >>> is_pattern(q.pattern(0))
2015 True
2016 >>> q.pattern(0)
2017 f(Var(0))
2018 """
2019 return isinstance(a, PatternRef)
2020
2021
2022def MultiPattern(*args):
2023 """Create a Z3 multi-pattern using the given expressions `*args`
2024
2025 >>> f = Function('f', IntSort(), IntSort())
2026 >>> g = Function('g', IntSort(), IntSort())
2027 >>> x = Int('x')
2028 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2029 >>> q
2030 ForAll(x, f(x) != g(x))
2031 >>> q.num_patterns()
2032 1
2033 >>> is_pattern(q.pattern(0))
2034 True
2035 >>> q.pattern(0)
2036 MultiPattern(f(Var(0)), g(Var(0)))
2037 """
2038 if z3_debug():
2039 _z3_assert(len(args) > 0, "At least one argument expected")
2040 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2041 ctx = args[0].ctx
2042 args, sz = _to_ast_array(args)
2043 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2044
2045
2047 if is_pattern(arg):
2048 return arg
2049 else:
2050 return MultiPattern(arg)
2051
2052
2057
2058
2060 """Universally and Existentially quantified formulas."""
2061
2062 def as_ast(self):
2063 return self.ast
2064
2065 def get_id(self):
2066 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2067
2068 def sort(self):
2069 """Return the Boolean sort or sort of Lambda."""
2070 if self.is_lambda():
2071 return _sort(self.ctx, self.as_ast())
2072 return BoolSort(self.ctx)
2073
2074 def is_forall(self):
2075 """Return `True` if `self` is a universal quantifier.
2076
2077 >>> f = Function('f', IntSort(), IntSort())
2078 >>> x = Int('x')
2079 >>> q = ForAll(x, f(x) == 0)
2080 >>> q.is_forall()
2081 True
2082 >>> q = Exists(x, f(x) != 0)
2083 >>> q.is_forall()
2084 False
2085 """
2087
2088 def is_exists(self):
2089 """Return `True` if `self` is an existential quantifier.
2090
2091 >>> f = Function('f', IntSort(), IntSort())
2092 >>> x = Int('x')
2093 >>> q = ForAll(x, f(x) == 0)
2094 >>> q.is_exists()
2095 False
2096 >>> q = Exists(x, f(x) != 0)
2097 >>> q.is_exists()
2098 True
2099 """
2100 return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
2101
2102 def is_lambda(self):
2103 """Return `True` if `self` is a lambda expression.
2104
2105 >>> f = Function('f', IntSort(), IntSort())
2106 >>> x = Int('x')
2107 >>> q = Lambda(x, f(x))
2108 >>> q.is_lambda()
2109 True
2110 >>> q = Exists(x, f(x) != 0)
2111 >>> q.is_lambda()
2112 False
2113 """
2114 return Z3_is_lambda(self.ctx_ref(), self.ast)
2115
2116 def __getitem__(self, arg):
2117 """Return the Z3 expression `self[arg]`.
2118 """
2119 if z3_debug():
2120 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2121 return _array_select(self, arg)
2122
2123 def weight(self):
2124 """Return the weight annotation of `self`.
2125
2126 >>> f = Function('f', IntSort(), IntSort())
2127 >>> x = Int('x')
2128 >>> q = ForAll(x, f(x) == 0)
2129 >>> q.weight()
2130 1
2131 >>> q = ForAll(x, f(x) == 0, weight=10)
2132 >>> q.weight()
2133 10
2134 """
2135 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
2136
2137 def skolem_id(self):
2138 """Return the skolem id of `self`.
2139 """
2140 return _symbol2py(self.ctx, Z3_get_quantifier_skolem_id(self.ctx_ref(), self.ast))
2141
2142 def qid(self):
2143 """Return the quantifier id of `self`.
2144 """
2145 return _symbol2py(self.ctx, Z3_get_quantifier_id(self.ctx_ref(), self.ast))
2146
2147 def num_patterns(self):
2148 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2149
2150 >>> f = Function('f', IntSort(), IntSort())
2151 >>> g = Function('g', IntSort(), IntSort())
2152 >>> x = Int('x')
2153 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2154 >>> q.num_patterns()
2155 2
2156 """
2157 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
2158
2159 def pattern(self, idx):
2160 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2161
2162 >>> f = Function('f', IntSort(), IntSort())
2163 >>> g = Function('g', IntSort(), IntSort())
2164 >>> x = Int('x')
2165 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2166 >>> q.num_patterns()
2167 2
2168 >>> q.pattern(0)
2169 f(Var(0))
2170 >>> q.pattern(1)
2171 g(Var(0))
2172 """
2173 if z3_debug():
2174 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2175 return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2176
2178 """Return the number of no-patterns."""
2179 return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
2180
2181 def no_pattern(self, idx):
2182 """Return a no-pattern."""
2183 if z3_debug():
2184 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2185 return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2186
2187 def body(self):
2188 """Return the expression being quantified.
2189
2190 >>> f = Function('f', IntSort(), IntSort())
2191 >>> x = Int('x')
2192 >>> q = ForAll(x, f(x) == 0)
2193 >>> q.body()
2194 f(Var(0)) == 0
2195 """
2196 return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
2197
2198 def num_vars(self):
2199 """Return the number of variables bounded by this quantifier.
2200
2201 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2202 >>> x = Int('x')
2203 >>> y = Int('y')
2204 >>> q = ForAll([x, y], f(x, y) >= x)
2205 >>> q.num_vars()
2206 2
2207 """
2208 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
2209
2210 def var_name(self, idx):
2211 """Return a string representing a name used when displaying the quantifier.
2212
2213 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2214 >>> x = Int('x')
2215 >>> y = Int('y')
2216 >>> q = ForAll([x, y], f(x, y) >= x)
2217 >>> q.var_name(0)
2218 'x'
2219 >>> q.var_name(1)
2220 'y'
2221 """
2222 if z3_debug():
2223 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2224 return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
2225
2226 def var_sort(self, idx):
2227 """Return the sort of a bound variable.
2228
2229 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2230 >>> x = Int('x')
2231 >>> y = Real('y')
2232 >>> q = ForAll([x, y], f(x, y) >= x)
2233 >>> q.var_sort(0)
2234 Int
2235 >>> q.var_sort(1)
2236 Real
2237 """
2238 if z3_debug():
2239 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2240 return _to_sort_ref(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
2241
2242 def children(self):
2243 """Return a list containing a single element self.body()
2244
2245 >>> f = Function('f', IntSort(), IntSort())
2246 >>> x = Int('x')
2247 >>> q = ForAll(x, f(x) == 0)
2248 >>> q.children()
2249 [f(Var(0)) == 0]
2250 """
2251 return [self.body()]
2252
2253
2255 """Return `True` if `a` is a Z3 quantifier.
2256
2257 >>> f = Function('f', IntSort(), IntSort())
2258 >>> x = Int('x')
2259 >>> q = ForAll(x, f(x) == 0)
2260 >>> is_quantifier(q)
2261 True
2262 >>> is_quantifier(f(x))
2263 False
2264 """
2265 return isinstance(a, QuantifierRef)
2266
2267
2268def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2269 if z3_debug():
2270 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2271 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2272 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2273 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2274 if is_app(vs):
2275 ctx = vs.ctx
2276 vs = [vs]
2277 else:
2278 ctx = vs[0].ctx
2279 if not is_expr(body):
2280 body = BoolVal(body, ctx)
2281 num_vars = len(vs)
2282 if num_vars == 0:
2283 return body
2284 _vs = (Ast * num_vars)()
2285 for i in range(num_vars):
2286 # TODO: Check if is constant
2287 _vs[i] = vs[i].as_ast()
2288 patterns = [_to_pattern(p) for p in patterns]
2289 num_pats = len(patterns)
2290 _pats = (Pattern * num_pats)()
2291 for i in range(num_pats):
2292 _pats[i] = patterns[i].ast
2293 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2294 qid = to_symbol(qid, ctx)
2295 skid = to_symbol(skid, ctx)
2296 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2297 num_vars, _vs,
2298 num_pats, _pats,
2299 num_no_pats, _no_pats,
2300 body.as_ast()), ctx)
2301
2302
2303def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2304 """Create a Z3 forall formula.
2305
2306 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2307
2308 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2309 >>> x = Int('x')
2310 >>> y = Int('y')
2311 >>> ForAll([x, y], f(x, y) >= x)
2312 ForAll([x, y], f(x, y) >= x)
2313 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2314 ForAll([x, y], f(x, y) >= x)
2315 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2316 ForAll([x, y], f(x, y) >= x)
2317 """
2318 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2319
2320
2321def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2322 """Create a Z3 exists formula.
2323
2324 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2325
2326
2327 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2328 >>> x = Int('x')
2329 >>> y = Int('y')
2330 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2331 >>> q
2332 Exists([x, y], f(x, y) >= x)
2333 >>> is_quantifier(q)
2334 True
2335 >>> r = Tactic('nnf')(q).as_expr()
2336 >>> is_quantifier(r)
2337 False
2338 """
2339 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2340
2341
2342def Lambda(vs, body):
2343 """Create a Z3 lambda expression.
2344
2345 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2346 >>> mem0 = Array('mem0', IntSort(), IntSort())
2347 >>> lo, hi, e, i = Ints('lo hi e i')
2348 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2349 >>> mem1
2350 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2351 """
2352 ctx = body.ctx
2353 if is_app(vs):
2354 vs = [vs]
2355 num_vars = len(vs)
2356 _vs = (Ast * num_vars)()
2357 for i in range(num_vars):
2358 # TODO: Check if is constant
2359 _vs[i] = vs[i].as_ast()
2360 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2361
2362
2367
2368
2370 """Real and Integer sorts."""
2371
2372 def is_real(self):
2373 """Return `True` if `self` is of the sort Real.
2374
2375 >>> x = Real('x')
2376 >>> x.is_real()
2377 True
2378 >>> (x + 1).is_real()
2379 True
2380 >>> x = Int('x')
2381 >>> x.is_real()
2382 False
2383 """
2384 return self.kind() == Z3_REAL_SORT
2385
2386 def is_int(self):
2387 """Return `True` if `self` is of the sort Integer.
2388
2389 >>> x = Int('x')
2390 >>> x.is_int()
2391 True
2392 >>> (x + 1).is_int()
2393 True
2394 >>> x = Real('x')
2395 >>> x.is_int()
2396 False
2397 """
2398 return self.kind() == Z3_INT_SORT
2399
2400 def is_bool(self):
2401 return False
2402
2403 def subsort(self, other):
2404 """Return `True` if `self` is a subsort of `other`."""
2405 return self.is_int() and is_arith_sort(other) and other.is_real()
2406
2407 def cast(self, val):
2408 """Try to cast `val` as an Integer or Real.
2409
2410 >>> IntSort().cast(10)
2411 10
2412 >>> is_int(IntSort().cast(10))
2413 True
2414 >>> is_int(10)
2415 False
2416 >>> RealSort().cast(10)
2417 10
2418 >>> is_real(RealSort().cast(10))
2419 True
2420 """
2421 if is_expr(val):
2422 if z3_debug():
2423 _z3_assert(self.ctx == val.ctx, "Context mismatch")
2424 val_s = val.sort()
2425 if self.eq(val_s):
2426 return val
2427 if val_s.is_int() and self.is_real():
2428 return ToReal(val)
2429 if val_s.is_bool() and self.is_int():
2430 return If(val, 1, 0)
2431 if val_s.is_bool() and self.is_real():
2432 return ToReal(If(val, 1, 0))
2433 if z3_debug():
2434 _z3_assert(False, "Z3 Integer/Real expression expected")
2435 else:
2436 if self.is_int():
2437 return IntVal(val, self.ctx)
2438 if self.is_real():
2439 return RealVal(val, self.ctx)
2440 if z3_debug():
2441 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2442 _z3_assert(False, msg % self)
2443
2444
2445def is_arith_sort(s : Any) -> bool:
2446 """Return `True` if s is an arithmetical sort (type).
2447
2448 >>> is_arith_sort(IntSort())
2449 True
2450 >>> is_arith_sort(RealSort())
2451 True
2452 >>> is_arith_sort(BoolSort())
2453 False
2454 >>> n = Int('x') + 1
2455 >>> is_arith_sort(n.sort())
2456 True
2457 """
2458 return isinstance(s, ArithSortRef)
2459
2460
2462 """Integer and Real expressions."""
2463
2464 def sort(self):
2465 """Return the sort (type) of the arithmetical expression `self`.
2466
2467 >>> Int('x').sort()
2468 Int
2469 >>> (Real('x') + 1).sort()
2470 Real
2471 """
2472 return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
2473
2474 def is_int(self):
2475 """Return `True` if `self` is an integer expression.
2476
2477 >>> x = Int('x')
2478 >>> x.is_int()
2479 True
2480 >>> (x + 1).is_int()
2481 True
2482 >>> y = Real('y')
2483 >>> (x + y).is_int()
2484 False
2485 """
2486 return self.sort().is_int()
2487
2488 def is_real(self):
2489 """Return `True` if `self` is an real expression.
2490
2491 >>> x = Real('x')
2492 >>> x.is_real()
2493 True
2494 >>> (x + 1).is_real()
2495 True
2496 """
2497 return self.sort().is_real()
2498
2499 def __add__(self, other):
2500 """Create the Z3 expression `self + other`.
2501
2502 >>> x = Int('x')
2503 >>> y = Int('y')
2504 >>> x + y
2505 x + y
2506 >>> (x + y).sort()
2507 Int
2508 """
2509 a, b = _coerce_exprs(self, other)
2510 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctx)
2511
2512 def __radd__(self, other):
2513 """Create the Z3 expression `other + self`.
2514
2515 >>> x = Int('x')
2516 >>> 10 + x
2517 10 + x
2518 """
2519 a, b = _coerce_exprs(self, other)
2520 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctx)
2521
2522 def __mul__(self, other):
2523 """Create the Z3 expression `self * other`.
2524
2525 >>> x = Real('x')
2526 >>> y = Real('y')
2527 >>> x * y
2528 x*y
2529 >>> (x * y).sort()
2530 Real
2531 """
2532 if isinstance(other, BoolRef):
2533 return If(other, self, 0)
2534 a, b = _coerce_exprs(self, other)
2535 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
2536
2537 def __rmul__(self, other):
2538 """Create the Z3 expression `other * self`.
2539
2540 >>> x = Real('x')
2541 >>> 10 * x
2542 10*x
2543 """
2544 a, b = _coerce_exprs(self, other)
2545 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctx)
2546
2547 def __sub__(self, other):
2548 """Create the Z3 expression `self - other`.
2549
2550 >>> x = Int('x')
2551 >>> y = Int('y')
2552 >>> x - y
2553 x - y
2554 >>> (x - y).sort()
2555 Int
2556 """
2557 a, b = _coerce_exprs(self, other)
2558 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctx)
2559
2560 def __rsub__(self, other):
2561 """Create the Z3 expression `other - self`.
2562
2563 >>> x = Int('x')
2564 >>> 10 - x
2565 10 - x
2566 """
2567 a, b = _coerce_exprs(self, other)
2568 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctx)
2569
2570 def __pow__(self, other):
2571 """Create the Z3 expression `self**other` (** is the power operator).
2572
2573 >>> x = Real('x')
2574 >>> x**3
2575 x**3
2576 >>> (x**3).sort()
2577 Real
2578 >>> simplify(IntVal(2)**8)
2579 256
2580 """
2581 a, b = _coerce_exprs(self, other)
2582 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2583
2584 def __rpow__(self, other):
2585 """Create the Z3 expression `other**self` (** is the power operator).
2586
2587 >>> x = Real('x')
2588 >>> 2**x
2589 2**x
2590 >>> (2**x).sort()
2591 Real
2592 >>> simplify(2**IntVal(8))
2593 256
2594 """
2595 a, b = _coerce_exprs(self, other)
2596 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2597
2598 def __div__(self, other):
2599 """Create the Z3 expression `other/self`.
2600
2601 >>> x = Int('x')
2602 >>> y = Int('y')
2603 >>> x/y
2604 x/y
2605 >>> (x/y).sort()
2606 Int
2607 >>> (x/y).sexpr()
2608 '(div x y)'
2609 >>> x = Real('x')
2610 >>> y = Real('y')
2611 >>> x/y
2612 x/y
2613 >>> (x/y).sort()
2614 Real
2615 >>> (x/y).sexpr()
2616 '(/ x y)'
2617 """
2618 a, b = _coerce_exprs(self, other)
2619 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2620
2621 def __truediv__(self, other):
2622 """Create the Z3 expression `other/self`."""
2623 return self.__div__(other)
2624
2625 def __rdiv__(self, other):
2626 """Create the Z3 expression `other/self`.
2627
2628 >>> x = Int('x')
2629 >>> 10/x
2630 10/x
2631 >>> (10/x).sexpr()
2632 '(div 10 x)'
2633 >>> x = Real('x')
2634 >>> 10/x
2635 10/x
2636 >>> (10/x).sexpr()
2637 '(/ 10.0 x)'
2638 """
2639 a, b = _coerce_exprs(self, other)
2640 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2641
2642 def __rtruediv__(self, other):
2643 """Create the Z3 expression `other/self`."""
2644 return self.__rdiv__(other)
2645
2646 def __mod__(self, other):
2647 """Create the Z3 expression `other%self`.
2648
2649 >>> x = Int('x')
2650 >>> y = Int('y')
2651 >>> x % y
2652 x%y
2653 >>> simplify(IntVal(10) % IntVal(3))
2654 1
2655 """
2656 a, b = _coerce_exprs(self, other)
2657 if z3_debug():
2658 _z3_assert(a.is_int(), "Z3 integer expression expected")
2659 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2660
2661 def __rmod__(self, other):
2662 """Create the Z3 expression `other%self`.
2663
2664 >>> x = Int('x')
2665 >>> 10 % x
2666 10%x
2667 """
2668 a, b = _coerce_exprs(self, other)
2669 if z3_debug():
2670 _z3_assert(a.is_int(), "Z3 integer expression expected")
2671 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2672
2673 def __neg__(self):
2674 """Return an expression representing `-self`.
2675
2676 >>> x = Int('x')
2677 >>> -x
2678 -x
2679 >>> simplify(-(-x))
2680 x
2681 """
2682 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
2683
2684 def __pos__(self):
2685 """Return `self`.
2686
2687 >>> x = Int('x')
2688 >>> +x
2689 x
2690 """
2691 return self
2692
2693 def __le__(self, other):
2694 """Create the Z3 expression `other <= self`.
2695
2696 >>> x, y = Ints('x y')
2697 >>> x <= y
2698 x <= y
2699 >>> y = Real('y')
2700 >>> x <= y
2701 ToReal(x) <= y
2702 """
2703 a, b = _coerce_exprs(self, other)
2704 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2705
2706 def __lt__(self, other):
2707 """Create the Z3 expression `other < self`.
2708
2709 >>> x, y = Ints('x y')
2710 >>> x < y
2711 x < y
2712 >>> y = Real('y')
2713 >>> x < y
2714 ToReal(x) < y
2715 """
2716 a, b = _coerce_exprs(self, other)
2717 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2718
2719 def __gt__(self, other):
2720 """Create the Z3 expression `other > self`.
2721
2722 >>> x, y = Ints('x y')
2723 >>> x > y
2724 x > y
2725 >>> y = Real('y')
2726 >>> x > y
2727 ToReal(x) > y
2728 """
2729 a, b = _coerce_exprs(self, other)
2730 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2731
2732 def __ge__(self, other):
2733 """Create the Z3 expression `other >= self`.
2734
2735 >>> x, y = Ints('x y')
2736 >>> x >= y
2737 x >= y
2738 >>> y = Real('y')
2739 >>> x >= y
2740 ToReal(x) >= y
2741 """
2742 a, b = _coerce_exprs(self, other)
2743 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2744
2745
2747 """Return `True` if `a` is an arithmetical expression.
2748
2749 >>> x = Int('x')
2750 >>> is_arith(x)
2751 True
2752 >>> is_arith(x + 1)
2753 True
2754 >>> is_arith(1)
2755 False
2756 >>> is_arith(IntVal(1))
2757 True
2758 >>> y = Real('y')
2759 >>> is_arith(y)
2760 True
2761 >>> is_arith(y + 1)
2762 True
2763 """
2764 return isinstance(a, ArithRef)
2765
2766
2767def is_int(a) -> bool:
2768 """Return `True` if `a` is an integer expression.
2769
2770 >>> x = Int('x')
2771 >>> is_int(x + 1)
2772 True
2773 >>> is_int(1)
2774 False
2775 >>> is_int(IntVal(1))
2776 True
2777 >>> y = Real('y')
2778 >>> is_int(y)
2779 False
2780 >>> is_int(y + 1)
2781 False
2782 """
2783 return is_arith(a) and a.is_int()
2784
2785
2786def is_real(a):
2787 """Return `True` if `a` is a real expression.
2788
2789 >>> x = Int('x')
2790 >>> is_real(x + 1)
2791 False
2792 >>> y = Real('y')
2793 >>> is_real(y)
2794 True
2795 >>> is_real(y + 1)
2796 True
2797 >>> is_real(1)
2798 False
2799 >>> is_real(RealVal(1))
2800 True
2801 """
2802 return is_arith(a) and a.is_real()
2803
2804
2805def _is_numeral(ctx, a):
2806 return Z3_is_numeral_ast(ctx.ref(), a)
2807
2808
2809def _is_algebraic(ctx, a):
2810 return Z3_is_algebraic_number(ctx.ref(), a)
2811
2812
2814 """Return `True` if `a` is an integer value of sort Int.
2815
2816 >>> is_int_value(IntVal(1))
2817 True
2818 >>> is_int_value(1)
2819 False
2820 >>> is_int_value(Int('x'))
2821 False
2822 >>> n = Int('x') + 1
2823 >>> n
2824 x + 1
2825 >>> n.arg(1)
2826 1
2827 >>> is_int_value(n.arg(1))
2828 True
2829 >>> is_int_value(RealVal("1/3"))
2830 False
2831 >>> is_int_value(RealVal(1))
2832 False
2833 """
2834 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2835
2836
2838 """Return `True` if `a` is rational value of sort Real.
2839
2840 >>> is_rational_value(RealVal(1))
2841 True
2842 >>> is_rational_value(RealVal("3/5"))
2843 True
2844 >>> is_rational_value(IntVal(1))
2845 False
2846 >>> is_rational_value(1)
2847 False
2848 >>> n = Real('x') + 1
2849 >>> n.arg(1)
2850 1
2851 >>> is_rational_value(n.arg(1))
2852 True
2853 >>> is_rational_value(Real('x'))
2854 False
2855 """
2856 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2857
2858
2860 """Return `True` if `a` is an algebraic value of sort Real.
2861
2862 >>> is_algebraic_value(RealVal("3/5"))
2863 False
2864 >>> n = simplify(Sqrt(2))
2865 >>> n
2866 1.4142135623?
2867 >>> is_algebraic_value(n)
2868 True
2869 """
2870 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2871
2872
2873def is_add(a : Any) -> bool:
2874 """Return `True` if `a` is an expression of the form b + c.
2875
2876 >>> x, y = Ints('x y')
2877 >>> is_add(x + y)
2878 True
2879 >>> is_add(x - y)
2880 False
2881 """
2882 return is_app_of(a, Z3_OP_ADD)
2883
2884
2885def is_mul(a : Any) -> bool:
2886 """Return `True` if `a` is an expression of the form b * c.
2887
2888 >>> x, y = Ints('x y')
2889 >>> is_mul(x * y)
2890 True
2891 >>> is_mul(x - y)
2892 False
2893 """
2894 return is_app_of(a, Z3_OP_MUL)
2895
2896
2897def is_sub(a : Any) -> bool:
2898 """Return `True` if `a` is an expression of the form b - c.
2899
2900 >>> x, y = Ints('x y')
2901 >>> is_sub(x - y)
2902 True
2903 >>> is_sub(x + y)
2904 False
2905 """
2906 return is_app_of(a, Z3_OP_SUB)
2907
2908
2909def is_div(a : Any) -> bool:
2910 """Return `True` if `a` is an expression of the form b / c.
2911
2912 >>> x, y = Reals('x y')
2913 >>> is_div(x / y)
2914 True
2915 >>> is_div(x + y)
2916 False
2917 >>> x, y = Ints('x y')
2918 >>> is_div(x / y)
2919 False
2920 >>> is_idiv(x / y)
2921 True
2922 """
2923 return is_app_of(a, Z3_OP_DIV)
2924
2925
2926def is_idiv(a : Any) -> bool:
2927 """Return `True` if `a` is an expression of the form b div c.
2928
2929 >>> x, y = Ints('x y')
2930 >>> is_idiv(x / y)
2931 True
2932 >>> is_idiv(x + y)
2933 False
2934 """
2935 return is_app_of(a, Z3_OP_IDIV)
2936
2937
2938def is_mod(a : Any) -> bool:
2939 """Return `True` if `a` is an expression of the form b % c.
2940
2941 >>> x, y = Ints('x y')
2942 >>> is_mod(x % y)
2943 True
2944 >>> is_mod(x + y)
2945 False
2946 """
2947 return is_app_of(a, Z3_OP_MOD)
2948
2949
2950def is_le(a : Any) -> bool:
2951 """Return `True` if `a` is an expression of the form b <= c.
2952
2953 >>> x, y = Ints('x y')
2954 >>> is_le(x <= y)
2955 True
2956 >>> is_le(x < y)
2957 False
2958 """
2959 return is_app_of(a, Z3_OP_LE)
2960
2961
2962def is_lt(a : Any) -> bool:
2963 """Return `True` if `a` is an expression of the form b < c.
2964
2965 >>> x, y = Ints('x y')
2966 >>> is_lt(x < y)
2967 True
2968 >>> is_lt(x == y)
2969 False
2970 """
2971 return is_app_of(a, Z3_OP_LT)
2972
2973
2974def is_ge(a : Any) -> bool:
2975 """Return `True` if `a` is an expression of the form b >= c.
2976
2977 >>> x, y = Ints('x y')
2978 >>> is_ge(x >= y)
2979 True
2980 >>> is_ge(x == y)
2981 False
2982 """
2983 return is_app_of(a, Z3_OP_GE)
2984
2985
2986def is_gt(a : Any) -> bool:
2987 """Return `True` if `a` is an expression of the form b > c.
2988
2989 >>> x, y = Ints('x y')
2990 >>> is_gt(x > y)
2991 True
2992 >>> is_gt(x == y)
2993 False
2994 """
2995 return is_app_of(a, Z3_OP_GT)
2996
2997
2998def is_is_int(a : Any) -> bool:
2999 """Return `True` if `a` is an expression of the form IsInt(b).
3000
3001 >>> x = Real('x')
3002 >>> is_is_int(IsInt(x))
3003 True
3004 >>> is_is_int(x)
3005 False
3006 """
3007 return is_app_of(a, Z3_OP_IS_INT)
3008
3009
3010def is_to_real(a : Any) -> bool:
3011 """Return `True` if `a` is an expression of the form ToReal(b).
3012
3013 >>> x = Int('x')
3014 >>> n = ToReal(x)
3015 >>> n
3016 ToReal(x)
3017 >>> is_to_real(n)
3018 True
3019 >>> is_to_real(x)
3020 False
3021 """
3022 return is_app_of(a, Z3_OP_TO_REAL)
3023
3024
3025def is_to_int(a : Any) -> bool:
3026 """Return `True` if `a` is an expression of the form ToInt(b).
3027
3028 >>> x = Real('x')
3029 >>> n = ToInt(x)
3030 >>> n
3031 ToInt(x)
3032 >>> is_to_int(n)
3033 True
3034 >>> is_to_int(x)
3035 False
3036 """
3037 return is_app_of(a, Z3_OP_TO_INT)
3038
3039
3041 """Integer values."""
3042
3043 def as_long(self):
3044 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3045
3046 >>> v = IntVal(1)
3047 >>> v + 1
3048 1 + 1
3049 >>> v.as_long() + 1
3050 2
3051 """
3052 if z3_debug():
3053 _z3_assert(self.is_int(), "Integer value expected")
3054 return int(self.as_string())
3055
3056 def as_string(self):
3057 """Return a Z3 integer numeral as a Python string.
3058 >>> v = IntVal(100)
3059 >>> v.as_string()
3060 '100'
3061 """
3062 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3063
3065 """Return a Z3 integer numeral as a Python binary string.
3066 >>> v = IntVal(10)
3067 >>> v.as_binary_string()
3068 '1010'
3069 """
3070 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3071
3072 def py_value(self):
3073 return self.as_long()
3074
3075
3077 """Rational values."""
3078
3079 def numerator(self):
3080 """ Return the numerator of a Z3 rational numeral.
3081
3082 >>> is_rational_value(RealVal("3/5"))
3083 True
3084 >>> n = RealVal("3/5")
3085 >>> n.numerator()
3086 3
3087 >>> is_rational_value(Q(3,5))
3088 True
3089 >>> Q(3,5).numerator()
3090 3
3091 """
3092 return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
3093
3094 def denominator(self):
3095 """ Return the denominator of a Z3 rational numeral.
3096
3097 >>> is_rational_value(Q(3,5))
3098 True
3099 >>> n = Q(3,5)
3100 >>> n.denominator()
3101 5
3102 """
3103 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
3104
3106 """ Return the numerator as a Python long.
3107
3108 >>> v = RealVal(10000000000)
3109 >>> v
3110 10000000000
3111 >>> v + 1
3112 10000000000 + 1
3113 >>> v.numerator_as_long() + 1 == 10000000001
3114 True
3115 """
3116 return self.numerator().as_long()
3117
3119 """ Return the denominator as a Python long.
3120
3121 >>> v = RealVal("1/3")
3122 >>> v
3123 1/3
3124 >>> v.denominator_as_long()
3125 3
3126 """
3127 return self.denominator().as_long()
3128
3129 def is_int(self):
3130 return False
3131
3132 def is_real(self):
3133 return True
3134
3135 def is_int_value(self):
3136 return self.denominator().is_int() and self.denominator_as_long() == 1
3137
3138 def as_long(self):
3139 _z3_assert(self.is_int_value(), "Expected integer fraction")
3140 return self.numerator_as_long()
3141
3142 def as_decimal(self, prec):
3143 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3144
3145 >>> v = RealVal("1/5")
3146 >>> v.as_decimal(3)
3147 '0.2'
3148 >>> v = RealVal("1/3")
3149 >>> v.as_decimal(3)
3150 '0.333?'
3151 """
3152 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3153
3154 def as_string(self):
3155 """Return a Z3 rational numeral as a Python string.
3156
3157 >>> v = Q(3,6)
3158 >>> v.as_string()
3159 '1/2'
3160 """
3161 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3162
3163 def as_fraction(self):
3164 """Return a Z3 rational as a Python Fraction object.
3165
3166 >>> v = RealVal("1/5")
3167 >>> v.as_fraction()
3168 Fraction(1, 5)
3169 """
3170 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3171
3172 def py_value(self):
3173 return Z3_get_numeral_double(self.ctx_ref(), self.as_ast())
3174
3175
3177 """Algebraic irrational values."""
3178
3179 def approx(self, precision=10):
3180 """Return a Z3 rational number that approximates the algebraic number `self`.
3181 The result `r` is such that |r - self| <= 1/10^precision
3182
3183 >>> x = simplify(Sqrt(2))
3184 >>> x.approx(20)
3185 6838717160008073720548335/4835703278458516698824704
3186 >>> x.approx(5)
3187 2965821/2097152
3188 """
3189 return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
3190
3191 def as_decimal(self, prec):
3192 """Return a string representation of the algebraic number `self` in decimal notation
3193 using `prec` decimal places.
3194
3195 >>> x = simplify(Sqrt(2))
3196 >>> x.as_decimal(10)
3197 '1.4142135623?'
3198 >>> x.as_decimal(20)
3199 '1.41421356237309504880?'
3200 """
3201 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3202
3203 def poly(self):
3204 return AstVector(Z3_algebraic_get_poly(self.ctx_ref(), self.as_ast()), self.ctx)
3205
3206 def index(self):
3207 return Z3_algebraic_get_i(self.ctx_ref(), self.as_ast())
3208
3209
3210def _py2expr(a, ctx=None):
3211 if isinstance(a, bool):
3212 return BoolVal(a, ctx)
3213 if _is_int(a):
3214 return IntVal(a, ctx)
3215 if isinstance(a, float):
3216 return RealVal(a, ctx)
3217 if isinstance(a, str):
3218 return StringVal(a, ctx)
3219 if is_expr(a):
3220 return a
3221 if z3_debug():
3222 _z3_assert(False, "Python bool, int, long or float expected")
3223
3224
3225def IntSort(ctx=None):
3226 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3227
3228 >>> IntSort()
3229 Int
3230 >>> x = Const('x', IntSort())
3231 >>> is_int(x)
3232 True
3233 >>> x.sort() == IntSort()
3234 True
3235 >>> x.sort() == BoolSort()
3236 False
3237 """
3238 ctx = _get_ctx(ctx)
3239 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3240
3241
3242def RealSort(ctx=None):
3243 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3244
3245 >>> RealSort()
3246 Real
3247 >>> x = Const('x', RealSort())
3248 >>> is_real(x)
3249 True
3250 >>> is_int(x)
3251 False
3252 >>> x.sort() == RealSort()
3253 True
3254 """
3255 ctx = _get_ctx(ctx)
3256 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3257
3258
3260 if isinstance(val, float):
3261 return str(int(val))
3262 elif isinstance(val, bool):
3263 if val:
3264 return "1"
3265 else:
3266 return "0"
3267 else:
3268 return str(val)
3269
3270
3271def IntVal(val, ctx=None):
3272 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3273
3274 >>> IntVal(1)
3275 1
3276 >>> IntVal("100")
3277 100
3278 """
3279 ctx = _get_ctx(ctx)
3280 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3281
3282
3283def RealVal(val, ctx=None):
3284 """Return a Z3 real value.
3285
3286 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3287 If `ctx=None`, then the global context is used.
3288
3289 >>> RealVal(1)
3290 1
3291 >>> RealVal(1).sort()
3292 Real
3293 >>> RealVal("3/5")
3294 3/5
3295 >>> RealVal("1.5")
3296 3/2
3297 """
3298 ctx = _get_ctx(ctx)
3299 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3300
3301
3302def RatVal(a, b, ctx=None):
3303 """Return a Z3 rational a/b.
3304
3305 If `ctx=None`, then the global context is used.
3306
3307 >>> RatVal(3,5)
3308 3/5
3309 >>> RatVal(3,5).sort()
3310 Real
3311 """
3312 if z3_debug():
3313 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3314 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3315 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3316
3317
3318def Q(a, b, ctx=None):
3319 """Return a Z3 rational a/b.
3320
3321 If `ctx=None`, then the global context is used.
3322
3323 >>> Q(3,5)
3324 3/5
3325 >>> Q(3,5).sort()
3326 Real
3327 """
3328 return simplify(RatVal(a, b, ctx=ctx))
3329
3330
3331def Int(name, ctx=None):
3332 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3333
3334 >>> x = Int('x')
3335 >>> is_int(x)
3336 True
3337 >>> is_int(x + 1)
3338 True
3339 """
3340 ctx = _get_ctx(ctx)
3341 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3342
3343
3344def Ints(names, ctx=None):
3345 """Return a tuple of Integer constants.
3346
3347 >>> x, y, z = Ints('x y z')
3348 >>> Sum(x, y, z)
3349 x + y + z
3350 """
3351 ctx = _get_ctx(ctx)
3352 if isinstance(names, str):
3353 names = names.split(" ")
3354 return [Int(name, ctx) for name in names]
3355
3356
3357def IntVector(prefix, sz, ctx=None):
3358 """Return a list of integer constants of size `sz`.
3359
3360 >>> X = IntVector('x', 3)
3361 >>> X
3362 [x__0, x__1, x__2]
3363 >>> Sum(X)
3364 x__0 + x__1 + x__2
3365 """
3366 ctx = _get_ctx(ctx)
3367 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3368
3369
3370def FreshInt(prefix="x", ctx=None):
3371 """Return a fresh integer constant in the given context using the given prefix.
3372
3373 >>> x = FreshInt()
3374 >>> y = FreshInt()
3375 >>> eq(x, y)
3376 False
3377 >>> x.sort()
3378 Int
3379 """
3380 ctx = _get_ctx(ctx)
3381 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3382
3383
3384def Real(name, ctx=None):
3385 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3386
3387 >>> x = Real('x')
3388 >>> is_real(x)
3389 True
3390 >>> is_real(x + 1)
3391 True
3392 """
3393 ctx = _get_ctx(ctx)
3394 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3395
3396
3397def Reals(names, ctx=None):
3398 """Return a tuple of real constants.
3399
3400 >>> x, y, z = Reals('x y z')
3401 >>> Sum(x, y, z)
3402 x + y + z
3403 >>> Sum(x, y, z).sort()
3404 Real
3405 """
3406 ctx = _get_ctx(ctx)
3407 if isinstance(names, str):
3408 names = names.split(" ")
3409 return [Real(name, ctx) for name in names]
3410
3411
3412def RealVector(prefix, sz, ctx=None):
3413 """Return a list of real constants of size `sz`.
3414
3415 >>> X = RealVector('x', 3)
3416 >>> X
3417 [x__0, x__1, x__2]
3418 >>> Sum(X)
3419 x__0 + x__1 + x__2
3420 >>> Sum(X).sort()
3421 Real
3422 """
3423 ctx = _get_ctx(ctx)
3424 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3425
3426
3427def FreshReal(prefix="b", ctx=None):
3428 """Return a fresh real constant in the given context using the given prefix.
3429
3430 >>> x = FreshReal()
3431 >>> y = FreshReal()
3432 >>> eq(x, y)
3433 False
3434 >>> x.sort()
3435 Real
3436 """
3437 ctx = _get_ctx(ctx)
3438 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3439
3440
3441def ToReal(a):
3442 """ Return the Z3 expression ToReal(a).
3443
3444 >>> x = Int('x')
3445 >>> x.sort()
3446 Int
3447 >>> n = ToReal(x)
3448 >>> n
3449 ToReal(x)
3450 >>> n.sort()
3451 Real
3452 """
3453 ctx = a.ctx
3454 if isinstance(a, BoolRef):
3455 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3456 if z3_debug():
3457 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3458 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3459
3460
3461def ToInt(a):
3462 """ Return the Z3 expression ToInt(a).
3463
3464 >>> x = Real('x')
3465 >>> x.sort()
3466 Real
3467 >>> n = ToInt(x)
3468 >>> n
3469 ToInt(x)
3470 >>> n.sort()
3471 Int
3472 """
3473 if z3_debug():
3474 _z3_assert(a.is_real(), "Z3 real expression expected.")
3475 ctx = a.ctx
3476 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3477
3478
3479def IsInt(a):
3480 """ Return the Z3 predicate IsInt(a).
3481
3482 >>> x = Real('x')
3483 >>> IsInt(x + "1/2")
3484 IsInt(x + 1/2)
3485 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3486 [x = 1/2]
3487 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3488 no solution
3489 """
3490 if z3_debug():
3491 _z3_assert(a.is_real(), "Z3 real expression expected.")
3492 ctx = a.ctx
3493 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3494
3495
3496def Sqrt(a, ctx=None):
3497 """ Return a Z3 expression which represents the square root of a.
3498
3499 >>> x = Real('x')
3500 >>> Sqrt(x)
3501 x**(1/2)
3502 """
3503 if not is_expr(a):
3504 ctx = _get_ctx(ctx)
3505 a = RealVal(a, ctx)
3506 return a ** "1/2"
3507
3508
3509def Cbrt(a, ctx=None):
3510 """ Return a Z3 expression which represents the cubic root of a.
3511
3512 >>> x = Real('x')
3513 >>> Cbrt(x)
3514 x**(1/3)
3515 """
3516 if not is_expr(a):
3517 ctx = _get_ctx(ctx)
3518 a = RealVal(a, ctx)
3519 return a ** "1/3"
3520
3521
3526
3527
3529 """Bit-vector sort."""
3530
3531 def size(self):
3532 """Return the size (number of bits) of the bit-vector sort `self`.
3533
3534 >>> b = BitVecSort(32)
3535 >>> b.size()
3536 32
3537 """
3538 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
3539
3540 def subsort(self, other):
3541 return is_bv_sort(other) and self.size() < other.size()
3542
3543 def cast(self, val):
3544 """Try to cast `val` as a Bit-Vector.
3545
3546 >>> b = BitVecSort(32)
3547 >>> b.cast(10)
3548 10
3549 >>> b.cast(10).sexpr()
3550 '#x0000000a'
3551 """
3552 if is_expr(val):
3553 if z3_debug():
3554 _z3_assert(self.ctx == val.ctx, "Context mismatch")
3555 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3556 return val
3557 else:
3558 return BitVecVal(val, self)
3559
3560
3562 """Return True if `s` is a Z3 bit-vector sort.
3563
3564 >>> is_bv_sort(BitVecSort(32))
3565 True
3566 >>> is_bv_sort(IntSort())
3567 False
3568 """
3569 return isinstance(s, BitVecSortRef)
3570
3571
3573 """Bit-vector expressions."""
3574
3575 def sort(self):
3576 """Return the sort of the bit-vector expression `self`.
3577
3578 >>> x = BitVec('x', 32)
3579 >>> x.sort()
3580 BitVec(32)
3581 >>> x.sort() == BitVecSort(32)
3582 True
3583 """
3584 return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3585
3586 def size(self):
3587 """Return the number of bits of the bit-vector expression `self`.
3588
3589 >>> x = BitVec('x', 32)
3590 >>> (x + 1).size()
3591 32
3592 >>> Concat(x, x).size()
3593 64
3594 """
3595 return self.sort().size()
3596
3597 def __add__(self, other):
3598 """Create the Z3 expression `self + other`.
3599
3600 >>> x = BitVec('x', 32)
3601 >>> y = BitVec('y', 32)
3602 >>> x + y
3603 x + y
3604 >>> (x + y).sort()
3605 BitVec(32)
3606 """
3607 a, b = _coerce_exprs(self, other)
3608 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3609
3610 def __radd__(self, other):
3611 """Create the Z3 expression `other + self`.
3612
3613 >>> x = BitVec('x', 32)
3614 >>> 10 + x
3615 10 + x
3616 """
3617 a, b = _coerce_exprs(self, other)
3618 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3619
3620 def __mul__(self, other):
3621 """Create the Z3 expression `self * other`.
3622
3623 >>> x = BitVec('x', 32)
3624 >>> y = BitVec('y', 32)
3625 >>> x * y
3626 x*y
3627 >>> (x * y).sort()
3628 BitVec(32)
3629 """
3630 a, b = _coerce_exprs(self, other)
3631 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3632
3633 def __rmul__(self, other):
3634 """Create the Z3 expression `other * self`.
3635
3636 >>> x = BitVec('x', 32)
3637 >>> 10 * x
3638 10*x
3639 """
3640 a, b = _coerce_exprs(self, other)
3641 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3642
3643 def __sub__(self, other):
3644 """Create the Z3 expression `self - other`.
3645
3646 >>> x = BitVec('x', 32)
3647 >>> y = BitVec('y', 32)
3648 >>> x - y
3649 x - y
3650 >>> (x - y).sort()
3651 BitVec(32)
3652 """
3653 a, b = _coerce_exprs(self, other)
3654 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3655
3656 def __rsub__(self, other):
3657 """Create the Z3 expression `other - self`.
3658
3659 >>> x = BitVec('x', 32)
3660 >>> 10 - x
3661 10 - x
3662 """
3663 a, b = _coerce_exprs(self, other)
3664 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3665
3666 def __or__(self, other):
3667 """Create the Z3 expression bitwise-or `self | other`.
3668
3669 >>> x = BitVec('x', 32)
3670 >>> y = BitVec('y', 32)
3671 >>> x | y
3672 x | y
3673 >>> (x | y).sort()
3674 BitVec(32)
3675 """
3676 a, b = _coerce_exprs(self, other)
3677 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3678
3679 def __ror__(self, other):
3680 """Create the Z3 expression bitwise-or `other | self`.
3681
3682 >>> x = BitVec('x', 32)
3683 >>> 10 | x
3684 10 | x
3685 """
3686 a, b = _coerce_exprs(self, other)
3687 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3688
3689 def __and__(self, other):
3690 """Create the Z3 expression bitwise-and `self & other`.
3691
3692 >>> x = BitVec('x', 32)
3693 >>> y = BitVec('y', 32)
3694 >>> x & y
3695 x & y
3696 >>> (x & y).sort()
3697 BitVec(32)
3698 """
3699 a, b = _coerce_exprs(self, other)
3700 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3701
3702 def __rand__(self, other):
3703 """Create the Z3 expression bitwise-or `other & self`.
3704
3705 >>> x = BitVec('x', 32)
3706 >>> 10 & x
3707 10 & x
3708 """
3709 a, b = _coerce_exprs(self, other)
3710 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3711
3712 def __xor__(self, other):
3713 """Create the Z3 expression bitwise-xor `self ^ other`.
3714
3715 >>> x = BitVec('x', 32)
3716 >>> y = BitVec('y', 32)
3717 >>> x ^ y
3718 x ^ y
3719 >>> (x ^ y).sort()
3720 BitVec(32)
3721 """
3722 a, b = _coerce_exprs(self, other)
3723 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3724
3725 def __rxor__(self, other):
3726 """Create the Z3 expression bitwise-xor `other ^ self`.
3727
3728 >>> x = BitVec('x', 32)
3729 >>> 10 ^ x
3730 10 ^ x
3731 """
3732 a, b = _coerce_exprs(self, other)
3733 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3734
3735 def __pos__(self):
3736 """Return `self`.
3737
3738 >>> x = BitVec('x', 32)
3739 >>> +x
3740 x
3741 """
3742 return self
3743
3744 def __neg__(self):
3745 """Return an expression representing `-self`.
3746
3747 >>> x = BitVec('x', 32)
3748 >>> -x
3749 -x
3750 >>> simplify(-(-x))
3751 x
3752 """
3753 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3754
3755 def __invert__(self):
3756 """Create the Z3 expression bitwise-not `~self`.
3757
3758 >>> x = BitVec('x', 32)
3759 >>> ~x
3760 ~x
3761 >>> simplify(~(~x))
3762 x
3763 """
3764 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3765
3766 def __div__(self, other):
3767 """Create the Z3 expression (signed) division `self / other`.
3768
3769 Use the function UDiv() for unsigned division.
3770
3771 >>> x = BitVec('x', 32)
3772 >>> y = BitVec('y', 32)
3773 >>> x / y
3774 x/y
3775 >>> (x / y).sort()
3776 BitVec(32)
3777 >>> (x / y).sexpr()
3778 '(bvsdiv x y)'
3779 >>> UDiv(x, y).sexpr()
3780 '(bvudiv x y)'
3781 """
3782 a, b = _coerce_exprs(self, other)
3783 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3784
3785 def __truediv__(self, other):
3786 """Create the Z3 expression (signed) division `self / other`."""
3787 return self.__div__(other)
3788
3789 def __rdiv__(self, other):
3790 """Create the Z3 expression (signed) division `other / self`.
3791
3792 Use the function UDiv() for unsigned division.
3793
3794 >>> x = BitVec('x', 32)
3795 >>> 10 / x
3796 10/x
3797 >>> (10 / x).sexpr()
3798 '(bvsdiv #x0000000a x)'
3799 >>> UDiv(10, x).sexpr()
3800 '(bvudiv #x0000000a x)'
3801 """
3802 a, b = _coerce_exprs(self, other)
3803 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3804
3805 def __rtruediv__(self, other):
3806 """Create the Z3 expression (signed) division `other / self`."""
3807 return self.__rdiv__(other)
3808
3809 def __mod__(self, other):
3810 """Create the Z3 expression (signed) mod `self % other`.
3811
3812 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3813
3814 >>> x = BitVec('x', 32)
3815 >>> y = BitVec('y', 32)
3816 >>> x % y
3817 x%y
3818 >>> (x % y).sort()
3819 BitVec(32)
3820 >>> (x % y).sexpr()
3821 '(bvsmod x y)'
3822 >>> URem(x, y).sexpr()
3823 '(bvurem x y)'
3824 >>> SRem(x, y).sexpr()
3825 '(bvsrem x y)'
3826 """
3827 a, b = _coerce_exprs(self, other)
3828 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3829
3830 def __rmod__(self, other):
3831 """Create the Z3 expression (signed) mod `other % self`.
3832
3833 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3834
3835 >>> x = BitVec('x', 32)
3836 >>> 10 % x
3837 10%x
3838 >>> (10 % x).sexpr()
3839 '(bvsmod #x0000000a x)'
3840 >>> URem(10, x).sexpr()
3841 '(bvurem #x0000000a x)'
3842 >>> SRem(10, x).sexpr()
3843 '(bvsrem #x0000000a x)'
3844 """
3845 a, b = _coerce_exprs(self, other)
3846 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3847
3848 def __le__(self, other):
3849 """Create the Z3 expression (signed) `other <= self`.
3850
3851 Use the function ULE() for unsigned less than or equal to.
3852
3853 >>> x, y = BitVecs('x y', 32)
3854 >>> x <= y
3855 x <= y
3856 >>> (x <= y).sexpr()
3857 '(bvsle x y)'
3858 >>> ULE(x, y).sexpr()
3859 '(bvule x y)'
3860 """
3861 a, b = _coerce_exprs(self, other)
3862 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3863
3864 def __lt__(self, other):
3865 """Create the Z3 expression (signed) `other < self`.
3866
3867 Use the function ULT() for unsigned less than.
3868
3869 >>> x, y = BitVecs('x y', 32)
3870 >>> x < y
3871 x < y
3872 >>> (x < y).sexpr()
3873 '(bvslt x y)'
3874 >>> ULT(x, y).sexpr()
3875 '(bvult x y)'
3876 """
3877 a, b = _coerce_exprs(self, other)
3878 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3879
3880 def __gt__(self, other):
3881 """Create the Z3 expression (signed) `other > self`.
3882
3883 Use the function UGT() for unsigned greater than.
3884
3885 >>> x, y = BitVecs('x y', 32)
3886 >>> x > y
3887 x > y
3888 >>> (x > y).sexpr()
3889 '(bvsgt x y)'
3890 >>> UGT(x, y).sexpr()
3891 '(bvugt x y)'
3892 """
3893 a, b = _coerce_exprs(self, other)
3894 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3895
3896 def __ge__(self, other):
3897 """Create the Z3 expression (signed) `other >= self`.
3898
3899 Use the function UGE() for unsigned greater than or equal to.
3900
3901 >>> x, y = BitVecs('x y', 32)
3902 >>> x >= y
3903 x >= y
3904 >>> (x >= y).sexpr()
3905 '(bvsge x y)'
3906 >>> UGE(x, y).sexpr()
3907 '(bvuge x y)'
3908 """
3909 a, b = _coerce_exprs(self, other)
3910 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3911
3912 def __rshift__(self, other):
3913 """Create the Z3 expression (arithmetical) right shift `self >> other`
3914
3915 Use the function LShR() for the right logical shift
3916
3917 >>> x, y = BitVecs('x y', 32)
3918 >>> x >> y
3919 x >> y
3920 >>> (x >> y).sexpr()
3921 '(bvashr x y)'
3922 >>> LShR(x, y).sexpr()
3923 '(bvlshr x y)'
3924 >>> BitVecVal(4, 3)
3925 4
3926 >>> BitVecVal(4, 3).as_signed_long()
3927 -4
3928 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3929 -2
3930 >>> simplify(BitVecVal(4, 3) >> 1)
3931 6
3932 >>> simplify(LShR(BitVecVal(4, 3), 1))
3933 2
3934 >>> simplify(BitVecVal(2, 3) >> 1)
3935 1
3936 >>> simplify(LShR(BitVecVal(2, 3), 1))
3937 1
3938 """
3939 a, b = _coerce_exprs(self, other)
3940 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3941
3942 def __lshift__(self, other):
3943 """Create the Z3 expression left shift `self << other`
3944
3945 >>> x, y = BitVecs('x y', 32)
3946 >>> x << y
3947 x << y
3948 >>> (x << y).sexpr()
3949 '(bvshl x y)'
3950 >>> simplify(BitVecVal(2, 3) << 1)
3951 4
3952 """
3953 a, b = _coerce_exprs(self, other)
3954 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3955
3956 def __rrshift__(self, other):
3957 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
3958
3959 Use the function LShR() for the right logical shift
3960
3961 >>> x = BitVec('x', 32)
3962 >>> 10 >> x
3963 10 >> x
3964 >>> (10 >> x).sexpr()
3965 '(bvashr #x0000000a x)'
3966 """
3967 a, b = _coerce_exprs(self, other)
3968 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3969
3970 def __rlshift__(self, other):
3971 """Create the Z3 expression left shift `other << self`.
3972
3973 Use the function LShR() for the right logical shift
3974
3975 >>> x = BitVec('x', 32)
3976 >>> 10 << x
3977 10 << x
3978 >>> (10 << x).sexpr()
3979 '(bvshl #x0000000a x)'
3980 """
3981 a, b = _coerce_exprs(self, other)
3982 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3983
3984
3986 """Bit-vector values."""
3987
3988 def as_long(self):
3989 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
3990
3991 >>> v = BitVecVal(0xbadc0de, 32)
3992 >>> v
3993 195936478
3994 >>> print("0x%.8x" % v.as_long())
3995 0x0badc0de
3996 """
3997 return int(self.as_string())
3998
4000 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4001 The most significant bit is assumed to be the sign.
4002
4003 >>> BitVecVal(4, 3).as_signed_long()
4004 -4
4005 >>> BitVecVal(7, 3).as_signed_long()
4006 -1
4007 >>> BitVecVal(3, 3).as_signed_long()
4008 3
4009 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4010 -1
4011 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4012 -1
4013 """
4014 sz = self.size()
4015 val = self.as_long()
4016 if val >= 2**(sz - 1):
4017 val = val - 2**sz
4018 if val < -2**(sz - 1):
4019 val = val + 2**sz
4020 return int(val)
4021
4022 def as_string(self):
4023 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
4024
4026 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
4027
4028 def py_value(self):
4029 """Return the Python value of a Z3 bit-vector numeral."""
4030 return self.as_long()
4031
4032
4033
4034def is_bv(a):
4035 """Return `True` if `a` is a Z3 bit-vector expression.
4036
4037 >>> b = BitVec('b', 32)
4038 >>> is_bv(b)
4039 True
4040 >>> is_bv(b + 10)
4041 True
4042 >>> is_bv(Int('x'))
4043 False
4044 """
4045 return isinstance(a, BitVecRef)
4046
4047
4049 """Return `True` if `a` is a Z3 bit-vector numeral value.
4050
4051 >>> b = BitVec('b', 32)
4052 >>> is_bv_value(b)
4053 False
4054 >>> b = BitVecVal(10, 32)
4055 >>> b
4056 10
4057 >>> is_bv_value(b)
4058 True
4059 """
4060 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4061
4062
4063def BV2Int(a, is_signed=False):
4064 """Return the Z3 expression BV2Int(a).
4065
4066 >>> b = BitVec('b', 3)
4067 >>> BV2Int(b).sort()
4068 Int
4069 >>> x = Int('x')
4070 >>> x > BV2Int(b)
4071 x > BV2Int(b)
4072 >>> x > BV2Int(b, is_signed=False)
4073 x > BV2Int(b)
4074 >>> x > BV2Int(b, is_signed=True)
4075 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4076 >>> solve(x > BV2Int(b), b == 1, x < 3)
4077 [x = 2, b = 1]
4078 """
4079 if z3_debug():
4080 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4081 ctx = a.ctx
4082 # investigate problem with bv2int
4083 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4084
4085
4086def Int2BV(a, num_bits):
4087 """Return the z3 expression Int2BV(a, num_bits).
4088 It is a bit-vector of width num_bits and represents the
4089 modulo of a by 2^num_bits
4090 """
4091 ctx = a.ctx
4092 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4093
4094
4095def BitVecSort(sz, ctx=None):
4096 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4097
4098 >>> Byte = BitVecSort(8)
4099 >>> Word = BitVecSort(16)
4100 >>> Byte
4101 BitVec(8)
4102 >>> x = Const('x', Byte)
4103 >>> eq(x, BitVec('x', 8))
4104 True
4105 """
4106 ctx = _get_ctx(ctx)
4107 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4108
4109
4110def BitVecVal(val, bv, ctx=None):
4111 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4112
4113 >>> v = BitVecVal(10, 32)
4114 >>> v
4115 10
4116 >>> print("0x%.8x" % v.as_long())
4117 0x0000000a
4118 """
4119 if is_bv_sort(bv):
4120 ctx = bv.ctx
4121 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4122 else:
4123 ctx = _get_ctx(ctx)
4124 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4125
4126
4127def BitVec(name, bv, ctx=None):
4128 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4129 If `ctx=None`, then the global context is used.
4130
4131 >>> x = BitVec('x', 16)
4132 >>> is_bv(x)
4133 True
4134 >>> x.size()
4135 16
4136 >>> x.sort()
4137 BitVec(16)
4138 >>> word = BitVecSort(16)
4139 >>> x2 = BitVec('x', word)
4140 >>> eq(x, x2)
4141 True
4142 """
4143 if isinstance(bv, BitVecSortRef):
4144 ctx = bv.ctx
4145 else:
4146 ctx = _get_ctx(ctx)
4147 bv = BitVecSort(bv, ctx)
4148 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4149
4150
4151def BitVecs(names, bv, ctx=None):
4152 """Return a tuple of bit-vector constants of size bv.
4153
4154 >>> x, y, z = BitVecs('x y z', 16)
4155 >>> x.size()
4156 16
4157 >>> x.sort()
4158 BitVec(16)
4159 >>> Sum(x, y, z)
4160 0 + x + y + z
4161 >>> Product(x, y, z)
4162 1*x*y*z
4163 >>> simplify(Product(x, y, z))
4164 x*y*z
4165 """
4166 ctx = _get_ctx(ctx)
4167 if isinstance(names, str):
4168 names = names.split(" ")
4169 return [BitVec(name, bv, ctx) for name in names]
4170
4171
4172def Concat(*args):
4173 """Create a Z3 bit-vector concatenation expression.
4174
4175 >>> v = BitVecVal(1, 4)
4176 >>> Concat(v, v+1, v)
4177 Concat(Concat(1, 1 + 1), 1)
4178 >>> simplify(Concat(v, v+1, v))
4179 289
4180 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4181 121
4182 """
4183 args = _get_args(args)
4184 sz = len(args)
4185 if z3_debug():
4186 _z3_assert(sz >= 2, "At least two arguments expected.")
4187
4188 ctx = None
4189 for a in args:
4190 if is_expr(a):
4191 ctx = a.ctx
4192 break
4193 if is_seq(args[0]) or isinstance(args[0], str):
4194 args = [_coerce_seq(s, ctx) for s in args]
4195 if z3_debug():
4196 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4197 v = (Ast * sz)()
4198 for i in range(sz):
4199 v[i] = args[i].as_ast()
4200 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4201
4202 if is_re(args[0]):
4203 if z3_debug():
4204 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4205 v = (Ast * sz)()
4206 for i in range(sz):
4207 v[i] = args[i].as_ast()
4208 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4209
4210 if z3_debug():
4211 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4212 r = args[0]
4213 for i in range(sz - 1):
4214 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4215 return r
4216
4217
4218def Extract(high, low, a):
4219 """Create a Z3 bit-vector extraction expression.
4220 Extract is overloaded to also work on sequence extraction.
4221 The functions SubString and SubSeq are redirected to Extract.
4222 For this case, the arguments are reinterpreted as:
4223 high - is a sequence (string)
4224 low - is an offset
4225 a - is the length to be extracted
4226
4227 >>> x = BitVec('x', 8)
4228 >>> Extract(6, 2, x)
4229 Extract(6, 2, x)
4230 >>> Extract(6, 2, x).sort()
4231 BitVec(5)
4232 >>> simplify(Extract(StringVal("abcd"),2,1))
4233 "c"
4234 """
4235 if isinstance(high, str):
4236 high = StringVal(high)
4237 if is_seq(high):
4238 s = high
4239 offset, length = _coerce_exprs(low, a, s.ctx)
4240 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4241 if z3_debug():
4242 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4243 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4244 "First and second arguments must be non negative integers")
4245 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4246 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4247
4248
4250 if z3_debug():
4251 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4252
4253
4254def ULE(a, b):
4255 """Create the Z3 expression (unsigned) `other <= self`.
4256
4257 Use the operator <= for signed less than or equal to.
4258
4259 >>> x, y = BitVecs('x y', 32)
4260 >>> ULE(x, y)
4261 ULE(x, y)
4262 >>> (x <= y).sexpr()
4263 '(bvsle x y)'
4264 >>> ULE(x, y).sexpr()
4265 '(bvule x y)'
4266 """
4267 _check_bv_args(a, b)
4268 a, b = _coerce_exprs(a, b)
4269 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4270
4271
4272def ULT(a, b):
4273 """Create the Z3 expression (unsigned) `other < self`.
4274
4275 Use the operator < for signed less than.
4276
4277 >>> x, y = BitVecs('x y', 32)
4278 >>> ULT(x, y)
4279 ULT(x, y)
4280 >>> (x < y).sexpr()
4281 '(bvslt x y)'
4282 >>> ULT(x, y).sexpr()
4283 '(bvult x y)'
4284 """
4285 _check_bv_args(a, b)
4286 a, b = _coerce_exprs(a, b)
4287 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4288
4289
4290def UGE(a, b):
4291 """Create the Z3 expression (unsigned) `other >= self`.
4292
4293 Use the operator >= for signed greater than or equal to.
4294
4295 >>> x, y = BitVecs('x y', 32)
4296 >>> UGE(x, y)
4297 UGE(x, y)
4298 >>> (x >= y).sexpr()
4299 '(bvsge x y)'
4300 >>> UGE(x, y).sexpr()
4301 '(bvuge x y)'
4302 """
4303 _check_bv_args(a, b)
4304 a, b = _coerce_exprs(a, b)
4305 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4306
4307
4308def UGT(a, b):
4309 """Create the Z3 expression (unsigned) `other > self`.
4310
4311 Use the operator > for signed greater than.
4312
4313 >>> x, y = BitVecs('x y', 32)
4314 >>> UGT(x, y)
4315 UGT(x, y)
4316 >>> (x > y).sexpr()
4317 '(bvsgt x y)'
4318 >>> UGT(x, y).sexpr()
4319 '(bvugt x y)'
4320 """
4321 _check_bv_args(a, b)
4322 a, b = _coerce_exprs(a, b)
4323 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4324
4325
4326def UDiv(a, b):
4327 """Create the Z3 expression (unsigned) division `self / other`.
4328
4329 Use the operator / for signed division.
4330
4331 >>> x = BitVec('x', 32)
4332 >>> y = BitVec('y', 32)
4333 >>> UDiv(x, y)
4334 UDiv(x, y)
4335 >>> UDiv(x, y).sort()
4336 BitVec(32)
4337 >>> (x / y).sexpr()
4338 '(bvsdiv x y)'
4339 >>> UDiv(x, y).sexpr()
4340 '(bvudiv x y)'
4341 """
4342 _check_bv_args(a, b)
4343 a, b = _coerce_exprs(a, b)
4344 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4345
4346
4347def URem(a, b):
4348 """Create the Z3 expression (unsigned) remainder `self % other`.
4349
4350 Use the operator % for signed modulus, and SRem() for signed remainder.
4351
4352 >>> x = BitVec('x', 32)
4353 >>> y = BitVec('y', 32)
4354 >>> URem(x, y)
4355 URem(x, y)
4356 >>> URem(x, y).sort()
4357 BitVec(32)
4358 >>> (x % y).sexpr()
4359 '(bvsmod x y)'
4360 >>> URem(x, y).sexpr()
4361 '(bvurem x y)'
4362 """
4363 _check_bv_args(a, b)
4364 a, b = _coerce_exprs(a, b)
4365 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4366
4367
4368def SRem(a, b):
4369 """Create the Z3 expression signed remainder.
4370
4371 Use the operator % for signed modulus, and URem() for unsigned remainder.
4372
4373 >>> x = BitVec('x', 32)
4374 >>> y = BitVec('y', 32)
4375 >>> SRem(x, y)
4376 SRem(x, y)
4377 >>> SRem(x, y).sort()
4378 BitVec(32)
4379 >>> (x % y).sexpr()
4380 '(bvsmod x y)'
4381 >>> SRem(x, y).sexpr()
4382 '(bvsrem x y)'
4383 """
4384 _check_bv_args(a, b)
4385 a, b = _coerce_exprs(a, b)
4386 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4387
4388
4389def LShR(a, b):
4390 """Create the Z3 expression logical right shift.
4391
4392 Use the operator >> for the arithmetical right shift.
4393
4394 >>> x, y = BitVecs('x y', 32)
4395 >>> LShR(x, y)
4396 LShR(x, y)
4397 >>> (x >> y).sexpr()
4398 '(bvashr x y)'
4399 >>> LShR(x, y).sexpr()
4400 '(bvlshr x y)'
4401 >>> BitVecVal(4, 3)
4402 4
4403 >>> BitVecVal(4, 3).as_signed_long()
4404 -4
4405 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4406 -2
4407 >>> simplify(BitVecVal(4, 3) >> 1)
4408 6
4409 >>> simplify(LShR(BitVecVal(4, 3), 1))
4410 2
4411 >>> simplify(BitVecVal(2, 3) >> 1)
4412 1
4413 >>> simplify(LShR(BitVecVal(2, 3), 1))
4414 1
4415 """
4416 _check_bv_args(a, b)
4417 a, b = _coerce_exprs(a, b)
4418 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4419
4420
4421def RotateLeft(a, b):
4422 """Return an expression representing `a` rotated to the left `b` times.
4423
4424 >>> a, b = BitVecs('a b', 16)
4425 >>> RotateLeft(a, b)
4426 RotateLeft(a, b)
4427 >>> simplify(RotateLeft(a, 0))
4428 a
4429 >>> simplify(RotateLeft(a, 16))
4430 a
4431 """
4432 _check_bv_args(a, b)
4433 a, b = _coerce_exprs(a, b)
4434 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4435
4436
4437def RotateRight(a, b):
4438 """Return an expression representing `a` rotated to the right `b` times.
4439
4440 >>> a, b = BitVecs('a b', 16)
4441 >>> RotateRight(a, b)
4442 RotateRight(a, b)
4443 >>> simplify(RotateRight(a, 0))
4444 a
4445 >>> simplify(RotateRight(a, 16))
4446 a
4447 """
4448 _check_bv_args(a, b)
4449 a, b = _coerce_exprs(a, b)
4450 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4451
4452
4453def SignExt(n, a):
4454 """Return a bit-vector expression with `n` extra sign-bits.
4455
4456 >>> x = BitVec('x', 16)
4457 >>> n = SignExt(8, x)
4458 >>> n.size()
4459 24
4460 >>> n
4461 SignExt(8, x)
4462 >>> n.sort()
4463 BitVec(24)
4464 >>> v0 = BitVecVal(2, 2)
4465 >>> v0
4466 2
4467 >>> v0.size()
4468 2
4469 >>> v = simplify(SignExt(6, v0))
4470 >>> v
4471 254
4472 >>> v.size()
4473 8
4474 >>> print("%.x" % v.as_long())
4475 fe
4476 """
4477 if z3_debug():
4478 _z3_assert(_is_int(n), "First argument must be an integer")
4479 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4480 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4481
4482
4483def ZeroExt(n, a):
4484 """Return a bit-vector expression with `n` extra zero-bits.
4485
4486 >>> x = BitVec('x', 16)
4487 >>> n = ZeroExt(8, x)
4488 >>> n.size()
4489 24
4490 >>> n
4491 ZeroExt(8, x)
4492 >>> n.sort()
4493 BitVec(24)
4494 >>> v0 = BitVecVal(2, 2)
4495 >>> v0
4496 2
4497 >>> v0.size()
4498 2
4499 >>> v = simplify(ZeroExt(6, v0))
4500 >>> v
4501 2
4502 >>> v.size()
4503 8
4504 """
4505 if z3_debug():
4506 _z3_assert(_is_int(n), "First argument must be an integer")
4507 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4508 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4509
4510
4512 """Return an expression representing `n` copies of `a`.
4513
4514 >>> x = BitVec('x', 8)
4515 >>> n = RepeatBitVec(4, x)
4516 >>> n
4517 RepeatBitVec(4, x)
4518 >>> n.size()
4519 32
4520 >>> v0 = BitVecVal(10, 4)
4521 >>> print("%.x" % v0.as_long())
4522 a
4523 >>> v = simplify(RepeatBitVec(4, v0))
4524 >>> v.size()
4525 16
4526 >>> print("%.x" % v.as_long())
4527 aaaa
4528 """
4529 if z3_debug():
4530 _z3_assert(_is_int(n), "First argument must be an integer")
4531 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4532 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4533
4534
4536 """Return the reduction-and expression of `a`."""
4537 if z3_debug():
4538 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4539 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4540
4541
4542def BVRedOr(a):
4543 """Return the reduction-or expression of `a`."""
4544 if z3_debug():
4545 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4546 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4547
4548
4549def BVAddNoOverflow(a, b, signed):
4550 """A predicate the determines that bit-vector addition does not overflow"""
4551 _check_bv_args(a, b)
4552 a, b = _coerce_exprs(a, b)
4553 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4554
4555
4557 """A predicate the determines that signed bit-vector addition does not underflow"""
4558 _check_bv_args(a, b)
4559 a, b = _coerce_exprs(a, b)
4560 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4561
4562
4564 """A predicate the determines that bit-vector subtraction does not overflow"""
4565 _check_bv_args(a, b)
4566 a, b = _coerce_exprs(a, b)
4567 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4568
4569
4570def BVSubNoUnderflow(a, b, signed):
4571 """A predicate the determines that bit-vector subtraction does not underflow"""
4572 _check_bv_args(a, b)
4573 a, b = _coerce_exprs(a, b)
4574 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4575
4576
4578 """A predicate the determines that bit-vector signed division does not overflow"""
4579 _check_bv_args(a, b)
4580 a, b = _coerce_exprs(a, b)
4581 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4582
4583
4585 """A predicate the determines that bit-vector unary negation does not overflow"""
4586 if z3_debug():
4587 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4588 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4589
4590
4591def BVMulNoOverflow(a, b, signed):
4592 """A predicate the determines that bit-vector multiplication does not overflow"""
4593 _check_bv_args(a, b)
4594 a, b = _coerce_exprs(a, b)
4595 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4596
4597
4599 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4600 _check_bv_args(a, b)
4601 a, b = _coerce_exprs(a, b)
4602 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4603
4604
4605
4610
4612 """Array sorts."""
4613
4614 def domain(self):
4615 """Return the domain of the array sort `self`.
4616
4617 >>> A = ArraySort(IntSort(), BoolSort())
4618 >>> A.domain()
4619 Int
4620 """
4622
4623 def domain_n(self, i):
4624 """Return the domain of the array sort `self`.
4625 """
4626 return _to_sort_ref(Z3_get_array_sort_domain_n(self.ctx_ref(), self.ast, i), self.ctx)
4627
4628 def range(self):
4629 """Return the range of the array sort `self`.
4630
4631 >>> A = ArraySort(IntSort(), BoolSort())
4632 >>> A.range()
4633 Bool
4634 """
4635 return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
4636
4637
4639 """Array expressions. """
4640
4641 def sort(self):
4642 """Return the array sort of the array expression `self`.
4643
4644 >>> a = Array('a', IntSort(), BoolSort())
4645 >>> a.sort()
4646 Array(Int, Bool)
4647 """
4648 return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4649
4650 def domain(self):
4651 """Shorthand for `self.sort().domain()`.
4652
4653 >>> a = Array('a', IntSort(), BoolSort())
4654 >>> a.domain()
4655 Int
4656 """
4657 return self.sort().domain()
4658
4659 def domain_n(self, i):
4660 """Shorthand for self.sort().domain_n(i)`."""
4661 return self.sort().domain_n(i)
4662
4663 def range(self):
4664 """Shorthand for `self.sort().range()`.
4665
4666 >>> a = Array('a', IntSort(), BoolSort())
4667 >>> a.range()
4668 Bool
4669 """
4670 return self.sort().range()
4671
4672 def __getitem__(self, arg):
4673 """Return the Z3 expression `self[arg]`.
4674
4675 >>> a = Array('a', IntSort(), BoolSort())
4676 >>> i = Int('i')
4677 >>> a[i]
4678 a[i]
4679 >>> a[i].sexpr()
4680 '(select a i)'
4681 """
4682 return _array_select(self, arg)
4683
4684 def default(self):
4685 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)
4686
4687
4688def _array_select(ar, arg):
4689 if isinstance(arg, tuple):
4690 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4691 _args, sz = _to_ast_array(args)
4692 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4693 arg = ar.sort().domain().cast(arg)
4694 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4695
4696
4698 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4699
4700
4701def is_array(a : Any) -> bool:
4702 """Return `True` if `a` is a Z3 array expression.
4703
4704 >>> a = Array('a', IntSort(), IntSort())
4705 >>> is_array(a)
4706 True
4707 >>> is_array(Store(a, 0, 1))
4708 True
4709 >>> is_array(a[0])
4710 False
4711 """
4712 return isinstance(a, ArrayRef)
4713
4714
4716 """Return `True` if `a` is a Z3 constant array.
4717
4718 >>> a = K(IntSort(), 10)
4719 >>> is_const_array(a)
4720 True
4721 >>> a = Array('a', IntSort(), IntSort())
4722 >>> is_const_array(a)
4723 False
4724 """
4725 return is_app_of(a, Z3_OP_CONST_ARRAY)
4726
4727
4728def is_K(a):
4729 """Return `True` if `a` is a Z3 constant array.
4730
4731 >>> a = K(IntSort(), 10)
4732 >>> is_K(a)
4733 True
4734 >>> a = Array('a', IntSort(), IntSort())
4735 >>> is_K(a)
4736 False
4737 """
4738 return is_app_of(a, Z3_OP_CONST_ARRAY)
4739
4740
4741def is_map(a):
4742 """Return `True` if `a` is a Z3 map array expression.
4743
4744 >>> f = Function('f', IntSort(), IntSort())
4745 >>> b = Array('b', IntSort(), IntSort())
4746 >>> a = Map(f, b)
4747 >>> a
4748 Map(f, b)
4749 >>> is_map(a)
4750 True
4751 >>> is_map(b)
4752 False
4753 """
4754 return is_app_of(a, Z3_OP_ARRAY_MAP)
4755
4756
4758 """Return `True` if `a` is a Z3 default array expression.
4759 >>> d = Default(K(IntSort(), 10))
4760 >>> is_default(d)
4761 True
4762 """
4763 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4764
4765
4767 """Return the function declaration associated with a Z3 map array expression.
4768
4769 >>> f = Function('f', IntSort(), IntSort())
4770 >>> b = Array('b', IntSort(), IntSort())
4771 >>> a = Map(f, b)
4772 >>> eq(f, get_map_func(a))
4773 True
4774 >>> get_map_func(a)
4775 f
4776 >>> get_map_func(a)(0)
4777 f(0)
4778 """
4779 if z3_debug():
4780 _z3_assert(is_map(a), "Z3 array map expression expected.")
4781 return FuncDeclRef(
4783 a.ctx_ref(),
4784 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4785 ),
4786 ctx=a.ctx,
4787 )
4788
4789
4790def ArraySort(*sig):
4791 """Return the Z3 array sort with the given domain and range sorts.
4792
4793 >>> A = ArraySort(IntSort(), BoolSort())
4794 >>> A
4795 Array(Int, Bool)
4796 >>> A.domain()
4797 Int
4798 >>> A.range()
4799 Bool
4800 >>> AA = ArraySort(IntSort(), A)
4801 >>> AA
4802 Array(Int, Array(Int, Bool))
4803 """
4804 sig = _get_args(sig)
4805 if z3_debug():
4806 _z3_assert(len(sig) > 1, "At least two arguments expected")
4807 arity = len(sig) - 1
4808 r = sig[arity]
4809 d = sig[0]
4810 if z3_debug():
4811 for s in sig:
4812 _z3_assert(is_sort(s), "Z3 sort expected")
4813 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4814 ctx = d.ctx
4815 if len(sig) == 2:
4816 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4817 dom = (Sort * arity)()
4818 for i in range(arity):
4819 dom[i] = sig[i].ast
4820 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4821
4822
4823def Array(name, *sorts):
4824 """Return an array constant named `name` with the given domain and range sorts.
4825
4826 >>> a = Array('a', IntSort(), IntSort())
4827 >>> a.sort()
4828 Array(Int, Int)
4829 >>> a[0]
4830 a[0]
4831 """
4832 s = ArraySort(sorts)
4833 ctx = s.ctx
4834 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4835
4836
4837def Update(a, *args):
4838 """Return a Z3 store array expression.
4839
4840 >>> a = Array('a', IntSort(), IntSort())
4841 >>> i, v = Ints('i v')
4842 >>> s = Update(a, i, v)
4843 >>> s.sort()
4844 Array(Int, Int)
4845 >>> prove(s[i] == v)
4846 proved
4847 >>> j = Int('j')
4848 >>> prove(Implies(i != j, s[j] == a[j]))
4849 proved
4850 """
4851 if z3_debug():
4852 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4853 args = _get_args(args)
4854 ctx = a.ctx
4855 if len(args) <= 1:
4856 raise Z3Exception("array update requires index and value arguments")
4857 if len(args) == 2:
4858 i = args[0]
4859 v = args[1]
4860 i = a.sort().domain().cast(i)
4861 v = a.sort().range().cast(v)
4862 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4863 v = a.sort().range().cast(args[-1])
4864 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4865 _args, sz = _to_ast_array(idxs)
4866 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4867
4868
4869def Default(a):
4870 """ Return a default value for array expression.
4871 >>> b = K(IntSort(), 1)
4872 >>> prove(Default(b) == 1)
4873 proved
4874 """
4875 if z3_debug():
4876 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4877 return a.default()
4878
4879
4880def Store(a, *args):
4881 """Return a Z3 store array expression.
4882
4883 >>> a = Array('a', IntSort(), IntSort())
4884 >>> i, v = Ints('i v')
4885 >>> s = Store(a, i, v)
4886 >>> s.sort()
4887 Array(Int, Int)
4888 >>> prove(s[i] == v)
4889 proved
4890 >>> j = Int('j')
4891 >>> prove(Implies(i != j, s[j] == a[j]))
4892 proved
4893 """
4894 return Update(a, args)
4895
4896
4897def Select(a, *args):
4898 """Return a Z3 select array expression.
4899
4900 >>> a = Array('a', IntSort(), IntSort())
4901 >>> i = Int('i')
4902 >>> Select(a, i)
4903 a[i]
4904 >>> eq(Select(a, i), a[i])
4905 True
4906 """
4907 args = _get_args(args)
4908 if z3_debug():
4909 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4910 return a[args]
4911
4912
4913def Map(f, *args):
4914 """Return a Z3 map array expression.
4915
4916 >>> f = Function('f', IntSort(), IntSort(), IntSort())
4917 >>> a1 = Array('a1', IntSort(), IntSort())
4918 >>> a2 = Array('a2', IntSort(), IntSort())
4919 >>> b = Map(f, a1, a2)
4920 >>> b
4921 Map(f, a1, a2)
4922 >>> prove(b[0] == f(a1[0], a2[0]))
4923 proved
4924 """
4925 args = _get_args(args)
4926 if z3_debug():
4927 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
4928 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
4929 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
4930 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
4931 _args, sz = _to_ast_array(args)
4932 ctx = f.ctx
4933 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
4934
4935
4936def K(dom, v):
4937 """Return a Z3 constant array expression.
4938
4939 >>> a = K(IntSort(), 10)
4940 >>> a
4941 K(Int, 10)
4942 >>> a.sort()
4943 Array(Int, Int)
4944 >>> i = Int('i')
4945 >>> a[i]
4946 K(Int, 10)[i]
4947 >>> simplify(a[i])
4948 10
4949 """
4950 if z3_debug():
4951 _z3_assert(is_sort(dom), "Z3 sort expected")
4952 ctx = dom.ctx
4953 if not is_expr(v):
4954 v = _py2expr(v, ctx)
4955 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
4956
4957
4958def Ext(a, b):
4959 """Return extensionality index for one-dimensional arrays.
4960 >> a, b = Consts('a b', SetSort(IntSort()))
4961 >> Ext(a, b)
4962 Ext(a, b)
4963 """
4964 ctx = a.ctx
4965 if z3_debug():
4966 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
4967 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
4968
4969
4970def SetHasSize(a, k):
4971 ctx = a.ctx
4972 k = _py2expr(k, ctx)
4973 return _to_expr_ref(Z3_mk_set_has_size(ctx.ref(), a.as_ast(), k.as_ast()), ctx)
4974
4975
4977 """Return `True` if `a` is a Z3 array select application.
4978
4979 >>> a = Array('a', IntSort(), IntSort())
4980 >>> is_select(a)
4981 False
4982 >>> i = Int('i')
4983 >>> is_select(a[i])
4984 True
4985 """
4986 return is_app_of(a, Z3_OP_SELECT)
4987
4988
4990 """Return `True` if `a` is a Z3 array store application.
4991
4992 >>> a = Array('a', IntSort(), IntSort())
4993 >>> is_store(a)
4994 False
4995 >>> is_store(Store(a, 0, 1))
4996 True
4997 """
4998 return is_app_of(a, Z3_OP_STORE)
4999
5000
5005
5006
5007def SetSort(s):
5008 """ Create a set sort over element sort s"""
5009 return ArraySort(s, BoolSort())
5010
5011
5013 """Create the empty set
5014 >>> EmptySet(IntSort())
5015 K(Int, False)
5016 """
5017 ctx = s.ctx
5018 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5019
5020
5021def FullSet(s):
5022 """Create the full set
5023 >>> FullSet(IntSort())
5024 K(Int, True)
5025 """
5026 ctx = s.ctx
5027 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5028
5029
5030def SetUnion(*args):
5031 """ Take the union of sets
5032 >>> a = Const('a', SetSort(IntSort()))
5033 >>> b = Const('b', SetSort(IntSort()))
5034 >>> SetUnion(a, b)
5035 union(a, b)
5036 """
5037 args = _get_args(args)
5038 ctx = _ctx_from_ast_arg_list(args)
5039 _args, sz = _to_ast_array(args)
5040 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5041
5042
5043def SetIntersect(*args):
5044 """ Take the union of sets
5045 >>> a = Const('a', SetSort(IntSort()))
5046 >>> b = Const('b', SetSort(IntSort()))
5047 >>> SetIntersect(a, b)
5048 intersection(a, b)
5049 """
5050 args = _get_args(args)
5051 ctx = _ctx_from_ast_arg_list(args)
5052 _args, sz = _to_ast_array(args)
5053 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5054
5055
5056def SetAdd(s, e):
5057 """ Add element e to set s
5058 >>> a = Const('a', SetSort(IntSort()))
5059 >>> SetAdd(a, 1)
5060 Store(a, 1, True)
5061 """
5062 ctx = _ctx_from_ast_arg_list([s, e])
5063 e = _py2expr(e, ctx)
5064 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5065
5066
5067def SetDel(s, e):
5068 """ Remove element e to set s
5069 >>> a = Const('a', SetSort(IntSort()))
5070 >>> SetDel(a, 1)
5071 Store(a, 1, False)
5072 """
5073 ctx = _ctx_from_ast_arg_list([s, e])
5074 e = _py2expr(e, ctx)
5075 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5076
5077
5079 """ The complement of set s
5080 >>> a = Const('a', SetSort(IntSort()))
5081 >>> SetComplement(a)
5082 complement(a)
5083 """
5084 ctx = s.ctx
5085 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5086
5087
5089 """ The set difference of a and b
5090 >>> a = Const('a', SetSort(IntSort()))
5091 >>> b = Const('b', SetSort(IntSort()))
5092 >>> SetDifference(a, b)
5093 setminus(a, b)
5094 """
5095 ctx = _ctx_from_ast_arg_list([a, b])
5096 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5097
5098
5099def IsMember(e, s):
5100 """ Check if e is a member of set s
5101 >>> a = Const('a', SetSort(IntSort()))
5102 >>> IsMember(1, a)
5103 a[1]
5104 """
5105 ctx = _ctx_from_ast_arg_list([s, e])
5106 e = _py2expr(e, ctx)
5107 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5108
5109
5110def IsSubset(a, b):
5111 """ Check if a is a subset of b
5112 >>> a = Const('a', SetSort(IntSort()))
5113 >>> b = Const('b', SetSort(IntSort()))
5114 >>> IsSubset(a, b)
5115 subset(a, b)
5116 """
5117 ctx = _ctx_from_ast_arg_list([a, b])
5118 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5119
5120
5121
5126
5128 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5129 if not isinstance(acc, tuple):
5130 return False
5131 if len(acc) != 2:
5132 return False
5133 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5134
5135
5137 """Helper class for declaring Z3 datatypes.
5138
5139 >>> List = Datatype('List')
5140 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5141 >>> List.declare('nil')
5142 >>> List = List.create()
5143 >>> # List is now a Z3 declaration
5144 >>> List.nil
5145 nil
5146 >>> List.cons(10, List.nil)
5147 cons(10, nil)
5148 >>> List.cons(10, List.nil).sort()
5149 List
5150 >>> cons = List.cons
5151 >>> nil = List.nil
5152 >>> car = List.car
5153 >>> cdr = List.cdr
5154 >>> n = cons(1, cons(0, nil))
5155 >>> n
5156 cons(1, cons(0, nil))
5157 >>> simplify(cdr(n))
5158 cons(0, nil)
5159 >>> simplify(car(n))
5160 1
5161 """
5162
5163 def __init__(self, name, ctx=None):
5164 self.ctx = _get_ctx(ctx)
5165 self.name = name
5167
5168 def __deepcopy__(self, memo={}):
5169 r = Datatype(self.name, self.ctx)
5170 r.constructors = copy.deepcopy(self.constructors)
5171 return r
5172
5173 def declare_core(self, name, rec_name, *args):
5174 if z3_debug():
5175 _z3_assert(isinstance(name, str), "String expected")
5176 _z3_assert(isinstance(rec_name, str), "String expected")
5177 _z3_assert(
5178 all([_valid_accessor(a) for a in args]),
5179 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5180 )
5181 self.constructors.append((name, rec_name, args))
5182
5183 def declare(self, name, *args):
5184 """Declare constructor named `name` with the given accessors `args`.
5185 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5186 or a reference to the datatypes being declared.
5187
5188 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5189 declares the constructor named `cons` that builds a new List using an integer and a List.
5190 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5191 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5192 we use the method create() to create the actual datatype in Z3.
5193
5194 >>> List = Datatype('List')
5195 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5196 >>> List.declare('nil')
5197 >>> List = List.create()
5198 """
5199 if z3_debug():
5200 _z3_assert(isinstance(name, str), "String expected")
5201 _z3_assert(name != "", "Constructor name cannot be empty")
5202 return self.declare_core(name, "is-" + name, *args)
5203
5204 def __repr__(self):
5205 return "Datatype(%s, %s)" % (self.name, self.constructors)
5206
5207 def create(self):
5208 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5209
5210 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5211
5212 >>> List = Datatype('List')
5213 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5214 >>> List.declare('nil')
5215 >>> List = List.create()
5216 >>> List.nil
5217 nil
5218 >>> List.cons(10, List.nil)
5219 cons(10, nil)
5220 """
5221 return CreateDatatypes([self])[0]
5222
5223
5225 """Auxiliary object used to create Z3 datatypes."""
5226
5227 def __init__(self, c, ctx):
5228 self.c = c
5229 self.ctx = ctx
5230
5231 def __del__(self):
5232 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5233 Z3_del_constructor(self.ctx.ref(), self.c)
5234
5235
5237 """Auxiliary object used to create Z3 datatypes."""
5238
5239 def __init__(self, c, ctx):
5240 self.c = c
5241 self.ctx = ctx
5242
5243 def __del__(self):
5244 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5245 Z3_del_constructor_list(self.ctx.ref(), self.c)
5246
5247
5249 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5250
5251 In the following example we define a Tree-List using two mutually recursive datatypes.
5252
5253 >>> TreeList = Datatype('TreeList')
5254 >>> Tree = Datatype('Tree')
5255 >>> # Tree has two constructors: leaf and node
5256 >>> Tree.declare('leaf', ('val', IntSort()))
5257 >>> # a node contains a list of trees
5258 >>> Tree.declare('node', ('children', TreeList))
5259 >>> TreeList.declare('nil')
5260 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5261 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5262 >>> Tree.val(Tree.leaf(10))
5263 val(leaf(10))
5264 >>> simplify(Tree.val(Tree.leaf(10)))
5265 10
5266 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5267 >>> n1
5268 node(cons(leaf(10), cons(leaf(20), nil)))
5269 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5270 >>> simplify(n2 == n1)
5271 False
5272 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5273 True
5274 """
5275 ds = _get_args(ds)
5276 if z3_debug():
5277 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5278 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5279 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5280 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5281 ctx = ds[0].ctx
5282 num = len(ds)
5283 names = (Symbol * num)()
5284 out = (Sort * num)()
5285 clists = (ConstructorList * num)()
5286 to_delete = []
5287 for i in range(num):
5288 d = ds[i]
5289 names[i] = to_symbol(d.name, ctx)
5290 num_cs = len(d.constructors)
5291 cs = (Constructor * num_cs)()
5292 for j in range(num_cs):
5293 c = d.constructors[j]
5294 cname = to_symbol(c[0], ctx)
5295 rname = to_symbol(c[1], ctx)
5296 fs = c[2]
5297 num_fs = len(fs)
5298 fnames = (Symbol * num_fs)()
5299 sorts = (Sort * num_fs)()
5300 refs = (ctypes.c_uint * num_fs)()
5301 for k in range(num_fs):
5302 fname = fs[k][0]
5303 ftype = fs[k][1]
5304 fnames[k] = to_symbol(fname, ctx)
5305 if isinstance(ftype, Datatype):
5306 if z3_debug():
5307 _z3_assert(
5308 ds.count(ftype) == 1,
5309 "One and only one occurrence of each datatype is expected",
5310 )
5311 sorts[k] = None
5312 refs[k] = ds.index(ftype)
5313 else:
5314 if z3_debug():
5315 _z3_assert(is_sort(ftype), "Z3 sort expected")
5316 sorts[k] = ftype.ast
5317 refs[k] = 0
5318 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5319 to_delete.append(ScopedConstructor(cs[j], ctx))
5320 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5321 to_delete.append(ScopedConstructorList(clists[i], ctx))
5322 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5323 result = []
5324 # Create a field for every constructor, recognizer and accessor
5325 for i in range(num):
5326 dref = DatatypeSortRef(out[i], ctx)
5327 num_cs = dref.num_constructors()
5328 for j in range(num_cs):
5329 cref = dref.constructor(j)
5330 cref_name = cref.name()
5331 cref_arity = cref.arity()
5332 if cref.arity() == 0:
5333 cref = cref()
5334 setattr(dref, cref_name, cref)
5335 rref = dref.recognizer(j)
5336 setattr(dref, "is_" + cref_name, rref)
5337 for k in range(cref_arity):
5338 aref = dref.accessor(j, k)
5339 setattr(dref, aref.name(), aref)
5340 result.append(dref)
5341 return tuple(result)
5342
5343
5345 """Datatype sorts."""
5346
5348 """Return the number of constructors in the given Z3 datatype.
5349
5350 >>> List = Datatype('List')
5351 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5352 >>> List.declare('nil')
5353 >>> List = List.create()
5354 >>> # List is now a Z3 declaration
5355 >>> List.num_constructors()
5356 2
5357 """
5359
5360 def constructor(self, idx):
5361 """Return a constructor of the datatype `self`.
5362
5363 >>> List = Datatype('List')
5364 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5365 >>> List.declare('nil')
5366 >>> List = List.create()
5367 >>> # List is now a Z3 declaration
5368 >>> List.num_constructors()
5369 2
5370 >>> List.constructor(0)
5371 cons
5372 >>> List.constructor(1)
5373 nil
5374 """
5375 if z3_debug():
5376 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5378
5379 def recognizer(self, idx):
5380 """In Z3, each constructor has an associated recognizer predicate.
5381
5382 If the constructor is named `name`, then the recognizer `is_name`.
5383
5384 >>> List = Datatype('List')
5385 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5386 >>> List.declare('nil')
5387 >>> List = List.create()
5388 >>> # List is now a Z3 declaration
5389 >>> List.num_constructors()
5390 2
5391 >>> List.recognizer(0)
5392 is(cons)
5393 >>> List.recognizer(1)
5394 is(nil)
5395 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5396 False
5397 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5398 True
5399 >>> l = Const('l', List)
5400 >>> simplify(List.is_cons(l))
5401 is(cons, l)
5402 """
5403 if z3_debug():
5404 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5405 return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
5406
5407 def accessor(self, i, j):
5408 """In Z3, each constructor has 0 or more accessor.
5409 The number of accessors is equal to the arity of the constructor.
5410
5411 >>> List = Datatype('List')
5412 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5413 >>> List.declare('nil')
5414 >>> List = List.create()
5415 >>> List.num_constructors()
5416 2
5417 >>> List.constructor(0)
5418 cons
5419 >>> num_accs = List.constructor(0).arity()
5420 >>> num_accs
5421 2
5422 >>> List.accessor(0, 0)
5423 car
5424 >>> List.accessor(0, 1)
5425 cdr
5426 >>> List.constructor(1)
5427 nil
5428 >>> num_accs = List.constructor(1).arity()
5429 >>> num_accs
5430 0
5431 """
5432 if z3_debug():
5433 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5434 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5435 return FuncDeclRef(
5437 ctx=self.ctx,
5438 )
5439
5440
5442 """Datatype expressions."""
5443
5444 def sort(self):
5445 """Return the datatype sort of the datatype expression `self`."""
5446 return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5447
5448def DatatypeSort(name, ctx = None):
5449 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype"""
5450 ctx = _get_ctx(ctx)
5451 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
5452
5453def TupleSort(name, sorts, ctx=None):
5454 """Create a named tuple sort base on a set of underlying sorts
5455 Example:
5456 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5457 """
5458 tuple = Datatype(name, ctx)
5459 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5460 tuple.declare(name, *projects)
5461 tuple = tuple.create()
5462 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5463
5464
5465def DisjointSum(name, sorts, ctx=None):
5466 """Create a named tagged union sort base on a set of underlying sorts
5467 Example:
5468 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5469 """
5470 sum = Datatype(name, ctx)
5471 for i in range(len(sorts)):
5472 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5473 sum = sum.create()
5474 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5475
5476
5477def EnumSort(name, values, ctx=None):
5478 """Return a new enumeration sort named `name` containing the given values.
5479
5480 The result is a pair (sort, list of constants).
5481 Example:
5482 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5483 """
5484 if z3_debug():
5485 _z3_assert(isinstance(name, str), "Name must be a string")
5486 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5487 _z3_assert(len(values) > 0, "At least one value expected")
5488 ctx = _get_ctx(ctx)
5489 num = len(values)
5490 _val_names = (Symbol * num)()
5491 for i in range(num):
5492 _val_names[i] = to_symbol(values[i], ctx)
5493 _values = (FuncDecl * num)()
5494 _testers = (FuncDecl * num)()
5495 name = to_symbol(name, ctx)
5496 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5497 V = []
5498 for i in range(num):
5499 V.append(FuncDeclRef(_values[i], ctx))
5500 V = [a() for a in V]
5501 return S, V
5502
5503
5508
5509
5511 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5512
5513 Consider using the function `args2params` to create instances of this object.
5514 """
5515
5516 def __init__(self, ctx=None, params=None):
5517 self.ctx = _get_ctx(ctx)
5518 if params is None:
5519 self.params = Z3_mk_params(self.ctx.ref())
5520 else:
5521 self.params = params
5522 Z3_params_inc_ref(self.ctx.ref(), self.params)
5523
5524 def __deepcopy__(self, memo={}):
5525 return ParamsRef(self.ctx, self.params)
5526
5527 def __del__(self):
5528 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5529 Z3_params_dec_ref(self.ctx.ref(), self.params)
5530
5531 def set(self, name, val):
5532 """Set parameter name with value val."""
5533 if z3_debug():
5534 _z3_assert(isinstance(name, str), "parameter name must be a string")
5535 name_sym = to_symbol(name, self.ctx)
5536 if isinstance(val, bool):
5537 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5538 elif _is_int(val):
5539 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5540 elif isinstance(val, float):
5541 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5542 elif isinstance(val, str):
5543 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5544 else:
5545 if z3_debug():
5546 _z3_assert(False, "invalid parameter value")
5547
5548 def __repr__(self):
5549 return Z3_params_to_string(self.ctx.ref(), self.params)
5550
5551 def validate(self, ds):
5552 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5553 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5554
5555
5556def args2params(arguments, keywords, ctx=None):
5557 """Convert python arguments into a Z3_params object.
5558 A ':' is added to the keywords, and '_' is replaced with '-'
5559
5560 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5561 (params model true relevancy 2 elim_and true)
5562 """
5563 if z3_debug():
5564 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5565 prev = None
5566 r = ParamsRef(ctx)
5567 for a in arguments:
5568 if prev is None:
5569 prev = a
5570 else:
5571 r.set(prev, a)
5572 prev = None
5573 for k in keywords:
5574 v = keywords[k]
5575 r.set(k, v)
5576 return r
5577
5578
5580 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5581 """
5582
5583 def __init__(self, descr, ctx=None):
5584 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5585 self.ctx = _get_ctx(ctx)
5586 self.descr = descr
5587 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5588
5589 def __deepcopy__(self, memo={}):
5590 return ParamsDescrsRef(self.descr, self.ctx)
5591
5592 def __del__(self):
5593 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5594 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5595
5596 def size(self):
5597 """Return the size of in the parameter description `self`.
5598 """
5599 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5600
5601 def __len__(self):
5602 """Return the size of in the parameter description `self`.
5603 """
5604 return self.size()
5605
5606 def get_name(self, i):
5607 """Return the i-th parameter name in the parameter description `self`.
5608 """
5609 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5610
5611 def get_kind(self, n):
5612 """Return the kind of the parameter named `n`.
5613 """
5614 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5615
5616 def get_documentation(self, n):
5617 """Return the documentation string of the parameter named `n`.
5618 """
5619 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5620
5621 def __getitem__(self, arg):
5622 if _is_int(arg):
5623 return self.get_name(arg)
5624 else:
5625 return self.get_kind(arg)
5626
5627 def __repr__(self):
5628 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5629
5630
5635
5636
5638 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5639
5640 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5641 A goal has a solution if one of its subgoals has a solution.
5642 A goal is unsatisfiable if all subgoals are unsatisfiable.
5643 """
5644
5645 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5646 if z3_debug():
5647 _z3_assert(goal is None or ctx is not None,
5648 "If goal is different from None, then ctx must be also different from None")
5649 self.ctx = _get_ctx(ctx)
5650 self.goal = goal
5651 if self.goal is None:
5652 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5653 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5654
5655 def __del__(self):
5656 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5657 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5658
5659 def depth(self):
5660 """Return the depth of the goal `self`.
5661 The depth corresponds to the number of tactics applied to `self`.
5662
5663 >>> x, y = Ints('x y')
5664 >>> g = Goal()
5665 >>> g.add(x == 0, y >= x + 1)
5666 >>> g.depth()
5667 0
5668 >>> r = Then('simplify', 'solve-eqs')(g)
5669 >>> # r has 1 subgoal
5670 >>> len(r)
5671 1
5672 >>> r[0].depth()
5673 2
5674 """
5675 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5676
5677 def inconsistent(self):
5678 """Return `True` if `self` contains the `False` constraints.
5679
5680 >>> x, y = Ints('x y')
5681 >>> g = Goal()
5682 >>> g.inconsistent()
5683 False
5684 >>> g.add(x == 0, x == 1)
5685 >>> g
5686 [x == 0, x == 1]
5687 >>> g.inconsistent()
5688 False
5689 >>> g2 = Tactic('propagate-values')(g)[0]
5690 >>> g2.inconsistent()
5691 True
5692 """
5693 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5694
5695 def prec(self):
5696 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5697
5698 >>> g = Goal()
5699 >>> g.prec() == Z3_GOAL_PRECISE
5700 True
5701 >>> x, y = Ints('x y')
5702 >>> g.add(x == y + 1)
5703 >>> g.prec() == Z3_GOAL_PRECISE
5704 True
5705 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5706 >>> g2 = t(g)[0]
5707 >>> g2
5708 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5709 >>> g2.prec() == Z3_GOAL_PRECISE
5710 False
5711 >>> g2.prec() == Z3_GOAL_UNDER
5712 True
5713 """
5714 return Z3_goal_precision(self.ctx.ref(), self.goal)
5715
5716 def precision(self):
5717 """Alias for `prec()`.
5718
5719 >>> g = Goal()
5720 >>> g.precision() == Z3_GOAL_PRECISE
5721 True
5722 """
5723 return self.prec()
5724
5725 def size(self):
5726 """Return the number of constraints in the goal `self`.
5727
5728 >>> g = Goal()
5729 >>> g.size()
5730 0
5731 >>> x, y = Ints('x y')
5732 >>> g.add(x == 0, y > x)
5733 >>> g.size()
5734 2
5735 """
5736 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5737
5738 def __len__(self):
5739 """Return the number of constraints in the goal `self`.
5740
5741 >>> g = Goal()
5742 >>> len(g)
5743 0
5744 >>> x, y = Ints('x y')
5745 >>> g.add(x == 0, y > x)
5746 >>> len(g)
5747 2
5748 """
5749 return self.size()
5750
5751 def get(self, i):
5752 """Return a constraint in the goal `self`.
5753
5754 >>> g = Goal()
5755 >>> x, y = Ints('x y')
5756 >>> g.add(x == 0, y > x)
5757 >>> g.get(0)
5758 x == 0
5759 >>> g.get(1)
5760 y > x
5761 """
5762 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5763
5764 def __getitem__(self, arg):
5765 """Return a constraint in the goal `self`.
5766
5767 >>> g = Goal()
5768 >>> x, y = Ints('x y')
5769 >>> g.add(x == 0, y > x)
5770 >>> g[0]
5771 x == 0
5772 >>> g[1]
5773 y > x
5774 """
5775 if arg >= len(self):
5776 raise IndexError
5777 return self.get(arg)
5778
5779 def assert_exprs(self, *args):
5780 """Assert constraints into the goal.
5781
5782 >>> x = Int('x')
5783 >>> g = Goal()
5784 >>> g.assert_exprs(x > 0, x < 2)
5785 >>> g
5786 [x > 0, x < 2]
5787 """
5788 args = _get_args(args)
5789 s = BoolSort(self.ctx)
5790 for arg in args:
5791 arg = s.cast(arg)
5792 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5793
5794 def append(self, *args):
5795 """Add constraints.
5796
5797 >>> x = Int('x')
5798 >>> g = Goal()
5799 >>> g.append(x > 0, x < 2)
5800 >>> g
5801 [x > 0, x < 2]
5802 """
5803 self.assert_exprs(*args)
5804
5805 def insert(self, *args):
5806 """Add constraints.
5807
5808 >>> x = Int('x')
5809 >>> g = Goal()
5810 >>> g.insert(x > 0, x < 2)
5811 >>> g
5812 [x > 0, x < 2]
5813 """
5814 self.assert_exprs(*args)
5815
5816 def add(self, *args):
5817 """Add constraints.
5818
5819 >>> x = Int('x')
5820 >>> g = Goal()
5821 >>> g.add(x > 0, x < 2)
5822 >>> g
5823 [x > 0, x < 2]
5824 """
5825 self.assert_exprs(*args)
5826
5827 def convert_model(self, model):
5828 """Retrieve model from a satisfiable goal
5829 >>> a, b = Ints('a b')
5830 >>> g = Goal()
5831 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5832 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5833 >>> r = t(g)
5834 >>> r[0]
5835 [Or(b == 0, b == 1), Not(0 <= b)]
5836 >>> r[1]
5837 [Or(b == 0, b == 1), Not(1 <= b)]
5838 >>> # Remark: the subgoal r[0] is unsatisfiable
5839 >>> # Creating a solver for solving the second subgoal
5840 >>> s = Solver()
5841 >>> s.add(r[1])
5842 >>> s.check()
5843 sat
5844 >>> s.model()
5845 [b = 0]
5846 >>> # Model s.model() does not assign a value to `a`
5847 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5848 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5849 >>> r[1].convert_model(s.model())
5850 [b = 0, a = 1]
5851 """
5852 if z3_debug():
5853 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5854 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5855
5856 def __repr__(self):
5857 return obj_to_string(self)
5858
5859 def sexpr(self):
5860 """Return a textual representation of the s-expression representing the goal."""
5861 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5862
5863 def dimacs(self, include_names=True):
5864 """Return a textual representation of the goal in DIMACS format."""
5865 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5866
5867 def translate(self, target):
5868 """Copy goal `self` to context `target`.
5869
5870 >>> x = Int('x')
5871 >>> g = Goal()
5872 >>> g.add(x > 10)
5873 >>> g
5874 [x > 10]
5875 >>> c2 = Context()
5876 >>> g2 = g.translate(c2)
5877 >>> g2
5878 [x > 10]
5879 >>> g.ctx == main_ctx()
5880 True
5881 >>> g2.ctx == c2
5882 True
5883 >>> g2.ctx == main_ctx()
5884 False
5885 """
5886 if z3_debug():
5887 _z3_assert(isinstance(target, Context), "target must be a context")
5888 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5889
5890 def __copy__(self):
5891 return self.translate(self.ctx)
5892
5893 def __deepcopy__(self, memo={}):
5894 return self.translate(self.ctx)
5895
5896 def simplify(self, *arguments, **keywords):
5897 """Return a new simplified goal.
5898
5899 This method is essentially invoking the simplify tactic.
5900
5901 >>> g = Goal()
5902 >>> x = Int('x')
5903 >>> g.add(x + 1 >= 2)
5904 >>> g
5905 [x + 1 >= 2]
5906 >>> g2 = g.simplify()
5907 >>> g2
5908 [x >= 1]
5909 >>> # g was not modified
5910 >>> g
5911 [x + 1 >= 2]
5912 """
5913 t = Tactic("simplify")
5914 return t.apply(self, *arguments, **keywords)[0]
5915
5916 def as_expr(self):
5917 """Return goal `self` as a single Z3 expression.
5918
5919 >>> x = Int('x')
5920 >>> g = Goal()
5921 >>> g.as_expr()
5922 True
5923 >>> g.add(x > 1)
5924 >>> g.as_expr()
5925 x > 1
5926 >>> g.add(x < 10)
5927 >>> g.as_expr()
5928 And(x > 1, x < 10)
5929 """
5930 sz = len(self)
5931 if sz == 0:
5932 return BoolVal(True, self.ctx)
5933 elif sz == 1:
5934 return self.get(0)
5935 else:
5936 return And([self.get(i) for i in range(len(self))], self.ctx)
5937
5938
5943
5944
5946 """A collection (vector) of ASTs."""
5947
5948 def __init__(self, v=None, ctx=None):
5949 self.vector = None
5950 if v is None:
5951 self.ctx = _get_ctx(ctx)
5952 self.vector = Z3_mk_ast_vector(self.ctx.ref())
5953 else:
5954 self.vector = v
5955 assert ctx is not None
5956 self.ctx = ctx
5957 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
5958
5959 def __del__(self):
5960 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
5961 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
5962
5963 def __len__(self):
5964 """Return the size of the vector `self`.
5965
5966 >>> A = AstVector()
5967 >>> len(A)
5968 0
5969 >>> A.push(Int('x'))
5970 >>> A.push(Int('x'))
5971 >>> len(A)
5972 2
5973 """
5974 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
5975
5976 def __getitem__(self, i):
5977 """Return the AST at position `i`.
5978
5979 >>> A = AstVector()
5980 >>> A.push(Int('x') + 1)
5981 >>> A.push(Int('y'))
5982 >>> A[0]
5983 x + 1
5984 >>> A[1]
5985 y
5986 """
5987
5988 if isinstance(i, int):
5989 if i < 0:
5990 i += self.__len__()
5991
5992 if i >= self.__len__():
5993 raise IndexError
5994 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
5995
5996 elif isinstance(i, slice):
5997 result = []
5998 for ii in range(*i.indices(self.__len__())):
5999 result.append(_to_ast_ref(
6000 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6001 self.ctx,
6002 ))
6003 return result
6004
6005 def __setitem__(self, i, v):
6006 """Update AST at position `i`.
6007
6008 >>> A = AstVector()
6009 >>> A.push(Int('x') + 1)
6010 >>> A.push(Int('y'))
6011 >>> A[0]
6012 x + 1
6013 >>> A[0] = Int('x')
6014 >>> A[0]
6015 x
6016 """
6017 if i >= self.__len__():
6018 raise IndexError
6019 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6020
6021 def push(self, v):
6022 """Add `v` in the end of the vector.
6023
6024 >>> A = AstVector()
6025 >>> len(A)
6026 0
6027 >>> A.push(Int('x'))
6028 >>> len(A)
6029 1
6030 """
6031 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6032
6033 def resize(self, sz):
6034 """Resize the vector to `sz` elements.
6035
6036 >>> A = AstVector()
6037 >>> A.resize(10)
6038 >>> len(A)
6039 10
6040 >>> for i in range(10): A[i] = Int('x')
6041 >>> A[5]
6042 x
6043 """
6044 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6045
6046 def __contains__(self, item):
6047 """Return `True` if the vector contains `item`.
6048
6049 >>> x = Int('x')
6050 >>> A = AstVector()
6051 >>> x in A
6052 False
6053 >>> A.push(x)
6054 >>> x in A
6055 True
6056 >>> (x+1) in A
6057 False
6058 >>> A.push(x+1)
6059 >>> (x+1) in A
6060 True
6061 >>> A
6062 [x, x + 1]
6063 """
6064 for elem in self:
6065 if elem.eq(item):
6066 return True
6067 return False
6068
6069 def translate(self, other_ctx):
6070 """Copy vector `self` to context `other_ctx`.
6071
6072 >>> x = Int('x')
6073 >>> A = AstVector()
6074 >>> A.push(x)
6075 >>> c2 = Context()
6076 >>> B = A.translate(c2)
6077 >>> B
6078 [x]
6079 """
6080 return AstVector(
6081 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6082 ctx=other_ctx,
6083 )
6084
6085 def __copy__(self):
6086 return self.translate(self.ctx)
6087
6088 def __deepcopy__(self, memo={}):
6089 return self.translate(self.ctx)
6090
6091 def __repr__(self):
6092 return obj_to_string(self)
6093
6094 def sexpr(self):
6095 """Return a textual representation of the s-expression representing the vector."""
6096 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6097
6098
6103
6104
6106 """A mapping from ASTs to ASTs."""
6107
6108 def __init__(self, m=None, ctx=None):
6109 self.map = None
6110 if m is None:
6111 self.ctx = _get_ctx(ctx)
6112 self.map = Z3_mk_ast_map(self.ctx.ref())
6113 else:
6114 self.map = m
6115 assert ctx is not None
6116 self.ctx = ctx
6117 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6118
6119 def __deepcopy__(self, memo={}):
6120 return AstMap(self.map, self.ctx)
6121
6122 def __del__(self):
6123 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6124 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6125
6126 def __len__(self):
6127 """Return the size of the map.
6128
6129 >>> M = AstMap()
6130 >>> len(M)
6131 0
6132 >>> x = Int('x')
6133 >>> M[x] = IntVal(1)
6134 >>> len(M)
6135 1
6136 """
6137 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6138
6139 def __contains__(self, key):
6140 """Return `True` if the map contains key `key`.
6141
6142 >>> M = AstMap()
6143 >>> x = Int('x')
6144 >>> M[x] = x + 1
6145 >>> x in M
6146 True
6147 >>> x+1 in M
6148 False
6149 """
6150 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6151
6152 def __getitem__(self, key):
6153 """Retrieve the value associated with key `key`.
6154
6155 >>> M = AstMap()
6156 >>> x = Int('x')
6157 >>> M[x] = x + 1
6158 >>> M[x]
6159 x + 1
6160 """
6161 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6162
6163 def __setitem__(self, k, v):
6164 """Add/Update key `k` with value `v`.
6165
6166 >>> M = AstMap()
6167 >>> x = Int('x')
6168 >>> M[x] = x + 1
6169 >>> len(M)
6170 1
6171 >>> M[x]
6172 x + 1
6173 >>> M[x] = IntVal(1)
6174 >>> M[x]
6175 1
6176 """
6177 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6178
6179 def __repr__(self):
6180 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6181
6182 def erase(self, k):
6183 """Remove the entry associated with key `k`.
6184
6185 >>> M = AstMap()
6186 >>> x = Int('x')
6187 >>> M[x] = x + 1
6188 >>> len(M)
6189 1
6190 >>> M.erase(x)
6191 >>> len(M)
6192 0
6193 """
6194 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6195
6196 def reset(self):
6197 """Remove all entries from the map.
6198
6199 >>> M = AstMap()
6200 >>> x = Int('x')
6201 >>> M[x] = x + 1
6202 >>> M[x+x] = IntVal(1)
6203 >>> len(M)
6204 2
6205 >>> M.reset()
6206 >>> len(M)
6207 0
6208 """
6209 Z3_ast_map_reset(self.ctx.ref(), self.map)
6210
6211 def keys(self):
6212 """Return an AstVector containing all keys in the map.
6213
6214 >>> M = AstMap()
6215 >>> x = Int('x')
6216 >>> M[x] = x + 1
6217 >>> M[x+x] = IntVal(1)
6218 >>> M.keys()
6219 [x, x + x]
6220 """
6221 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6222
6223
6228
6229
6231 """Store the value of the interpretation of a function in a particular point."""
6232
6233 def __init__(self, entry, ctx):
6234 self.entry = entry
6235 self.ctx = ctx
6236 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6237
6238 def __deepcopy__(self, memo={}):
6239 return FuncEntry(self.entry, self.ctx)
6240
6241 def __del__(self):
6242 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6243 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6244
6245 def num_args(self):
6246 """Return the number of arguments in the given entry.
6247
6248 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6249 >>> s = Solver()
6250 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6251 >>> s.check()
6252 sat
6253 >>> m = s.model()
6254 >>> f_i = m[f]
6255 >>> f_i.num_entries()
6256 1
6257 >>> e = f_i.entry(0)
6258 >>> e.num_args()
6259 2
6260 """
6261 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6262
6263 def arg_value(self, idx):
6264 """Return the value of argument `idx`.
6265
6266 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6267 >>> s = Solver()
6268 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6269 >>> s.check()
6270 sat
6271 >>> m = s.model()
6272 >>> f_i = m[f]
6273 >>> f_i.num_entries()
6274 1
6275 >>> e = f_i.entry(0)
6276 >>> e
6277 [1, 2, 20]
6278 >>> e.num_args()
6279 2
6280 >>> e.arg_value(0)
6281 1
6282 >>> e.arg_value(1)
6283 2
6284 >>> try:
6285 ... e.arg_value(2)
6286 ... except IndexError:
6287 ... print("index error")
6288 index error
6289 """
6290 if idx >= self.num_args():
6291 raise IndexError
6292 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6293
6294 def value(self):
6295 """Return the value of the function at point `self`.
6296
6297 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6298 >>> s = Solver()
6299 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6300 >>> s.check()
6301 sat
6302 >>> m = s.model()
6303 >>> f_i = m[f]
6304 >>> f_i.num_entries()
6305 1
6306 >>> e = f_i.entry(0)
6307 >>> e
6308 [1, 2, 20]
6309 >>> e.num_args()
6310 2
6311 >>> e.value()
6312 20
6313 """
6314 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6315
6316 def as_list(self):
6317 """Return entry `self` as a Python list.
6318 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6319 >>> s = Solver()
6320 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6321 >>> s.check()
6322 sat
6323 >>> m = s.model()
6324 >>> f_i = m[f]
6325 >>> f_i.num_entries()
6326 1
6327 >>> e = f_i.entry(0)
6328 >>> e.as_list()
6329 [1, 2, 20]
6330 """
6331 args = [self.arg_value(i) for i in range(self.num_args())]
6332 args.append(self.value())
6333 return args
6334
6335 def __repr__(self):
6336 return repr(self.as_list())
6337
6338
6340 """Stores the interpretation of a function in a Z3 model."""
6341
6342 def __init__(self, f, ctx):
6343 self.f = f
6344 self.ctx = ctx
6345 if self.f is not None:
6346 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6347
6348 def __del__(self):
6349 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6350 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6351
6352 def else_value(self):
6353 """
6354 Return the `else` value for a function interpretation.
6355 Return None if Z3 did not specify the `else` value for
6356 this object.
6357
6358 >>> f = Function('f', IntSort(), IntSort())
6359 >>> s = Solver()
6360 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6361 >>> s.check()
6362 sat
6363 >>> m = s.model()
6364 >>> m[f]
6365 [2 -> 0, else -> 1]
6366 >>> m[f].else_value()
6367 1
6368 """
6369 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6370 if r:
6371 return _to_expr_ref(r, self.ctx)
6372 else:
6373 return None
6374
6375 def num_entries(self):
6376 """Return the number of entries/points in the function interpretation `self`.
6377
6378 >>> f = Function('f', IntSort(), IntSort())
6379 >>> s = Solver()
6380 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6381 >>> s.check()
6382 sat
6383 >>> m = s.model()
6384 >>> m[f]
6385 [2 -> 0, else -> 1]
6386 >>> m[f].num_entries()
6387 1
6388 """
6389 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6390
6391 def arity(self):
6392 """Return the number of arguments for each entry in the function interpretation `self`.
6393
6394 >>> f = Function('f', IntSort(), IntSort())
6395 >>> s = Solver()
6396 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6397 >>> s.check()
6398 sat
6399 >>> m = s.model()
6400 >>> m[f].arity()
6401 1
6402 """
6403 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6404
6405 def entry(self, idx):
6406 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6407
6408 >>> f = Function('f', IntSort(), IntSort())
6409 >>> s = Solver()
6410 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6411 >>> s.check()
6412 sat
6413 >>> m = s.model()
6414 >>> m[f]
6415 [2 -> 0, else -> 1]
6416 >>> m[f].num_entries()
6417 1
6418 >>> m[f].entry(0)
6419 [2, 0]
6420 """
6421 if idx >= self.num_entries():
6422 raise IndexError
6423 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6424
6425 def translate(self, other_ctx):
6426 """Copy model 'self' to context 'other_ctx'.
6427 """
6428 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6429
6430 def __copy__(self):
6431 return self.translate(self.ctx)
6432
6433 def __deepcopy__(self, memo={}):
6434 return self.translate(self.ctx)
6435
6436 def as_list(self):
6437 """Return the function interpretation as a Python list.
6438 >>> f = Function('f', IntSort(), IntSort())
6439 >>> s = Solver()
6440 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6441 >>> s.check()
6442 sat
6443 >>> m = s.model()
6444 >>> m[f]
6445 [2 -> 0, else -> 1]
6446 >>> m[f].as_list()
6447 [[2, 0], 1]
6448 """
6449 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6450 r.append(self.else_value())
6451 return r
6452
6453 def __repr__(self):
6454 return obj_to_string(self)
6455
6456
6458 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6459
6460 def __init__(self, m, ctx):
6461 assert ctx is not None
6462 self.model = m
6463 self.ctx = ctx
6464 Z3_model_inc_ref(self.ctx.ref(), self.model)
6465
6466 def __del__(self):
6467 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6468 Z3_model_dec_ref(self.ctx.ref(), self.model)
6469
6470 def __repr__(self):
6471 return obj_to_string(self)
6472
6473 def sexpr(self):
6474 """Return a textual representation of the s-expression representing the model."""
6475 return Z3_model_to_string(self.ctx.ref(), self.model)
6476
6477 def eval(self, t, model_completion=False):
6478 """Evaluate the expression `t` in the model `self`.
6479 If `model_completion` is enabled, then a default interpretation is automatically added
6480 for symbols that do not have an interpretation in the model `self`.
6481
6482 >>> x = Int('x')
6483 >>> s = Solver()
6484 >>> s.add(x > 0, x < 2)
6485 >>> s.check()
6486 sat
6487 >>> m = s.model()
6488 >>> m.eval(x + 1)
6489 2
6490 >>> m.eval(x == 1)
6491 True
6492 >>> y = Int('y')
6493 >>> m.eval(y + x)
6494 1 + y
6495 >>> m.eval(y)
6496 y
6497 >>> m.eval(y, model_completion=True)
6498 0
6499 >>> # Now, m contains an interpretation for y
6500 >>> m.eval(y + x)
6501 1
6502 """
6503 r = (Ast * 1)()
6504 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6505 return _to_expr_ref(r[0], self.ctx)
6506 raise Z3Exception("failed to evaluate expression in the model")
6507
6508 def evaluate(self, t, model_completion=False):
6509 """Alias for `eval`.
6510
6511 >>> x = Int('x')
6512 >>> s = Solver()
6513 >>> s.add(x > 0, x < 2)
6514 >>> s.check()
6515 sat
6516 >>> m = s.model()
6517 >>> m.evaluate(x + 1)
6518 2
6519 >>> m.evaluate(x == 1)
6520 True
6521 >>> y = Int('y')
6522 >>> m.evaluate(y + x)
6523 1 + y
6524 >>> m.evaluate(y)
6525 y
6526 >>> m.evaluate(y, model_completion=True)
6527 0
6528 >>> # Now, m contains an interpretation for y
6529 >>> m.evaluate(y + x)
6530 1
6531 """
6532 return self.eval(t, model_completion)
6533
6534 def __len__(self):
6535 """Return the number of constant and function declarations in the model `self`.
6536
6537 >>> f = Function('f', IntSort(), IntSort())
6538 >>> x = Int('x')
6539 >>> s = Solver()
6540 >>> s.add(x > 0, f(x) != x)
6541 >>> s.check()
6542 sat
6543 >>> m = s.model()
6544 >>> len(m)
6545 2
6546 """
6547 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6548 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6549 return num_consts + num_funcs
6550
6551 def get_interp(self, decl):
6552 """Return the interpretation for a given declaration or constant.
6553
6554 >>> f = Function('f', IntSort(), IntSort())
6555 >>> x = Int('x')
6556 >>> s = Solver()
6557 >>> s.add(x > 0, x < 2, f(x) == 0)
6558 >>> s.check()
6559 sat
6560 >>> m = s.model()
6561 >>> m[x]
6562 1
6563 >>> m[f]
6564 [else -> 0]
6565 """
6566 if z3_debug():
6567 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6568 if is_const(decl):
6569 decl = decl.decl()
6570 try:
6571 if decl.arity() == 0:
6572 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6573 if _r.value is None:
6574 return None
6575 r = _to_expr_ref(_r, self.ctx)
6576 if is_as_array(r):
6577 fi = self.get_interp(get_as_array_func(r))
6578 if fi is None:
6579 return fi
6580 e = fi.else_value()
6581 if e is None:
6582 return fi
6583 if fi.arity() != 1:
6584 return fi
6585 srt = decl.range()
6586 dom = srt.domain()
6587 e = K(dom, e)
6588 i = 0
6589 sz = fi.num_entries()
6590 n = fi.arity()
6591 while i < sz:
6592 fe = fi.entry(i)
6593 e = Store(e, fe.arg_value(0), fe.value())
6594 i += 1
6595 return e
6596 else:
6597 return r
6598 else:
6599 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6600 except Z3Exception:
6601 return None
6602
6603 def num_sorts(self):
6604 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6605
6606 >>> A = DeclareSort('A')
6607 >>> a, b = Consts('a b', A)
6608 >>> s = Solver()
6609 >>> s.add(a != b)
6610 >>> s.check()
6611 sat
6612 >>> m = s.model()
6613 >>> m.num_sorts()
6614 1
6615 """
6616 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6617
6618 def get_sort(self, idx):
6619 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6620
6621 >>> A = DeclareSort('A')
6622 >>> B = DeclareSort('B')
6623 >>> a1, a2 = Consts('a1 a2', A)
6624 >>> b1, b2 = Consts('b1 b2', B)
6625 >>> s = Solver()
6626 >>> s.add(a1 != a2, b1 != b2)
6627 >>> s.check()
6628 sat
6629 >>> m = s.model()
6630 >>> m.num_sorts()
6631 2
6632 >>> m.get_sort(0)
6633 A
6634 >>> m.get_sort(1)
6635 B
6636 """
6637 if idx >= self.num_sorts():
6638 raise IndexError
6639 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6640
6641 def sorts(self):
6642 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6643
6644 >>> A = DeclareSort('A')
6645 >>> B = DeclareSort('B')
6646 >>> a1, a2 = Consts('a1 a2', A)
6647 >>> b1, b2 = Consts('b1 b2', B)
6648 >>> s = Solver()
6649 >>> s.add(a1 != a2, b1 != b2)
6650 >>> s.check()
6651 sat
6652 >>> m = s.model()
6653 >>> m.sorts()
6654 [A, B]
6655 """
6656 return [self.get_sort(i) for i in range(self.num_sorts())]
6657
6658 def get_universe(self, s):
6659 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6660
6661 >>> A = DeclareSort('A')
6662 >>> a, b = Consts('a b', A)
6663 >>> s = Solver()
6664 >>> s.add(a != b)
6665 >>> s.check()
6666 sat
6667 >>> m = s.model()
6668 >>> m.get_universe(A)
6669 [A!val!1, A!val!0]
6670 """
6671 if z3_debug():
6672 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6673 try:
6674 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6675 except Z3Exception:
6676 return None
6677
6678 def __getitem__(self, idx):
6679 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6680 If `idx` is a declaration, then the actual interpretation is returned.
6681
6682 The elements can be retrieved using position or the actual declaration.
6683
6684 >>> f = Function('f', IntSort(), IntSort())
6685 >>> x = Int('x')
6686 >>> s = Solver()
6687 >>> s.add(x > 0, x < 2, f(x) == 0)
6688 >>> s.check()
6689 sat
6690 >>> m = s.model()
6691 >>> len(m)
6692 2
6693 >>> m[0]
6694 x
6695 >>> m[1]
6696 f
6697 >>> m[x]
6698 1
6699 >>> m[f]
6700 [else -> 0]
6701 >>> for d in m: print("%s -> %s" % (d, m[d]))
6702 x -> 1
6703 f -> [else -> 0]
6704 """
6705 if _is_int(idx):
6706 if idx >= len(self):
6707 raise IndexError
6708 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6709 if (idx < num_consts):
6710 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6711 else:
6712 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6713 if isinstance(idx, FuncDeclRef):
6714 return self.get_interp(idx)
6715 if is_const(idx):
6716 return self.get_interp(idx.decl())
6717 if isinstance(idx, SortRef):
6718 return self.get_universe(idx)
6719 if z3_debug():
6720 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6721 return None
6722
6723 def decls(self):
6724 """Return a list with all symbols that have an interpretation in the model `self`.
6725 >>> f = Function('f', IntSort(), IntSort())
6726 >>> x = Int('x')
6727 >>> s = Solver()
6728 >>> s.add(x > 0, x < 2, f(x) == 0)
6729 >>> s.check()
6730 sat
6731 >>> m = s.model()
6732 >>> m.decls()
6733 [x, f]
6734 """
6735 r = []
6736 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6737 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6738 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6739 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6740 return r
6741
6742 def update_value(self, x, value):
6743 """Update the interpretation of a constant"""
6744 if is_expr(x):
6745 x = x.decl()
6746 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6747 fi1 = value.f
6748 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6749 fi2 = FuncInterp(fi2, x.ctx)
6750 for i in range(value.num_entries()):
6751 e = value.entry(i)
6752 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6753 v = AstVector()
6754 for j in range(n):
6755 v.push(e.arg_value(j))
6756 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6757 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6758 return
6759 if not is_func_decl(x) or x.arity() != 0:
6760 raise Z3Exception("Expecting 0-ary function or constant expression")
6761 value = _py2expr(value)
6762 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6763
6764 def translate(self, target):
6765 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6766 """
6767 if z3_debug():
6768 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6769 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6770 return ModelRef(model, target)
6771
6772 def project(self, vars, fml):
6773 """Perform model-based projection on fml with respect to vars.
6774 Assume that the model satisfies fml. Then compute a projection fml_p, such
6775 that vars do not occur free in fml_p, fml_p is true in the model and
6776 fml_p => exists vars . fml
6777 """
6778 ctx = self.ctx.ref()
6779 _vars = (Ast * len(vars))()
6780 for i in range(len(vars)):
6781 _vars[i] = vars[i].as_ast()
6782 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6783
6784 def project_with_witness(self, vars, fml):
6785 """Perform model-based projection, but also include realizer terms for the projected variables"""
6786 ctx = self.ctx.ref()
6787 _vars = (Ast * len(vars))()
6788 for i in range(len(vars)):
6789 _vars[i] = vars[i].as_ast()
6790 defs = AstMap()
6791 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6792 result = _to_expr_ref(result, self.ctx)
6793 return result, defs
6794
6795
6796 def __copy__(self):
6797 return self.translate(self.ctx)
6798
6799 def __deepcopy__(self, memo={}):
6800 return self.translate(self.ctx)
6801
6802
6803def Model(ctx=None, eval = {}):
6804 ctx = _get_ctx(ctx)
6805 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6806 for k, v in eval.items():
6807 mdl.update_value(k, v)
6808 return mdl
6809
6810
6812 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6813 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6814
6815
6817 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6818 if z3_debug():
6819 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6820 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6821
6822
6827
6828
6830 """Statistics for `Solver.check()`."""
6831
6832 def __init__(self, stats, ctx):
6833 self.stats = stats
6834 self.ctx = ctx
6835 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6836
6837 def __deepcopy__(self, memo={}):
6838 return Statistics(self.stats, self.ctx)
6839
6840 def __del__(self):
6841 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6842 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6843
6844 def __repr__(self):
6845 if in_html_mode():
6846 out = io.StringIO()
6847 even = True
6848 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6849 for k, v in self:
6850 if even:
6851 out.write(u('<tr style="background-color:#CFCFCF">'))
6852 even = False
6853 else:
6854 out.write(u("<tr>"))
6855 even = True
6856 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6857 out.write(u("</table>"))
6858 return out.getvalue()
6859 else:
6860 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6861
6862 def __len__(self):
6863 """Return the number of statistical counters.
6864
6865 >>> x = Int('x')
6866 >>> s = Then('simplify', 'nlsat').solver()
6867 >>> s.add(x > 0)
6868 >>> s.check()
6869 sat
6870 >>> st = s.statistics()
6871 >>> len(st)
6872 7
6873 """
6874 return int(Z3_stats_size(self.ctx.ref(), self.stats))
6875
6876 def __getitem__(self, idx):
6877 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6878
6879 >>> x = Int('x')
6880 >>> s = Then('simplify', 'nlsat').solver()
6881 >>> s.add(x > 0)
6882 >>> s.check()
6883 sat
6884 >>> st = s.statistics()
6885 >>> len(st)
6886 7
6887 >>> st[0]
6888 ('nlsat propagations', 2)
6889 >>> st[1]
6890 ('nlsat restarts', 1)
6891 """
6892 if idx >= len(self):
6893 raise IndexError
6894 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6895 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6896 else:
6897 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6898 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
6899
6900 def keys(self):
6901 """Return the list of statistical counters.
6902
6903 >>> x = Int('x')
6904 >>> s = Then('simplify', 'nlsat').solver()
6905 >>> s.add(x > 0)
6906 >>> s.check()
6907 sat
6908 >>> st = s.statistics()
6909 """
6910 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
6911
6912 def get_key_value(self, key):
6913 """Return the value of a particular statistical counter.
6914
6915 >>> x = Int('x')
6916 >>> s = Then('simplify', 'nlsat').solver()
6917 >>> s.add(x > 0)
6918 >>> s.check()
6919 sat
6920 >>> st = s.statistics()
6921 >>> st.get_key_value('nlsat propagations')
6922 2
6923 """
6924 for idx in range(len(self)):
6925 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
6926 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6927 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6928 else:
6929 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6930 raise Z3Exception("unknown key")
6931
6932 def __getattr__(self, name):
6933 """Access the value of statistical using attributes.
6934
6935 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
6936 we should use '_' (e.g., 'nlsat_propagations').
6937
6938 >>> x = Int('x')
6939 >>> s = Then('simplify', 'nlsat').solver()
6940 >>> s.add(x > 0)
6941 >>> s.check()
6942 sat
6943 >>> st = s.statistics()
6944 >>> st.nlsat_propagations
6945 2
6946 >>> st.nlsat_stages
6947 2
6948 """
6949 key = name.replace("_", " ")
6950 try:
6951 return self.get_key_value(key)
6952 except Z3Exception:
6953 raise AttributeError
6954
6955
6960
6961
6963 """Represents the result of a satisfiability check: sat, unsat, unknown.
6964
6965 >>> s = Solver()
6966 >>> s.check()
6967 sat
6968 >>> r = s.check()
6969 >>> isinstance(r, CheckSatResult)
6970 True
6971 """
6972
6973 def __init__(self, r):
6974 self.r = r
6975
6976 def __deepcopy__(self, memo={}):
6977 return CheckSatResult(self.r)
6978
6979 def __eq__(self, other):
6980 return isinstance(other, CheckSatResult) and self.r == other.r
6981
6982 def __ne__(self, other):
6983 return not self.__eq__(other)
6984
6985 def __repr__(self):
6986 if in_html_mode():
6987 if self.r == Z3_L_TRUE:
6988 return "<b>sat</b>"
6989 elif self.r == Z3_L_FALSE:
6990 return "<b>unsat</b>"
6991 else:
6992 return "<b>unknown</b>"
6993 else:
6994 if self.r == Z3_L_TRUE:
6995 return "sat"
6996 elif self.r == Z3_L_FALSE:
6997 return "unsat"
6998 else:
6999 return "unknown"
7000
7001 def _repr_html_(self):
7002 in_html = in_html_mode()
7003 set_html_mode(True)
7004 res = repr(self)
7005 set_html_mode(in_html)
7006 return res
7007
7008
7009sat = CheckSatResult(Z3_L_TRUE)
7010unsat = CheckSatResult(Z3_L_FALSE)
7011unknown = CheckSatResult(Z3_L_UNDEF)
7012
7013
7015 """
7016 Solver API provides methods for implementing the main SMT 2.0 commands:
7017 push, pop, check, get-model, etc.
7018 """
7019
7020 def __init__(self, solver=None, ctx=None, logFile=None):
7021 assert solver is None or ctx is not None
7022 self.ctx = _get_ctx(ctx)
7023 self.backtrack_level = 4000000000
7024 self.solver = None
7025 if solver is None:
7026 self.solver = Z3_mk_solver(self.ctx.ref())
7027 else:
7028 self.solver = solver
7029 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7030 if logFile is not None:
7031 self.set("smtlib2_log", logFile)
7032
7033 def __del__(self):
7034 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7035 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7036
7037 def __enter__(self):
7038 self.push()
7039 return self
7040
7041 def __exit__(self, *exc_info):
7042 self.pop()
7043
7044 def set(self, *args, **keys):
7045 """Set a configuration option.
7046 The method `help()` return a string containing all available options.
7047
7048 >>> s = Solver()
7049 >>> # The option MBQI can be set using three different approaches.
7050 >>> s.set(mbqi=True)
7051 >>> s.set('MBQI', True)
7052 >>> s.set(':mbqi', True)
7053 """
7054 p = args2params(args, keys, self.ctx)
7055 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7056
7057 def push(self):
7058 """Create a backtracking point.
7059
7060 >>> x = Int('x')
7061 >>> s = Solver()
7062 >>> s.add(x > 0)
7063 >>> s
7064 [x > 0]
7065 >>> s.push()
7066 >>> s.add(x < 1)
7067 >>> s
7068 [x > 0, x < 1]
7069 >>> s.check()
7070 unsat
7071 >>> s.pop()
7072 >>> s.check()
7073 sat
7074 >>> s
7075 [x > 0]
7076 """
7077 Z3_solver_push(self.ctx.ref(), self.solver)
7078
7079 def pop(self, num=1):
7080 """Backtrack \\c num backtracking points.
7081
7082 >>> x = Int('x')
7083 >>> s = Solver()
7084 >>> s.add(x > 0)
7085 >>> s
7086 [x > 0]
7087 >>> s.push()
7088 >>> s.add(x < 1)
7089 >>> s
7090 [x > 0, x < 1]
7091 >>> s.check()
7092 unsat
7093 >>> s.pop()
7094 >>> s.check()
7095 sat
7096 >>> s
7097 [x > 0]
7098 """
7099 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7100
7101 def num_scopes(self):
7102 """Return the current number of backtracking points.
7103
7104 >>> s = Solver()
7105 >>> s.num_scopes()
7106 0
7107 >>> s.push()
7108 >>> s.num_scopes()
7109 1
7110 >>> s.push()
7111 >>> s.num_scopes()
7112 2
7113 >>> s.pop()
7114 >>> s.num_scopes()
7115 1
7116 """
7117 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7118
7119 def reset(self):
7120 """Remove all asserted constraints and backtracking points created using `push()`.
7121
7122 >>> x = Int('x')
7123 >>> s = Solver()
7124 >>> s.add(x > 0)
7125 >>> s
7126 [x > 0]
7127 >>> s.reset()
7128 >>> s
7129 []
7130 """
7131 Z3_solver_reset(self.ctx.ref(), self.solver)
7132
7133 def assert_exprs(self, *args):
7134 """Assert constraints into the solver.
7135
7136 >>> x = Int('x')
7137 >>> s = Solver()
7138 >>> s.assert_exprs(x > 0, x < 2)
7139 >>> s
7140 [x > 0, x < 2]
7141 """
7142 args = _get_args(args)
7143 s = BoolSort(self.ctx)
7144 for arg in args:
7145 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7146 for f in arg:
7147 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7148 else:
7149 arg = s.cast(arg)
7150 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7151
7152 def add(self, *args):
7153 """Assert constraints into the solver.
7154
7155 >>> x = Int('x')
7156 >>> s = Solver()
7157 >>> s.add(x > 0, x < 2)
7158 >>> s
7159 [x > 0, x < 2]
7160 """
7161 self.assert_exprs(*args)
7162
7163 def __iadd__(self, fml):
7164 self.add(fml)
7165 return self
7166
7167 def append(self, *args):
7168 """Assert constraints into the solver.
7169
7170 >>> x = Int('x')
7171 >>> s = Solver()
7172 >>> s.append(x > 0, x < 2)
7173 >>> s
7174 [x > 0, x < 2]
7175 """
7176 self.assert_exprs(*args)
7177
7178 def insert(self, *args):
7179 """Assert constraints into the solver.
7180
7181 >>> x = Int('x')
7182 >>> s = Solver()
7183 >>> s.insert(x > 0, x < 2)
7184 >>> s
7185 [x > 0, x < 2]
7186 """
7187 self.assert_exprs(*args)
7188
7189 def assert_and_track(self, a, p):
7190 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7191
7192 If `p` is a string, it will be automatically converted into a Boolean constant.
7193
7194 >>> x = Int('x')
7195 >>> p3 = Bool('p3')
7196 >>> s = Solver()
7197 >>> s.set(unsat_core=True)
7198 >>> s.assert_and_track(x > 0, 'p1')
7199 >>> s.assert_and_track(x != 1, 'p2')
7200 >>> s.assert_and_track(x < 0, p3)
7201 >>> print(s.check())
7202 unsat
7203 >>> c = s.unsat_core()
7204 >>> len(c)
7205 2
7206 >>> Bool('p1') in c
7207 True
7208 >>> Bool('p2') in c
7209 False
7210 >>> p3 in c
7211 True
7212 """
7213 if isinstance(p, str):
7214 p = Bool(p, self.ctx)
7215 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7216 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7217 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7218
7219 def check(self, *assumptions):
7220 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7221
7222 >>> x = Int('x')
7223 >>> s = Solver()
7224 >>> s.check()
7225 sat
7226 >>> s.add(x > 0, x < 2)
7227 >>> s.check()
7228 sat
7229 >>> s.model().eval(x)
7230 1
7231 >>> s.add(x < 1)
7232 >>> s.check()
7233 unsat
7234 >>> s.reset()
7235 >>> s.add(2**x == 4)
7236 >>> s.check()
7237 unknown
7238 """
7239 s = BoolSort(self.ctx)
7240 assumptions = _get_args(assumptions)
7241 num = len(assumptions)
7242 _assumptions = (Ast * num)()
7243 for i in range(num):
7244 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7245 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7246 return CheckSatResult(r)
7247
7248 def model(self):
7249 """Return a model for the last `check()`.
7250
7251 This function raises an exception if
7252 a model is not available (e.g., last `check()` returned unsat).
7253
7254 >>> s = Solver()
7255 >>> a = Int('a')
7256 >>> s.add(a + 2 == 0)
7257 >>> s.check()
7258 sat
7259 >>> s.model()
7260 [a = -2]
7261 """
7262 try:
7263 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7264 except Z3Exception:
7265 raise Z3Exception("model is not available")
7266
7267 def import_model_converter(self, other):
7268 """Import model converter from other into the current solver"""
7269 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7270
7271 def interrupt(self):
7272 """Interrupt the execution of the solver object.
7273 Remarks: This ensures that the interrupt applies only
7274 to the given solver object and it applies only if it is running.
7275 """
7276 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7277
7278 def unsat_core(self):
7279 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7280
7281 These are the assumptions Z3 used in the unsatisfiability proof.
7282 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7283 They may be also used to "retract" assumptions. Note that, assumptions are not really
7284 "soft constraints", but they can be used to implement them.
7285
7286 >>> p1, p2, p3 = Bools('p1 p2 p3')
7287 >>> x, y = Ints('x y')
7288 >>> s = Solver()
7289 >>> s.add(Implies(p1, x > 0))
7290 >>> s.add(Implies(p2, y > x))
7291 >>> s.add(Implies(p2, y < 1))
7292 >>> s.add(Implies(p3, y > -3))
7293 >>> s.check(p1, p2, p3)
7294 unsat
7295 >>> core = s.unsat_core()
7296 >>> len(core)
7297 2
7298 >>> p1 in core
7299 True
7300 >>> p2 in core
7301 True
7302 >>> p3 in core
7303 False
7304 >>> # "Retracting" p2
7305 >>> s.check(p1, p3)
7306 sat
7307 """
7308 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7309
7310 def consequences(self, assumptions, variables):
7311 """Determine fixed values for the variables based on the solver state and assumptions.
7312 >>> s = Solver()
7313 >>> a, b, c, d = Bools('a b c d')
7314 >>> s.add(Implies(a,b), Implies(b, c))
7315 >>> s.consequences([a],[b,c,d])
7316 (sat, [Implies(a, b), Implies(a, c)])
7317 >>> s.consequences([Not(c),d],[a,b,c,d])
7318 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7319 """
7320 if isinstance(assumptions, list):
7321 _asms = AstVector(None, self.ctx)
7322 for a in assumptions:
7323 _asms.push(a)
7324 assumptions = _asms
7325 if isinstance(variables, list):
7326 _vars = AstVector(None, self.ctx)
7327 for a in variables:
7328 _vars.push(a)
7329 variables = _vars
7330 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7331 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7332 consequences = AstVector(None, self.ctx)
7333 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7334 variables.vector, consequences.vector)
7335 sz = len(consequences)
7336 consequences = [consequences[i] for i in range(sz)]
7337 return CheckSatResult(r), consequences
7338
7339 def from_file(self, filename):
7340 """Parse assertions from a file"""
7341 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7342
7343 def from_string(self, s):
7344 """Parse assertions from a string"""
7345 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7346
7347 def cube(self, vars=None):
7348 """Get set of cubes
7349 The method takes an optional set of variables that restrict which
7350 variables may be used as a starting point for cubing.
7351 If vars is not None, then the first case split is based on a variable in
7352 this set.
7353 """
7354 self.cube_vs = AstVector(None, self.ctx)
7355 if vars is not None:
7356 for v in vars:
7357 self.cube_vs.push(v)
7358 while True:
7359 lvl = self.backtrack_level
7360 self.backtrack_level = 4000000000
7361 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7362 if (len(r) == 1 and is_false(r[0])):
7363 return
7364 yield r
7365 if (len(r) == 0):
7366 return
7367
7368 def cube_vars(self):
7369 """Access the set of variables that were touched by the most recently generated cube.
7370 This set of variables can be used as a starting point for additional cubes.
7371 The idea is that variables that appear in clauses that are reduced by the most recent
7372 cube are likely more useful to cube on."""
7373 return self.cube_vs
7374
7375 def root(self, t):
7376 """Retrieve congruence closure root of the term t relative to the current search state
7377 The function primarily works for SimpleSolver. Terms and variables that are
7378 eliminated during pre-processing are not visible to the congruence closure.
7379 """
7380 t = _py2expr(t, self.ctx)
7381 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7382
7383 def next(self, t):
7384 """Retrieve congruence closure sibling of the term t relative to the current search state
7385 The function primarily works for SimpleSolver. Terms and variables that are
7386 eliminated during pre-processing are not visible to the congruence closure.
7387 """
7388 t = _py2expr(t, self.ctx)
7389 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7390
7391 def explain_congruent(self, a, b):
7392 """Explain congruence of a and b relative to the current search state"""
7393 a = _py2expr(a, self.ctx)
7394 b = _py2expr(b, self.ctx)
7395 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7396
7397 def solve_for1(self, t):
7398 """Retrieve a solution for t relative to linear equations maintained in the current state.
7399 The function primarily works for SimpleSolver and when there is a solution using linear arithmetic."""
7400 t = _py2expr(t, self.ctx)
7401 return _to_expr_ref(Z3_solver_solve_for1(self.ctx.ref(), self.solver, t.ast), self.ctx)
7402
7403 def solve_for(self, ts):
7404 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7405 vars = AstVector(ctx=self.ctx);
7406 terms = AstVector(ctx=self.ctx);
7407 guards = AstVector(ctx=self.ctx);
7408 for t in ts:
7409 t = _py2expr(t, self.ctx)
7410 vars.push(t)
7411 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7412 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7413
7414
7415 def proof(self):
7416 """Return a proof for the last `check()`. Proof construction must be enabled."""
7417 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7418
7419 def assertions(self):
7420 """Return an AST vector containing all added constraints.
7421
7422 >>> s = Solver()
7423 >>> s.assertions()
7424 []
7425 >>> a = Int('a')
7426 >>> s.add(a > 0)
7427 >>> s.add(a < 10)
7428 >>> s.assertions()
7429 [a > 0, a < 10]
7430 """
7431 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7432
7433 def units(self):
7434 """Return an AST vector containing all currently inferred units.
7435 """
7436 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7437
7438 def non_units(self):
7439 """Return an AST vector containing all atomic formulas in solver state that are not units.
7440 """
7441 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7442
7443 def trail_levels(self):
7444 """Return trail and decision levels of the solver state after a check() call.
7445 """
7446 trail = self.trail()
7447 levels = (ctypes.c_uint * len(trail))()
7448 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7449 return trail, levels
7450
7451 def set_initial_value(self, var, value):
7452 """initialize the solver's state by setting the initial value of var to value
7453 """
7454 s = var.sort()
7455 value = s.cast(value)
7456 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7457
7458 def trail(self):
7459 """Return trail of the solver state after a check() call.
7460 """
7461 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7462
7463 def statistics(self):
7464 """Return statistics for the last `check()`.
7465
7466 >>> s = SimpleSolver()
7467 >>> x = Int('x')
7468 >>> s.add(x > 0)
7469 >>> s.check()
7470 sat
7471 >>> st = s.statistics()
7472 >>> st.get_key_value('final checks')
7473 1
7474 >>> len(st) > 0
7475 True
7476 >>> st[0] != 0
7477 True
7478 """
7479 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7480
7481 def reason_unknown(self):
7482 """Return a string describing why the last `check()` returned `unknown`.
7483
7484 >>> x = Int('x')
7485 >>> s = SimpleSolver()
7486 >>> s.add(2**x == 4)
7487 >>> s.check()
7488 unknown
7489 >>> s.reason_unknown()
7490 '(incomplete (theory arithmetic))'
7491 """
7492 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7493
7494 def help(self):
7495 """Display a string describing all available options."""
7496 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7497
7498 def param_descrs(self):
7499 """Return the parameter description set."""
7500 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7501
7502 def __repr__(self):
7503 """Return a formatted string with all added constraints."""
7504 return obj_to_string(self)
7505
7506 def translate(self, target):
7507 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7508
7509 >>> c1 = Context()
7510 >>> c2 = Context()
7511 >>> s1 = Solver(ctx=c1)
7512 >>> s2 = s1.translate(c2)
7513 """
7514 if z3_debug():
7515 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7516 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7517 return Solver(solver, target)
7518
7519 def __copy__(self):
7520 return self.translate(self.ctx)
7521
7522 def __deepcopy__(self, memo={}):
7523 return self.translate(self.ctx)
7524
7525 def sexpr(self):
7526 """Return a formatted string (in Lisp-like format) with all added constraints.
7527 We say the string is in s-expression format.
7528
7529 >>> x = Int('x')
7530 >>> s = Solver()
7531 >>> s.add(x > 0)
7532 >>> s.add(x < 2)
7533 >>> r = s.sexpr()
7534 """
7535 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7536
7537 def dimacs(self, include_names=True):
7538 """Return a textual representation of the solver in DIMACS format."""
7539 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7540
7541 def to_smt2(self):
7542 """return SMTLIB2 formatted benchmark for solver's assertions"""
7543 es = self.assertions()
7544 sz = len(es)
7545 sz1 = sz
7546 if sz1 > 0:
7547 sz1 -= 1
7548 v = (Ast * sz1)()
7549 for i in range(sz1):
7550 v[i] = es[i].as_ast()
7551 if sz > 0:
7552 e = es[sz1].as_ast()
7553 else:
7554 e = BoolVal(True, self.ctx).as_ast()
7555 return Z3_benchmark_to_smtlib_string(
7556 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7557 )
7558
7559
7560def SolverFor(logic, ctx=None, logFile=None):
7561 """Create a solver customized for the given logic.
7562
7563 The parameter `logic` is a string. It should be contains
7564 the name of a SMT-LIB logic.
7565 See http://www.smtlib.org/ for the name of all available logics.
7566
7567 >>> s = SolverFor("QF_LIA")
7568 >>> x = Int('x')
7569 >>> s.add(x > 0)
7570 >>> s.add(x < 2)
7571 >>> s.check()
7572 sat
7573 >>> s.model()
7574 [x = 1]
7575 """
7576 ctx = _get_ctx(ctx)
7577 logic = to_symbol(logic)
7578 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7579
7580
7581def SimpleSolver(ctx=None, logFile=None):
7582 """Return a simple general purpose solver with limited amount of preprocessing.
7583
7584 >>> s = SimpleSolver()
7585 >>> x = Int('x')
7586 >>> s.add(x > 0)
7587 >>> s.check()
7588 sat
7589 """
7590 ctx = _get_ctx(ctx)
7591 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7592
7593#########################################
7594#
7595# Fixedpoint
7596#
7597#########################################
7598
7599
7600class Fixedpoint(Z3PPObject):
7601 """Fixedpoint API provides methods for solving with recursive predicates"""
7602
7603 def __init__(self, fixedpoint=None, ctx=None):
7604 assert fixedpoint is None or ctx is not None
7605 self.ctx = _get_ctx(ctx)
7606 self.fixedpoint = None
7607 if fixedpoint is None:
7608 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7609 else:
7610 self.fixedpoint = fixedpoint
7611 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7612 self.vars = []
7613
7614 def __deepcopy__(self, memo={}):
7615 return FixedPoint(self.fixedpoint, self.ctx)
7616
7617 def __del__(self):
7618 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7619 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7620
7621 def set(self, *args, **keys):
7622 """Set a configuration option. The method `help()` return a string containing all available options.
7623 """
7624 p = args2params(args, keys, self.ctx)
7625 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7626
7627 def help(self):
7628 """Display a string describing all available options."""
7629 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7630
7631 def param_descrs(self):
7632 """Return the parameter description set."""
7633 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7634
7635 def assert_exprs(self, *args):
7636 """Assert constraints as background axioms for the fixedpoint solver."""
7637 args = _get_args(args)
7638 s = BoolSort(self.ctx)
7639 for arg in args:
7640 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7641 for f in arg:
7642 f = self.abstract(f)
7643 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7644 else:
7645 arg = s.cast(arg)
7646 arg = self.abstract(arg)
7647 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7648
7649 def add(self, *args):
7650 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7651 self.assert_exprs(*args)
7652
7653 def __iadd__(self, fml):
7654 self.add(fml)
7655 return self
7656
7657 def append(self, *args):
7658 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7659 self.assert_exprs(*args)
7660
7661 def insert(self, *args):
7662 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7663 self.assert_exprs(*args)
7664
7665 def add_rule(self, head, body=None, name=None):
7666 """Assert rules defining recursive predicates to the fixedpoint solver.
7667 >>> a = Bool('a')
7668 >>> b = Bool('b')
7669 >>> s = Fixedpoint()
7670 >>> s.register_relation(a.decl())
7671 >>> s.register_relation(b.decl())
7672 >>> s.fact(a)
7673 >>> s.rule(b, a)
7674 >>> s.query(b)
7675 sat
7676 """
7677 if name is None:
7678 name = ""
7679 name = to_symbol(name, self.ctx)
7680 if body is None:
7681 head = self.abstract(head)
7682 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7683 else:
7684 body = _get_args(body)
7685 f = self.abstract(Implies(And(body, self.ctx), head))
7686 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7687
7688 def rule(self, head, body=None, name=None):
7689 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7690 self.add_rule(head, body, name)
7691
7692 def fact(self, head, name=None):
7693 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7694 self.add_rule(head, None, name)
7695
7696 def query(self, *query):
7697 """Query the fixedpoint engine whether formula is derivable.
7698 You can also pass an tuple or list of recursive predicates.
7699 """
7700 query = _get_args(query)
7701 sz = len(query)
7702 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7703 _decls = (FuncDecl * sz)()
7704 i = 0
7705 for q in query:
7706 _decls[i] = q.ast
7707 i = i + 1
7708 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7709 else:
7710 if sz == 1:
7711 query = query[0]
7712 else:
7713 query = And(query, self.ctx)
7714 query = self.abstract(query, False)
7715 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7716 return CheckSatResult(r)
7717
7718 def query_from_lvl(self, lvl, *query):
7719 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7720 """
7721 query = _get_args(query)
7722 sz = len(query)
7723 if sz >= 1 and isinstance(query[0], FuncDecl):
7724 _z3_assert(False, "unsupported")
7725 else:
7726 if sz == 1:
7727 query = query[0]
7728 else:
7729 query = And(query)
7730 query = self.abstract(query, False)
7731 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7732 return CheckSatResult(r)
7733
7734 def update_rule(self, head, body, name):
7735 """update rule"""
7736 if name is None:
7737 name = ""
7738 name = to_symbol(name, self.ctx)
7739 body = _get_args(body)
7740 f = self.abstract(Implies(And(body, self.ctx), head))
7741 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7742
7743 def get_answer(self):
7744 """Retrieve answer from last query call."""
7745 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7746 return _to_expr_ref(r, self.ctx)
7747
7748 def get_ground_sat_answer(self):
7749 """Retrieve a ground cex from last query call."""
7750 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7751 return _to_expr_ref(r, self.ctx)
7752
7753 def get_rules_along_trace(self):
7754 """retrieve rules along the counterexample trace"""
7755 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7756
7757 def get_rule_names_along_trace(self):
7758 """retrieve rule names along the counterexample trace"""
7759 # this is a hack as I don't know how to return a list of symbols from C++;
7760 # obtain names as a single string separated by semicolons
7761 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7762 # split into individual names
7763 return names.split(";")
7764
7765 def get_num_levels(self, predicate):
7766 """Retrieve number of levels used for predicate in PDR engine"""
7767 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7768
7769 def get_cover_delta(self, level, predicate):
7770 """Retrieve properties known about predicate for the level'th unfolding.
7771 -1 is treated as the limit (infinity)
7772 """
7773 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7774 return _to_expr_ref(r, self.ctx)
7775
7776 def add_cover(self, level, predicate, property):
7777 """Add property to predicate for the level'th unfolding.
7778 -1 is treated as infinity (infinity)
7779 """
7780 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7781
7782 def register_relation(self, *relations):
7783 """Register relation as recursive"""
7784 relations = _get_args(relations)
7785 for f in relations:
7786 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7787
7788 def set_predicate_representation(self, f, *representations):
7789 """Control how relation is represented"""
7790 representations = _get_args(representations)
7791 representations = [to_symbol(s) for s in representations]
7792 sz = len(representations)
7793 args = (Symbol * sz)()
7794 for i in range(sz):
7795 args[i] = representations[i]
7796 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7797
7798 def parse_string(self, s):
7799 """Parse rules and queries from a string"""
7800 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7801
7802 def parse_file(self, f):
7803 """Parse rules and queries from a file"""
7804 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7805
7806 def get_rules(self):
7807 """retrieve rules that have been added to fixedpoint context"""
7808 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7809
7810 def get_assertions(self):
7811 """retrieve assertions that have been added to fixedpoint context"""
7812 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7813
7814 def __repr__(self):
7815 """Return a formatted string with all added rules and constraints."""
7816 return self.sexpr()
7817
7818 def sexpr(self):
7819 """Return a formatted string (in Lisp-like format) with all added constraints.
7820 We say the string is in s-expression format.
7821 """
7822 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7823
7824 def to_string(self, queries):
7825 """Return a formatted string (in Lisp-like format) with all added constraints.
7826 We say the string is in s-expression format.
7827 Include also queries.
7828 """
7829 args, len = _to_ast_array(queries)
7830 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7831
7832 def statistics(self):
7833 """Return statistics for the last `query()`.
7834 """
7835 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7836
7837 def reason_unknown(self):
7838 """Return a string describing why the last `query()` returned `unknown`.
7839 """
7840 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7841
7842 def declare_var(self, *vars):
7843 """Add variable or several variables.
7844 The added variable or variables will be bound in the rules
7845 and queries
7846 """
7847 vars = _get_args(vars)
7848 for v in vars:
7849 self.vars += [v]
7850
7851 def abstract(self, fml, is_forall=True):
7852 if self.vars == []:
7853 return fml
7854 if is_forall:
7855 return ForAll(self.vars, fml)
7856 else:
7857 return Exists(self.vars, fml)
7858
7859
7860#########################################
7861#
7862# Finite domains
7863#
7864#########################################
7865
7866class FiniteDomainSortRef(SortRef):
7867 """Finite domain sort."""
7868
7869 def size(self):
7870 """Return the size of the finite domain sort"""
7871 r = (ctypes.c_ulonglong * 1)()
7872 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7873 return r[0]
7874 else:
7875 raise Z3Exception("Failed to retrieve finite domain sort size")
7876
7877
7878def FiniteDomainSort(name, sz, ctx=None):
7879 """Create a named finite domain sort of a given size sz"""
7880 if not isinstance(name, Symbol):
7881 name = to_symbol(name)
7882 ctx = _get_ctx(ctx)
7883 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7884
7885
7886def is_finite_domain_sort(s):
7887 """Return True if `s` is a Z3 finite-domain sort.
7888
7889 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7890 True
7891 >>> is_finite_domain_sort(IntSort())
7892 False
7893 """
7894 return isinstance(s, FiniteDomainSortRef)
7895
7896
7897class FiniteDomainRef(ExprRef):
7898 """Finite-domain expressions."""
7899
7900 def sort(self):
7901 """Return the sort of the finite-domain expression `self`."""
7902 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7903
7904 def as_string(self):
7905 """Return a Z3 floating point expression as a Python string."""
7906 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7907
7908
7909def is_finite_domain(a):
7910 """Return `True` if `a` is a Z3 finite-domain expression.
7911
7912 >>> s = FiniteDomainSort('S', 100)
7913 >>> b = Const('b', s)
7914 >>> is_finite_domain(b)
7915 True
7916 >>> is_finite_domain(Int('x'))
7917 False
7918 """
7919 return isinstance(a, FiniteDomainRef)
7920
7921
7922class FiniteDomainNumRef(FiniteDomainRef):
7923 """Integer values."""
7924
7925 def as_long(self):
7926 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7927
7928 >>> s = FiniteDomainSort('S', 100)
7929 >>> v = FiniteDomainVal(3, s)
7930 >>> v
7931 3
7932 >>> v.as_long() + 1
7933 4
7934 """
7935 return int(self.as_string())
7936
7937 def as_string(self):
7938 """Return a Z3 finite-domain numeral as a Python string.
7939
7940 >>> s = FiniteDomainSort('S', 100)
7941 >>> v = FiniteDomainVal(42, s)
7942 >>> v.as_string()
7943 '42'
7944 """
7945 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
7946
7947
7948def FiniteDomainVal(val, sort, ctx=None):
7949 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
7950
7951 >>> s = FiniteDomainSort('S', 256)
7952 >>> FiniteDomainVal(255, s)
7953 255
7954 >>> FiniteDomainVal('100', s)
7955 100
7956 """
7957 if z3_debug():
7958 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
7959 ctx = sort.ctx
7960 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
7961
7962
7963def is_finite_domain_value(a):
7964 """Return `True` if `a` is a Z3 finite-domain value.
7965
7966 >>> s = FiniteDomainSort('S', 100)
7967 >>> b = Const('b', s)
7968 >>> is_finite_domain_value(b)
7969 False
7970 >>> b = FiniteDomainVal(10, s)
7971 >>> b
7972 10
7973 >>> is_finite_domain_value(b)
7974 True
7975 """
7976 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
7977
7978
7979#########################################
7980#
7981# Optimize
7982#
7983#########################################
7984
7985class OptimizeObjective:
7986 def __init__(self, opt, value, is_max):
7987 self._opt = opt
7988 self._value = value
7989 self._is_max = is_max
7990
7991 def lower(self):
7992 opt = self._opt
7993 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7994
7995 def upper(self):
7996 opt = self._opt
7997 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7998
7999 def lower_values(self):
8000 opt = self._opt
8001 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8002
8003 def upper_values(self):
8004 opt = self._opt
8005 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8006
8007 def value(self):
8008 if self._is_max:
8009 return self.upper()
8010 else:
8011 return self.lower()
8012
8013 def __str__(self):
8014 return "%s:%s" % (self._value, self._is_max)
8015
8016
8017_on_models = {}
8018
8019
8020def _global_on_model(ctx):
8021 (fn, mdl) = _on_models[ctx]
8022 fn(mdl)
8023
8024
8025_on_model_eh = on_model_eh_type(_global_on_model)
8026
8027
8028class Optimize(Z3PPObject):
8029 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8030
8031 def __init__(self, optimize=None, ctx=None):
8032 self.ctx = _get_ctx(ctx)
8033 if optimize is None:
8034 self.optimize = Z3_mk_optimize(self.ctx.ref())
8035 else:
8036 self.optimize = optimize
8037 self._on_models_id = None
8038 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8039
8040 def __deepcopy__(self, memo={}):
8041 return Optimize(self.optimize, self.ctx)
8042
8043 def __del__(self):
8044 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8045 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8046 if self._on_models_id is not None:
8047 del _on_models[self._on_models_id]
8048
8049 def __enter__(self):
8050 self.push()
8051 return self
8052
8053 def __exit__(self, *exc_info):
8054 self.pop()
8055
8056 def set(self, *args, **keys):
8057 """Set a configuration option.
8058 The method `help()` return a string containing all available options.
8059 """
8060 p = args2params(args, keys, self.ctx)
8061 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8062
8063 def help(self):
8064 """Display a string describing all available options."""
8065 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8066
8067 def param_descrs(self):
8068 """Return the parameter description set."""
8069 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8070
8071 def assert_exprs(self, *args):
8072 """Assert constraints as background axioms for the optimize solver."""
8073 args = _get_args(args)
8074 s = BoolSort(self.ctx)
8075 for arg in args:
8076 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8077 for f in arg:
8078 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8079 else:
8080 arg = s.cast(arg)
8081 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8082
8083 def add(self, *args):
8084 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8085 self.assert_exprs(*args)
8086
8087 def __iadd__(self, fml):
8088 self.add(fml)
8089 return self
8090
8091 def assert_and_track(self, a, p):
8092 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8093
8094 If `p` is a string, it will be automatically converted into a Boolean constant.
8095
8096 >>> x = Int('x')
8097 >>> p3 = Bool('p3')
8098 >>> s = Optimize()
8099 >>> s.assert_and_track(x > 0, 'p1')
8100 >>> s.assert_and_track(x != 1, 'p2')
8101 >>> s.assert_and_track(x < 0, p3)
8102 >>> print(s.check())
8103 unsat
8104 >>> c = s.unsat_core()
8105 >>> len(c)
8106 2
8107 >>> Bool('p1') in c
8108 True
8109 >>> Bool('p2') in c
8110 False
8111 >>> p3 in c
8112 True
8113 """
8114 if isinstance(p, str):
8115 p = Bool(p, self.ctx)
8116 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8117 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8118 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8119
8120 def add_soft(self, arg, weight="1", id=None):
8121 """Add soft constraint with optional weight and optional identifier.
8122 If no weight is supplied, then the penalty for violating the soft constraint
8123 is 1.
8124 Soft constraints are grouped by identifiers. Soft constraints that are
8125 added without identifiers are grouped by default.
8126 """
8127 if _is_int(weight):
8128 weight = "%d" % weight
8129 elif isinstance(weight, float):
8130 weight = "%f" % weight
8131 if not isinstance(weight, str):
8132 raise Z3Exception("weight should be a string or an integer")
8133 if id is None:
8134 id = ""
8135 id = to_symbol(id, self.ctx)
8136
8137 def asoft(a):
8138 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8139 return OptimizeObjective(self, v, False)
8140 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8141 return [asoft(a) for a in arg]
8142 return asoft(arg)
8143
8144 def set_initial_value(self, var, value):
8145 """initialize the solver's state by setting the initial value of var to value
8146 """
8147 s = var.sort()
8148 value = s.cast(value)
8149 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8150
8151 def maximize(self, arg):
8152 """Add objective function to maximize."""
8153 return OptimizeObjective(
8154 self,
8155 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8156 is_max=True,
8157 )
8158
8159 def minimize(self, arg):
8160 """Add objective function to minimize."""
8161 return OptimizeObjective(
8162 self,
8163 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8164 is_max=False,
8165 )
8166
8167 def push(self):
8168 """create a backtracking point for added rules, facts and assertions"""
8169 Z3_optimize_push(self.ctx.ref(), self.optimize)
8170
8171 def pop(self):
8172 """restore to previously created backtracking point"""
8173 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8174
8175 def check(self, *assumptions):
8176 """Check consistency and produce optimal values."""
8177 assumptions = _get_args(assumptions)
8178 num = len(assumptions)
8179 _assumptions = (Ast * num)()
8180 for i in range(num):
8181 _assumptions[i] = assumptions[i].as_ast()
8182 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8183
8184 def reason_unknown(self):
8185 """Return a string that describes why the last `check()` returned `unknown`."""
8186 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8187
8188 def model(self):
8189 """Return a model for the last check()."""
8190 try:
8191 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8192 except Z3Exception:
8193 raise Z3Exception("model is not available")
8194
8195 def unsat_core(self):
8196 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8197
8198 def lower(self, obj):
8199 if not isinstance(obj, OptimizeObjective):
8200 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8201 return obj.lower()
8202
8203 def upper(self, obj):
8204 if not isinstance(obj, OptimizeObjective):
8205 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8206 return obj.upper()
8207
8208 def lower_values(self, obj):
8209 if not isinstance(obj, OptimizeObjective):
8210 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8211 return obj.lower_values()
8212
8213 def upper_values(self, obj):
8214 if not isinstance(obj, OptimizeObjective):
8215 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8216 return obj.upper_values()
8217
8218 def from_file(self, filename):
8219 """Parse assertions and objectives from a file"""
8220 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8221
8222 def from_string(self, s):
8223 """Parse assertions and objectives from a string"""
8224 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8225
8226 def assertions(self):
8227 """Return an AST vector containing all added constraints."""
8228 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8229
8230 def objectives(self):
8231 """returns set of objective functions"""
8232 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8233
8234 def __repr__(self):
8235 """Return a formatted string with all added rules and constraints."""
8236 return self.sexpr()
8237
8238 def sexpr(self):
8239 """Return a formatted string (in Lisp-like format) with all added constraints.
8240 We say the string is in s-expression format.
8241 """
8242 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8243
8244 def statistics(self):
8245 """Return statistics for the last check`.
8246 """
8247 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8248
8249 def set_on_model(self, on_model):
8250 """Register a callback that is invoked with every incremental improvement to
8251 objective values. The callback takes a model as argument.
8252 The life-time of the model is limited to the callback so the
8253 model has to be (deep) copied if it is to be used after the callback
8254 """
8255 id = len(_on_models) + 41
8256 mdl = Model(self.ctx)
8257 _on_models[id] = (on_model, mdl)
8258 self._on_models_id = id
8259 Z3_optimize_register_model_eh(
8260 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8261 )
8262
8263
8264#########################################
8265#
8266# ApplyResult
8267#
8268#########################################
8269class ApplyResult(Z3PPObject):
8270 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8271 It also contains model and proof converters.
8272 """
8273
8274 def __init__(self, result, ctx):
8275 self.result = result
8276 self.ctx = ctx
8277 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8278
8279 def __deepcopy__(self, memo={}):
8280 return ApplyResult(self.result, self.ctx)
8281
8282 def __del__(self):
8283 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8284 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8285
8286 def __len__(self):
8287 """Return the number of subgoals in `self`.
8288
8289 >>> a, b = Ints('a b')
8290 >>> g = Goal()
8291 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8292 >>> t = Tactic('split-clause')
8293 >>> r = t(g)
8294 >>> len(r)
8295 2
8296 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8297 >>> len(t(g))
8298 4
8299 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8300 >>> len(t(g))
8301 1
8302 """
8303 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8304
8305 def __getitem__(self, idx):
8306 """Return one of the subgoals stored in ApplyResult object `self`.
8307
8308 >>> a, b = Ints('a b')
8309 >>> g = Goal()
8310 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8311 >>> t = Tactic('split-clause')
8312 >>> r = t(g)
8313 >>> r[0]
8314 [a == 0, Or(b == 0, b == 1), a > b]
8315 >>> r[1]
8316 [a == 1, Or(b == 0, b == 1), a > b]
8317 """
8318 if idx >= len(self):
8319 raise IndexError
8320 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8321
8322 def __repr__(self):
8323 return obj_to_string(self)
8324
8325 def sexpr(self):
8326 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8327 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8328
8329 def as_expr(self):
8330 """Return a Z3 expression consisting of all subgoals.
8331
8332 >>> x = Int('x')
8333 >>> g = Goal()
8334 >>> g.add(x > 1)
8335 >>> g.add(Or(x == 2, x == 3))
8336 >>> r = Tactic('simplify')(g)
8337 >>> r
8338 [[Not(x <= 1), Or(x == 2, x == 3)]]
8339 >>> r.as_expr()
8340 And(Not(x <= 1), Or(x == 2, x == 3))
8341 >>> r = Tactic('split-clause')(g)
8342 >>> r
8343 [[x > 1, x == 2], [x > 1, x == 3]]
8344 >>> r.as_expr()
8345 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8346 """
8347 sz = len(self)
8348 if sz == 0:
8349 return BoolVal(False, self.ctx)
8350 elif sz == 1:
8351 return self[0].as_expr()
8352 else:
8353 return Or([self[i].as_expr() for i in range(len(self))])
8354
8355#########################################
8356#
8357# Simplifiers
8358#
8359#########################################
8360
8361class Simplifier:
8362 """Simplifiers act as pre-processing utilities for solvers.
8363 Build a custom simplifier and add it to a solver"""
8364
8365 def __init__(self, simplifier, ctx=None):
8366 self.ctx = _get_ctx(ctx)
8367 self.simplifier = None
8368 if isinstance(simplifier, SimplifierObj):
8369 self.simplifier = simplifier
8370 elif isinstance(simplifier, list):
8371 simps = [Simplifier(s, ctx) for s in simplifier]
8372 self.simplifier = simps[0].simplifier
8373 for i in range(1, len(simps)):
8374 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8375 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8376 return
8377 else:
8378 if z3_debug():
8379 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8380 try:
8381 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8382 except Z3Exception:
8383 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8384 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8385
8386 def __deepcopy__(self, memo={}):
8387 return Simplifier(self.simplifier, self.ctx)
8388
8389 def __del__(self):
8390 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8391 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8392
8393 def using_params(self, *args, **keys):
8394 """Return a simplifier that uses the given configuration options"""
8395 p = args2params(args, keys, self.ctx)
8396 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8397
8398 def add(self, solver):
8399 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8400 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8401
8402 def help(self):
8403 """Display a string containing a description of the available options for the `self` simplifier."""
8404 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8405
8406 def param_descrs(self):
8407 """Return the parameter description set."""
8408 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8409
8410
8411#########################################
8412#
8413# Tactics
8414#
8415#########################################
8416
8417
8418class Tactic:
8419 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8420 A Tactic can be converted into a Solver using the method solver().
8421
8422 Several combinators are available for creating new tactics using the built-in ones:
8423 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8424 """
8425
8426 def __init__(self, tactic, ctx=None):
8427 self.ctx = _get_ctx(ctx)
8428 self.tactic = None
8429 if isinstance(tactic, TacticObj):
8430 self.tactic = tactic
8431 else:
8432 if z3_debug():
8433 _z3_assert(isinstance(tactic, str), "tactic name expected")
8434 try:
8435 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8436 except Z3Exception:
8437 raise Z3Exception("unknown tactic '%s'" % tactic)
8438 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8439
8440 def __deepcopy__(self, memo={}):
8441 return Tactic(self.tactic, self.ctx)
8442
8443 def __del__(self):
8444 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8445 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8446
8447 def solver(self, logFile=None):
8448 """Create a solver using the tactic `self`.
8449
8450 The solver supports the methods `push()` and `pop()`, but it
8451 will always solve each `check()` from scratch.
8452
8453 >>> t = Then('simplify', 'nlsat')
8454 >>> s = t.solver()
8455 >>> x = Real('x')
8456 >>> s.add(x**2 == 2, x > 0)
8457 >>> s.check()
8458 sat
8459 >>> s.model()
8460 [x = 1.4142135623?]
8461 """
8462 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8463
8464 def apply(self, goal, *arguments, **keywords):
8465 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8466
8467 >>> x, y = Ints('x y')
8468 >>> t = Tactic('solve-eqs')
8469 >>> t.apply(And(x == 0, y >= x + 1))
8470 [[y >= 1]]
8471 """
8472 if z3_debug():
8473 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8474 goal = _to_goal(goal)
8475 if len(arguments) > 0 or len(keywords) > 0:
8476 p = args2params(arguments, keywords, self.ctx)
8477 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8478 else:
8479 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8480
8481 def __call__(self, goal, *arguments, **keywords):
8482 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8483
8484 >>> x, y = Ints('x y')
8485 >>> t = Tactic('solve-eqs')
8486 >>> t(And(x == 0, y >= x + 1))
8487 [[y >= 1]]
8488 """
8489 return self.apply(goal, *arguments, **keywords)
8490
8491 def help(self):
8492 """Display a string containing a description of the available options for the `self` tactic."""
8493 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8494
8495 def param_descrs(self):
8496 """Return the parameter description set."""
8497 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8498
8499
8500def _to_goal(a):
8501 if isinstance(a, BoolRef):
8502 goal = Goal(ctx=a.ctx)
8503 goal.add(a)
8504 return goal
8505 else:
8506 return a
8507
8508
8509def _to_tactic(t, ctx=None):
8510 if isinstance(t, Tactic):
8511 return t
8512 else:
8513 return Tactic(t, ctx)
8514
8515
8516def _and_then(t1, t2, ctx=None):
8517 t1 = _to_tactic(t1, ctx)
8518 t2 = _to_tactic(t2, ctx)
8519 if z3_debug():
8520 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8521 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8522
8523
8524def _or_else(t1, t2, ctx=None):
8525 t1 = _to_tactic(t1, ctx)
8526 t2 = _to_tactic(t2, ctx)
8527 if z3_debug():
8528 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8529 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8530
8531
8532def AndThen(*ts, **ks):
8533 """Return a tactic that applies the tactics in `*ts` in sequence.
8534
8535 >>> x, y = Ints('x y')
8536 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8537 >>> t(And(x == 0, y > x + 1))
8538 [[Not(y <= 1)]]
8539 >>> t(And(x == 0, y > x + 1)).as_expr()
8540 Not(y <= 1)
8541 """
8542 if z3_debug():
8543 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8544 ctx = ks.get("ctx", None)
8545 num = len(ts)
8546 r = ts[0]
8547 for i in range(num - 1):
8548 r = _and_then(r, ts[i + 1], ctx)
8549 return r
8550
8551
8552def Then(*ts, **ks):
8553 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8554
8555 >>> x, y = Ints('x y')
8556 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8557 >>> t(And(x == 0, y > x + 1))
8558 [[Not(y <= 1)]]
8559 >>> t(And(x == 0, y > x + 1)).as_expr()
8560 Not(y <= 1)
8561 """
8562 return AndThen(*ts, **ks)
8563
8564
8565def OrElse(*ts, **ks):
8566 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8567
8568 >>> x = Int('x')
8569 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8570 >>> # Tactic split-clause fails if there is no clause in the given goal.
8571 >>> t(x == 0)
8572 [[x == 0]]
8573 >>> t(Or(x == 0, x == 1))
8574 [[x == 0], [x == 1]]
8575 """
8576 if z3_debug():
8577 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8578 ctx = ks.get("ctx", None)
8579 num = len(ts)
8580 r = ts[0]
8581 for i in range(num - 1):
8582 r = _or_else(r, ts[i + 1], ctx)
8583 return r
8584
8585
8586def ParOr(*ts, **ks):
8587 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8588
8589 >>> x = Int('x')
8590 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8591 >>> t(x + 1 == 2)
8592 [[x == 1]]
8593 """
8594 if z3_debug():
8595 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8596 ctx = _get_ctx(ks.get("ctx", None))
8597 ts = [_to_tactic(t, ctx) for t in ts]
8598 sz = len(ts)
8599 _args = (TacticObj * sz)()
8600 for i in range(sz):
8601 _args[i] = ts[i].tactic
8602 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8603
8604
8605def ParThen(t1, t2, ctx=None):
8606 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8607 The subgoals are processed in parallel.
8608
8609 >>> x, y = Ints('x y')
8610 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8611 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8612 [[x == 1, y == 2], [x == 2, y == 3]]
8613 """
8614 t1 = _to_tactic(t1, ctx)
8615 t2 = _to_tactic(t2, ctx)
8616 if z3_debug():
8617 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8618 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8619
8620
8621def ParAndThen(t1, t2, ctx=None):
8622 """Alias for ParThen(t1, t2, ctx)."""
8623 return ParThen(t1, t2, ctx)
8624
8625
8626def With(t, *args, **keys):
8627 """Return a tactic that applies tactic `t` using the given configuration options.
8628
8629 >>> x, y = Ints('x y')
8630 >>> t = With(Tactic('simplify'), som=True)
8631 >>> t((x + 1)*(y + 2) == 0)
8632 [[2*x + y + x*y == -2]]
8633 """
8634 ctx = keys.pop("ctx", None)
8635 t = _to_tactic(t, ctx)
8636 p = args2params(args, keys, t.ctx)
8637 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8638
8639
8640def WithParams(t, p):
8641 """Return a tactic that applies tactic `t` using the given configuration options.
8642
8643 >>> x, y = Ints('x y')
8644 >>> p = ParamsRef()
8645 >>> p.set("som", True)
8646 >>> t = WithParams(Tactic('simplify'), p)
8647 >>> t((x + 1)*(y + 2) == 0)
8648 [[2*x + y + x*y == -2]]
8649 """
8650 t = _to_tactic(t, None)
8651 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8652
8653
8654def Repeat(t, max=4294967295, ctx=None):
8655 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8656 or the maximum number of iterations `max` is reached.
8657
8658 >>> x, y = Ints('x y')
8659 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8660 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8661 >>> r = t(c)
8662 >>> for subgoal in r: print(subgoal)
8663 [x == 0, y == 0, x > y]
8664 [x == 0, y == 1, x > y]
8665 [x == 1, y == 0, x > y]
8666 [x == 1, y == 1, x > y]
8667 >>> t = Then(t, Tactic('propagate-values'))
8668 >>> t(c)
8669 [[x == 1, y == 0]]
8670 """
8671 t = _to_tactic(t, ctx)
8672 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8673
8674
8675def TryFor(t, ms, ctx=None):
8676 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8677
8678 If `t` does not terminate in `ms` milliseconds, then it fails.
8679 """
8680 t = _to_tactic(t, ctx)
8681 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8682
8683
8684def tactics(ctx=None):
8685 """Return a list of all available tactics in Z3.
8686
8687 >>> l = tactics()
8688 >>> l.count('simplify') == 1
8689 True
8690 """
8691 ctx = _get_ctx(ctx)
8692 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8693
8694
8695def tactic_description(name, ctx=None):
8696 """Return a short description for the tactic named `name`.
8697
8698 >>> d = tactic_description('simplify')
8699 """
8700 ctx = _get_ctx(ctx)
8701 return Z3_tactic_get_descr(ctx.ref(), name)
8702
8703
8704def describe_tactics():
8705 """Display a (tabular) description of all available tactics in Z3."""
8706 if in_html_mode():
8707 even = True
8708 print('<table border="1" cellpadding="2" cellspacing="0">')
8709 for t in tactics():
8710 if even:
8711 print('<tr style="background-color:#CFCFCF">')
8712 even = False
8713 else:
8714 print("<tr>")
8715 even = True
8716 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8717 print("</table>")
8718 else:
8719 for t in tactics():
8720 print("%s : %s" % (t, tactic_description(t)))
8721
8722
8723class Probe:
8724 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8725 to decide which solver and/or preprocessing step will be used.
8726 """
8727
8728 def __init__(self, probe, ctx=None):
8729 self.ctx = _get_ctx(ctx)
8730 self.probe = None
8731 if isinstance(probe, ProbeObj):
8732 self.probe = probe
8733 elif isinstance(probe, float):
8734 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8735 elif _is_int(probe):
8736 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8737 elif isinstance(probe, bool):
8738 if probe:
8739 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8740 else:
8741 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8742 else:
8743 if z3_debug():
8744 _z3_assert(isinstance(probe, str), "probe name expected")
8745 try:
8746 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8747 except Z3Exception:
8748 raise Z3Exception("unknown probe '%s'" % probe)
8749 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8750
8751 def __deepcopy__(self, memo={}):
8752 return Probe(self.probe, self.ctx)
8753
8754 def __del__(self):
8755 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8756 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8757
8758 def __lt__(self, other):
8759 """Return a probe that evaluates to "true" when the value returned by `self`
8760 is less than the value returned by `other`.
8761
8762 >>> p = Probe('size') < 10
8763 >>> x = Int('x')
8764 >>> g = Goal()
8765 >>> g.add(x > 0)
8766 >>> g.add(x < 10)
8767 >>> p(g)
8768 1.0
8769 """
8770 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8771
8772 def __gt__(self, other):
8773 """Return a probe that evaluates to "true" when the value returned by `self`
8774 is greater than the value returned by `other`.
8775
8776 >>> p = Probe('size') > 10
8777 >>> x = Int('x')
8778 >>> g = Goal()
8779 >>> g.add(x > 0)
8780 >>> g.add(x < 10)
8781 >>> p(g)
8782 0.0
8783 """
8784 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8785
8786 def __le__(self, other):
8787 """Return a probe that evaluates to "true" when the value returned by `self`
8788 is less than or equal to the value returned by `other`.
8789
8790 >>> p = Probe('size') <= 2
8791 >>> x = Int('x')
8792 >>> g = Goal()
8793 >>> g.add(x > 0)
8794 >>> g.add(x < 10)
8795 >>> p(g)
8796 1.0
8797 """
8798 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8799
8800 def __ge__(self, other):
8801 """Return a probe that evaluates to "true" when the value returned by `self`
8802 is greater than or equal to the value returned by `other`.
8803
8804 >>> p = Probe('size') >= 2
8805 >>> x = Int('x')
8806 >>> g = Goal()
8807 >>> g.add(x > 0)
8808 >>> g.add(x < 10)
8809 >>> p(g)
8810 1.0
8811 """
8812 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8813
8814 def __eq__(self, other):
8815 """Return a probe that evaluates to "true" when the value returned by `self`
8816 is equal to the value returned by `other`.
8817
8818 >>> p = Probe('size') == 2
8819 >>> x = Int('x')
8820 >>> g = Goal()
8821 >>> g.add(x > 0)
8822 >>> g.add(x < 10)
8823 >>> p(g)
8824 1.0
8825 """
8826 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8827
8828 def __ne__(self, other):
8829 """Return a probe that evaluates to "true" when the value returned by `self`
8830 is not equal to the value returned by `other`.
8831
8832 >>> p = Probe('size') != 2
8833 >>> x = Int('x')
8834 >>> g = Goal()
8835 >>> g.add(x > 0)
8836 >>> g.add(x < 10)
8837 >>> p(g)
8838 0.0
8839 """
8840 p = self.__eq__(other)
8841 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8842
8843 def __call__(self, goal):
8844 """Evaluate the probe `self` in the given goal.
8845
8846 >>> p = Probe('size')
8847 >>> x = Int('x')
8848 >>> g = Goal()
8849 >>> g.add(x > 0)
8850 >>> g.add(x < 10)
8851 >>> p(g)
8852 2.0
8853 >>> g.add(x < 20)
8854 >>> p(g)
8855 3.0
8856 >>> p = Probe('num-consts')
8857 >>> p(g)
8858 1.0
8859 >>> p = Probe('is-propositional')
8860 >>> p(g)
8861 0.0
8862 >>> p = Probe('is-qflia')
8863 >>> p(g)
8864 1.0
8865 """
8866 if z3_debug():
8867 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8868 goal = _to_goal(goal)
8869 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8870
8871
8872def is_probe(p):
8873 """Return `True` if `p` is a Z3 probe.
8874
8875 >>> is_probe(Int('x'))
8876 False
8877 >>> is_probe(Probe('memory'))
8878 True
8879 """
8880 return isinstance(p, Probe)
8881
8882
8883def _to_probe(p, ctx=None):
8884 if is_probe(p):
8885 return p
8886 else:
8887 return Probe(p, ctx)
8888
8889
8890def probes(ctx=None):
8891 """Return a list of all available probes in Z3.
8892
8893 >>> l = probes()
8894 >>> l.count('memory') == 1
8895 True
8896 """
8897 ctx = _get_ctx(ctx)
8898 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8899
8900
8901def probe_description(name, ctx=None):
8902 """Return a short description for the probe named `name`.
8903
8904 >>> d = probe_description('memory')
8905 """
8906 ctx = _get_ctx(ctx)
8907 return Z3_probe_get_descr(ctx.ref(), name)
8908
8909
8910def describe_probes():
8911 """Display a (tabular) description of all available probes in Z3."""
8912 if in_html_mode():
8913 even = True
8914 print('<table border="1" cellpadding="2" cellspacing="0">')
8915 for p in probes():
8916 if even:
8917 print('<tr style="background-color:#CFCFCF">')
8918 even = False
8919 else:
8920 print("<tr>")
8921 even = True
8922 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
8923 print("</table>")
8924 else:
8925 for p in probes():
8926 print("%s : %s" % (p, probe_description(p)))
8927
8928
8929def _probe_nary(f, args, ctx):
8930 if z3_debug():
8931 _z3_assert(len(args) > 0, "At least one argument expected")
8932 num = len(args)
8933 r = _to_probe(args[0], ctx)
8934 for i in range(num - 1):
8935 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
8936 return r
8937
8938
8939def _probe_and(args, ctx):
8940 return _probe_nary(Z3_probe_and, args, ctx)
8941
8942
8943def _probe_or(args, ctx):
8944 return _probe_nary(Z3_probe_or, args, ctx)
8945
8946
8947def FailIf(p, ctx=None):
8948 """Return a tactic that fails if the probe `p` evaluates to true.
8949 Otherwise, it returns the input goal unmodified.
8950
8951 In the following example, the tactic applies 'simplify' if and only if there are
8952 more than 2 constraints in the goal.
8953
8954 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
8955 >>> x, y = Ints('x y')
8956 >>> g = Goal()
8957 >>> g.add(x > 0)
8958 >>> g.add(y > 0)
8959 >>> t(g)
8960 [[x > 0, y > 0]]
8961 >>> g.add(x == y + 1)
8962 >>> t(g)
8963 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8964 """
8965 p = _to_probe(p, ctx)
8966 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
8967
8968
8969def When(p, t, ctx=None):
8970 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
8971 Otherwise, it returns the input goal unmodified.
8972
8973 >>> t = When(Probe('size') > 2, Tactic('simplify'))
8974 >>> x, y = Ints('x y')
8975 >>> g = Goal()
8976 >>> g.add(x > 0)
8977 >>> g.add(y > 0)
8978 >>> t(g)
8979 [[x > 0, y > 0]]
8980 >>> g.add(x == y + 1)
8981 >>> t(g)
8982 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8983 """
8984 p = _to_probe(p, ctx)
8985 t = _to_tactic(t, ctx)
8986 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
8987
8988
8989def Cond(p, t1, t2, ctx=None):
8990 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
8991
8992 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
8993 """
8994 p = _to_probe(p, ctx)
8995 t1 = _to_tactic(t1, ctx)
8996 t2 = _to_tactic(t2, ctx)
8997 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
8998
8999#########################################
9000#
9001# Utils
9002#
9003#########################################
9004
9005
9006def simplify(a, *arguments, **keywords):
9007 """Simplify the expression `a` using the given options.
9008
9009 This function has many options. Use `help_simplify` to obtain the complete list.
9010
9011 >>> x = Int('x')
9012 >>> y = Int('y')
9013 >>> simplify(x + 1 + y + x + 1)
9014 2 + 2*x + y
9015 >>> simplify((x + 1)*(y + 1), som=True)
9016 1 + x + y + x*y
9017 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9018 And(Not(x == y), Not(x == 1), Not(y == 1))
9019 >>> simplify(And(x == 0, y == 1), elim_and=True)
9020 Not(Or(Not(x == 0), Not(y == 1)))
9021 """
9022 if z3_debug():
9023 _z3_assert(is_expr(a), "Z3 expression expected")
9024 if len(arguments) > 0 or len(keywords) > 0:
9025 p = args2params(arguments, keywords, a.ctx)
9026 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9027 else:
9028 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9029
9030
9031def help_simplify():
9032 """Return a string describing all options available for Z3 `simplify` procedure."""
9033 print(Z3_simplify_get_help(main_ctx().ref()))
9034
9035
9036def simplify_param_descrs():
9037 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9038 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9039
9040
9041def substitute(t, *m):
9042 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9043 Every occurrence in t of from is replaced with to.
9044
9045 >>> x = Int('x')
9046 >>> y = Int('y')
9047 >>> substitute(x + 1, (x, y + 1))
9048 y + 1 + 1
9049 >>> f = Function('f', IntSort(), IntSort())
9050 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9051 1 + 1
9052 """
9053 if isinstance(m, tuple):
9054 m1 = _get_args(m)
9055 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9056 m = m1
9057 if z3_debug():
9058 _z3_assert(is_expr(t), "Z3 expression expected")
9059 _z3_assert(
9060 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9061 "Z3 invalid substitution, expression pairs expected.")
9062 _z3_assert(
9063 all([p[0].sort().eq(p[1].sort()) for p in m]),
9064 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9065 num = len(m)
9066 _from = (Ast * num)()
9067 _to = (Ast * num)()
9068 for i in range(num):
9069 _from[i] = m[i][0].as_ast()
9070 _to[i] = m[i][1].as_ast()
9071 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9072
9073
9074def substitute_vars(t, *m):
9075 """Substitute the free variables in t with the expression in m.
9076
9077 >>> v0 = Var(0, IntSort())
9078 >>> v1 = Var(1, IntSort())
9079 >>> x = Int('x')
9080 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9081 >>> # replace v0 with x+1 and v1 with x
9082 >>> substitute_vars(f(v0, v1), x + 1, x)
9083 f(x + 1, x)
9084 """
9085 if z3_debug():
9086 _z3_assert(is_expr(t), "Z3 expression expected")
9087 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9088 num = len(m)
9089 _to = (Ast * num)()
9090 for i in range(num):
9091 _to[i] = m[i].as_ast()
9092 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9093
9094def substitute_funs(t, *m):
9095 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9096 Every occurrence in to of the function from is replaced with the expression to.
9097 The expression to can have free variables, that refer to the arguments of from.
9098 For examples, see
9099 """
9100 if isinstance(m, tuple):
9101 m1 = _get_args(m)
9102 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9103 m = m1
9104 if z3_debug():
9105 _z3_assert(is_expr(t), "Z3 expression expected")
9106 _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.")
9107 num = len(m)
9108 _from = (FuncDecl * num)()
9109 _to = (Ast * num)()
9110 for i in range(num):
9111 _from[i] = m[i][0].as_func_decl()
9112 _to[i] = m[i][1].as_ast()
9113 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9114
9115
9116def Sum(*args):
9117 """Create the sum of the Z3 expressions.
9118
9119 >>> a, b, c = Ints('a b c')
9120 >>> Sum(a, b, c)
9121 a + b + c
9122 >>> Sum([a, b, c])
9123 a + b + c
9124 >>> A = IntVector('a', 5)
9125 >>> Sum(A)
9126 a__0 + a__1 + a__2 + a__3 + a__4
9127 """
9128 args = _get_args(args)
9129 if len(args) == 0:
9130 return 0
9131 ctx = _ctx_from_ast_arg_list(args)
9132 if ctx is None:
9133 return _reduce(lambda a, b: a + b, args, 0)
9134 args = _coerce_expr_list(args, ctx)
9135 if is_bv(args[0]):
9136 return _reduce(lambda a, b: a + b, args, 0)
9137 else:
9138 _args, sz = _to_ast_array(args)
9139 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9140
9141
9142def Product(*args):
9143 """Create the product of the Z3 expressions.
9144
9145 >>> a, b, c = Ints('a b c')
9146 >>> Product(a, b, c)
9147 a*b*c
9148 >>> Product([a, b, c])
9149 a*b*c
9150 >>> A = IntVector('a', 5)
9151 >>> Product(A)
9152 a__0*a__1*a__2*a__3*a__4
9153 """
9154 args = _get_args(args)
9155 if len(args) == 0:
9156 return 1
9157 ctx = _ctx_from_ast_arg_list(args)
9158 if ctx is None:
9159 return _reduce(lambda a, b: a * b, args, 1)
9160 args = _coerce_expr_list(args, ctx)
9161 if is_bv(args[0]):
9162 return _reduce(lambda a, b: a * b, args, 1)
9163 else:
9164 _args, sz = _to_ast_array(args)
9165 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9166
9167def Abs(arg):
9168 """Create the absolute value of an arithmetic expression"""
9169 return If(arg > 0, arg, -arg)
9170
9171
9172def AtMost(*args):
9173 """Create an at-most Pseudo-Boolean k constraint.
9174
9175 >>> a, b, c = Bools('a b c')
9176 >>> f = AtMost(a, b, c, 2)
9177 """
9178 args = _get_args(args)
9179 if z3_debug():
9180 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9181 ctx = _ctx_from_ast_arg_list(args)
9182 if z3_debug():
9183 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9184 args1 = _coerce_expr_list(args[:-1], ctx)
9185 k = args[-1]
9186 _args, sz = _to_ast_array(args1)
9187 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9188
9189
9190def AtLeast(*args):
9191 """Create an at-least Pseudo-Boolean k constraint.
9192
9193 >>> a, b, c = Bools('a b c')
9194 >>> f = AtLeast(a, b, c, 2)
9195 """
9196 args = _get_args(args)
9197 if z3_debug():
9198 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9199 ctx = _ctx_from_ast_arg_list(args)
9200 if z3_debug():
9201 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9202 args1 = _coerce_expr_list(args[:-1], ctx)
9203 k = args[-1]
9204 _args, sz = _to_ast_array(args1)
9205 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9206
9207
9208def _reorder_pb_arg(arg):
9209 a, b = arg
9210 if not _is_int(b) and _is_int(a):
9211 return b, a
9212 return arg
9213
9214
9215def _pb_args_coeffs(args, default_ctx=None):
9216 args = _get_args_ast_list(args)
9217 if len(args) == 0:
9218 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9219 args = [_reorder_pb_arg(arg) for arg in args]
9220 args, coeffs = zip(*args)
9221 if z3_debug():
9222 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9223 ctx = _ctx_from_ast_arg_list(args)
9224 if z3_debug():
9225 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9226 args = _coerce_expr_list(args, ctx)
9227 _args, sz = _to_ast_array(args)
9228 _coeffs = (ctypes.c_int * len(coeffs))()
9229 for i in range(len(coeffs)):
9230 _z3_check_cint_overflow(coeffs[i], "coefficient")
9231 _coeffs[i] = coeffs[i]
9232 return ctx, sz, _args, _coeffs, args
9233
9234
9235def PbLe(args, k):
9236 """Create a Pseudo-Boolean inequality k constraint.
9237
9238 >>> a, b, c = Bools('a b c')
9239 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9240 """
9241 _z3_check_cint_overflow(k, "k")
9242 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9243 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9244
9245
9246def PbGe(args, k):
9247 """Create a Pseudo-Boolean inequality k constraint.
9248
9249 >>> a, b, c = Bools('a b c')
9250 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9251 """
9252 _z3_check_cint_overflow(k, "k")
9253 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9254 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9255
9256
9257def PbEq(args, k, ctx=None):
9258 """Create a Pseudo-Boolean equality k constraint.
9259
9260 >>> a, b, c = Bools('a b c')
9261 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9262 """
9263 _z3_check_cint_overflow(k, "k")
9264 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9265 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9266
9267
9268def solve(*args, **keywords):
9269 """Solve the constraints `*args`.
9270
9271 This is a simple function for creating demonstrations. It creates a solver,
9272 configure it using the options in `keywords`, adds the constraints
9273 in `args`, and invokes check.
9274
9275 >>> a = Int('a')
9276 >>> solve(a > 0, a < 2)
9277 [a = 1]
9278 """
9279 show = keywords.pop("show", False)
9280 s = Solver()
9281 s.set(**keywords)
9282 s.add(*args)
9283 if show:
9284 print(s)
9285 r = s.check()
9286 if r == unsat:
9287 print("no solution")
9288 elif r == unknown:
9289 print("failed to solve")
9290 try:
9291 print(s.model())
9292 except Z3Exception:
9293 return
9294 else:
9295 print(s.model())
9296
9297
9298def solve_using(s, *args, **keywords):
9299 """Solve the constraints `*args` using solver `s`.
9300
9301 This is a simple function for creating demonstrations. It is similar to `solve`,
9302 but it uses the given solver `s`.
9303 It configures solver `s` using the options in `keywords`, adds the constraints
9304 in `args`, and invokes check.
9305 """
9306 show = keywords.pop("show", False)
9307 if z3_debug():
9308 _z3_assert(isinstance(s, Solver), "Solver object expected")
9309 s.set(**keywords)
9310 s.add(*args)
9311 if show:
9312 print("Problem:")
9313 print(s)
9314 r = s.check()
9315 if r == unsat:
9316 print("no solution")
9317 elif r == unknown:
9318 print("failed to solve")
9319 try:
9320 print(s.model())
9321 except Z3Exception:
9322 return
9323 else:
9324 if show:
9325 print("Solution:")
9326 print(s.model())
9327
9328
9329def prove(claim, show=False, **keywords):
9330 """Try to prove the given claim.
9331
9332 This is a simple function for creating demonstrations. It tries to prove
9333 `claim` by showing the negation is unsatisfiable.
9334
9335 >>> p, q = Bools('p q')
9336 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9337 proved
9338 """
9339 if z3_debug():
9340 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9341 s = Solver()
9342 s.set(**keywords)
9343 s.add(Not(claim))
9344 if show:
9345 print(s)
9346 r = s.check()
9347 if r == unsat:
9348 print("proved")
9349 elif r == unknown:
9350 print("failed to prove")
9351 print(s.model())
9352 else:
9353 print("counterexample")
9354 print(s.model())
9355
9356
9357def _solve_html(*args, **keywords):
9358 """Version of function `solve` that renders HTML output."""
9359 show = keywords.pop("show", False)
9360 s = Solver()
9361 s.set(**keywords)
9362 s.add(*args)
9363 if show:
9364 print("<b>Problem:</b>")
9365 print(s)
9366 r = s.check()
9367 if r == unsat:
9368 print("<b>no solution</b>")
9369 elif r == unknown:
9370 print("<b>failed to solve</b>")
9371 try:
9372 print(s.model())
9373 except Z3Exception:
9374 return
9375 else:
9376 if show:
9377 print("<b>Solution:</b>")
9378 print(s.model())
9379
9380
9381def _solve_using_html(s, *args, **keywords):
9382 """Version of function `solve_using` that renders HTML."""
9383 show = keywords.pop("show", False)
9384 if z3_debug():
9385 _z3_assert(isinstance(s, Solver), "Solver object expected")
9386 s.set(**keywords)
9387 s.add(*args)
9388 if show:
9389 print("<b>Problem:</b>")
9390 print(s)
9391 r = s.check()
9392 if r == unsat:
9393 print("<b>no solution</b>")
9394 elif r == unknown:
9395 print("<b>failed to solve</b>")
9396 try:
9397 print(s.model())
9398 except Z3Exception:
9399 return
9400 else:
9401 if show:
9402 print("<b>Solution:</b>")
9403 print(s.model())
9404
9405
9406def _prove_html(claim, show=False, **keywords):
9407 """Version of function `prove` that renders HTML."""
9408 if z3_debug():
9409 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9410 s = Solver()
9411 s.set(**keywords)
9412 s.add(Not(claim))
9413 if show:
9414 print(s)
9415 r = s.check()
9416 if r == unsat:
9417 print("<b>proved</b>")
9418 elif r == unknown:
9419 print("<b>failed to prove</b>")
9420 print(s.model())
9421 else:
9422 print("<b>counterexample</b>")
9423 print(s.model())
9424
9425
9426def _dict2sarray(sorts, ctx):
9427 sz = len(sorts)
9428 _names = (Symbol * sz)()
9429 _sorts = (Sort * sz)()
9430 i = 0
9431 for k in sorts:
9432 v = sorts[k]
9433 if z3_debug():
9434 _z3_assert(isinstance(k, str), "String expected")
9435 _z3_assert(is_sort(v), "Z3 sort expected")
9436 _names[i] = to_symbol(k, ctx)
9437 _sorts[i] = v.ast
9438 i = i + 1
9439 return sz, _names, _sorts
9440
9441
9442def _dict2darray(decls, ctx):
9443 sz = len(decls)
9444 _names = (Symbol * sz)()
9445 _decls = (FuncDecl * sz)()
9446 i = 0
9447 for k in decls:
9448 v = decls[k]
9449 if z3_debug():
9450 _z3_assert(isinstance(k, str), "String expected")
9451 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9452 _names[i] = to_symbol(k, ctx)
9453 if is_const(v):
9454 _decls[i] = v.decl().ast
9455 else:
9456 _decls[i] = v.ast
9457 i = i + 1
9458 return sz, _names, _decls
9459
9460class ParserContext:
9461 def __init__(self, ctx= None):
9462 self.ctx = _get_ctx(ctx)
9463 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9464 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9465
9466 def __del__(self):
9467 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9468 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9469 self.pctx = None
9470
9471 def add_sort(self, sort):
9472 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9473
9474 def add_decl(self, decl):
9475 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9476
9477 def from_string(self, s):
9478 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9479
9480def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9481 """Parse a string in SMT 2.0 format using the given sorts and decls.
9482
9483 The arguments sorts and decls are Python dictionaries used to initialize
9484 the symbol table used for the SMT 2.0 parser.
9485
9486 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9487 [x > 0, x < 10]
9488 >>> x, y = Ints('x y')
9489 >>> f = Function('f', IntSort(), IntSort())
9490 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9491 [x + f(y) > 0]
9492 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9493 [a > 0]
9494 """
9495 ctx = _get_ctx(ctx)
9496 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9497 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9498 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9499
9500
9501def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9502 """Parse a file in SMT 2.0 format using the given sorts and decls.
9503
9504 This function is similar to parse_smt2_string().
9505 """
9506 ctx = _get_ctx(ctx)
9507 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9508 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9509 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9510
9511
9512#########################################
9513#
9514# Floating-Point Arithmetic
9515#
9516#########################################
9517
9518
9519# Global default rounding mode
9520_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9521_dflt_fpsort_ebits = 11
9522_dflt_fpsort_sbits = 53
9523
9524
9525def get_default_rounding_mode(ctx=None):
9526 """Retrieves the global default rounding mode."""
9527 global _dflt_rounding_mode
9528 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9529 return RTZ(ctx)
9530 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9531 return RTN(ctx)
9532 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9533 return RTP(ctx)
9534 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9535 return RNE(ctx)
9536 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9537 return RNA(ctx)
9538
9539
9540_ROUNDING_MODES = frozenset({
9541 Z3_OP_FPA_RM_TOWARD_ZERO,
9542 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9543 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9544 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9545 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9546})
9547
9548
9549def set_default_rounding_mode(rm, ctx=None):
9550 global _dflt_rounding_mode
9551 if is_fprm_value(rm):
9552 _dflt_rounding_mode = rm.kind()
9553 else:
9554 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9555 _dflt_rounding_mode = rm
9556
9557
9558def get_default_fp_sort(ctx=None):
9559 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9560
9561
9562def set_default_fp_sort(ebits, sbits, ctx=None):
9563 global _dflt_fpsort_ebits
9564 global _dflt_fpsort_sbits
9565 _dflt_fpsort_ebits = ebits
9566 _dflt_fpsort_sbits = sbits
9567
9568
9569def _dflt_rm(ctx=None):
9570 return get_default_rounding_mode(ctx)
9571
9572
9573def _dflt_fps(ctx=None):
9574 return get_default_fp_sort(ctx)
9575
9576
9577def _coerce_fp_expr_list(alist, ctx):
9578 first_fp_sort = None
9579 for a in alist:
9580 if is_fp(a):
9581 if first_fp_sort is None:
9582 first_fp_sort = a.sort()
9583 elif first_fp_sort == a.sort():
9584 pass # OK, same as before
9585 else:
9586 # we saw at least 2 different float sorts; something will
9587 # throw a sort mismatch later, for now assume None.
9588 first_fp_sort = None
9589 break
9590
9591 r = []
9592 for i in range(len(alist)):
9593 a = alist[i]
9594 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9595 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9596 r.append(FPVal(a, None, first_fp_sort, ctx))
9597 else:
9598 r.append(a)
9599 return _coerce_expr_list(r, ctx)
9600
9601
9602# FP Sorts
9603
9604class FPSortRef(SortRef):
9605 """Floating-point sort."""
9606
9607 def ebits(self):
9608 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9609 >>> b = FPSort(8, 24)
9610 >>> b.ebits()
9611 8
9612 """
9613 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9614
9615 def sbits(self):
9616 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9617 >>> b = FPSort(8, 24)
9618 >>> b.sbits()
9619 24
9620 """
9621 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9622
9623 def cast(self, val):
9624 """Try to cast `val` as a floating-point expression.
9625 >>> b = FPSort(8, 24)
9626 >>> b.cast(1.0)
9627 1
9628 >>> b.cast(1.0).sexpr()
9629 '(fp #b0 #x7f #b00000000000000000000000)'
9630 """
9631 if is_expr(val):
9632 if z3_debug():
9633 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9634 return val
9635 else:
9636 return FPVal(val, None, self, self.ctx)
9637
9638
9639def Float16(ctx=None):
9640 """Floating-point 16-bit (half) sort."""
9641 ctx = _get_ctx(ctx)
9642 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9643
9644
9645def FloatHalf(ctx=None):
9646 """Floating-point 16-bit (half) sort."""
9647 ctx = _get_ctx(ctx)
9648 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9649
9650
9651def Float32(ctx=None):
9652 """Floating-point 32-bit (single) sort."""
9653 ctx = _get_ctx(ctx)
9654 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9655
9656
9657def FloatSingle(ctx=None):
9658 """Floating-point 32-bit (single) sort."""
9659 ctx = _get_ctx(ctx)
9660 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9661
9662
9663def Float64(ctx=None):
9664 """Floating-point 64-bit (double) sort."""
9665 ctx = _get_ctx(ctx)
9666 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9667
9668
9669def FloatDouble(ctx=None):
9670 """Floating-point 64-bit (double) sort."""
9671 ctx = _get_ctx(ctx)
9672 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9673
9674
9675def Float128(ctx=None):
9676 """Floating-point 128-bit (quadruple) sort."""
9677 ctx = _get_ctx(ctx)
9678 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9679
9680
9681def FloatQuadruple(ctx=None):
9682 """Floating-point 128-bit (quadruple) sort."""
9683 ctx = _get_ctx(ctx)
9684 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9685
9686
9687class FPRMSortRef(SortRef):
9688 """"Floating-point rounding mode sort."""
9689
9690
9691def is_fp_sort(s):
9692 """Return True if `s` is a Z3 floating-point sort.
9693
9694 >>> is_fp_sort(FPSort(8, 24))
9695 True
9696 >>> is_fp_sort(IntSort())
9697 False
9698 """
9699 return isinstance(s, FPSortRef)
9700
9701
9702def is_fprm_sort(s):
9703 """Return True if `s` is a Z3 floating-point rounding mode sort.
9704
9705 >>> is_fprm_sort(FPSort(8, 24))
9706 False
9707 >>> is_fprm_sort(RNE().sort())
9708 True
9709 """
9710 return isinstance(s, FPRMSortRef)
9711
9712# FP Expressions
9713
9714
9715class FPRef(ExprRef):
9716 """Floating-point expressions."""
9717
9718 def sort(self):
9719 """Return the sort of the floating-point expression `self`.
9720
9721 >>> x = FP('1.0', FPSort(8, 24))
9722 >>> x.sort()
9723 FPSort(8, 24)
9724 >>> x.sort() == FPSort(8, 24)
9725 True
9726 """
9727 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9728
9729 def ebits(self):
9730 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9731 >>> b = FPSort(8, 24)
9732 >>> b.ebits()
9733 8
9734 """
9735 return self.sort().ebits()
9736
9737 def sbits(self):
9738 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9739 >>> b = FPSort(8, 24)
9740 >>> b.sbits()
9741 24
9742 """
9743 return self.sort().sbits()
9744
9745 def as_string(self):
9746 """Return a Z3 floating point expression as a Python string."""
9747 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9748
9749 def __le__(self, other):
9750 return fpLEQ(self, other, self.ctx)
9751
9752 def __lt__(self, other):
9753 return fpLT(self, other, self.ctx)
9754
9755 def __ge__(self, other):
9756 return fpGEQ(self, other, self.ctx)
9757
9758 def __gt__(self, other):
9759 return fpGT(self, other, self.ctx)
9760
9761 def __add__(self, other):
9762 """Create the Z3 expression `self + other`.
9763
9764 >>> x = FP('x', FPSort(8, 24))
9765 >>> y = FP('y', FPSort(8, 24))
9766 >>> x + y
9767 x + y
9768 >>> (x + y).sort()
9769 FPSort(8, 24)
9770 """
9771 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9772 return fpAdd(_dflt_rm(), a, b, self.ctx)
9773
9774 def __radd__(self, other):
9775 """Create the Z3 expression `other + self`.
9776
9777 >>> x = FP('x', FPSort(8, 24))
9778 >>> 10 + x
9779 1.25*(2**3) + x
9780 """
9781 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9782 return fpAdd(_dflt_rm(), a, b, self.ctx)
9783
9784 def __sub__(self, other):
9785 """Create the Z3 expression `self - other`.
9786
9787 >>> x = FP('x', FPSort(8, 24))
9788 >>> y = FP('y', FPSort(8, 24))
9789 >>> x - y
9790 x - y
9791 >>> (x - y).sort()
9792 FPSort(8, 24)
9793 """
9794 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9795 return fpSub(_dflt_rm(), a, b, self.ctx)
9796
9797 def __rsub__(self, other):
9798 """Create the Z3 expression `other - self`.
9799
9800 >>> x = FP('x', FPSort(8, 24))
9801 >>> 10 - x
9802 1.25*(2**3) - x
9803 """
9804 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9805 return fpSub(_dflt_rm(), a, b, self.ctx)
9806
9807 def __mul__(self, other):
9808 """Create the Z3 expression `self * other`.
9809
9810 >>> x = FP('x', FPSort(8, 24))
9811 >>> y = FP('y', FPSort(8, 24))
9812 >>> x * y
9813 x * y
9814 >>> (x * y).sort()
9815 FPSort(8, 24)
9816 >>> 10 * y
9817 1.25*(2**3) * y
9818 """
9819 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9820 return fpMul(_dflt_rm(), a, b, self.ctx)
9821
9822 def __rmul__(self, other):
9823 """Create the Z3 expression `other * self`.
9824
9825 >>> x = FP('x', FPSort(8, 24))
9826 >>> y = FP('y', FPSort(8, 24))
9827 >>> x * y
9828 x * y
9829 >>> x * 10
9830 x * 1.25*(2**3)
9831 """
9832 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9833 return fpMul(_dflt_rm(), a, b, self.ctx)
9834
9835 def __pos__(self):
9836 """Create the Z3 expression `+self`."""
9837 return self
9838
9839 def __neg__(self):
9840 """Create the Z3 expression `-self`.
9841
9842 >>> x = FP('x', Float32())
9843 >>> -x
9844 -x
9845 """
9846 return fpNeg(self)
9847
9848 def __div__(self, other):
9849 """Create the Z3 expression `self / other`.
9850
9851 >>> x = FP('x', FPSort(8, 24))
9852 >>> y = FP('y', FPSort(8, 24))
9853 >>> x / y
9854 x / y
9855 >>> (x / y).sort()
9856 FPSort(8, 24)
9857 >>> 10 / y
9858 1.25*(2**3) / y
9859 """
9860 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9861 return fpDiv(_dflt_rm(), a, b, self.ctx)
9862
9863 def __rdiv__(self, other):
9864 """Create the Z3 expression `other / self`.
9865
9866 >>> x = FP('x', FPSort(8, 24))
9867 >>> y = FP('y', FPSort(8, 24))
9868 >>> x / y
9869 x / y
9870 >>> x / 10
9871 x / 1.25*(2**3)
9872 """
9873 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9874 return fpDiv(_dflt_rm(), a, b, self.ctx)
9875
9876 def __truediv__(self, other):
9877 """Create the Z3 expression division `self / other`."""
9878 return self.__div__(other)
9879
9880 def __rtruediv__(self, other):
9881 """Create the Z3 expression division `other / self`."""
9882 return self.__rdiv__(other)
9883
9884 def __mod__(self, other):
9885 """Create the Z3 expression mod `self % other`."""
9886 return fpRem(self, other)
9887
9888 def __rmod__(self, other):
9889 """Create the Z3 expression mod `other % self`."""
9890 return fpRem(other, self)
9891
9892
9893class FPRMRef(ExprRef):
9894 """Floating-point rounding mode expressions"""
9895
9896 def as_string(self):
9897 """Return a Z3 floating point expression as a Python string."""
9898 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9899
9900
9901def RoundNearestTiesToEven(ctx=None):
9902 ctx = _get_ctx(ctx)
9903 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9904
9905
9906def RNE(ctx=None):
9907 ctx = _get_ctx(ctx)
9908 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9909
9910
9911def RoundNearestTiesToAway(ctx=None):
9912 ctx = _get_ctx(ctx)
9913 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9914
9915
9916def RNA(ctx=None):
9917 ctx = _get_ctx(ctx)
9918 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9919
9920
9921def RoundTowardPositive(ctx=None):
9922 ctx = _get_ctx(ctx)
9923 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9924
9925
9926def RTP(ctx=None):
9927 ctx = _get_ctx(ctx)
9928 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9929
9930
9931def RoundTowardNegative(ctx=None):
9932 ctx = _get_ctx(ctx)
9933 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9934
9935
9936def RTN(ctx=None):
9937 ctx = _get_ctx(ctx)
9938 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9939
9940
9941def RoundTowardZero(ctx=None):
9942 ctx = _get_ctx(ctx)
9943 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9944
9945
9946def RTZ(ctx=None):
9947 ctx = _get_ctx(ctx)
9948 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9949
9950
9951def is_fprm(a):
9952 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
9953
9954 >>> rm = RNE()
9955 >>> is_fprm(rm)
9956 True
9957 >>> rm = 1.0
9958 >>> is_fprm(rm)
9959 False
9960 """
9961 return isinstance(a, FPRMRef)
9962
9963
9964def is_fprm_value(a):
9965 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
9966 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
9967
9968# FP Numerals
9969
9970
9971class FPNumRef(FPRef):
9972 """The sign of the numeral.
9973
9974 >>> x = FPVal(+1.0, FPSort(8, 24))
9975 >>> x.sign()
9976 False
9977 >>> x = FPVal(-1.0, FPSort(8, 24))
9978 >>> x.sign()
9979 True
9980 """
9981
9982 def sign(self):
9983 num = (ctypes.c_int)()
9984 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
9985 if nsign is False:
9986 raise Z3Exception("error retrieving the sign of a numeral.")
9987 return num.value != 0
9988
9989 """The sign of a floating-point numeral as a bit-vector expression.
9990
9991 Remark: NaN's are invalid arguments.
9992 """
9993
9994 def sign_as_bv(self):
9995 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9996
9997 """The significand of the numeral.
9998
9999 >>> x = FPVal(2.5, FPSort(8, 24))
10000 >>> x.significand()
10001 1.25
10002 """
10003
10004 def significand(self):
10005 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10006
10007 """The significand of the numeral as a long.
10008
10009 >>> x = FPVal(2.5, FPSort(8, 24))
10010 >>> x.significand_as_long()
10011 1.25
10012 """
10013
10014 def significand_as_long(self):
10015 ptr = (ctypes.c_ulonglong * 1)()
10016 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10017 raise Z3Exception("error retrieving the significand of a numeral.")
10018 return ptr[0]
10019
10020 """The significand of the numeral as a bit-vector expression.
10021
10022 Remark: NaN are invalid arguments.
10023 """
10024
10025 def significand_as_bv(self):
10026 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10027
10028 """The exponent of the numeral.
10029
10030 >>> x = FPVal(2.5, FPSort(8, 24))
10031 >>> x.exponent()
10032 1
10033 """
10034
10035 def exponent(self, biased=True):
10036 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10037
10038 """The exponent of the numeral as a long.
10039
10040 >>> x = FPVal(2.5, FPSort(8, 24))
10041 >>> x.exponent_as_long()
10042 1
10043 """
10044
10045 def exponent_as_long(self, biased=True):
10046 ptr = (ctypes.c_longlong * 1)()
10047 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10048 raise Z3Exception("error retrieving the exponent of a numeral.")
10049 return ptr[0]
10050
10051 """The exponent of the numeral as a bit-vector expression.
10052
10053 Remark: NaNs are invalid arguments.
10054 """
10055
10056 def exponent_as_bv(self, biased=True):
10057 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10058
10059 """Indicates whether the numeral is a NaN."""
10060
10061 def isNaN(self):
10062 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10063
10064 """Indicates whether the numeral is +oo or -oo."""
10065
10066 def isInf(self):
10067 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10068
10069 """Indicates whether the numeral is +zero or -zero."""
10070
10071 def isZero(self):
10072 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10073
10074 """Indicates whether the numeral is normal."""
10075
10076 def isNormal(self):
10077 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10078
10079 """Indicates whether the numeral is subnormal."""
10080
10081 def isSubnormal(self):
10082 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10083
10084 """Indicates whether the numeral is positive."""
10085
10086 def isPositive(self):
10087 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10088
10089 """Indicates whether the numeral is negative."""
10090
10091 def isNegative(self):
10092 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10093
10094 """
10095 The string representation of the numeral.
10096
10097 >>> x = FPVal(20, FPSort(8, 24))
10098 >>> x.as_string()
10099 1.25*(2**4)
10100 """
10101
10102 def as_string(self):
10103 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10104 return ("FPVal(%s, %s)" % (s, self.sort()))
10105
10106 def py_value(self):
10107 bv = simplify(fpToIEEEBV(self))
10108 binary = bv.py_value()
10109 if not isinstance(binary, int):
10110 return None
10111 # Decode the IEEE 754 binary representation
10112 import struct
10113 bytes_rep = binary.to_bytes(8, byteorder='big')
10114 return struct.unpack('>d', bytes_rep)[0]
10115
10116
10117def is_fp(a):
10118 """Return `True` if `a` is a Z3 floating-point expression.
10119
10120 >>> b = FP('b', FPSort(8, 24))
10121 >>> is_fp(b)
10122 True
10123 >>> is_fp(b + 1.0)
10124 True
10125 >>> is_fp(Int('x'))
10126 False
10127 """
10128 return isinstance(a, FPRef)
10129
10130
10131def is_fp_value(a):
10132 """Return `True` if `a` is a Z3 floating-point numeral value.
10133
10134 >>> b = FP('b', FPSort(8, 24))
10135 >>> is_fp_value(b)
10136 False
10137 >>> b = FPVal(1.0, FPSort(8, 24))
10138 >>> b
10139 1
10140 >>> is_fp_value(b)
10141 True
10142 """
10143 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10144
10145
10146def FPSort(ebits, sbits, ctx=None):
10147 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10148
10149 >>> Single = FPSort(8, 24)
10150 >>> Double = FPSort(11, 53)
10151 >>> Single
10152 FPSort(8, 24)
10153 >>> x = Const('x', Single)
10154 >>> eq(x, FP('x', FPSort(8, 24)))
10155 True
10156 """
10157 ctx = _get_ctx(ctx)
10158 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10159
10160
10161def _to_float_str(val, exp=0):
10162 if isinstance(val, float):
10163 if math.isnan(val):
10164 res = "NaN"
10165 elif val == 0.0:
10166 sone = math.copysign(1.0, val)
10167 if sone < 0.0:
10168 return "-0.0"
10169 else:
10170 return "+0.0"
10171 elif val == float("+inf"):
10172 res = "+oo"
10173 elif val == float("-inf"):
10174 res = "-oo"
10175 else:
10176 v = val.as_integer_ratio()
10177 num = v[0]
10178 den = v[1]
10179 rvs = str(num) + "/" + str(den)
10180 res = rvs + "p" + _to_int_str(exp)
10181 elif isinstance(val, bool):
10182 if val:
10183 res = "1.0"
10184 else:
10185 res = "0.0"
10186 elif _is_int(val):
10187 res = str(val)
10188 elif isinstance(val, str):
10189 inx = val.find("*(2**")
10190 if inx == -1:
10191 res = val
10192 elif val[-1] == ")":
10193 res = val[0:inx]
10194 exp = str(int(val[inx + 5:-1]) + int(exp))
10195 else:
10196 _z3_assert(False, "String does not have floating-point numeral form.")
10197 elif z3_debug():
10198 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10199 if exp == 0:
10200 return res
10201 else:
10202 return res + "p" + exp
10203
10204
10205def fpNaN(s):
10206 """Create a Z3 floating-point NaN term.
10207
10208 >>> s = FPSort(8, 24)
10209 >>> set_fpa_pretty(True)
10210 >>> fpNaN(s)
10211 NaN
10212 >>> pb = get_fpa_pretty()
10213 >>> set_fpa_pretty(False)
10214 >>> fpNaN(s)
10215 fpNaN(FPSort(8, 24))
10216 >>> set_fpa_pretty(pb)
10217 """
10218 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10219 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10220
10221
10222def fpPlusInfinity(s):
10223 """Create a Z3 floating-point +oo term.
10224
10225 >>> s = FPSort(8, 24)
10226 >>> pb = get_fpa_pretty()
10227 >>> set_fpa_pretty(True)
10228 >>> fpPlusInfinity(s)
10229 +oo
10230 >>> set_fpa_pretty(False)
10231 >>> fpPlusInfinity(s)
10232 fpPlusInfinity(FPSort(8, 24))
10233 >>> set_fpa_pretty(pb)
10234 """
10235 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10236 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10237
10238
10239def fpMinusInfinity(s):
10240 """Create a Z3 floating-point -oo term."""
10241 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10242 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10243
10244
10245def fpInfinity(s, negative):
10246 """Create a Z3 floating-point +oo or -oo term."""
10247 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10248 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10249 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10250
10251
10252def fpPlusZero(s):
10253 """Create a Z3 floating-point +0.0 term."""
10254 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10255 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10256
10257
10258def fpMinusZero(s):
10259 """Create a Z3 floating-point -0.0 term."""
10260 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10261 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10262
10263
10264def fpZero(s, negative):
10265 """Create a Z3 floating-point +0.0 or -0.0 term."""
10266 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10267 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10268 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10269
10270
10271def FPVal(sig, exp=None, fps=None, ctx=None):
10272 """Return a floating-point value of value `val` and sort `fps`.
10273 If `ctx=None`, then the global context is used.
10274
10275 >>> v = FPVal(20.0, FPSort(8, 24))
10276 >>> v
10277 1.25*(2**4)
10278 >>> print("0x%.8x" % v.exponent_as_long(False))
10279 0x00000004
10280 >>> v = FPVal(2.25, FPSort(8, 24))
10281 >>> v
10282 1.125*(2**1)
10283 >>> v = FPVal(-2.25, FPSort(8, 24))
10284 >>> v
10285 -1.125*(2**1)
10286 >>> FPVal(-0.0, FPSort(8, 24))
10287 -0.0
10288 >>> FPVal(0.0, FPSort(8, 24))
10289 +0.0
10290 >>> FPVal(+0.0, FPSort(8, 24))
10291 +0.0
10292 """
10293 ctx = _get_ctx(ctx)
10294 if is_fp_sort(exp):
10295 fps = exp
10296 exp = None
10297 elif fps is None:
10298 fps = _dflt_fps(ctx)
10299 _z3_assert(is_fp_sort(fps), "sort mismatch")
10300 if exp is None:
10301 exp = 0
10302 val = _to_float_str(sig)
10303 if val == "NaN" or val == "nan":
10304 return fpNaN(fps)
10305 elif val == "-0.0":
10306 return fpMinusZero(fps)
10307 elif val == "0.0" or val == "+0.0":
10308 return fpPlusZero(fps)
10309 elif val == "+oo" or val == "+inf" or val == "+Inf":
10310 return fpPlusInfinity(fps)
10311 elif val == "-oo" or val == "-inf" or val == "-Inf":
10312 return fpMinusInfinity(fps)
10313 else:
10314 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10315
10316
10317def FP(name, fpsort, ctx=None):
10318 """Return a floating-point constant named `name`.
10319 `fpsort` is the floating-point sort.
10320 If `ctx=None`, then the global context is used.
10321
10322 >>> x = FP('x', FPSort(8, 24))
10323 >>> is_fp(x)
10324 True
10325 >>> x.ebits()
10326 8
10327 >>> x.sort()
10328 FPSort(8, 24)
10329 >>> word = FPSort(8, 24)
10330 >>> x2 = FP('x', word)
10331 >>> eq(x, x2)
10332 True
10333 """
10334 if isinstance(fpsort, FPSortRef) and ctx is None:
10335 ctx = fpsort.ctx
10336 else:
10337 ctx = _get_ctx(ctx)
10338 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10339
10340
10341def FPs(names, fpsort, ctx=None):
10342 """Return an array of floating-point constants.
10343
10344 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10345 >>> x.sort()
10346 FPSort(8, 24)
10347 >>> x.sbits()
10348 24
10349 >>> x.ebits()
10350 8
10351 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10352 (x + y) * z
10353 """
10354 ctx = _get_ctx(ctx)
10355 if isinstance(names, str):
10356 names = names.split(" ")
10357 return [FP(name, fpsort, ctx) for name in names]
10358
10359
10360def fpAbs(a, ctx=None):
10361 """Create a Z3 floating-point absolute value expression.
10362
10363 >>> s = FPSort(8, 24)
10364 >>> rm = RNE()
10365 >>> x = FPVal(1.0, s)
10366 >>> fpAbs(x)
10367 fpAbs(1)
10368 >>> y = FPVal(-20.0, s)
10369 >>> y
10370 -1.25*(2**4)
10371 >>> fpAbs(y)
10372 fpAbs(-1.25*(2**4))
10373 >>> fpAbs(-1.25*(2**4))
10374 fpAbs(-1.25*(2**4))
10375 >>> fpAbs(x).sort()
10376 FPSort(8, 24)
10377 """
10378 ctx = _get_ctx(ctx)
10379 [a] = _coerce_fp_expr_list([a], ctx)
10380 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10381
10382
10383def fpNeg(a, ctx=None):
10384 """Create a Z3 floating-point addition expression.
10385
10386 >>> s = FPSort(8, 24)
10387 >>> rm = RNE()
10388 >>> x = FP('x', s)
10389 >>> fpNeg(x)
10390 -x
10391 >>> fpNeg(x).sort()
10392 FPSort(8, 24)
10393 """
10394 ctx = _get_ctx(ctx)
10395 [a] = _coerce_fp_expr_list([a], ctx)
10396 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10397
10398
10399def _mk_fp_unary(f, rm, a, ctx):
10400 ctx = _get_ctx(ctx)
10401 [a] = _coerce_fp_expr_list([a], ctx)
10402 if z3_debug():
10403 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10404 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10405 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10406
10407
10408def _mk_fp_unary_pred(f, a, ctx):
10409 ctx = _get_ctx(ctx)
10410 [a] = _coerce_fp_expr_list([a], ctx)
10411 if z3_debug():
10412 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10413 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10414
10415
10416def _mk_fp_bin(f, rm, a, b, ctx):
10417 ctx = _get_ctx(ctx)
10418 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10419 if z3_debug():
10420 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10421 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10422 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10423
10424
10425def _mk_fp_bin_norm(f, a, b, ctx):
10426 ctx = _get_ctx(ctx)
10427 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10428 if z3_debug():
10429 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10430 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10431
10432
10433def _mk_fp_bin_pred(f, a, b, ctx):
10434 ctx = _get_ctx(ctx)
10435 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10436 if z3_debug():
10437 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10438 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10439
10440
10441def _mk_fp_tern(f, rm, a, b, c, ctx):
10442 ctx = _get_ctx(ctx)
10443 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10444 if z3_debug():
10445 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10446 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10447 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10448 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10449
10450
10451def fpAdd(rm, a, b, ctx=None):
10452 """Create a Z3 floating-point addition expression.
10453
10454 >>> s = FPSort(8, 24)
10455 >>> rm = RNE()
10456 >>> x = FP('x', s)
10457 >>> y = FP('y', s)
10458 >>> fpAdd(rm, x, y)
10459 x + y
10460 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10461 fpAdd(RTZ(), x, y)
10462 >>> fpAdd(rm, x, y).sort()
10463 FPSort(8, 24)
10464 """
10465 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10466
10467
10468def fpSub(rm, a, b, ctx=None):
10469 """Create a Z3 floating-point subtraction expression.
10470
10471 >>> s = FPSort(8, 24)
10472 >>> rm = RNE()
10473 >>> x = FP('x', s)
10474 >>> y = FP('y', s)
10475 >>> fpSub(rm, x, y)
10476 x - y
10477 >>> fpSub(rm, x, y).sort()
10478 FPSort(8, 24)
10479 """
10480 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10481
10482
10483def fpMul(rm, a, b, ctx=None):
10484 """Create a Z3 floating-point multiplication expression.
10485
10486 >>> s = FPSort(8, 24)
10487 >>> rm = RNE()
10488 >>> x = FP('x', s)
10489 >>> y = FP('y', s)
10490 >>> fpMul(rm, x, y)
10491 x * y
10492 >>> fpMul(rm, x, y).sort()
10493 FPSort(8, 24)
10494 """
10495 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10496
10497
10498def fpDiv(rm, a, b, ctx=None):
10499 """Create a Z3 floating-point division expression.
10500
10501 >>> s = FPSort(8, 24)
10502 >>> rm = RNE()
10503 >>> x = FP('x', s)
10504 >>> y = FP('y', s)
10505 >>> fpDiv(rm, x, y)
10506 x / y
10507 >>> fpDiv(rm, x, y).sort()
10508 FPSort(8, 24)
10509 """
10510 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10511
10512
10513def fpRem(a, b, ctx=None):
10514 """Create a Z3 floating-point remainder expression.
10515
10516 >>> s = FPSort(8, 24)
10517 >>> x = FP('x', s)
10518 >>> y = FP('y', s)
10519 >>> fpRem(x, y)
10520 fpRem(x, y)
10521 >>> fpRem(x, y).sort()
10522 FPSort(8, 24)
10523 """
10524 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10525
10526
10527def fpMin(a, b, ctx=None):
10528 """Create a Z3 floating-point minimum expression.
10529
10530 >>> s = FPSort(8, 24)
10531 >>> rm = RNE()
10532 >>> x = FP('x', s)
10533 >>> y = FP('y', s)
10534 >>> fpMin(x, y)
10535 fpMin(x, y)
10536 >>> fpMin(x, y).sort()
10537 FPSort(8, 24)
10538 """
10539 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10540
10541
10542def fpMax(a, b, ctx=None):
10543 """Create a Z3 floating-point maximum expression.
10544
10545 >>> s = FPSort(8, 24)
10546 >>> rm = RNE()
10547 >>> x = FP('x', s)
10548 >>> y = FP('y', s)
10549 >>> fpMax(x, y)
10550 fpMax(x, y)
10551 >>> fpMax(x, y).sort()
10552 FPSort(8, 24)
10553 """
10554 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10555
10556
10557def fpFMA(rm, a, b, c, ctx=None):
10558 """Create a Z3 floating-point fused multiply-add expression.
10559 """
10560 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10561
10562
10563def fpSqrt(rm, a, ctx=None):
10564 """Create a Z3 floating-point square root expression.
10565 """
10566 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10567
10568
10569def fpRoundToIntegral(rm, a, ctx=None):
10570 """Create a Z3 floating-point roundToIntegral expression.
10571 """
10572 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10573
10574
10575def fpIsNaN(a, ctx=None):
10576 """Create a Z3 floating-point isNaN expression.
10577
10578 >>> s = FPSort(8, 24)
10579 >>> x = FP('x', s)
10580 >>> y = FP('y', s)
10581 >>> fpIsNaN(x)
10582 fpIsNaN(x)
10583 """
10584 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10585
10586
10587def fpIsInf(a, ctx=None):
10588 """Create a Z3 floating-point isInfinite expression.
10589
10590 >>> s = FPSort(8, 24)
10591 >>> x = FP('x', s)
10592 >>> fpIsInf(x)
10593 fpIsInf(x)
10594 """
10595 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10596
10597
10598def fpIsZero(a, ctx=None):
10599 """Create a Z3 floating-point isZero expression.
10600 """
10601 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10602
10603
10604def fpIsNormal(a, ctx=None):
10605 """Create a Z3 floating-point isNormal expression.
10606 """
10607 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10608
10609
10610def fpIsSubnormal(a, ctx=None):
10611 """Create a Z3 floating-point isSubnormal expression.
10612 """
10613 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10614
10615
10616def fpIsNegative(a, ctx=None):
10617 """Create a Z3 floating-point isNegative expression.
10618 """
10619 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10620
10621
10622def fpIsPositive(a, ctx=None):
10623 """Create a Z3 floating-point isPositive expression.
10624 """
10625 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10626
10627
10628def _check_fp_args(a, b):
10629 if z3_debug():
10630 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10631
10632
10633def fpLT(a, b, ctx=None):
10634 """Create the Z3 floating-point expression `other < self`.
10635
10636 >>> x, y = FPs('x y', FPSort(8, 24))
10637 >>> fpLT(x, y)
10638 x < y
10639 >>> (x < y).sexpr()
10640 '(fp.lt x y)'
10641 """
10642 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10643
10644
10645def fpLEQ(a, b, ctx=None):
10646 """Create the Z3 floating-point expression `other <= self`.
10647
10648 >>> x, y = FPs('x y', FPSort(8, 24))
10649 >>> fpLEQ(x, y)
10650 x <= y
10651 >>> (x <= y).sexpr()
10652 '(fp.leq x y)'
10653 """
10654 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10655
10656
10657def fpGT(a, b, ctx=None):
10658 """Create the Z3 floating-point expression `other > self`.
10659
10660 >>> x, y = FPs('x y', FPSort(8, 24))
10661 >>> fpGT(x, y)
10662 x > y
10663 >>> (x > y).sexpr()
10664 '(fp.gt x y)'
10665 """
10666 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10667
10668
10669def fpGEQ(a, b, ctx=None):
10670 """Create the Z3 floating-point expression `other >= self`.
10671
10672 >>> x, y = FPs('x y', FPSort(8, 24))
10673 >>> fpGEQ(x, y)
10674 x >= y
10675 >>> (x >= y).sexpr()
10676 '(fp.geq x y)'
10677 """
10678 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10679
10680
10681def fpEQ(a, b, ctx=None):
10682 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10683
10684 >>> x, y = FPs('x y', FPSort(8, 24))
10685 >>> fpEQ(x, y)
10686 fpEQ(x, y)
10687 >>> fpEQ(x, y).sexpr()
10688 '(fp.eq x y)'
10689 """
10690 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10691
10692
10693def fpNEQ(a, b, ctx=None):
10694 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10695
10696 >>> x, y = FPs('x y', FPSort(8, 24))
10697 >>> fpNEQ(x, y)
10698 Not(fpEQ(x, y))
10699 >>> (x != y).sexpr()
10700 '(distinct x y)'
10701 """
10702 return Not(fpEQ(a, b, ctx))
10703
10704
10705def fpFP(sgn, exp, sig, ctx=None):
10706 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10707
10708 >>> s = FPSort(8, 24)
10709 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10710 >>> print(x)
10711 fpFP(1, 127, 4194304)
10712 >>> xv = FPVal(-1.5, s)
10713 >>> print(xv)
10714 -1.5
10715 >>> slvr = Solver()
10716 >>> slvr.add(fpEQ(x, xv))
10717 >>> slvr.check()
10718 sat
10719 >>> xv = FPVal(+1.5, s)
10720 >>> print(xv)
10721 1.5
10722 >>> slvr = Solver()
10723 >>> slvr.add(fpEQ(x, xv))
10724 >>> slvr.check()
10725 unsat
10726 """
10727 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10728 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10729 ctx = _get_ctx(ctx)
10730 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10731 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10732
10733
10734def fpToFP(a1, a2=None, a3=None, ctx=None):
10735 """Create a Z3 floating-point conversion expression from other term sorts
10736 to floating-point.
10737
10738 From a bit-vector term in IEEE 754-2008 format:
10739 >>> x = FPVal(1.0, Float32())
10740 >>> x_bv = fpToIEEEBV(x)
10741 >>> simplify(fpToFP(x_bv, Float32()))
10742 1
10743
10744 From a floating-point term with different precision:
10745 >>> x = FPVal(1.0, Float32())
10746 >>> x_db = fpToFP(RNE(), x, Float64())
10747 >>> x_db.sort()
10748 FPSort(11, 53)
10749
10750 From a real term:
10751 >>> x_r = RealVal(1.5)
10752 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10753 1.5
10754
10755 From a signed bit-vector term:
10756 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10757 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10758 -1.25*(2**2)
10759 """
10760 ctx = _get_ctx(ctx)
10761 if is_bv(a1) and is_fp_sort(a2):
10762 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10763 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10764 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10765 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10766 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10767 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10768 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10769 else:
10770 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10771
10772
10773def fpBVToFP(v, sort, ctx=None):
10774 """Create a Z3 floating-point conversion expression that represents the
10775 conversion from a bit-vector term to a floating-point term.
10776
10777 >>> x_bv = BitVecVal(0x3F800000, 32)
10778 >>> x_fp = fpBVToFP(x_bv, Float32())
10779 >>> x_fp
10780 fpToFP(1065353216)
10781 >>> simplify(x_fp)
10782 1
10783 """
10784 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10785 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10786 ctx = _get_ctx(ctx)
10787 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10788
10789
10790def fpFPToFP(rm, v, sort, ctx=None):
10791 """Create a Z3 floating-point conversion expression that represents the
10792 conversion from a floating-point term to a floating-point term of different precision.
10793
10794 >>> x_sgl = FPVal(1.0, Float32())
10795 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10796 >>> x_dbl
10797 fpToFP(RNE(), 1)
10798 >>> simplify(x_dbl)
10799 1
10800 >>> x_dbl.sort()
10801 FPSort(11, 53)
10802 """
10803 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10804 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10805 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10806 ctx = _get_ctx(ctx)
10807 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10808
10809
10810def fpRealToFP(rm, v, sort, ctx=None):
10811 """Create a Z3 floating-point conversion expression that represents the
10812 conversion from a real term to a floating-point term.
10813
10814 >>> x_r = RealVal(1.5)
10815 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10816 >>> x_fp
10817 fpToFP(RNE(), 3/2)
10818 >>> simplify(x_fp)
10819 1.5
10820 """
10821 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10822 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10823 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10824 ctx = _get_ctx(ctx)
10825 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10826
10827
10828def fpSignedToFP(rm, v, sort, ctx=None):
10829 """Create a Z3 floating-point conversion expression that represents the
10830 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10831
10832 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10833 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10834 >>> x_fp
10835 fpToFP(RNE(), 4294967291)
10836 >>> simplify(x_fp)
10837 -1.25*(2**2)
10838 """
10839 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10840 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10841 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10842 ctx = _get_ctx(ctx)
10843 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10844
10845
10846def fpUnsignedToFP(rm, v, sort, ctx=None):
10847 """Create a Z3 floating-point conversion expression that represents the
10848 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10849
10850 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10851 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10852 >>> x_fp
10853 fpToFPUnsigned(RNE(), 4294967291)
10854 >>> simplify(x_fp)
10855 1*(2**32)
10856 """
10857 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10858 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10859 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10860 ctx = _get_ctx(ctx)
10861 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10862
10863
10864def fpToFPUnsigned(rm, x, s, ctx=None):
10865 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10866 if z3_debug():
10867 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10868 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10869 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10870 ctx = _get_ctx(ctx)
10871 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10872
10873
10874def fpToSBV(rm, x, s, ctx=None):
10875 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10876
10877 >>> x = FP('x', FPSort(8, 24))
10878 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10879 >>> print(is_fp(x))
10880 True
10881 >>> print(is_bv(y))
10882 True
10883 >>> print(is_fp(y))
10884 False
10885 >>> print(is_bv(x))
10886 False
10887 """
10888 if z3_debug():
10889 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10890 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10891 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10892 ctx = _get_ctx(ctx)
10893 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10894
10895
10896def fpToUBV(rm, x, s, ctx=None):
10897 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10898
10899 >>> x = FP('x', FPSort(8, 24))
10900 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10901 >>> print(is_fp(x))
10902 True
10903 >>> print(is_bv(y))
10904 True
10905 >>> print(is_fp(y))
10906 False
10907 >>> print(is_bv(x))
10908 False
10909 """
10910 if z3_debug():
10911 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10912 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10913 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10914 ctx = _get_ctx(ctx)
10915 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10916
10917
10918def fpToReal(x, ctx=None):
10919 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
10920
10921 >>> x = FP('x', FPSort(8, 24))
10922 >>> y = fpToReal(x)
10923 >>> print(is_fp(x))
10924 True
10925 >>> print(is_real(y))
10926 True
10927 >>> print(is_fp(y))
10928 False
10929 >>> print(is_real(x))
10930 False
10931 """
10932 if z3_debug():
10933 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10934 ctx = _get_ctx(ctx)
10935 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
10936
10937
10938def fpToIEEEBV(x, ctx=None):
10939 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
10940
10941 The size of the resulting bit-vector is automatically determined.
10942
10943 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
10944 knows only one NaN and it will always produce the same bit-vector representation of
10945 that NaN.
10946
10947 >>> x = FP('x', FPSort(8, 24))
10948 >>> y = fpToIEEEBV(x)
10949 >>> print(is_fp(x))
10950 True
10951 >>> print(is_bv(y))
10952 True
10953 >>> print(is_fp(y))
10954 False
10955 >>> print(is_bv(x))
10956 False
10957 """
10958 if z3_debug():
10959 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10960 ctx = _get_ctx(ctx)
10961 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
10962
10963
10964#########################################
10965#
10966# Strings, Sequences and Regular expressions
10967#
10968#########################################
10969
10970class SeqSortRef(SortRef):
10971 """Sequence sort."""
10972
10973 def is_string(self):
10974 """Determine if sort is a string
10975 >>> s = StringSort()
10976 >>> s.is_string()
10977 True
10978 >>> s = SeqSort(IntSort())
10979 >>> s.is_string()
10980 False
10981 """
10982 return Z3_is_string_sort(self.ctx_ref(), self.ast)
10983
10984 def basis(self):
10985 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10986
10987class CharSortRef(SortRef):
10988 """Character sort."""
10989
10990
10991def StringSort(ctx=None):
10992 """Create a string sort
10993 >>> s = StringSort()
10994 >>> print(s)
10995 String
10996 """
10997 ctx = _get_ctx(ctx)
10998 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
10999
11000def CharSort(ctx=None):
11001 """Create a character sort
11002 >>> ch = CharSort()
11003 >>> print(ch)
11004 Char
11005 """
11006 ctx = _get_ctx(ctx)
11007 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11008
11009
11010def SeqSort(s):
11011 """Create a sequence sort over elements provided in the argument
11012 >>> s = SeqSort(IntSort())
11013 >>> s == Unit(IntVal(1)).sort()
11014 True
11015 """
11016 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11017
11018
11019class SeqRef(ExprRef):
11020 """Sequence expression."""
11021
11022 def sort(self):
11023 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11024
11025 def __add__(self, other):
11026 return Concat(self, other)
11027
11028 def __radd__(self, other):
11029 return Concat(other, self)
11030
11031 def __getitem__(self, i):
11032 if _is_int(i):
11033 i = IntVal(i, self.ctx)
11034 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11035
11036 def at(self, i):
11037 if _is_int(i):
11038 i = IntVal(i, self.ctx)
11039 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11040
11041 def is_string(self):
11042 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11043
11044 def is_string_value(self):
11045 return Z3_is_string(self.ctx_ref(), self.as_ast())
11046
11047 def as_string(self):
11048 """Return a string representation of sequence expression."""
11049 if self.is_string_value():
11050 string_length = ctypes.c_uint()
11051 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11052 return string_at(chars, size=string_length.value).decode("latin-1")
11053 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11054
11055 def py_value(self):
11056 return self.as_string()
11057
11058 def __le__(self, other):
11059 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11060
11061 def __lt__(self, other):
11062 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11063
11064 def __ge__(self, other):
11065 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11066
11067 def __gt__(self, other):
11068 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11069
11070
11071def _coerce_char(ch, ctx=None):
11072 if isinstance(ch, str):
11073 ctx = _get_ctx(ctx)
11074 ch = CharVal(ch, ctx)
11075 if not is_expr(ch):
11076 raise Z3Exception("Character expression expected")
11077 return ch
11078
11079class CharRef(ExprRef):
11080 """Character expression."""
11081
11082 def __le__(self, other):
11083 other = _coerce_char(other, self.ctx)
11084 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11085
11086 def to_int(self):
11087 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11088
11089 def to_bv(self):
11090 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11091
11092 def is_digit(self):
11093 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11094
11095
11096def CharVal(ch, ctx=None):
11097 ctx = _get_ctx(ctx)
11098 if isinstance(ch, str):
11099 ch = ord(ch)
11100 if not isinstance(ch, int):
11101 raise Z3Exception("character value should be an ordinal")
11102 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11103
11104def CharFromBv(bv):
11105 if not is_expr(bv):
11106 raise Z3Exception("Bit-vector expression needed")
11107 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11108
11109def CharToBv(ch, ctx=None):
11110 ch = _coerce_char(ch, ctx)
11111 return ch.to_bv()
11112
11113def CharToInt(ch, ctx=None):
11114 ch = _coerce_char(ch, ctx)
11115 return ch.to_int()
11116
11117def CharIsDigit(ch, ctx=None):
11118 ch = _coerce_char(ch, ctx)
11119 return ch.is_digit()
11120
11121def _coerce_seq(s, ctx=None):
11122 if isinstance(s, str):
11123 ctx = _get_ctx(ctx)
11124 s = StringVal(s, ctx)
11125 if not is_expr(s):
11126 raise Z3Exception("Non-expression passed as a sequence")
11127 if not is_seq(s):
11128 raise Z3Exception("Non-sequence passed as a sequence")
11129 return s
11130
11131
11132def _get_ctx2(a, b, ctx=None):
11133 if is_expr(a):
11134 return a.ctx
11135 if is_expr(b):
11136 return b.ctx
11137 if ctx is None:
11138 ctx = main_ctx()
11139 return ctx
11140
11141
11142def is_seq(a):
11143 """Return `True` if `a` is a Z3 sequence expression.
11144 >>> print (is_seq(Unit(IntVal(0))))
11145 True
11146 >>> print (is_seq(StringVal("abc")))
11147 True
11148 """
11149 return isinstance(a, SeqRef)
11150
11151
11152def is_string(a: Any) -> bool:
11153 """Return `True` if `a` is a Z3 string expression.
11154 >>> print (is_string(StringVal("ab")))
11155 True
11156 """
11157 return isinstance(a, SeqRef) and a.is_string()
11158
11159
11160def is_string_value(a: Any) -> bool:
11161 """return 'True' if 'a' is a Z3 string constant expression.
11162 >>> print (is_string_value(StringVal("a")))
11163 True
11164 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11165 False
11166 """
11167 return isinstance(a, SeqRef) and a.is_string_value()
11168
11169def StringVal(s, ctx=None):
11170 """create a string expression"""
11171 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11172 ctx = _get_ctx(ctx)
11173 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11174
11175
11176def String(name, ctx=None):
11177 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11178
11179 >>> x = String('x')
11180 """
11181 ctx = _get_ctx(ctx)
11182 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11183
11184
11185def Strings(names, ctx=None):
11186 """Return a tuple of String constants. """
11187 ctx = _get_ctx(ctx)
11188 if isinstance(names, str):
11189 names = names.split(" ")
11190 return [String(name, ctx) for name in names]
11191
11192
11193def SubString(s, offset, length):
11194 """Extract substring or subsequence starting at offset"""
11195 return Extract(s, offset, length)
11196
11197
11198def SubSeq(s, offset, length):
11199 """Extract substring or subsequence starting at offset"""
11200 return Extract(s, offset, length)
11201
11202
11203def Empty(s):
11204 """Create the empty sequence of the given sort
11205 >>> e = Empty(StringSort())
11206 >>> e2 = StringVal("")
11207 >>> print(e.eq(e2))
11208 True
11209 >>> e3 = Empty(SeqSort(IntSort()))
11210 >>> print(e3)
11211 Empty(Seq(Int))
11212 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11213 >>> print(e4)
11214 Empty(ReSort(Seq(Int)))
11215 """
11216 if isinstance(s, SeqSortRef):
11217 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11218 if isinstance(s, ReSortRef):
11219 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11220 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11221
11222
11223def Full(s):
11224 """Create the regular expression that accepts the universal language
11225 >>> e = Full(ReSort(SeqSort(IntSort())))
11226 >>> print(e)
11227 Full(ReSort(Seq(Int)))
11228 >>> e1 = Full(ReSort(StringSort()))
11229 >>> print(e1)
11230 Full(ReSort(String))
11231 """
11232 if isinstance(s, ReSortRef):
11233 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11234 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11235
11236
11237
11238def Unit(a):
11239 """Create a singleton sequence"""
11240 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11241
11242
11243def PrefixOf(a, b):
11244 """Check if 'a' is a prefix of 'b'
11245 >>> s1 = PrefixOf("ab", "abc")
11246 >>> simplify(s1)
11247 True
11248 >>> s2 = PrefixOf("bc", "abc")
11249 >>> simplify(s2)
11250 False
11251 """
11252 ctx = _get_ctx2(a, b)
11253 a = _coerce_seq(a, ctx)
11254 b = _coerce_seq(b, ctx)
11255 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11256
11257
11258def SuffixOf(a, b):
11259 """Check if 'a' is a suffix of 'b'
11260 >>> s1 = SuffixOf("ab", "abc")
11261 >>> simplify(s1)
11262 False
11263 >>> s2 = SuffixOf("bc", "abc")
11264 >>> simplify(s2)
11265 True
11266 """
11267 ctx = _get_ctx2(a, b)
11268 a = _coerce_seq(a, ctx)
11269 b = _coerce_seq(b, ctx)
11270 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11271
11272
11273def Contains(a, b):
11274 """Check if 'a' contains 'b'
11275 >>> s1 = Contains("abc", "ab")
11276 >>> simplify(s1)
11277 True
11278 >>> s2 = Contains("abc", "bc")
11279 >>> simplify(s2)
11280 True
11281 >>> x, y, z = Strings('x y z')
11282 >>> s3 = Contains(Concat(x,y,z), y)
11283 >>> simplify(s3)
11284 True
11285 """
11286 ctx = _get_ctx2(a, b)
11287 a = _coerce_seq(a, ctx)
11288 b = _coerce_seq(b, ctx)
11289 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11290
11291
11292def Replace(s, src, dst):
11293 """Replace the first occurrence of 'src' by 'dst' in 's'
11294 >>> r = Replace("aaa", "a", "b")
11295 >>> simplify(r)
11296 "baa"
11297 """
11298 ctx = _get_ctx2(dst, s)
11299 if ctx is None and is_expr(src):
11300 ctx = src.ctx
11301 src = _coerce_seq(src, ctx)
11302 dst = _coerce_seq(dst, ctx)
11303 s = _coerce_seq(s, ctx)
11304 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11305
11306
11307def IndexOf(s, substr, offset=None):
11308 """Retrieve the index of substring within a string starting at a specified offset.
11309 >>> simplify(IndexOf("abcabc", "bc", 0))
11310 1
11311 >>> simplify(IndexOf("abcabc", "bc", 2))
11312 4
11313 """
11314 if offset is None:
11315 offset = IntVal(0)
11316 ctx = None
11317 if is_expr(offset):
11318 ctx = offset.ctx
11319 ctx = _get_ctx2(s, substr, ctx)
11320 s = _coerce_seq(s, ctx)
11321 substr = _coerce_seq(substr, ctx)
11322 if _is_int(offset):
11323 offset = IntVal(offset, ctx)
11324 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11325
11326
11327def LastIndexOf(s, substr):
11328 """Retrieve the last index of substring within a string"""
11329 ctx = None
11330 ctx = _get_ctx2(s, substr, ctx)
11331 s = _coerce_seq(s, ctx)
11332 substr = _coerce_seq(substr, ctx)
11333 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11334
11335
11336def Length(s):
11337 """Obtain the length of a sequence 's'
11338 >>> l = Length(StringVal("abc"))
11339 >>> simplify(l)
11340 3
11341 """
11342 s = _coerce_seq(s)
11343 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11344
11345def SeqMap(f, s):
11346 """Map function 'f' over sequence 's'"""
11347 ctx = _get_ctx2(f, s)
11348 s = _coerce_seq(s, ctx)
11349 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11350
11351def SeqMapI(f, i, s):
11352 """Map function 'f' over sequence 's' at index 'i'"""
11353 ctx = _get_ctx2(f, s)
11354 s = _coerce_seq(s, ctx)
11355 if not is_expr(i):
11356 i = _py2expr(i)
11357 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11358
11359def SeqFoldLeft(f, a, s):
11360 ctx = _get_ctx2(f, s)
11361 s = _coerce_seq(s, ctx)
11362 a = _py2expr(a)
11363 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11364
11365def SeqFoldLeftI(f, i, a, s):
11366 ctx = _get_ctx2(f, s)
11367 s = _coerce_seq(s, ctx)
11368 a = _py2expr(a)
11369 i = _py2epxr(i)
11370 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11371
11372def StrToInt(s):
11373 """Convert string expression to integer
11374 >>> a = StrToInt("1")
11375 >>> simplify(1 == a)
11376 True
11377 >>> b = StrToInt("2")
11378 >>> simplify(1 == b)
11379 False
11380 >>> c = StrToInt(IntToStr(2))
11381 >>> simplify(1 == c)
11382 False
11383 """
11384 s = _coerce_seq(s)
11385 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11386
11387
11388def IntToStr(s):
11389 """Convert integer expression to string"""
11390 if not is_expr(s):
11391 s = _py2expr(s)
11392 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11393
11394
11395def StrToCode(s):
11396 """Convert a unit length string to integer code"""
11397 if not is_expr(s):
11398 s = _py2expr(s)
11399 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11400
11401def StrFromCode(c):
11402 """Convert code to a string"""
11403 if not is_expr(c):
11404 c = _py2expr(c)
11405 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11406
11407def Re(s, ctx=None):
11408 """The regular expression that accepts sequence 's'
11409 >>> s1 = Re("ab")
11410 >>> s2 = Re(StringVal("ab"))
11411 >>> s3 = Re(Unit(BoolVal(True)))
11412 """
11413 s = _coerce_seq(s, ctx)
11414 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11415
11416
11417# Regular expressions
11418
11419class ReSortRef(SortRef):
11420 """Regular expression sort."""
11421
11422 def basis(self):
11423 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11424
11425
11426def ReSort(s):
11427 if is_ast(s):
11428 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11429 if s is None or isinstance(s, Context):
11430 ctx = _get_ctx(s)
11431 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11432 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11433
11434
11435class ReRef(ExprRef):
11436 """Regular expressions."""
11437
11438 def __add__(self, other):
11439 return Union(self, other)
11440
11441
11442def is_re(s):
11443 return isinstance(s, ReRef)
11444
11445
11446def InRe(s, re):
11447 """Create regular expression membership test
11448 >>> re = Union(Re("a"),Re("b"))
11449 >>> print (simplify(InRe("a", re)))
11450 True
11451 >>> print (simplify(InRe("b", re)))
11452 True
11453 >>> print (simplify(InRe("c", re)))
11454 False
11455 """
11456 s = _coerce_seq(s, re.ctx)
11457 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11458
11459
11460def Union(*args):
11461 """Create union of regular expressions.
11462 >>> re = Union(Re("a"), Re("b"), Re("c"))
11463 >>> print (simplify(InRe("d", re)))
11464 False
11465 """
11466 args = _get_args(args)
11467 sz = len(args)
11468 if z3_debug():
11469 _z3_assert(sz > 0, "At least one argument expected.")
11470 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11471 if sz == 1:
11472 return args[0]
11473 ctx = args[0].ctx
11474 v = (Ast * sz)()
11475 for i in range(sz):
11476 v[i] = args[i].as_ast()
11477 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11478
11479
11480def Intersect(*args):
11481 """Create intersection of regular expressions.
11482 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11483 """
11484 args = _get_args(args)
11485 sz = len(args)
11486 if z3_debug():
11487 _z3_assert(sz > 0, "At least one argument expected.")
11488 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11489 if sz == 1:
11490 return args[0]
11491 ctx = args[0].ctx
11492 v = (Ast * sz)()
11493 for i in range(sz):
11494 v[i] = args[i].as_ast()
11495 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11496
11497
11498def Plus(re):
11499 """Create the regular expression accepting one or more repetitions of argument.
11500 >>> re = Plus(Re("a"))
11501 >>> print(simplify(InRe("aa", re)))
11502 True
11503 >>> print(simplify(InRe("ab", re)))
11504 False
11505 >>> print(simplify(InRe("", re)))
11506 False
11507 """
11508 if z3_debug():
11509 _z3_assert(is_expr(re), "expression expected")
11510 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11511
11512
11513def Option(re):
11514 """Create the regular expression that optionally accepts the argument.
11515 >>> re = Option(Re("a"))
11516 >>> print(simplify(InRe("a", re)))
11517 True
11518 >>> print(simplify(InRe("", re)))
11519 True
11520 >>> print(simplify(InRe("aa", re)))
11521 False
11522 """
11523 if z3_debug():
11524 _z3_assert(is_expr(re), "expression expected")
11525 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11526
11527
11528def Complement(re):
11529 """Create the complement regular expression."""
11530 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11531
11532
11533def Star(re):
11534 """Create the regular expression accepting zero or more repetitions of argument.
11535 >>> re = Star(Re("a"))
11536 >>> print(simplify(InRe("aa", re)))
11537 True
11538 >>> print(simplify(InRe("ab", re)))
11539 False
11540 >>> print(simplify(InRe("", re)))
11541 True
11542 """
11543 if z3_debug():
11544 _z3_assert(is_expr(re), "expression expected")
11545 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11546
11547
11548def Loop(re, lo, hi=0):
11549 """Create the regular expression accepting between a lower and upper bound repetitions
11550 >>> re = Loop(Re("a"), 1, 3)
11551 >>> print(simplify(InRe("aa", re)))
11552 True
11553 >>> print(simplify(InRe("aaaa", re)))
11554 False
11555 >>> print(simplify(InRe("", re)))
11556 False
11557 """
11558 if z3_debug():
11559 _z3_assert(is_expr(re), "expression expected")
11560 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11561
11562
11563def Range(lo, hi, ctx=None):
11564 """Create the range regular expression over two sequences of length 1
11565 >>> range = Range("a","z")
11566 >>> print(simplify(InRe("b", range)))
11567 True
11568 >>> print(simplify(InRe("bb", range)))
11569 False
11570 """
11571 lo = _coerce_seq(lo, ctx)
11572 hi = _coerce_seq(hi, ctx)
11573 if z3_debug():
11574 _z3_assert(is_expr(lo), "expression expected")
11575 _z3_assert(is_expr(hi), "expression expected")
11576 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11577
11578def Diff(a, b, ctx=None):
11579 """Create the difference regular expression
11580 """
11581 if z3_debug():
11582 _z3_assert(is_expr(a), "expression expected")
11583 _z3_assert(is_expr(b), "expression expected")
11584 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11585
11586def AllChar(regex_sort, ctx=None):
11587 """Create a regular expression that accepts all single character strings
11588 """
11589 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11590
11591# Special Relations
11592
11593
11594def PartialOrder(a, index):
11595 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11596
11597
11598def LinearOrder(a, index):
11599 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11600
11601
11602def TreeOrder(a, index):
11603 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11604
11605
11606def PiecewiseLinearOrder(a, index):
11607 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11608
11609
11610def TransitiveClosure(f):
11611 """Given a binary relation R, such that the two arguments have the same sort
11612 create the transitive closure relation R+.
11613 The transitive closure R+ is a new relation.
11614 """
11615 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11616
11617def to_Ast(ptr,):
11618 ast = Ast(ptr)
11619 super(ctypes.c_void_p, ast).__init__(ptr)
11620 return ast
11621
11622def to_ContextObj(ptr,):
11623 ctx = ContextObj(ptr)
11624 super(ctypes.c_void_p, ctx).__init__(ptr)
11625 return ctx
11626
11627def to_AstVectorObj(ptr,):
11628 v = AstVectorObj(ptr)
11629 super(ctypes.c_void_p, v).__init__(ptr)
11630 return v
11631
11632# NB. my-hacky-class only works for a single instance of OnClause
11633# it should be replaced with a proper correlation between OnClause
11634# and object references that can be passed over the FFI.
11635# for UserPropagator we use a global dictionary, which isn't great code.
11636
11637_my_hacky_class = None
11638def on_clause_eh(ctx, p, n, dep, clause):
11639 onc = _my_hacky_class
11640 p = _to_expr_ref(to_Ast(p), onc.ctx)
11641 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11642 deps = [dep[i] for i in range(n)]
11643 onc.on_clause(p, deps, clause)
11644
11645_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11646
11647class OnClause:
11648 def __init__(self, s, on_clause):
11649 self.s = s
11650 self.ctx = s.ctx
11651 self.on_clause = on_clause
11652 self.idx = 22
11653 global _my_hacky_class
11654 _my_hacky_class = self
11655 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11656
11657
11658class PropClosures:
11659 def __init__(self):
11660 self.bases = {}
11661 self.lock = None
11662
11663 def set_threaded(self):
11664 if self.lock is None:
11665 import threading
11666 self.lock = threading.Lock()
11667
11668 def get(self, ctx):
11669 if self.lock:
11670 with self.lock:
11671 r = self.bases[ctx]
11672 else:
11673 r = self.bases[ctx]
11674 return r
11675
11676 def set(self, ctx, r):
11677 if self.lock:
11678 with self.lock:
11679 self.bases[ctx] = r
11680 else:
11681 self.bases[ctx] = r
11682
11683 def insert(self, r):
11684 if self.lock:
11685 with self.lock:
11686 id = len(self.bases) + 3
11687 self.bases[id] = r
11688 else:
11689 id = len(self.bases) + 3
11690 self.bases[id] = r
11691 return id
11692
11693
11694_prop_closures = None
11695
11696
11697def ensure_prop_closures():
11698 global _prop_closures
11699 if _prop_closures is None:
11700 _prop_closures = PropClosures()
11701
11702
11703def user_prop_push(ctx, cb):
11704 prop = _prop_closures.get(ctx)
11705 prop.cb = cb
11706 prop.push()
11707
11708
11709def user_prop_pop(ctx, cb, num_scopes):
11710 prop = _prop_closures.get(ctx)
11711 prop.cb = cb
11712 prop.pop(num_scopes)
11713
11714
11715def user_prop_fresh(ctx, _new_ctx):
11716 _prop_closures.set_threaded()
11717 prop = _prop_closures.get(ctx)
11718 nctx = Context()
11719 Z3_del_context(nctx.ctx)
11720 new_ctx = to_ContextObj(_new_ctx)
11721 nctx.ctx = new_ctx
11722 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11723 nctx.owner = False
11724 new_prop = prop.fresh(nctx)
11725 _prop_closures.set(new_prop.id, new_prop)
11726 return new_prop.id
11727
11728
11729def user_prop_fixed(ctx, cb, id, value):
11730 prop = _prop_closures.get(ctx)
11731 old_cb = prop.cb
11732 prop.cb = cb
11733 id = _to_expr_ref(to_Ast(id), prop.ctx())
11734 value = _to_expr_ref(to_Ast(value), prop.ctx())
11735 prop.fixed(id, value)
11736 prop.cb = old_cb
11737
11738def user_prop_created(ctx, cb, id):
11739 prop = _prop_closures.get(ctx)
11740 old_cb = prop.cb
11741 prop.cb = cb
11742 id = _to_expr_ref(to_Ast(id), prop.ctx())
11743 prop.created(id)
11744 prop.cb = old_cb
11745
11746
11747def user_prop_final(ctx, cb):
11748 prop = _prop_closures.get(ctx)
11749 old_cb = prop.cb
11750 prop.cb = cb
11751 prop.final()
11752 prop.cb = old_cb
11753
11754def user_prop_eq(ctx, cb, x, y):
11755 prop = _prop_closures.get(ctx)
11756 old_cb = prop.cb
11757 prop.cb = cb
11758 x = _to_expr_ref(to_Ast(x), prop.ctx())
11759 y = _to_expr_ref(to_Ast(y), prop.ctx())
11760 prop.eq(x, y)
11761 prop.cb = old_cb
11762
11763def user_prop_diseq(ctx, cb, x, y):
11764 prop = _prop_closures.get(ctx)
11765 old_cb = prop.cb
11766 prop.cb = cb
11767 x = _to_expr_ref(to_Ast(x), prop.ctx())
11768 y = _to_expr_ref(to_Ast(y), prop.ctx())
11769 prop.diseq(x, y)
11770 prop.cb = old_cb
11771
11772def user_prop_decide(ctx, cb, t_ref, idx, phase):
11773 prop = _prop_closures.get(ctx)
11774 old_cb = prop.cb
11775 prop.cb = cb
11776 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11777 prop.decide(t, idx, phase)
11778 prop.cb = old_cb
11779
11780
11781_user_prop_push = Z3_push_eh(user_prop_push)
11782_user_prop_pop = Z3_pop_eh(user_prop_pop)
11783_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11784_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11785_user_prop_created = Z3_created_eh(user_prop_created)
11786_user_prop_final = Z3_final_eh(user_prop_final)
11787_user_prop_eq = Z3_eq_eh(user_prop_eq)
11788_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11789_user_prop_decide = Z3_decide_eh(user_prop_decide)
11790
11791
11792def PropagateFunction(name, *sig):
11793 """Create a function that gets tracked by user propagator.
11794 Every term headed by this function symbol is tracked.
11795 If a term is fixed and the fixed callback is registered a
11796 callback is invoked that the term headed by this function is fixed.
11797 """
11798 sig = _get_args(sig)
11799 if z3_debug():
11800 _z3_assert(len(sig) > 0, "At least two arguments expected")
11801 arity = len(sig) - 1
11802 rng = sig[arity]
11803 if z3_debug():
11804 _z3_assert(is_sort(rng), "Z3 sort expected")
11805 dom = (Sort * arity)()
11806 for i in range(arity):
11807 if z3_debug():
11808 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11809 dom[i] = sig[i].ast
11810 ctx = rng.ctx
11811 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11812
11813
11814
11815class UserPropagateBase:
11816
11817 #
11818 # Either solver is set or ctx is set.
11819 # Propagators that are created through callbacks
11820 # to "fresh" inherit the context of that is supplied
11821 # as argument to the callback.
11822 # This context should not be deleted. It is owned by the solver.
11823 #
11824 def __init__(self, s, ctx=None):
11825 assert s is None or ctx is None
11826 ensure_prop_closures()
11827 self.solver = s
11828 self._ctx = None
11829 self.fresh_ctx = None
11830 self.cb = None
11831 self.id = _prop_closures.insert(self)
11832 self.fixed = None
11833 self.final = None
11834 self.eq = None
11835 self.diseq = None
11836 self.decide = None
11837 self.created = None
11838 if ctx:
11839 self.fresh_ctx = ctx
11840 if s:
11841 Z3_solver_propagate_init(self.ctx_ref(),
11842 s.solver,
11843 ctypes.c_void_p(self.id),
11844 _user_prop_push,
11845 _user_prop_pop,
11846 _user_prop_fresh)
11847
11848 def __del__(self):
11849 if self._ctx:
11850 self._ctx.ctx = None
11851
11852 def ctx(self):
11853 if self.fresh_ctx:
11854 return self.fresh_ctx
11855 else:
11856 return self.solver.ctx
11857
11858 def ctx_ref(self):
11859 return self.ctx().ref()
11860
11861 def add_fixed(self, fixed):
11862 assert not self.fixed
11863 assert not self._ctx
11864 if self.solver:
11865 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11866 self.fixed = fixed
11867
11868 def add_created(self, created):
11869 assert not self.created
11870 assert not self._ctx
11871 if self.solver:
11872 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
11873 self.created = created
11874
11875 def add_final(self, final):
11876 assert not self.final
11877 assert not self._ctx
11878 if self.solver:
11879 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
11880 self.final = final
11881
11882 def add_eq(self, eq):
11883 assert not self.eq
11884 assert not self._ctx
11885 if self.solver:
11886 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
11887 self.eq = eq
11888
11889 def add_diseq(self, diseq):
11890 assert not self.diseq
11891 assert not self._ctx
11892 if self.solver:
11893 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
11894 self.diseq = diseq
11895
11896 def add_decide(self, decide):
11897 assert not self.decide
11898 assert not self._ctx
11899 if self.solver:
11900 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
11901 self.decide = decide
11902
11903 def push(self):
11904 raise Z3Exception("push needs to be overwritten")
11905
11906 def pop(self, num_scopes):
11907 raise Z3Exception("pop needs to be overwritten")
11908
11909 def fresh(self, new_ctx):
11910 raise Z3Exception("fresh needs to be overwritten")
11911
11912 def add(self, e):
11913 assert not self._ctx
11914 if self.solver:
11915 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
11916 else:
11917 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
11918
11919 #
11920 # Tell the solver to perform the next split on a given term
11921 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
11922 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
11923 #
11924 def next_split(self, t, idx, phase):
11925 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
11926
11927 #
11928 # Propagation can only be invoked as during a fixed or final callback.
11929 #
11930 def propagate(self, e, ids, eqs=[]):
11931 _ids, num_fixed = _to_ast_array(ids)
11932 num_eqs = len(eqs)
11933 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
11934 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
11935 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
11936 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
11937
11938 def conflict(self, deps = [], eqs = []):
11939 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3179
as_decimal(self, prec)
Definition z3py.py:3191
__rmod__(self, other)
Definition z3py.py:2661
__mod__(self, other)
Definition z3py.py:2646
__pow__(self, other)
Definition z3py.py:2570
__gt__(self, other)
Definition z3py.py:2719
__lt__(self, other)
Definition z3py.py:2706
__rtruediv__(self, other)
Definition z3py.py:2642
__rmul__(self, other)
Definition z3py.py:2537
__rsub__(self, other)
Definition z3py.py:2560
__add__(self, other)
Definition z3py.py:2499
__sub__(self, other)
Definition z3py.py:2547
is_real(self)
Definition z3py.py:2488
is_int(self)
Definition z3py.py:2474
__radd__(self, other)
Definition z3py.py:2512
__truediv__(self, other)
Definition z3py.py:2621
__le__(self, other)
Definition z3py.py:2693
__rpow__(self, other)
Definition z3py.py:2584
__pos__(self)
Definition z3py.py:2684
sort(self)
Definition z3py.py:2464
__mul__(self, other)
Definition z3py.py:2522
__rdiv__(self, other)
Definition z3py.py:2625
__ge__(self, other)
Definition z3py.py:2732
__neg__(self)
Definition z3py.py:2673
__div__(self, other)
Definition z3py.py:2598
Arithmetic.
Definition z3py.py:2369
subsort(self, other)
Definition z3py.py:2403
cast(self, val)
Definition z3py.py:2407
domain(self)
Definition z3py.py:4650
domain_n(self, i)
Definition z3py.py:4659
__getitem__(self, arg)
Definition z3py.py:4672
range(self)
Definition z3py.py:4663
sort(self)
Definition z3py.py:4641
default(self)
Definition z3py.py:4684
domain_n(self, i)
Definition z3py.py:4623
erase(self, k)
Definition z3py.py:6182
__deepcopy__(self, memo={})
Definition z3py.py:6119
__init__(self, m=None, ctx=None)
Definition z3py.py:6108
__repr__(self)
Definition z3py.py:6179
__len__(self)
Definition z3py.py:6126
keys(self)
Definition z3py.py:6211
__setitem__(self, k, v)
Definition z3py.py:6163
__contains__(self, key)
Definition z3py.py:6139
__del__(self)
Definition z3py.py:6122
__getitem__(self, key)
Definition z3py.py:6152
reset(self)
Definition z3py.py:6196
__deepcopy__(self, memo={})
Definition z3py.py:365
__nonzero__(self)
Definition z3py.py:380
as_ast(self)
Definition z3py.py:402
translate(self, target)
Definition z3py.py:431
__hash__(self)
Definition z3py.py:377
__init__(self, ast, ctx=None)
Definition z3py.py:355
__str__(self)
Definition z3py.py:368
ctx_ref(self)
Definition z3py.py:410
py_value(self)
Definition z3py.py:460
__repr__(self)
Definition z3py.py:371
get_id(self)
Definition z3py.py:406
hash(self)
Definition z3py.py:450
__eq__(self, other)
Definition z3py.py:374
eq(self, other)
Definition z3py.py:414
sexpr(self)
Definition z3py.py:393
__del__(self)
Definition z3py.py:360
__bool__(self)
Definition z3py.py:383
__copy__(self)
Definition z3py.py:447
__deepcopy__(self, memo={})
Definition z3py.py:6088
translate(self, other_ctx)
Definition z3py.py:6069
__repr__(self)
Definition z3py.py:6091
__len__(self)
Definition z3py.py:5963
__init__(self, v=None, ctx=None)
Definition z3py.py:5948
push(self, v)
Definition z3py.py:6021
__getitem__(self, i)
Definition z3py.py:5976
sexpr(self)
Definition z3py.py:6094
__del__(self)
Definition z3py.py:5959
__setitem__(self, i, v)
Definition z3py.py:6005
__contains__(self, item)
Definition z3py.py:6046
__copy__(self)
Definition z3py.py:6085
resize(self, sz)
Definition z3py.py:6033
as_binary_string(self)
Definition z3py.py:4025
as_signed_long(self)
Definition z3py.py:3999
as_string(self)
Definition z3py.py:4022
__and__(self, other)
Definition z3py.py:3689
__rmod__(self, other)
Definition z3py.py:3830
__rrshift__(self, other)
Definition z3py.py:3956
__mod__(self, other)
Definition z3py.py:3809
__or__(self, other)
Definition z3py.py:3666
__rlshift__(self, other)
Definition z3py.py:3970
__gt__(self, other)
Definition z3py.py:3880
__lt__(self, other)
Definition z3py.py:3864
__invert__(self)
Definition z3py.py:3755
__rtruediv__(self, other)
Definition z3py.py:3805
__rmul__(self, other)
Definition z3py.py:3633
__rxor__(self, other)
Definition z3py.py:3725
__ror__(self, other)
Definition z3py.py:3679
__rsub__(self, other)
Definition z3py.py:3656
__add__(self, other)
Definition z3py.py:3597
__sub__(self, other)
Definition z3py.py:3643
__radd__(self, other)
Definition z3py.py:3610
size(self)
Definition z3py.py:3586
__rand__(self, other)
Definition z3py.py:3702
__truediv__(self, other)
Definition z3py.py:3785
__le__(self, other)
Definition z3py.py:3848
__xor__(self, other)
Definition z3py.py:3712
__lshift__(self, other)
Definition z3py.py:3942
__pos__(self)
Definition z3py.py:3735
sort(self)
Definition z3py.py:3575
__mul__(self, other)
Definition z3py.py:3620
__rdiv__(self, other)
Definition z3py.py:3789
__ge__(self, other)
Definition z3py.py:3896
__neg__(self)
Definition z3py.py:3744
__rshift__(self, other)
Definition z3py.py:3912
__div__(self, other)
Definition z3py.py:3766
Bit-Vectors.
Definition z3py.py:3528
subsort(self, other)
Definition z3py.py:3540
cast(self, val)
Definition z3py.py:3543
__and__(self, other)
Definition z3py.py:1620
__or__(self, other)
Definition z3py.py:1623
__invert__(self)
Definition z3py.py:1629
__rmul__(self, other)
Definition z3py.py:1606
__add__(self, other)
Definition z3py.py:1598
py_value(self)
Definition z3py.py:1632
__radd__(self, other)
Definition z3py.py:1603
__xor__(self, other)
Definition z3py.py:1626
sort(self)
Definition z3py.py:1595
__mul__(self, other)
Definition z3py.py:1609
Booleans.
Definition z3py.py:1556
subsort(self, other)
Definition z3py.py:1582
is_bool(self)
Definition z3py.py:1588
cast(self, val)
Definition z3py.py:1559
__deepcopy__(self, memo={})
Definition z3py.py:6976
__eq__(self, other)
Definition z3py.py:6979
__ne__(self, other)
Definition z3py.py:6982
__init__(self, r)
Definition z3py.py:6973
param_descrs(self)
Definition z3py.py:240
__init__(self, *args, **kws)
Definition z3py.py:202
interrupt(self)
Definition z3py.py:232
__del__(self)
Definition z3py.py:222
ref(self)
Definition z3py.py:228
bool owner
Definition z3py.py:217
__deepcopy__(self, memo={})
Definition z3py.py:5168
create(self)
Definition z3py.py:5207
__init__(self, name, ctx=None)
Definition z3py.py:5163
__repr__(self)
Definition z3py.py:5204
list constructors
Definition z3py.py:5166
declare(self, name, *args)
Definition z3py.py:5183
declare_core(self, name, rec_name, *args)
Definition z3py.py:5173
constructor(self, idx)
Definition z3py.py:5360
accessor(self, i, j)
Definition z3py.py:5407
num_constructors(self)
Definition z3py.py:5347
recognizer(self, idx)
Definition z3py.py:5379
Expressions.
Definition z3py.py:997
as_ast(self)
Definition z3py.py:1008
__hash__(self)
Definition z3py.py:1054
kind(self)
Definition z3py.py:1094
children(self)
Definition z3py.py:1138
serialize(self)
Definition z3py.py:1156
get_id(self)
Definition z3py.py:1011
num_args(self)
Definition z3py.py:1101
__eq__(self, other)
Definition z3py.py:1037
__ne__(self, other)
Definition z3py.py:1058
from_string(self, s)
Definition z3py.py:1153
sort_kind(self)
Definition z3py.py:1026
arg(self, idx)
Definition z3py.py:1117
sort(self)
Definition z3py.py:1014
params(self)
Definition z3py.py:1076
decl(self)
Definition z3py.py:1079
Function Declarations.
Definition z3py.py:754
as_func_decl(self)
Definition z3py.py:768
domain(self, i)
Definition z3py.py:792
as_ast(self)
Definition z3py.py:762
__call__(self, *args)
Definition z3py.py:855
arity(self)
Definition z3py.py:782
get_id(self)
Definition z3py.py:765
range(self)
Definition z3py.py:804
params(self)
Definition z3py.py:827
Definition z3py.py:6230
__deepcopy__(self, memo={})
Definition z3py.py:6238
ctx
Definition z3py.py:6235
__repr__(self)
Definition z3py.py:6335
num_args(self)
Definition z3py.py:6245
entry
Definition z3py.py:6234
value(self)
Definition z3py.py:6294
__init__(self, entry, ctx)
Definition z3py.py:6233
__del__(self)
Definition z3py.py:6241
as_list(self)
Definition z3py.py:6316
arg_value(self, idx)
Definition z3py.py:6263
__deepcopy__(self, memo={})
Definition z3py.py:6433
translate(self, other_ctx)
Definition z3py.py:6425
arity(self)
Definition z3py.py:6391
__repr__(self)
Definition z3py.py:6453
num_entries(self)
Definition z3py.py:6375
__init__(self, f, ctx)
Definition z3py.py:6342
__del__(self)
Definition z3py.py:6348
as_list(self)
Definition z3py.py:6436
else_value(self)
Definition z3py.py:6352
entry(self, idx)
Definition z3py.py:6405
__copy__(self)
Definition z3py.py:6430
__deepcopy__(self, memo={})
Definition z3py.py:5893
get(self, i)
Definition z3py.py:5751
prec(self)
Definition z3py.py:5695
translate(self, target)
Definition z3py.py:5867
append(self, *args)
Definition z3py.py:5794
as_expr(self)
Definition z3py.py:5916
assert_exprs(self, *args)
Definition z3py.py:5779
__repr__(self)
Definition z3py.py:5856
__len__(self)
Definition z3py.py:5738
inconsistent(self)
Definition z3py.py:5677
dimacs(self, include_names=True)
Definition z3py.py:5863
__getitem__(self, arg)
Definition z3py.py:5764
size(self)
Definition z3py.py:5725
precision(self)
Definition z3py.py:5716
simplify(self, *arguments, **keywords)
Definition z3py.py:5896
sexpr(self)
Definition z3py.py:5859
add(self, *args)
Definition z3py.py:5816
__del__(self)
Definition z3py.py:5655
convert_model(self, model)
Definition z3py.py:5827
insert(self, *args)
Definition z3py.py:5805
depth(self)
Definition z3py.py:5659
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5645
__copy__(self)
Definition z3py.py:5890
as_binary_string(self)
Definition z3py.py:3064
py_value(self)
Definition z3py.py:3072
as_long(self)
Definition z3py.py:3043
as_string(self)
Definition z3py.py:3056
__deepcopy__(self, memo={})
Definition z3py.py:6799
eval(self, t, model_completion=False)
Definition z3py.py:6477
translate(self, target)
Definition z3py.py:6764
__getitem__(self, idx)
Definition z3py.py:6678
num_sorts(self)
Definition z3py.py:6603
get_universe(self, s)
Definition z3py.py:6658
get_sort(self, idx)
Definition z3py.py:6618
project(self, vars, fml)
Definition z3py.py:6772
__repr__(self)
Definition z3py.py:6470
__len__(self)
Definition z3py.py:6534
get_interp(self, decl)
Definition z3py.py:6551
__init__(self, m, ctx)
Definition z3py.py:6460
sexpr(self)
Definition z3py.py:6473
sorts(self)
Definition z3py.py:6641
__del__(self)
Definition z3py.py:6466
decls(self)
Definition z3py.py:6723
project_with_witness(self, vars, fml)
Definition z3py.py:6784
update_value(self, x, value)
Definition z3py.py:6742
evaluate(self, t, model_completion=False)
Definition z3py.py:6508
__copy__(self)
Definition z3py.py:6796
__deepcopy__(self, memo={})
Definition z3py.py:5589
__init__(self, descr, ctx=None)
Definition z3py.py:5583
get_kind(self, n)
Definition z3py.py:5611
get_documentation(self, n)
Definition z3py.py:5616
__getitem__(self, arg)
Definition z3py.py:5621
get_name(self, i)
Definition z3py.py:5606
Parameter Sets.
Definition z3py.py:5510
__deepcopy__(self, memo={})
Definition z3py.py:5524
validate(self, ds)
Definition z3py.py:5551
__repr__(self)
Definition z3py.py:5548
__init__(self, ctx=None, params=None)
Definition z3py.py:5516
set(self, name, val)
Definition z3py.py:5531
__del__(self)
Definition z3py.py:5527
Patterns.
Definition z3py.py:1992
as_ast(self)
Definition z3py.py:1997
get_id(self)
Definition z3py.py:2000
Quantifiers.
Definition z3py.py:2059
num_no_patterns(self)
Definition z3py.py:2177
no_pattern(self, idx)
Definition z3py.py:2181
num_patterns(self)
Definition z3py.py:2147
var_name(self, idx)
Definition z3py.py:2210
__getitem__(self, arg)
Definition z3py.py:2116
var_sort(self, idx)
Definition z3py.py:2226
pattern(self, idx)
Definition z3py.py:2159
numerator_as_long(self)
Definition z3py.py:3105
is_int_value(self)
Definition z3py.py:3135
as_fraction(self)
Definition z3py.py:3163
py_value(self)
Definition z3py.py:3172
numerator(self)
Definition z3py.py:3079
is_real(self)
Definition z3py.py:3132
as_long(self)
Definition z3py.py:3138
is_int(self)
Definition z3py.py:3129
denominator_as_long(self)
Definition z3py.py:3118
as_string(self)
Definition z3py.py:3154
denominator(self)
Definition z3py.py:3094
as_decimal(self, prec)
Definition z3py.py:3142
__init__(self, c, ctx)
Definition z3py.py:5227
__init__(self, c, ctx)
Definition z3py.py:5239
Strings, Sequences and Regular expressions.
Definition z3py.py:10970
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7020
assert_and_track(self, a, p)
Definition z3py.py:7189
num_scopes(self)
Definition z3py.py:7101
append(self, *args)
Definition z3py.py:7167
__iadd__(self, fml)
Definition z3py.py:7163
pop(self, num=1)
Definition z3py.py:7079
import_model_converter(self, other)
Definition z3py.py:7267
assert_exprs(self, *args)
Definition z3py.py:7133
model(self)
Definition z3py.py:7248
set(self, *args, **keys)
Definition z3py.py:7044
__enter__(self)
Definition z3py.py:7037
add(self, *args)
Definition z3py.py:7152
__del__(self)
Definition z3py.py:7033
int backtrack_level
Definition z3py.py:7023
insert(self, *args)
Definition z3py.py:7178
check(self, *assumptions)
Definition z3py.py:7219
push(self)
Definition z3py.py:7057
__exit__(self, *exc_info)
Definition z3py.py:7041
reset(self)
Definition z3py.py:7119
subsort(self, other)
Definition z3py.py:599
as_ast(self)
Definition z3py.py:576
__hash__(self)
Definition z3py.py:656
kind(self)
Definition z3py.py:582
get_id(self)
Definition z3py.py:579
__eq__(self, other)
Definition z3py.py:632
__ne__(self, other)
Definition z3py.py:645
cast(self, val)
Definition z3py.py:607
name(self)
Definition z3py.py:622
Statistics.
Definition z3py.py:6829
__deepcopy__(self, memo={})
Definition z3py.py:6837
__getattr__(self, name)
Definition z3py.py:6932
__getitem__(self, idx)
Definition z3py.py:6876
__init__(self, stats, ctx)
Definition z3py.py:6832
__repr__(self)
Definition z3py.py:6844
__len__(self)
Definition z3py.py:6862
__del__(self)
Definition z3py.py:6840
get_key_value(self, key)
Definition z3py.py:6912
subsort(self, other)
Definition z3py.py:730
cast(self, val)
Definition z3py.py:733
ASTs base class.
Definition z3py.py:338
_repr_html_(self)
Definition z3py.py:344
use_pp(self)
Definition z3py.py:341
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_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_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 const sorts[], unsigned sort_refs[])
Create a constructor.
Z3_string Z3_API Z3_goal_to_string(Z3_context c, Z3_goal g)
Convert a goal into a string.
bool Z3_API Z3_is_eq_sort(Z3_context c, Z3_sort s1, Z3_sort s2)
compare sorts.
void Z3_API Z3_del_config(Z3_config c)
Delete the given configuration object.
double Z3_API Z3_get_numeral_double(Z3_context c, Z3_ast a)
Return numeral as a double.
void Z3_API Z3_inc_ref(Z3_context c, Z3_ast a)
Increment the reference counter of the given AST. The context c should have been created using Z3_mk_...
Z3_ast Z3_API Z3_mk_real2int(Z3_context c, Z3_ast t1)
Coerce a real to an integer.
Z3_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f)
Return the interpretation of the function f in the model m. Return NULL, if the model does not assign...
void Z3_API Z3_solver_inc_ref(Z3_context c, Z3_solver s)
Increment the reference counter of the given solver.
Z3_symbol Z3_API Z3_get_quantifier_id(Z3_context c, Z3_ast a)
Obtain id of quantifier.
Z3_ast Z3_API Z3_mk_ext_rotate_right(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the right t2 times.
Z3_string Z3_API Z3_get_numeral_decimal_string(Z3_context c, Z3_ast a, unsigned precision)
Return numeral as a string in decimal notation. The result has at most precision decimal places.
Z3_sort Z3_API Z3_get_sort(Z3_context c, Z3_ast a)
Return the sort of an AST node.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(Z3_context c, Z3_sort t, unsigned idx_c, unsigned idx_a)
Return idx_a'th accessor for the idx_c'th constructor.
Z3_ast Z3_API Z3_mk_bvredor(Z3_context c, Z3_ast t1)
Take disjunction of bits in vector, return vector of length 1.
void Z3_API Z3_ast_map_reset(Z3_context c, Z3_ast_map m)
Remove all keys from the given map.
void Z3_API Z3_solver_reset(Z3_context c, Z3_solver s)
Remove all assertions from the solver.
bool Z3_API Z3_is_algebraic_number(Z3_context c, Z3_ast a)
Return true if the given AST is a real algebraic number.
_py2expr(a, ctx=None)
Definition z3py.py:3210
RotateRight(a, b)
Definition z3py.py:4437
_symbol2py(ctx, s)
Definition z3py.py:140
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4110
BVSNegNoOverflow(a)
Definition z3py.py:4584
SetAdd(s, e)
Definition z3py.py:5056
SetSort(s)
Sets.
Definition z3py.py:5007
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1245
UGT(a, b)
Definition z3py.py:4308
is_probe(p)
Definition z3py.py:8872
SetDel(s, e)
Definition z3py.py:5067
bool is_le(Any a)
Definition z3py.py:2950
BoolSort(ctx=None)
Definition z3py.py:1762
is_bv_sort(s)
Definition z3py.py:3561
_ctx_from_ast_args(*args)
Definition z3py.py:525
RatVal(a, b, ctx=None)
Definition z3py.py:3302
_to_func_decl_ref(a, ctx)
Definition z3py.py:941
SetUnion(*args)
Definition z3py.py:5030
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5127
BitVec(name, bv, ctx=None)
Definition z3py.py:4127
EmptySet(s)
Definition z3py.py:5012
BVMulNoUnderflow(a, b)
Definition z3py.py:4598
CreateDatatypes(*ds)
Definition z3py.py:5248
is_func_decl(a)
Definition z3py.py:886
get_as_array_func(n)
Definition z3py.py:6816
Distinct(*args)
Definition z3py.py:1447
RecAddDefinition(f, args, body)
Definition z3py.py:963
ToInt(a)
Definition z3py.py:3461
Implies(a, b, ctx=None)
Definition z3py.py:1856
UGE(a, b)
Definition z3py.py:4290
Ext(a, b)
Definition z3py.py:4958
_to_ast_array(args)
Definition z3py.py:537
bool is_sort(Any s)
Definition z3py.py:661
_check_bv_args(a, b)
Definition z3py.py:4249
RealSort(ctx=None)
Definition z3py.py:3242
IsSubset(a, b)
Definition z3py.py:5110
DeclareTypeVar(name, ctx=None)
Definition z3py.py:737
_get_args_ast_list(args)
Definition z3py.py:168
bool is_to_real(Any a)
Definition z3py.py:3010
_to_ref_array(ref, args)
Definition z3py.py:545
get_map_func(a)
Definition z3py.py:4766
_z3_check_cint_overflow(n, name)
Definition z3py.py:118
bool is_and(Any a)
Definition z3py.py:1692
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5453
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1273
is_select(a)
Definition z3py.py:4976
SignExt(n, a)
Definition z3py.py:4453
Int(name, ctx=None)
Definition z3py.py:3331
Bools(names, ctx=None)
Definition z3py.py:1811
_probe_and(args, ctx)
Definition z3py.py:8939
Int2BV(a, num_bits)
Definition z3py.py:4086
Lambda(vs, body)
Definition z3py.py:2342
_to_param_value(val)
Definition z3py.py:178
FreshFunction(*sig)
Definition z3py.py:922
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3412
BVRedOr(a)
Definition z3py.py:4542
SRem(a, b)
Definition z3py.py:4368
SortRef _sort(Context ctx, Any a)
Definition z3py.py:705
set_option(*args, **kws)
Definition z3py.py:311
ExprRef RealVar(int idx, ctx=None)
Definition z3py.py:1528
bool is_sub(Any a)
Definition z3py.py:2897
is_bv(a)
Definition z3py.py:4034
SetDifference(a, b)
Definition z3py.py:5088
bool is_arith_sort(Any s)
Definition z3py.py:2445
BitVecs(names, bv, ctx=None)
Definition z3py.py:4151
bool is_mod(Any a)
Definition z3py.py:2938
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1827
_has_probe(args)
Definition z3py.py:1912
IsMember(e, s)
Definition z3py.py:5099
get_param(name)
Definition z3py.py:317
BVAddNoUnderflow(a, b)
Definition z3py.py:4556
deserialize(st)
Definition z3py.py:1162
bool is_not(Any a)
Definition z3py.py:1728
Extract(high, low, a)
Definition z3py.py:4218
Function(name, *sig)
Definition z3py.py:899
get_version()
Definition z3py.py:100
FreshConst(sort, prefix="c")
Definition z3py.py:1507
ULT(a, b)
Definition z3py.py:4272
EnumSort(name, values, ctx=None)
Definition z3py.py:5477
bool is_is_int(Any a)
Definition z3py.py:2998
_to_int_str(val)
Definition z3py.py:3259
is_algebraic_value(a)
Definition z3py.py:2859
is_bv_value(a)
Definition z3py.py:4048
BVSDivNoOverflow(a, b)
Definition z3py.py:4577
bool is_eq(Any a)
Definition z3py.py:1740
Context main_ctx()
Definition z3py.py:249
SetIntersect(*args)
Definition z3py.py:5043
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9006
BV2Int(a, is_signed=False)
Definition z3py.py:4063
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3370
_to_ast_ref(a, ctx)
Definition z3py.py:553
_to_func_decl_array(args)
Definition z3py.py:529
disable_trace(msg)
Definition z3py.py:87
bool is_to_int(Any a)
Definition z3py.py:3025
is_map(a)
Definition z3py.py:4741
Context _get_ctx(ctx)
Definition z3py.py:270
Or(*args)
Definition z3py.py:1953
is_re(s)
Definition z3py.py:11442
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5556
bool is_idiv(Any a)
Definition z3py.py:2926
Consts(names, sort)
Definition z3py.py:1492
Cond(p, t1, t2, ctx=None)
Definition z3py.py:8989
_to_pattern(arg)
Definition z3py.py:2046
RealVarVector(int n, ctx=None)
Definition z3py.py:1538
is_arith(a)
Definition z3py.py:2746
bool is_true(Any a)
Definition z3py.py:1660
bool is_false(Any a)
Definition z3py.py:1678
bool is_int(a)
Definition z3py.py:2767
If(a, b, c, ctx=None)
Definition z3py.py:1424
bool eq(AstRef a, AstRef b)
Definition z3py.py:486
is_app_of(a, k)
Definition z3py.py:1411
is_app(a)
Definition z3py.py:1308
bool is_add(Any a)
Definition z3py.py:2873
z3_error_handler(c, e)
Definition z3py.py:184
None reset_params()
Definition z3py.py:305
Reals(names, ctx=None)
Definition z3py.py:3397
is_int_value(a)
Definition z3py.py:2813
set_param(*args, **kws)
Definition z3py.py:281
is_pattern(a)
Definition z3py.py:2004
_coerce_seq(s, ctx=None)
Definition z3py.py:11121
bool is_distinct(Any a)
Definition z3py.py:1750
bool is_lt(Any a)
Definition z3py.py:2962
ULE(a, b)
Definition z3py.py:4254
is_real(a)
Definition z3py.py:2786
FullSet(s)
Definition z3py.py:5021
to_symbol(s, ctx=None)
Definition z3py.py:132
bool is_mul(Any a)
Definition z3py.py:2885
bool is_ast(Any a)
Definition z3py.py:465
_get_args(args)
Definition z3py.py:152
And(*args)
Definition z3py.py:1920
RepeatBitVec(n, a)
Definition z3py.py:4511
SetHasSize(a, k)
Definition z3py.py:4970
get_version_string()
Definition z3py.py:91
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3427
Array(name, *sorts)
Definition z3py.py:4823
Concat(*args)
Definition z3py.py:4172
_reduce(func, sequence, initial)
Definition z3py.py:1266
_is_algebraic(ctx, a)
Definition z3py.py:2809
Ints(names, ctx=None)
Definition z3py.py:3344
Select(a, *args)
Definition z3py.py:4897
Const(name, sort)
Definition z3py.py:1480
is_array_sort(a)
Definition z3py.py:4697
bool is_div(Any a)
Definition z3py.py:2909
ExprRef Var(int idx, SortRef s)
Definition z3py.py:1513
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4549
Real(name, ctx=None)
Definition z3py.py:3384
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1842
BitVecSort(sz, ctx=None)
Definition z3py.py:4095
open_log(fname)
Definition z3py.py:122
RecFunction(name, *sig)
Definition z3py.py:945
bool is_ge(Any a)
Definition z3py.py:2974
Model(ctx=None, eval={})
Definition z3py.py:6803
BVSubNoOverflow(a, b)
Definition z3py.py:4563
bool is_gt(Any a)
Definition z3py.py:2986
is_default(a)
Definition z3py.py:4757
is_K(a)
Definition z3py.py:4728
Bool(name, ctx=None)
Definition z3py.py:1799
_is_int(v)
Definition z3py.py:76
is_const_array(a)
Definition z3py.py:4715
Sqrt(a, ctx=None)
Definition z3py.py:3496
Default(a)
Definition z3py.py:4869
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:511
SetComplement(s)
Definition z3py.py:5078
is_as_array(n)
Definition z3py.py:6811
is_store(a)
Definition z3py.py:4989
bool is_or(Any a)
Definition z3py.py:1704
is_quantifier(a)
Definition z3py.py:2254
_mk_bin(f, a, b)
Definition z3py.py:1471
K(dom, v)
Definition z3py.py:4936
Xor(a, b, ctx=None)
Definition z3py.py:1870
Store(a, *args)
Definition z3py.py:4880
bool is_array(Any a)
Definition z3py.py:4701
mk_not(a)
Definition z3py.py:1905
is_expr(a)
Definition z3py.py:1285
_array_select(ar, arg)
Definition z3py.py:4688
is_const(a)
Definition z3py.py:1334
BoolVal(val, ctx=None)
Definition z3py.py:1780
RealVal(val, ctx=None)
Definition z3py.py:3283
bool is_implies(Any a)
Definition z3py.py:1716
z3_debug()
Definition z3py.py:70
get_full_version()
Definition z3py.py:109
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3357
_coerce_expr_merge(s, a)
Definition z3py.py:1226
Context get_ctx(ctx)
Definition z3py.py:277
LShR(a, b)
Definition z3py.py:4389
ArraySort(*sig)
Definition z3py.py:4790
Map(f, *args)
Definition z3py.py:4913
is_rational_value(a)
Definition z3py.py:2837
_probe_or(args, ctx)
Definition z3py.py:8943
BVRedAnd(a)
Definition z3py.py:4535
Cbrt(a, ctx=None)
Definition z3py.py:3509
_to_expr_ref(a, ctx)
Definition z3py.py:1176
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5465
IntSort(ctx=None)
Definition z3py.py:3225
is_seq(a)
Definition z3py.py:11142
Not(a, ctx=None)
Definition z3py.py:1886
_to_sort_ref(s, ctx)
Definition z3py.py:674
enable_trace(msg)
Definition z3py.py:83
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2321
ToReal(a)
Definition z3py.py:3441
URem(a, b)
Definition z3py.py:4347
bool is_bool(Any a)
Definition z3py.py:1642
StringVal(s, ctx=None)
Definition z3py.py:11169
IsInt(a)
Definition z3py.py:3479
_is_numeral(ctx, a)
Definition z3py.py:2805
MultiPattern(*args)
Definition z3py.py:2022
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2303
ZeroExt(n, a)
Definition z3py.py:4483
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:569
int _ast_kind(Context ctx, Any a)
Definition z3py.py:505
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4570
UDiv(a, b)
Definition z3py.py:4326
DatatypeSort(name, ctx=None)
Definition z3py.py:5448
Q(a, b, ctx=None)
Definition z3py.py:3318
Update(a, *args)
Definition z3py.py:4837
get_var_index(a)
Definition z3py.py:1378
append_log(s)
Definition z3py.py:127
is_var(a)
Definition z3py.py:1353
SortRef DeclareSort(name, ctx=None)
Definition z3py.py:709
IntVal(val, ctx=None)
Definition z3py.py:3271
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4591
RotateLeft(a, b)
Definition z3py.py:4421
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2268
_z3_assert(cond, msg)
Definition z3py.py:113