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
7398 def solve_for(self, ts):
7399 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7400 vars = AstVector(ctx=self.ctx);
7401 terms = AstVector(ctx=self.ctx);
7402 guards = AstVector(ctx=self.ctx);
7403 for t in ts:
7404 t = _py2expr(t, self.ctx)
7405 vars.push(t)
7406 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7407 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7408
7409
7410 def proof(self):
7411 """Return a proof for the last `check()`. Proof construction must be enabled."""
7412 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7413
7414 def assertions(self):
7415 """Return an AST vector containing all added constraints.
7416
7417 >>> s = Solver()
7418 >>> s.assertions()
7419 []
7420 >>> a = Int('a')
7421 >>> s.add(a > 0)
7422 >>> s.add(a < 10)
7423 >>> s.assertions()
7424 [a > 0, a < 10]
7425 """
7426 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7427
7428 def units(self):
7429 """Return an AST vector containing all currently inferred units.
7430 """
7431 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7432
7433 def non_units(self):
7434 """Return an AST vector containing all atomic formulas in solver state that are not units.
7435 """
7436 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7437
7438 def trail_levels(self):
7439 """Return trail and decision levels of the solver state after a check() call.
7440 """
7441 trail = self.trail()
7442 levels = (ctypes.c_uint * len(trail))()
7443 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7444 return trail, levels
7445
7446 def set_initial_value(self, var, value):
7447 """initialize the solver's state by setting the initial value of var to value
7448 """
7449 s = var.sort()
7450 value = s.cast(value)
7451 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7452
7453 def trail(self):
7454 """Return trail of the solver state after a check() call.
7455 """
7456 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7457
7458 def statistics(self):
7459 """Return statistics for the last `check()`.
7460
7461 >>> s = SimpleSolver()
7462 >>> x = Int('x')
7463 >>> s.add(x > 0)
7464 >>> s.check()
7465 sat
7466 >>> st = s.statistics()
7467 >>> st.get_key_value('final checks')
7468 1
7469 >>> len(st) > 0
7470 True
7471 >>> st[0] != 0
7472 True
7473 """
7474 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7475
7476 def reason_unknown(self):
7477 """Return a string describing why the last `check()` returned `unknown`.
7478
7479 >>> x = Int('x')
7480 >>> s = SimpleSolver()
7481 >>> s.add(2**x == 4)
7482 >>> s.check()
7483 unknown
7484 >>> s.reason_unknown()
7485 '(incomplete (theory arithmetic))'
7486 """
7487 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7488
7489 def help(self):
7490 """Display a string describing all available options."""
7491 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7492
7493 def param_descrs(self):
7494 """Return the parameter description set."""
7495 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7496
7497 def __repr__(self):
7498 """Return a formatted string with all added constraints."""
7499 return obj_to_string(self)
7500
7501 def translate(self, target):
7502 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7503
7504 >>> c1 = Context()
7505 >>> c2 = Context()
7506 >>> s1 = Solver(ctx=c1)
7507 >>> s2 = s1.translate(c2)
7508 """
7509 if z3_debug():
7510 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7511 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7512 return Solver(solver, target)
7513
7514 def __copy__(self):
7515 return self.translate(self.ctx)
7516
7517 def __deepcopy__(self, memo={}):
7518 return self.translate(self.ctx)
7519
7520 def sexpr(self):
7521 """Return a formatted string (in Lisp-like format) with all added constraints.
7522 We say the string is in s-expression format.
7523
7524 >>> x = Int('x')
7525 >>> s = Solver()
7526 >>> s.add(x > 0)
7527 >>> s.add(x < 2)
7528 >>> r = s.sexpr()
7529 """
7530 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7531
7532 def dimacs(self, include_names=True):
7533 """Return a textual representation of the solver in DIMACS format."""
7534 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7535
7536 def to_smt2(self):
7537 """return SMTLIB2 formatted benchmark for solver's assertions"""
7538 es = self.assertions()
7539 sz = len(es)
7540 sz1 = sz
7541 if sz1 > 0:
7542 sz1 -= 1
7543 v = (Ast * sz1)()
7544 for i in range(sz1):
7545 v[i] = es[i].as_ast()
7546 if sz > 0:
7547 e = es[sz1].as_ast()
7548 else:
7549 e = BoolVal(True, self.ctx).as_ast()
7550 return Z3_benchmark_to_smtlib_string(
7551 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7552 )
7553
7554
7555def SolverFor(logic, ctx=None, logFile=None):
7556 """Create a solver customized for the given logic.
7557
7558 The parameter `logic` is a string. It should be contains
7559 the name of a SMT-LIB logic.
7560 See http://www.smtlib.org/ for the name of all available logics.
7561
7562 >>> s = SolverFor("QF_LIA")
7563 >>> x = Int('x')
7564 >>> s.add(x > 0)
7565 >>> s.add(x < 2)
7566 >>> s.check()
7567 sat
7568 >>> s.model()
7569 [x = 1]
7570 """
7571 ctx = _get_ctx(ctx)
7572 logic = to_symbol(logic)
7573 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7574
7575
7576def SimpleSolver(ctx=None, logFile=None):
7577 """Return a simple general purpose solver with limited amount of preprocessing.
7578
7579 >>> s = SimpleSolver()
7580 >>> x = Int('x')
7581 >>> s.add(x > 0)
7582 >>> s.check()
7583 sat
7584 """
7585 ctx = _get_ctx(ctx)
7586 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7587
7588#########################################
7589#
7590# Fixedpoint
7591#
7592#########################################
7593
7594
7595class Fixedpoint(Z3PPObject):
7596 """Fixedpoint API provides methods for solving with recursive predicates"""
7597
7598 def __init__(self, fixedpoint=None, ctx=None):
7599 assert fixedpoint is None or ctx is not None
7600 self.ctx = _get_ctx(ctx)
7601 self.fixedpoint = None
7602 if fixedpoint is None:
7603 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7604 else:
7605 self.fixedpoint = fixedpoint
7606 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7607 self.vars = []
7608
7609 def __deepcopy__(self, memo={}):
7610 return FixedPoint(self.fixedpoint, self.ctx)
7611
7612 def __del__(self):
7613 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7614 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7615
7616 def set(self, *args, **keys):
7617 """Set a configuration option. The method `help()` return a string containing all available options.
7618 """
7619 p = args2params(args, keys, self.ctx)
7620 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7621
7622 def help(self):
7623 """Display a string describing all available options."""
7624 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7625
7626 def param_descrs(self):
7627 """Return the parameter description set."""
7628 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7629
7630 def assert_exprs(self, *args):
7631 """Assert constraints as background axioms for the fixedpoint solver."""
7632 args = _get_args(args)
7633 s = BoolSort(self.ctx)
7634 for arg in args:
7635 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7636 for f in arg:
7637 f = self.abstract(f)
7638 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7639 else:
7640 arg = s.cast(arg)
7641 arg = self.abstract(arg)
7642 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7643
7644 def add(self, *args):
7645 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7646 self.assert_exprs(*args)
7647
7648 def __iadd__(self, fml):
7649 self.add(fml)
7650 return self
7651
7652 def append(self, *args):
7653 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7654 self.assert_exprs(*args)
7655
7656 def insert(self, *args):
7657 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7658 self.assert_exprs(*args)
7659
7660 def add_rule(self, head, body=None, name=None):
7661 """Assert rules defining recursive predicates to the fixedpoint solver.
7662 >>> a = Bool('a')
7663 >>> b = Bool('b')
7664 >>> s = Fixedpoint()
7665 >>> s.register_relation(a.decl())
7666 >>> s.register_relation(b.decl())
7667 >>> s.fact(a)
7668 >>> s.rule(b, a)
7669 >>> s.query(b)
7670 sat
7671 """
7672 if name is None:
7673 name = ""
7674 name = to_symbol(name, self.ctx)
7675 if body is None:
7676 head = self.abstract(head)
7677 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7678 else:
7679 body = _get_args(body)
7680 f = self.abstract(Implies(And(body, self.ctx), head))
7681 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7682
7683 def rule(self, head, body=None, name=None):
7684 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7685 self.add_rule(head, body, name)
7686
7687 def fact(self, head, name=None):
7688 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7689 self.add_rule(head, None, name)
7690
7691 def query(self, *query):
7692 """Query the fixedpoint engine whether formula is derivable.
7693 You can also pass an tuple or list of recursive predicates.
7694 """
7695 query = _get_args(query)
7696 sz = len(query)
7697 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7698 _decls = (FuncDecl * sz)()
7699 i = 0
7700 for q in query:
7701 _decls[i] = q.ast
7702 i = i + 1
7703 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7704 else:
7705 if sz == 1:
7706 query = query[0]
7707 else:
7708 query = And(query, self.ctx)
7709 query = self.abstract(query, False)
7710 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7711 return CheckSatResult(r)
7712
7713 def query_from_lvl(self, lvl, *query):
7714 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7715 """
7716 query = _get_args(query)
7717 sz = len(query)
7718 if sz >= 1 and isinstance(query[0], FuncDecl):
7719 _z3_assert(False, "unsupported")
7720 else:
7721 if sz == 1:
7722 query = query[0]
7723 else:
7724 query = And(query)
7725 query = self.abstract(query, False)
7726 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7727 return CheckSatResult(r)
7728
7729 def update_rule(self, head, body, name):
7730 """update rule"""
7731 if name is None:
7732 name = ""
7733 name = to_symbol(name, self.ctx)
7734 body = _get_args(body)
7735 f = self.abstract(Implies(And(body, self.ctx), head))
7736 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7737
7738 def get_answer(self):
7739 """Retrieve answer from last query call."""
7740 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7741 return _to_expr_ref(r, self.ctx)
7742
7743 def get_ground_sat_answer(self):
7744 """Retrieve a ground cex from last query call."""
7745 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7746 return _to_expr_ref(r, self.ctx)
7747
7748 def get_rules_along_trace(self):
7749 """retrieve rules along the counterexample trace"""
7750 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7751
7752 def get_rule_names_along_trace(self):
7753 """retrieve rule names along the counterexample trace"""
7754 # this is a hack as I don't know how to return a list of symbols from C++;
7755 # obtain names as a single string separated by semicolons
7756 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7757 # split into individual names
7758 return names.split(";")
7759
7760 def get_num_levels(self, predicate):
7761 """Retrieve number of levels used for predicate in PDR engine"""
7762 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7763
7764 def get_cover_delta(self, level, predicate):
7765 """Retrieve properties known about predicate for the level'th unfolding.
7766 -1 is treated as the limit (infinity)
7767 """
7768 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7769 return _to_expr_ref(r, self.ctx)
7770
7771 def add_cover(self, level, predicate, property):
7772 """Add property to predicate for the level'th unfolding.
7773 -1 is treated as infinity (infinity)
7774 """
7775 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7776
7777 def register_relation(self, *relations):
7778 """Register relation as recursive"""
7779 relations = _get_args(relations)
7780 for f in relations:
7781 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7782
7783 def set_predicate_representation(self, f, *representations):
7784 """Control how relation is represented"""
7785 representations = _get_args(representations)
7786 representations = [to_symbol(s) for s in representations]
7787 sz = len(representations)
7788 args = (Symbol * sz)()
7789 for i in range(sz):
7790 args[i] = representations[i]
7791 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7792
7793 def parse_string(self, s):
7794 """Parse rules and queries from a string"""
7795 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7796
7797 def parse_file(self, f):
7798 """Parse rules and queries from a file"""
7799 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7800
7801 def get_rules(self):
7802 """retrieve rules that have been added to fixedpoint context"""
7803 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7804
7805 def get_assertions(self):
7806 """retrieve assertions that have been added to fixedpoint context"""
7807 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7808
7809 def __repr__(self):
7810 """Return a formatted string with all added rules and constraints."""
7811 return self.sexpr()
7812
7813 def sexpr(self):
7814 """Return a formatted string (in Lisp-like format) with all added constraints.
7815 We say the string is in s-expression format.
7816 """
7817 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7818
7819 def to_string(self, queries):
7820 """Return a formatted string (in Lisp-like format) with all added constraints.
7821 We say the string is in s-expression format.
7822 Include also queries.
7823 """
7824 args, len = _to_ast_array(queries)
7825 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7826
7827 def statistics(self):
7828 """Return statistics for the last `query()`.
7829 """
7830 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7831
7832 def reason_unknown(self):
7833 """Return a string describing why the last `query()` returned `unknown`.
7834 """
7835 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7836
7837 def declare_var(self, *vars):
7838 """Add variable or several variables.
7839 The added variable or variables will be bound in the rules
7840 and queries
7841 """
7842 vars = _get_args(vars)
7843 for v in vars:
7844 self.vars += [v]
7845
7846 def abstract(self, fml, is_forall=True):
7847 if self.vars == []:
7848 return fml
7849 if is_forall:
7850 return ForAll(self.vars, fml)
7851 else:
7852 return Exists(self.vars, fml)
7853
7854
7855#########################################
7856#
7857# Finite domains
7858#
7859#########################################
7860
7861class FiniteDomainSortRef(SortRef):
7862 """Finite domain sort."""
7863
7864 def size(self):
7865 """Return the size of the finite domain sort"""
7866 r = (ctypes.c_ulonglong * 1)()
7867 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7868 return r[0]
7869 else:
7870 raise Z3Exception("Failed to retrieve finite domain sort size")
7871
7872
7873def FiniteDomainSort(name, sz, ctx=None):
7874 """Create a named finite domain sort of a given size sz"""
7875 if not isinstance(name, Symbol):
7876 name = to_symbol(name)
7877 ctx = _get_ctx(ctx)
7878 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7879
7880
7881def is_finite_domain_sort(s):
7882 """Return True if `s` is a Z3 finite-domain sort.
7883
7884 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7885 True
7886 >>> is_finite_domain_sort(IntSort())
7887 False
7888 """
7889 return isinstance(s, FiniteDomainSortRef)
7890
7891
7892class FiniteDomainRef(ExprRef):
7893 """Finite-domain expressions."""
7894
7895 def sort(self):
7896 """Return the sort of the finite-domain expression `self`."""
7897 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7898
7899 def as_string(self):
7900 """Return a Z3 floating point expression as a Python string."""
7901 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7902
7903
7904def is_finite_domain(a):
7905 """Return `True` if `a` is a Z3 finite-domain expression.
7906
7907 >>> s = FiniteDomainSort('S', 100)
7908 >>> b = Const('b', s)
7909 >>> is_finite_domain(b)
7910 True
7911 >>> is_finite_domain(Int('x'))
7912 False
7913 """
7914 return isinstance(a, FiniteDomainRef)
7915
7916
7917class FiniteDomainNumRef(FiniteDomainRef):
7918 """Integer values."""
7919
7920 def as_long(self):
7921 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7922
7923 >>> s = FiniteDomainSort('S', 100)
7924 >>> v = FiniteDomainVal(3, s)
7925 >>> v
7926 3
7927 >>> v.as_long() + 1
7928 4
7929 """
7930 return int(self.as_string())
7931
7932 def as_string(self):
7933 """Return a Z3 finite-domain numeral as a Python string.
7934
7935 >>> s = FiniteDomainSort('S', 100)
7936 >>> v = FiniteDomainVal(42, s)
7937 >>> v.as_string()
7938 '42'
7939 """
7940 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
7941
7942
7943def FiniteDomainVal(val, sort, ctx=None):
7944 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
7945
7946 >>> s = FiniteDomainSort('S', 256)
7947 >>> FiniteDomainVal(255, s)
7948 255
7949 >>> FiniteDomainVal('100', s)
7950 100
7951 """
7952 if z3_debug():
7953 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
7954 ctx = sort.ctx
7955 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
7956
7957
7958def is_finite_domain_value(a):
7959 """Return `True` if `a` is a Z3 finite-domain value.
7960
7961 >>> s = FiniteDomainSort('S', 100)
7962 >>> b = Const('b', s)
7963 >>> is_finite_domain_value(b)
7964 False
7965 >>> b = FiniteDomainVal(10, s)
7966 >>> b
7967 10
7968 >>> is_finite_domain_value(b)
7969 True
7970 """
7971 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
7972
7973
7974#########################################
7975#
7976# Optimize
7977#
7978#########################################
7979
7980class OptimizeObjective:
7981 def __init__(self, opt, value, is_max):
7982 self._opt = opt
7983 self._value = value
7984 self._is_max = is_max
7985
7986 def lower(self):
7987 opt = self._opt
7988 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7989
7990 def upper(self):
7991 opt = self._opt
7992 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7993
7994 def lower_values(self):
7995 opt = self._opt
7996 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
7997
7998 def upper_values(self):
7999 opt = self._opt
8000 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8001
8002 def value(self):
8003 if self._is_max:
8004 return self.upper()
8005 else:
8006 return self.lower()
8007
8008 def __str__(self):
8009 return "%s:%s" % (self._value, self._is_max)
8010
8011
8012_on_models = {}
8013
8014
8015def _global_on_model(ctx):
8016 (fn, mdl) = _on_models[ctx]
8017 fn(mdl)
8018
8019
8020_on_model_eh = on_model_eh_type(_global_on_model)
8021
8022
8023class Optimize(Z3PPObject):
8024 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8025
8026 def __init__(self, optimize=None, ctx=None):
8027 self.ctx = _get_ctx(ctx)
8028 if optimize is None:
8029 self.optimize = Z3_mk_optimize(self.ctx.ref())
8030 else:
8031 self.optimize = optimize
8032 self._on_models_id = None
8033 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8034
8035 def __deepcopy__(self, memo={}):
8036 return Optimize(self.optimize, self.ctx)
8037
8038 def __del__(self):
8039 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8040 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8041 if self._on_models_id is not None:
8042 del _on_models[self._on_models_id]
8043
8044 def __enter__(self):
8045 self.push()
8046 return self
8047
8048 def __exit__(self, *exc_info):
8049 self.pop()
8050
8051 def set(self, *args, **keys):
8052 """Set a configuration option.
8053 The method `help()` return a string containing all available options.
8054 """
8055 p = args2params(args, keys, self.ctx)
8056 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8057
8058 def help(self):
8059 """Display a string describing all available options."""
8060 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8061
8062 def param_descrs(self):
8063 """Return the parameter description set."""
8064 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8065
8066 def assert_exprs(self, *args):
8067 """Assert constraints as background axioms for the optimize solver."""
8068 args = _get_args(args)
8069 s = BoolSort(self.ctx)
8070 for arg in args:
8071 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8072 for f in arg:
8073 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8074 else:
8075 arg = s.cast(arg)
8076 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8077
8078 def add(self, *args):
8079 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8080 self.assert_exprs(*args)
8081
8082 def __iadd__(self, fml):
8083 self.add(fml)
8084 return self
8085
8086 def assert_and_track(self, a, p):
8087 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8088
8089 If `p` is a string, it will be automatically converted into a Boolean constant.
8090
8091 >>> x = Int('x')
8092 >>> p3 = Bool('p3')
8093 >>> s = Optimize()
8094 >>> s.assert_and_track(x > 0, 'p1')
8095 >>> s.assert_and_track(x != 1, 'p2')
8096 >>> s.assert_and_track(x < 0, p3)
8097 >>> print(s.check())
8098 unsat
8099 >>> c = s.unsat_core()
8100 >>> len(c)
8101 2
8102 >>> Bool('p1') in c
8103 True
8104 >>> Bool('p2') in c
8105 False
8106 >>> p3 in c
8107 True
8108 """
8109 if isinstance(p, str):
8110 p = Bool(p, self.ctx)
8111 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8112 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8113 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8114
8115 def add_soft(self, arg, weight="1", id=None):
8116 """Add soft constraint with optional weight and optional identifier.
8117 If no weight is supplied, then the penalty for violating the soft constraint
8118 is 1.
8119 Soft constraints are grouped by identifiers. Soft constraints that are
8120 added without identifiers are grouped by default.
8121 """
8122 if _is_int(weight):
8123 weight = "%d" % weight
8124 elif isinstance(weight, float):
8125 weight = "%f" % weight
8126 if not isinstance(weight, str):
8127 raise Z3Exception("weight should be a string or an integer")
8128 if id is None:
8129 id = ""
8130 id = to_symbol(id, self.ctx)
8131
8132 def asoft(a):
8133 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8134 return OptimizeObjective(self, v, False)
8135 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8136 return [asoft(a) for a in arg]
8137 return asoft(arg)
8138
8139 def set_initial_value(self, var, value):
8140 """initialize the solver's state by setting the initial value of var to value
8141 """
8142 s = var.sort()
8143 value = s.cast(value)
8144 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8145
8146 def maximize(self, arg):
8147 """Add objective function to maximize."""
8148 return OptimizeObjective(
8149 self,
8150 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8151 is_max=True,
8152 )
8153
8154 def minimize(self, arg):
8155 """Add objective function to minimize."""
8156 return OptimizeObjective(
8157 self,
8158 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8159 is_max=False,
8160 )
8161
8162 def push(self):
8163 """create a backtracking point for added rules, facts and assertions"""
8164 Z3_optimize_push(self.ctx.ref(), self.optimize)
8165
8166 def pop(self):
8167 """restore to previously created backtracking point"""
8168 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8169
8170 def check(self, *assumptions):
8171 """Check consistency and produce optimal values."""
8172 assumptions = _get_args(assumptions)
8173 num = len(assumptions)
8174 _assumptions = (Ast * num)()
8175 for i in range(num):
8176 _assumptions[i] = assumptions[i].as_ast()
8177 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8178
8179 def reason_unknown(self):
8180 """Return a string that describes why the last `check()` returned `unknown`."""
8181 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8182
8183 def model(self):
8184 """Return a model for the last check()."""
8185 try:
8186 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8187 except Z3Exception:
8188 raise Z3Exception("model is not available")
8189
8190 def unsat_core(self):
8191 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8192
8193 def lower(self, obj):
8194 if not isinstance(obj, OptimizeObjective):
8195 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8196 return obj.lower()
8197
8198 def upper(self, obj):
8199 if not isinstance(obj, OptimizeObjective):
8200 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8201 return obj.upper()
8202
8203 def lower_values(self, obj):
8204 if not isinstance(obj, OptimizeObjective):
8205 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8206 return obj.lower_values()
8207
8208 def upper_values(self, obj):
8209 if not isinstance(obj, OptimizeObjective):
8210 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8211 return obj.upper_values()
8212
8213 def from_file(self, filename):
8214 """Parse assertions and objectives from a file"""
8215 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8216
8217 def from_string(self, s):
8218 """Parse assertions and objectives from a string"""
8219 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8220
8221 def assertions(self):
8222 """Return an AST vector containing all added constraints."""
8223 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8224
8225 def objectives(self):
8226 """returns set of objective functions"""
8227 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8228
8229 def __repr__(self):
8230 """Return a formatted string with all added rules and constraints."""
8231 return self.sexpr()
8232
8233 def sexpr(self):
8234 """Return a formatted string (in Lisp-like format) with all added constraints.
8235 We say the string is in s-expression format.
8236 """
8237 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8238
8239 def statistics(self):
8240 """Return statistics for the last check`.
8241 """
8242 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8243
8244 def set_on_model(self, on_model):
8245 """Register a callback that is invoked with every incremental improvement to
8246 objective values. The callback takes a model as argument.
8247 The life-time of the model is limited to the callback so the
8248 model has to be (deep) copied if it is to be used after the callback
8249 """
8250 id = len(_on_models) + 41
8251 mdl = Model(self.ctx)
8252 _on_models[id] = (on_model, mdl)
8253 self._on_models_id = id
8254 Z3_optimize_register_model_eh(
8255 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8256 )
8257
8258
8259#########################################
8260#
8261# ApplyResult
8262#
8263#########################################
8264class ApplyResult(Z3PPObject):
8265 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8266 It also contains model and proof converters.
8267 """
8268
8269 def __init__(self, result, ctx):
8270 self.result = result
8271 self.ctx = ctx
8272 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8273
8274 def __deepcopy__(self, memo={}):
8275 return ApplyResult(self.result, self.ctx)
8276
8277 def __del__(self):
8278 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8279 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8280
8281 def __len__(self):
8282 """Return the number of subgoals in `self`.
8283
8284 >>> a, b = Ints('a b')
8285 >>> g = Goal()
8286 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8287 >>> t = Tactic('split-clause')
8288 >>> r = t(g)
8289 >>> len(r)
8290 2
8291 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8292 >>> len(t(g))
8293 4
8294 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8295 >>> len(t(g))
8296 1
8297 """
8298 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8299
8300 def __getitem__(self, idx):
8301 """Return one of the subgoals stored in ApplyResult object `self`.
8302
8303 >>> a, b = Ints('a b')
8304 >>> g = Goal()
8305 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8306 >>> t = Tactic('split-clause')
8307 >>> r = t(g)
8308 >>> r[0]
8309 [a == 0, Or(b == 0, b == 1), a > b]
8310 >>> r[1]
8311 [a == 1, Or(b == 0, b == 1), a > b]
8312 """
8313 if idx >= len(self):
8314 raise IndexError
8315 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8316
8317 def __repr__(self):
8318 return obj_to_string(self)
8319
8320 def sexpr(self):
8321 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8322 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8323
8324 def as_expr(self):
8325 """Return a Z3 expression consisting of all subgoals.
8326
8327 >>> x = Int('x')
8328 >>> g = Goal()
8329 >>> g.add(x > 1)
8330 >>> g.add(Or(x == 2, x == 3))
8331 >>> r = Tactic('simplify')(g)
8332 >>> r
8333 [[Not(x <= 1), Or(x == 2, x == 3)]]
8334 >>> r.as_expr()
8335 And(Not(x <= 1), Or(x == 2, x == 3))
8336 >>> r = Tactic('split-clause')(g)
8337 >>> r
8338 [[x > 1, x == 2], [x > 1, x == 3]]
8339 >>> r.as_expr()
8340 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8341 """
8342 sz = len(self)
8343 if sz == 0:
8344 return BoolVal(False, self.ctx)
8345 elif sz == 1:
8346 return self[0].as_expr()
8347 else:
8348 return Or([self[i].as_expr() for i in range(len(self))])
8349
8350#########################################
8351#
8352# Simplifiers
8353#
8354#########################################
8355
8356class Simplifier:
8357 """Simplifiers act as pre-processing utilities for solvers.
8358 Build a custom simplifier and add it to a solver"""
8359
8360 def __init__(self, simplifier, ctx=None):
8361 self.ctx = _get_ctx(ctx)
8362 self.simplifier = None
8363 if isinstance(simplifier, SimplifierObj):
8364 self.simplifier = simplifier
8365 elif isinstance(simplifier, list):
8366 simps = [Simplifier(s, ctx) for s in simplifier]
8367 self.simplifier = simps[0].simplifier
8368 for i in range(1, len(simps)):
8369 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8370 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8371 return
8372 else:
8373 if z3_debug():
8374 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8375 try:
8376 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8377 except Z3Exception:
8378 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8379 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8380
8381 def __deepcopy__(self, memo={}):
8382 return Simplifier(self.simplifier, self.ctx)
8383
8384 def __del__(self):
8385 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8386 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8387
8388 def using_params(self, *args, **keys):
8389 """Return a simplifier that uses the given configuration options"""
8390 p = args2params(args, keys, self.ctx)
8391 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8392
8393 def add(self, solver):
8394 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8395 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8396
8397 def help(self):
8398 """Display a string containing a description of the available options for the `self` simplifier."""
8399 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8400
8401 def param_descrs(self):
8402 """Return the parameter description set."""
8403 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8404
8405
8406#########################################
8407#
8408# Tactics
8409#
8410#########################################
8411
8412
8413class Tactic:
8414 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8415 A Tactic can be converted into a Solver using the method solver().
8416
8417 Several combinators are available for creating new tactics using the built-in ones:
8418 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8419 """
8420
8421 def __init__(self, tactic, ctx=None):
8422 self.ctx = _get_ctx(ctx)
8423 self.tactic = None
8424 if isinstance(tactic, TacticObj):
8425 self.tactic = tactic
8426 else:
8427 if z3_debug():
8428 _z3_assert(isinstance(tactic, str), "tactic name expected")
8429 try:
8430 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8431 except Z3Exception:
8432 raise Z3Exception("unknown tactic '%s'" % tactic)
8433 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8434
8435 def __deepcopy__(self, memo={}):
8436 return Tactic(self.tactic, self.ctx)
8437
8438 def __del__(self):
8439 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8440 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8441
8442 def solver(self, logFile=None):
8443 """Create a solver using the tactic `self`.
8444
8445 The solver supports the methods `push()` and `pop()`, but it
8446 will always solve each `check()` from scratch.
8447
8448 >>> t = Then('simplify', 'nlsat')
8449 >>> s = t.solver()
8450 >>> x = Real('x')
8451 >>> s.add(x**2 == 2, x > 0)
8452 >>> s.check()
8453 sat
8454 >>> s.model()
8455 [x = 1.4142135623?]
8456 """
8457 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8458
8459 def apply(self, goal, *arguments, **keywords):
8460 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8461
8462 >>> x, y = Ints('x y')
8463 >>> t = Tactic('solve-eqs')
8464 >>> t.apply(And(x == 0, y >= x + 1))
8465 [[y >= 1]]
8466 """
8467 if z3_debug():
8468 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8469 goal = _to_goal(goal)
8470 if len(arguments) > 0 or len(keywords) > 0:
8471 p = args2params(arguments, keywords, self.ctx)
8472 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8473 else:
8474 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8475
8476 def __call__(self, goal, *arguments, **keywords):
8477 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8478
8479 >>> x, y = Ints('x y')
8480 >>> t = Tactic('solve-eqs')
8481 >>> t(And(x == 0, y >= x + 1))
8482 [[y >= 1]]
8483 """
8484 return self.apply(goal, *arguments, **keywords)
8485
8486 def help(self):
8487 """Display a string containing a description of the available options for the `self` tactic."""
8488 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8489
8490 def param_descrs(self):
8491 """Return the parameter description set."""
8492 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8493
8494
8495def _to_goal(a):
8496 if isinstance(a, BoolRef):
8497 goal = Goal(ctx=a.ctx)
8498 goal.add(a)
8499 return goal
8500 else:
8501 return a
8502
8503
8504def _to_tactic(t, ctx=None):
8505 if isinstance(t, Tactic):
8506 return t
8507 else:
8508 return Tactic(t, ctx)
8509
8510
8511def _and_then(t1, t2, ctx=None):
8512 t1 = _to_tactic(t1, ctx)
8513 t2 = _to_tactic(t2, ctx)
8514 if z3_debug():
8515 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8516 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8517
8518
8519def _or_else(t1, t2, ctx=None):
8520 t1 = _to_tactic(t1, ctx)
8521 t2 = _to_tactic(t2, ctx)
8522 if z3_debug():
8523 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8524 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8525
8526
8527def AndThen(*ts, **ks):
8528 """Return a tactic that applies the tactics in `*ts` in sequence.
8529
8530 >>> x, y = Ints('x y')
8531 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8532 >>> t(And(x == 0, y > x + 1))
8533 [[Not(y <= 1)]]
8534 >>> t(And(x == 0, y > x + 1)).as_expr()
8535 Not(y <= 1)
8536 """
8537 if z3_debug():
8538 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8539 ctx = ks.get("ctx", None)
8540 num = len(ts)
8541 r = ts[0]
8542 for i in range(num - 1):
8543 r = _and_then(r, ts[i + 1], ctx)
8544 return r
8545
8546
8547def Then(*ts, **ks):
8548 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8549
8550 >>> x, y = Ints('x y')
8551 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8552 >>> t(And(x == 0, y > x + 1))
8553 [[Not(y <= 1)]]
8554 >>> t(And(x == 0, y > x + 1)).as_expr()
8555 Not(y <= 1)
8556 """
8557 return AndThen(*ts, **ks)
8558
8559
8560def OrElse(*ts, **ks):
8561 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8562
8563 >>> x = Int('x')
8564 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8565 >>> # Tactic split-clause fails if there is no clause in the given goal.
8566 >>> t(x == 0)
8567 [[x == 0]]
8568 >>> t(Or(x == 0, x == 1))
8569 [[x == 0], [x == 1]]
8570 """
8571 if z3_debug():
8572 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8573 ctx = ks.get("ctx", None)
8574 num = len(ts)
8575 r = ts[0]
8576 for i in range(num - 1):
8577 r = _or_else(r, ts[i + 1], ctx)
8578 return r
8579
8580
8581def ParOr(*ts, **ks):
8582 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8583
8584 >>> x = Int('x')
8585 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8586 >>> t(x + 1 == 2)
8587 [[x == 1]]
8588 """
8589 if z3_debug():
8590 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8591 ctx = _get_ctx(ks.get("ctx", None))
8592 ts = [_to_tactic(t, ctx) for t in ts]
8593 sz = len(ts)
8594 _args = (TacticObj * sz)()
8595 for i in range(sz):
8596 _args[i] = ts[i].tactic
8597 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8598
8599
8600def ParThen(t1, t2, ctx=None):
8601 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8602 The subgoals are processed in parallel.
8603
8604 >>> x, y = Ints('x y')
8605 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8606 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8607 [[x == 1, y == 2], [x == 2, y == 3]]
8608 """
8609 t1 = _to_tactic(t1, ctx)
8610 t2 = _to_tactic(t2, ctx)
8611 if z3_debug():
8612 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8613 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8614
8615
8616def ParAndThen(t1, t2, ctx=None):
8617 """Alias for ParThen(t1, t2, ctx)."""
8618 return ParThen(t1, t2, ctx)
8619
8620
8621def With(t, *args, **keys):
8622 """Return a tactic that applies tactic `t` using the given configuration options.
8623
8624 >>> x, y = Ints('x y')
8625 >>> t = With(Tactic('simplify'), som=True)
8626 >>> t((x + 1)*(y + 2) == 0)
8627 [[2*x + y + x*y == -2]]
8628 """
8629 ctx = keys.pop("ctx", None)
8630 t = _to_tactic(t, ctx)
8631 p = args2params(args, keys, t.ctx)
8632 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8633
8634
8635def WithParams(t, p):
8636 """Return a tactic that applies tactic `t` using the given configuration options.
8637
8638 >>> x, y = Ints('x y')
8639 >>> p = ParamsRef()
8640 >>> p.set("som", True)
8641 >>> t = WithParams(Tactic('simplify'), p)
8642 >>> t((x + 1)*(y + 2) == 0)
8643 [[2*x + y + x*y == -2]]
8644 """
8645 t = _to_tactic(t, None)
8646 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8647
8648
8649def Repeat(t, max=4294967295, ctx=None):
8650 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8651 or the maximum number of iterations `max` is reached.
8652
8653 >>> x, y = Ints('x y')
8654 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8655 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8656 >>> r = t(c)
8657 >>> for subgoal in r: print(subgoal)
8658 [x == 0, y == 0, x > y]
8659 [x == 0, y == 1, x > y]
8660 [x == 1, y == 0, x > y]
8661 [x == 1, y == 1, x > y]
8662 >>> t = Then(t, Tactic('propagate-values'))
8663 >>> t(c)
8664 [[x == 1, y == 0]]
8665 """
8666 t = _to_tactic(t, ctx)
8667 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8668
8669
8670def TryFor(t, ms, ctx=None):
8671 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8672
8673 If `t` does not terminate in `ms` milliseconds, then it fails.
8674 """
8675 t = _to_tactic(t, ctx)
8676 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8677
8678
8679def tactics(ctx=None):
8680 """Return a list of all available tactics in Z3.
8681
8682 >>> l = tactics()
8683 >>> l.count('simplify') == 1
8684 True
8685 """
8686 ctx = _get_ctx(ctx)
8687 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8688
8689
8690def tactic_description(name, ctx=None):
8691 """Return a short description for the tactic named `name`.
8692
8693 >>> d = tactic_description('simplify')
8694 """
8695 ctx = _get_ctx(ctx)
8696 return Z3_tactic_get_descr(ctx.ref(), name)
8697
8698
8699def describe_tactics():
8700 """Display a (tabular) description of all available tactics in Z3."""
8701 if in_html_mode():
8702 even = True
8703 print('<table border="1" cellpadding="2" cellspacing="0">')
8704 for t in tactics():
8705 if even:
8706 print('<tr style="background-color:#CFCFCF">')
8707 even = False
8708 else:
8709 print("<tr>")
8710 even = True
8711 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8712 print("</table>")
8713 else:
8714 for t in tactics():
8715 print("%s : %s" % (t, tactic_description(t)))
8716
8717
8718class Probe:
8719 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8720 to decide which solver and/or preprocessing step will be used.
8721 """
8722
8723 def __init__(self, probe, ctx=None):
8724 self.ctx = _get_ctx(ctx)
8725 self.probe = None
8726 if isinstance(probe, ProbeObj):
8727 self.probe = probe
8728 elif isinstance(probe, float):
8729 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8730 elif _is_int(probe):
8731 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8732 elif isinstance(probe, bool):
8733 if probe:
8734 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8735 else:
8736 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8737 else:
8738 if z3_debug():
8739 _z3_assert(isinstance(probe, str), "probe name expected")
8740 try:
8741 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8742 except Z3Exception:
8743 raise Z3Exception("unknown probe '%s'" % probe)
8744 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8745
8746 def __deepcopy__(self, memo={}):
8747 return Probe(self.probe, self.ctx)
8748
8749 def __del__(self):
8750 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8751 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8752
8753 def __lt__(self, other):
8754 """Return a probe that evaluates to "true" when the value returned by `self`
8755 is less than the value returned by `other`.
8756
8757 >>> p = Probe('size') < 10
8758 >>> x = Int('x')
8759 >>> g = Goal()
8760 >>> g.add(x > 0)
8761 >>> g.add(x < 10)
8762 >>> p(g)
8763 1.0
8764 """
8765 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8766
8767 def __gt__(self, other):
8768 """Return a probe that evaluates to "true" when the value returned by `self`
8769 is greater than the value returned by `other`.
8770
8771 >>> p = Probe('size') > 10
8772 >>> x = Int('x')
8773 >>> g = Goal()
8774 >>> g.add(x > 0)
8775 >>> g.add(x < 10)
8776 >>> p(g)
8777 0.0
8778 """
8779 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8780
8781 def __le__(self, other):
8782 """Return a probe that evaluates to "true" when the value returned by `self`
8783 is less than or equal to the value returned by `other`.
8784
8785 >>> p = Probe('size') <= 2
8786 >>> x = Int('x')
8787 >>> g = Goal()
8788 >>> g.add(x > 0)
8789 >>> g.add(x < 10)
8790 >>> p(g)
8791 1.0
8792 """
8793 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8794
8795 def __ge__(self, other):
8796 """Return a probe that evaluates to "true" when the value returned by `self`
8797 is greater than or equal to the value returned by `other`.
8798
8799 >>> p = Probe('size') >= 2
8800 >>> x = Int('x')
8801 >>> g = Goal()
8802 >>> g.add(x > 0)
8803 >>> g.add(x < 10)
8804 >>> p(g)
8805 1.0
8806 """
8807 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8808
8809 def __eq__(self, other):
8810 """Return a probe that evaluates to "true" when the value returned by `self`
8811 is equal to the value returned by `other`.
8812
8813 >>> p = Probe('size') == 2
8814 >>> x = Int('x')
8815 >>> g = Goal()
8816 >>> g.add(x > 0)
8817 >>> g.add(x < 10)
8818 >>> p(g)
8819 1.0
8820 """
8821 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8822
8823 def __ne__(self, other):
8824 """Return a probe that evaluates to "true" when the value returned by `self`
8825 is not equal to the value returned by `other`.
8826
8827 >>> p = Probe('size') != 2
8828 >>> x = Int('x')
8829 >>> g = Goal()
8830 >>> g.add(x > 0)
8831 >>> g.add(x < 10)
8832 >>> p(g)
8833 0.0
8834 """
8835 p = self.__eq__(other)
8836 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8837
8838 def __call__(self, goal):
8839 """Evaluate the probe `self` in the given goal.
8840
8841 >>> p = Probe('size')
8842 >>> x = Int('x')
8843 >>> g = Goal()
8844 >>> g.add(x > 0)
8845 >>> g.add(x < 10)
8846 >>> p(g)
8847 2.0
8848 >>> g.add(x < 20)
8849 >>> p(g)
8850 3.0
8851 >>> p = Probe('num-consts')
8852 >>> p(g)
8853 1.0
8854 >>> p = Probe('is-propositional')
8855 >>> p(g)
8856 0.0
8857 >>> p = Probe('is-qflia')
8858 >>> p(g)
8859 1.0
8860 """
8861 if z3_debug():
8862 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8863 goal = _to_goal(goal)
8864 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8865
8866
8867def is_probe(p):
8868 """Return `True` if `p` is a Z3 probe.
8869
8870 >>> is_probe(Int('x'))
8871 False
8872 >>> is_probe(Probe('memory'))
8873 True
8874 """
8875 return isinstance(p, Probe)
8876
8877
8878def _to_probe(p, ctx=None):
8879 if is_probe(p):
8880 return p
8881 else:
8882 return Probe(p, ctx)
8883
8884
8885def probes(ctx=None):
8886 """Return a list of all available probes in Z3.
8887
8888 >>> l = probes()
8889 >>> l.count('memory') == 1
8890 True
8891 """
8892 ctx = _get_ctx(ctx)
8893 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8894
8895
8896def probe_description(name, ctx=None):
8897 """Return a short description for the probe named `name`.
8898
8899 >>> d = probe_description('memory')
8900 """
8901 ctx = _get_ctx(ctx)
8902 return Z3_probe_get_descr(ctx.ref(), name)
8903
8904
8905def describe_probes():
8906 """Display a (tabular) description of all available probes in Z3."""
8907 if in_html_mode():
8908 even = True
8909 print('<table border="1" cellpadding="2" cellspacing="0">')
8910 for p in probes():
8911 if even:
8912 print('<tr style="background-color:#CFCFCF">')
8913 even = False
8914 else:
8915 print("<tr>")
8916 even = True
8917 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
8918 print("</table>")
8919 else:
8920 for p in probes():
8921 print("%s : %s" % (p, probe_description(p)))
8922
8923
8924def _probe_nary(f, args, ctx):
8925 if z3_debug():
8926 _z3_assert(len(args) > 0, "At least one argument expected")
8927 num = len(args)
8928 r = _to_probe(args[0], ctx)
8929 for i in range(num - 1):
8930 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
8931 return r
8932
8933
8934def _probe_and(args, ctx):
8935 return _probe_nary(Z3_probe_and, args, ctx)
8936
8937
8938def _probe_or(args, ctx):
8939 return _probe_nary(Z3_probe_or, args, ctx)
8940
8941
8942def FailIf(p, ctx=None):
8943 """Return a tactic that fails if the probe `p` evaluates to true.
8944 Otherwise, it returns the input goal unmodified.
8945
8946 In the following example, the tactic applies 'simplify' if and only if there are
8947 more than 2 constraints in the goal.
8948
8949 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
8950 >>> x, y = Ints('x y')
8951 >>> g = Goal()
8952 >>> g.add(x > 0)
8953 >>> g.add(y > 0)
8954 >>> t(g)
8955 [[x > 0, y > 0]]
8956 >>> g.add(x == y + 1)
8957 >>> t(g)
8958 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8959 """
8960 p = _to_probe(p, ctx)
8961 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
8962
8963
8964def When(p, t, ctx=None):
8965 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
8966 Otherwise, it returns the input goal unmodified.
8967
8968 >>> t = When(Probe('size') > 2, Tactic('simplify'))
8969 >>> x, y = Ints('x y')
8970 >>> g = Goal()
8971 >>> g.add(x > 0)
8972 >>> g.add(y > 0)
8973 >>> t(g)
8974 [[x > 0, y > 0]]
8975 >>> g.add(x == y + 1)
8976 >>> t(g)
8977 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
8978 """
8979 p = _to_probe(p, ctx)
8980 t = _to_tactic(t, ctx)
8981 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
8982
8983
8984def Cond(p, t1, t2, ctx=None):
8985 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
8986
8987 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
8988 """
8989 p = _to_probe(p, ctx)
8990 t1 = _to_tactic(t1, ctx)
8991 t2 = _to_tactic(t2, ctx)
8992 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
8993
8994#########################################
8995#
8996# Utils
8997#
8998#########################################
8999
9000
9001def simplify(a, *arguments, **keywords):
9002 """Simplify the expression `a` using the given options.
9003
9004 This function has many options. Use `help_simplify` to obtain the complete list.
9005
9006 >>> x = Int('x')
9007 >>> y = Int('y')
9008 >>> simplify(x + 1 + y + x + 1)
9009 2 + 2*x + y
9010 >>> simplify((x + 1)*(y + 1), som=True)
9011 1 + x + y + x*y
9012 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9013 And(Not(x == y), Not(x == 1), Not(y == 1))
9014 >>> simplify(And(x == 0, y == 1), elim_and=True)
9015 Not(Or(Not(x == 0), Not(y == 1)))
9016 """
9017 if z3_debug():
9018 _z3_assert(is_expr(a), "Z3 expression expected")
9019 if len(arguments) > 0 or len(keywords) > 0:
9020 p = args2params(arguments, keywords, a.ctx)
9021 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9022 else:
9023 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9024
9025
9026def help_simplify():
9027 """Return a string describing all options available for Z3 `simplify` procedure."""
9028 print(Z3_simplify_get_help(main_ctx().ref()))
9029
9030
9031def simplify_param_descrs():
9032 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9033 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9034
9035
9036def substitute(t, *m):
9037 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9038 Every occurrence in t of from is replaced with to.
9039
9040 >>> x = Int('x')
9041 >>> y = Int('y')
9042 >>> substitute(x + 1, (x, y + 1))
9043 y + 1 + 1
9044 >>> f = Function('f', IntSort(), IntSort())
9045 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9046 1 + 1
9047 """
9048 if isinstance(m, tuple):
9049 m1 = _get_args(m)
9050 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9051 m = m1
9052 if z3_debug():
9053 _z3_assert(is_expr(t), "Z3 expression expected")
9054 _z3_assert(
9055 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9056 "Z3 invalid substitution, expression pairs expected.")
9057 _z3_assert(
9058 all([p[0].sort().eq(p[1].sort()) for p in m]),
9059 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9060 num = len(m)
9061 _from = (Ast * num)()
9062 _to = (Ast * num)()
9063 for i in range(num):
9064 _from[i] = m[i][0].as_ast()
9065 _to[i] = m[i][1].as_ast()
9066 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9067
9068
9069def substitute_vars(t, *m):
9070 """Substitute the free variables in t with the expression in m.
9071
9072 >>> v0 = Var(0, IntSort())
9073 >>> v1 = Var(1, IntSort())
9074 >>> x = Int('x')
9075 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9076 >>> # replace v0 with x+1 and v1 with x
9077 >>> substitute_vars(f(v0, v1), x + 1, x)
9078 f(x + 1, x)
9079 """
9080 if z3_debug():
9081 _z3_assert(is_expr(t), "Z3 expression expected")
9082 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9083 num = len(m)
9084 _to = (Ast * num)()
9085 for i in range(num):
9086 _to[i] = m[i].as_ast()
9087 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9088
9089def substitute_funs(t, *m):
9090 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9091 Every occurrence in to of the function from is replaced with the expression to.
9092 The expression to can have free variables, that refer to the arguments of from.
9093 For examples, see
9094 """
9095 if isinstance(m, tuple):
9096 m1 = _get_args(m)
9097 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9098 m = m1
9099 if z3_debug():
9100 _z3_assert(is_expr(t), "Z3 expression expected")
9101 _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.")
9102 num = len(m)
9103 _from = (FuncDecl * num)()
9104 _to = (Ast * num)()
9105 for i in range(num):
9106 _from[i] = m[i][0].as_func_decl()
9107 _to[i] = m[i][1].as_ast()
9108 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9109
9110
9111def Sum(*args):
9112 """Create the sum of the Z3 expressions.
9113
9114 >>> a, b, c = Ints('a b c')
9115 >>> Sum(a, b, c)
9116 a + b + c
9117 >>> Sum([a, b, c])
9118 a + b + c
9119 >>> A = IntVector('a', 5)
9120 >>> Sum(A)
9121 a__0 + a__1 + a__2 + a__3 + a__4
9122 """
9123 args = _get_args(args)
9124 if len(args) == 0:
9125 return 0
9126 ctx = _ctx_from_ast_arg_list(args)
9127 if ctx is None:
9128 return _reduce(lambda a, b: a + b, args, 0)
9129 args = _coerce_expr_list(args, ctx)
9130 if is_bv(args[0]):
9131 return _reduce(lambda a, b: a + b, args, 0)
9132 else:
9133 _args, sz = _to_ast_array(args)
9134 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9135
9136
9137def Product(*args):
9138 """Create the product of the Z3 expressions.
9139
9140 >>> a, b, c = Ints('a b c')
9141 >>> Product(a, b, c)
9142 a*b*c
9143 >>> Product([a, b, c])
9144 a*b*c
9145 >>> A = IntVector('a', 5)
9146 >>> Product(A)
9147 a__0*a__1*a__2*a__3*a__4
9148 """
9149 args = _get_args(args)
9150 if len(args) == 0:
9151 return 1
9152 ctx = _ctx_from_ast_arg_list(args)
9153 if ctx is None:
9154 return _reduce(lambda a, b: a * b, args, 1)
9155 args = _coerce_expr_list(args, ctx)
9156 if is_bv(args[0]):
9157 return _reduce(lambda a, b: a * b, args, 1)
9158 else:
9159 _args, sz = _to_ast_array(args)
9160 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9161
9162def Abs(arg):
9163 """Create the absolute value of an arithmetic expression"""
9164 return If(arg > 0, arg, -arg)
9165
9166
9167def AtMost(*args):
9168 """Create an at-most Pseudo-Boolean k constraint.
9169
9170 >>> a, b, c = Bools('a b c')
9171 >>> f = AtMost(a, b, c, 2)
9172 """
9173 args = _get_args(args)
9174 if z3_debug():
9175 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9176 ctx = _ctx_from_ast_arg_list(args)
9177 if z3_debug():
9178 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9179 args1 = _coerce_expr_list(args[:-1], ctx)
9180 k = args[-1]
9181 _args, sz = _to_ast_array(args1)
9182 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9183
9184
9185def AtLeast(*args):
9186 """Create an at-least Pseudo-Boolean k constraint.
9187
9188 >>> a, b, c = Bools('a b c')
9189 >>> f = AtLeast(a, b, c, 2)
9190 """
9191 args = _get_args(args)
9192 if z3_debug():
9193 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9194 ctx = _ctx_from_ast_arg_list(args)
9195 if z3_debug():
9196 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9197 args1 = _coerce_expr_list(args[:-1], ctx)
9198 k = args[-1]
9199 _args, sz = _to_ast_array(args1)
9200 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9201
9202
9203def _reorder_pb_arg(arg):
9204 a, b = arg
9205 if not _is_int(b) and _is_int(a):
9206 return b, a
9207 return arg
9208
9209
9210def _pb_args_coeffs(args, default_ctx=None):
9211 args = _get_args_ast_list(args)
9212 if len(args) == 0:
9213 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9214 args = [_reorder_pb_arg(arg) for arg in args]
9215 args, coeffs = zip(*args)
9216 if z3_debug():
9217 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9218 ctx = _ctx_from_ast_arg_list(args)
9219 if z3_debug():
9220 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9221 args = _coerce_expr_list(args, ctx)
9222 _args, sz = _to_ast_array(args)
9223 _coeffs = (ctypes.c_int * len(coeffs))()
9224 for i in range(len(coeffs)):
9225 _z3_check_cint_overflow(coeffs[i], "coefficient")
9226 _coeffs[i] = coeffs[i]
9227 return ctx, sz, _args, _coeffs, args
9228
9229
9230def PbLe(args, k):
9231 """Create a Pseudo-Boolean inequality k constraint.
9232
9233 >>> a, b, c = Bools('a b c')
9234 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9235 """
9236 _z3_check_cint_overflow(k, "k")
9237 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9238 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9239
9240
9241def PbGe(args, k):
9242 """Create a Pseudo-Boolean inequality k constraint.
9243
9244 >>> a, b, c = Bools('a b c')
9245 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9246 """
9247 _z3_check_cint_overflow(k, "k")
9248 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9249 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9250
9251
9252def PbEq(args, k, ctx=None):
9253 """Create a Pseudo-Boolean equality k constraint.
9254
9255 >>> a, b, c = Bools('a b c')
9256 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9257 """
9258 _z3_check_cint_overflow(k, "k")
9259 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9260 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9261
9262
9263def solve(*args, **keywords):
9264 """Solve the constraints `*args`.
9265
9266 This is a simple function for creating demonstrations. It creates a solver,
9267 configure it using the options in `keywords`, adds the constraints
9268 in `args`, and invokes check.
9269
9270 >>> a = Int('a')
9271 >>> solve(a > 0, a < 2)
9272 [a = 1]
9273 """
9274 show = keywords.pop("show", False)
9275 s = Solver()
9276 s.set(**keywords)
9277 s.add(*args)
9278 if show:
9279 print(s)
9280 r = s.check()
9281 if r == unsat:
9282 print("no solution")
9283 elif r == unknown:
9284 print("failed to solve")
9285 try:
9286 print(s.model())
9287 except Z3Exception:
9288 return
9289 else:
9290 print(s.model())
9291
9292
9293def solve_using(s, *args, **keywords):
9294 """Solve the constraints `*args` using solver `s`.
9295
9296 This is a simple function for creating demonstrations. It is similar to `solve`,
9297 but it uses the given solver `s`.
9298 It configures solver `s` using the options in `keywords`, adds the constraints
9299 in `args`, and invokes check.
9300 """
9301 show = keywords.pop("show", False)
9302 if z3_debug():
9303 _z3_assert(isinstance(s, Solver), "Solver object expected")
9304 s.set(**keywords)
9305 s.add(*args)
9306 if show:
9307 print("Problem:")
9308 print(s)
9309 r = s.check()
9310 if r == unsat:
9311 print("no solution")
9312 elif r == unknown:
9313 print("failed to solve")
9314 try:
9315 print(s.model())
9316 except Z3Exception:
9317 return
9318 else:
9319 if show:
9320 print("Solution:")
9321 print(s.model())
9322
9323
9324def prove(claim, show=False, **keywords):
9325 """Try to prove the given claim.
9326
9327 This is a simple function for creating demonstrations. It tries to prove
9328 `claim` by showing the negation is unsatisfiable.
9329
9330 >>> p, q = Bools('p q')
9331 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9332 proved
9333 """
9334 if z3_debug():
9335 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9336 s = Solver()
9337 s.set(**keywords)
9338 s.add(Not(claim))
9339 if show:
9340 print(s)
9341 r = s.check()
9342 if r == unsat:
9343 print("proved")
9344 elif r == unknown:
9345 print("failed to prove")
9346 print(s.model())
9347 else:
9348 print("counterexample")
9349 print(s.model())
9350
9351
9352def _solve_html(*args, **keywords):
9353 """Version of function `solve` that renders HTML output."""
9354 show = keywords.pop("show", False)
9355 s = Solver()
9356 s.set(**keywords)
9357 s.add(*args)
9358 if show:
9359 print("<b>Problem:</b>")
9360 print(s)
9361 r = s.check()
9362 if r == unsat:
9363 print("<b>no solution</b>")
9364 elif r == unknown:
9365 print("<b>failed to solve</b>")
9366 try:
9367 print(s.model())
9368 except Z3Exception:
9369 return
9370 else:
9371 if show:
9372 print("<b>Solution:</b>")
9373 print(s.model())
9374
9375
9376def _solve_using_html(s, *args, **keywords):
9377 """Version of function `solve_using` that renders HTML."""
9378 show = keywords.pop("show", False)
9379 if z3_debug():
9380 _z3_assert(isinstance(s, Solver), "Solver object expected")
9381 s.set(**keywords)
9382 s.add(*args)
9383 if show:
9384 print("<b>Problem:</b>")
9385 print(s)
9386 r = s.check()
9387 if r == unsat:
9388 print("<b>no solution</b>")
9389 elif r == unknown:
9390 print("<b>failed to solve</b>")
9391 try:
9392 print(s.model())
9393 except Z3Exception:
9394 return
9395 else:
9396 if show:
9397 print("<b>Solution:</b>")
9398 print(s.model())
9399
9400
9401def _prove_html(claim, show=False, **keywords):
9402 """Version of function `prove` that renders HTML."""
9403 if z3_debug():
9404 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9405 s = Solver()
9406 s.set(**keywords)
9407 s.add(Not(claim))
9408 if show:
9409 print(s)
9410 r = s.check()
9411 if r == unsat:
9412 print("<b>proved</b>")
9413 elif r == unknown:
9414 print("<b>failed to prove</b>")
9415 print(s.model())
9416 else:
9417 print("<b>counterexample</b>")
9418 print(s.model())
9419
9420
9421def _dict2sarray(sorts, ctx):
9422 sz = len(sorts)
9423 _names = (Symbol * sz)()
9424 _sorts = (Sort * sz)()
9425 i = 0
9426 for k in sorts:
9427 v = sorts[k]
9428 if z3_debug():
9429 _z3_assert(isinstance(k, str), "String expected")
9430 _z3_assert(is_sort(v), "Z3 sort expected")
9431 _names[i] = to_symbol(k, ctx)
9432 _sorts[i] = v.ast
9433 i = i + 1
9434 return sz, _names, _sorts
9435
9436
9437def _dict2darray(decls, ctx):
9438 sz = len(decls)
9439 _names = (Symbol * sz)()
9440 _decls = (FuncDecl * sz)()
9441 i = 0
9442 for k in decls:
9443 v = decls[k]
9444 if z3_debug():
9445 _z3_assert(isinstance(k, str), "String expected")
9446 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9447 _names[i] = to_symbol(k, ctx)
9448 if is_const(v):
9449 _decls[i] = v.decl().ast
9450 else:
9451 _decls[i] = v.ast
9452 i = i + 1
9453 return sz, _names, _decls
9454
9455class ParserContext:
9456 def __init__(self, ctx= None):
9457 self.ctx = _get_ctx(ctx)
9458 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9459 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9460
9461 def __del__(self):
9462 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9463 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9464 self.pctx = None
9465
9466 def add_sort(self, sort):
9467 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9468
9469 def add_decl(self, decl):
9470 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9471
9472 def from_string(self, s):
9473 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9474
9475def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9476 """Parse a string in SMT 2.0 format using the given sorts and decls.
9477
9478 The arguments sorts and decls are Python dictionaries used to initialize
9479 the symbol table used for the SMT 2.0 parser.
9480
9481 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9482 [x > 0, x < 10]
9483 >>> x, y = Ints('x y')
9484 >>> f = Function('f', IntSort(), IntSort())
9485 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9486 [x + f(y) > 0]
9487 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9488 [a > 0]
9489 """
9490 ctx = _get_ctx(ctx)
9491 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9492 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9493 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9494
9495
9496def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9497 """Parse a file in SMT 2.0 format using the given sorts and decls.
9498
9499 This function is similar to parse_smt2_string().
9500 """
9501 ctx = _get_ctx(ctx)
9502 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9503 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9504 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9505
9506
9507#########################################
9508#
9509# Floating-Point Arithmetic
9510#
9511#########################################
9512
9513
9514# Global default rounding mode
9515_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9516_dflt_fpsort_ebits = 11
9517_dflt_fpsort_sbits = 53
9518
9519
9520def get_default_rounding_mode(ctx=None):
9521 """Retrieves the global default rounding mode."""
9522 global _dflt_rounding_mode
9523 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9524 return RTZ(ctx)
9525 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9526 return RTN(ctx)
9527 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9528 return RTP(ctx)
9529 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9530 return RNE(ctx)
9531 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9532 return RNA(ctx)
9533
9534
9535_ROUNDING_MODES = frozenset({
9536 Z3_OP_FPA_RM_TOWARD_ZERO,
9537 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9538 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9539 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9540 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9541})
9542
9543
9544def set_default_rounding_mode(rm, ctx=None):
9545 global _dflt_rounding_mode
9546 if is_fprm_value(rm):
9547 _dflt_rounding_mode = rm.kind()
9548 else:
9549 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9550 _dflt_rounding_mode = rm
9551
9552
9553def get_default_fp_sort(ctx=None):
9554 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9555
9556
9557def set_default_fp_sort(ebits, sbits, ctx=None):
9558 global _dflt_fpsort_ebits
9559 global _dflt_fpsort_sbits
9560 _dflt_fpsort_ebits = ebits
9561 _dflt_fpsort_sbits = sbits
9562
9563
9564def _dflt_rm(ctx=None):
9565 return get_default_rounding_mode(ctx)
9566
9567
9568def _dflt_fps(ctx=None):
9569 return get_default_fp_sort(ctx)
9570
9571
9572def _coerce_fp_expr_list(alist, ctx):
9573 first_fp_sort = None
9574 for a in alist:
9575 if is_fp(a):
9576 if first_fp_sort is None:
9577 first_fp_sort = a.sort()
9578 elif first_fp_sort == a.sort():
9579 pass # OK, same as before
9580 else:
9581 # we saw at least 2 different float sorts; something will
9582 # throw a sort mismatch later, for now assume None.
9583 first_fp_sort = None
9584 break
9585
9586 r = []
9587 for i in range(len(alist)):
9588 a = alist[i]
9589 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9590 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9591 r.append(FPVal(a, None, first_fp_sort, ctx))
9592 else:
9593 r.append(a)
9594 return _coerce_expr_list(r, ctx)
9595
9596
9597# FP Sorts
9598
9599class FPSortRef(SortRef):
9600 """Floating-point sort."""
9601
9602 def ebits(self):
9603 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9604 >>> b = FPSort(8, 24)
9605 >>> b.ebits()
9606 8
9607 """
9608 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9609
9610 def sbits(self):
9611 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9612 >>> b = FPSort(8, 24)
9613 >>> b.sbits()
9614 24
9615 """
9616 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9617
9618 def cast(self, val):
9619 """Try to cast `val` as a floating-point expression.
9620 >>> b = FPSort(8, 24)
9621 >>> b.cast(1.0)
9622 1
9623 >>> b.cast(1.0).sexpr()
9624 '(fp #b0 #x7f #b00000000000000000000000)'
9625 """
9626 if is_expr(val):
9627 if z3_debug():
9628 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9629 return val
9630 else:
9631 return FPVal(val, None, self, self.ctx)
9632
9633
9634def Float16(ctx=None):
9635 """Floating-point 16-bit (half) sort."""
9636 ctx = _get_ctx(ctx)
9637 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9638
9639
9640def FloatHalf(ctx=None):
9641 """Floating-point 16-bit (half) sort."""
9642 ctx = _get_ctx(ctx)
9643 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9644
9645
9646def Float32(ctx=None):
9647 """Floating-point 32-bit (single) sort."""
9648 ctx = _get_ctx(ctx)
9649 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9650
9651
9652def FloatSingle(ctx=None):
9653 """Floating-point 32-bit (single) sort."""
9654 ctx = _get_ctx(ctx)
9655 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9656
9657
9658def Float64(ctx=None):
9659 """Floating-point 64-bit (double) sort."""
9660 ctx = _get_ctx(ctx)
9661 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9662
9663
9664def FloatDouble(ctx=None):
9665 """Floating-point 64-bit (double) sort."""
9666 ctx = _get_ctx(ctx)
9667 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9668
9669
9670def Float128(ctx=None):
9671 """Floating-point 128-bit (quadruple) sort."""
9672 ctx = _get_ctx(ctx)
9673 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9674
9675
9676def FloatQuadruple(ctx=None):
9677 """Floating-point 128-bit (quadruple) sort."""
9678 ctx = _get_ctx(ctx)
9679 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9680
9681
9682class FPRMSortRef(SortRef):
9683 """"Floating-point rounding mode sort."""
9684
9685
9686def is_fp_sort(s):
9687 """Return True if `s` is a Z3 floating-point sort.
9688
9689 >>> is_fp_sort(FPSort(8, 24))
9690 True
9691 >>> is_fp_sort(IntSort())
9692 False
9693 """
9694 return isinstance(s, FPSortRef)
9695
9696
9697def is_fprm_sort(s):
9698 """Return True if `s` is a Z3 floating-point rounding mode sort.
9699
9700 >>> is_fprm_sort(FPSort(8, 24))
9701 False
9702 >>> is_fprm_sort(RNE().sort())
9703 True
9704 """
9705 return isinstance(s, FPRMSortRef)
9706
9707# FP Expressions
9708
9709
9710class FPRef(ExprRef):
9711 """Floating-point expressions."""
9712
9713 def sort(self):
9714 """Return the sort of the floating-point expression `self`.
9715
9716 >>> x = FP('1.0', FPSort(8, 24))
9717 >>> x.sort()
9718 FPSort(8, 24)
9719 >>> x.sort() == FPSort(8, 24)
9720 True
9721 """
9722 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9723
9724 def ebits(self):
9725 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9726 >>> b = FPSort(8, 24)
9727 >>> b.ebits()
9728 8
9729 """
9730 return self.sort().ebits()
9731
9732 def sbits(self):
9733 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9734 >>> b = FPSort(8, 24)
9735 >>> b.sbits()
9736 24
9737 """
9738 return self.sort().sbits()
9739
9740 def as_string(self):
9741 """Return a Z3 floating point expression as a Python string."""
9742 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9743
9744 def __le__(self, other):
9745 return fpLEQ(self, other, self.ctx)
9746
9747 def __lt__(self, other):
9748 return fpLT(self, other, self.ctx)
9749
9750 def __ge__(self, other):
9751 return fpGEQ(self, other, self.ctx)
9752
9753 def __gt__(self, other):
9754 return fpGT(self, other, self.ctx)
9755
9756 def __add__(self, other):
9757 """Create the Z3 expression `self + other`.
9758
9759 >>> x = FP('x', FPSort(8, 24))
9760 >>> y = FP('y', FPSort(8, 24))
9761 >>> x + y
9762 x + y
9763 >>> (x + y).sort()
9764 FPSort(8, 24)
9765 """
9766 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9767 return fpAdd(_dflt_rm(), a, b, self.ctx)
9768
9769 def __radd__(self, other):
9770 """Create the Z3 expression `other + self`.
9771
9772 >>> x = FP('x', FPSort(8, 24))
9773 >>> 10 + x
9774 1.25*(2**3) + x
9775 """
9776 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9777 return fpAdd(_dflt_rm(), a, b, self.ctx)
9778
9779 def __sub__(self, other):
9780 """Create the Z3 expression `self - other`.
9781
9782 >>> x = FP('x', FPSort(8, 24))
9783 >>> y = FP('y', FPSort(8, 24))
9784 >>> x - y
9785 x - y
9786 >>> (x - y).sort()
9787 FPSort(8, 24)
9788 """
9789 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9790 return fpSub(_dflt_rm(), a, b, self.ctx)
9791
9792 def __rsub__(self, other):
9793 """Create the Z3 expression `other - self`.
9794
9795 >>> x = FP('x', FPSort(8, 24))
9796 >>> 10 - x
9797 1.25*(2**3) - x
9798 """
9799 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9800 return fpSub(_dflt_rm(), a, b, self.ctx)
9801
9802 def __mul__(self, other):
9803 """Create the Z3 expression `self * other`.
9804
9805 >>> x = FP('x', FPSort(8, 24))
9806 >>> y = FP('y', FPSort(8, 24))
9807 >>> x * y
9808 x * y
9809 >>> (x * y).sort()
9810 FPSort(8, 24)
9811 >>> 10 * y
9812 1.25*(2**3) * y
9813 """
9814 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9815 return fpMul(_dflt_rm(), a, b, self.ctx)
9816
9817 def __rmul__(self, other):
9818 """Create the Z3 expression `other * self`.
9819
9820 >>> x = FP('x', FPSort(8, 24))
9821 >>> y = FP('y', FPSort(8, 24))
9822 >>> x * y
9823 x * y
9824 >>> x * 10
9825 x * 1.25*(2**3)
9826 """
9827 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9828 return fpMul(_dflt_rm(), a, b, self.ctx)
9829
9830 def __pos__(self):
9831 """Create the Z3 expression `+self`."""
9832 return self
9833
9834 def __neg__(self):
9835 """Create the Z3 expression `-self`.
9836
9837 >>> x = FP('x', Float32())
9838 >>> -x
9839 -x
9840 """
9841 return fpNeg(self)
9842
9843 def __div__(self, other):
9844 """Create the Z3 expression `self / other`.
9845
9846 >>> x = FP('x', FPSort(8, 24))
9847 >>> y = FP('y', FPSort(8, 24))
9848 >>> x / y
9849 x / y
9850 >>> (x / y).sort()
9851 FPSort(8, 24)
9852 >>> 10 / y
9853 1.25*(2**3) / y
9854 """
9855 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9856 return fpDiv(_dflt_rm(), a, b, self.ctx)
9857
9858 def __rdiv__(self, other):
9859 """Create the Z3 expression `other / self`.
9860
9861 >>> x = FP('x', FPSort(8, 24))
9862 >>> y = FP('y', FPSort(8, 24))
9863 >>> x / y
9864 x / y
9865 >>> x / 10
9866 x / 1.25*(2**3)
9867 """
9868 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9869 return fpDiv(_dflt_rm(), a, b, self.ctx)
9870
9871 def __truediv__(self, other):
9872 """Create the Z3 expression division `self / other`."""
9873 return self.__div__(other)
9874
9875 def __rtruediv__(self, other):
9876 """Create the Z3 expression division `other / self`."""
9877 return self.__rdiv__(other)
9878
9879 def __mod__(self, other):
9880 """Create the Z3 expression mod `self % other`."""
9881 return fpRem(self, other)
9882
9883 def __rmod__(self, other):
9884 """Create the Z3 expression mod `other % self`."""
9885 return fpRem(other, self)
9886
9887
9888class FPRMRef(ExprRef):
9889 """Floating-point rounding mode expressions"""
9890
9891 def as_string(self):
9892 """Return a Z3 floating point expression as a Python string."""
9893 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9894
9895
9896def RoundNearestTiesToEven(ctx=None):
9897 ctx = _get_ctx(ctx)
9898 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9899
9900
9901def RNE(ctx=None):
9902 ctx = _get_ctx(ctx)
9903 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9904
9905
9906def RoundNearestTiesToAway(ctx=None):
9907 ctx = _get_ctx(ctx)
9908 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9909
9910
9911def RNA(ctx=None):
9912 ctx = _get_ctx(ctx)
9913 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9914
9915
9916def RoundTowardPositive(ctx=None):
9917 ctx = _get_ctx(ctx)
9918 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9919
9920
9921def RTP(ctx=None):
9922 ctx = _get_ctx(ctx)
9923 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9924
9925
9926def RoundTowardNegative(ctx=None):
9927 ctx = _get_ctx(ctx)
9928 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9929
9930
9931def RTN(ctx=None):
9932 ctx = _get_ctx(ctx)
9933 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9934
9935
9936def RoundTowardZero(ctx=None):
9937 ctx = _get_ctx(ctx)
9938 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9939
9940
9941def RTZ(ctx=None):
9942 ctx = _get_ctx(ctx)
9943 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9944
9945
9946def is_fprm(a):
9947 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
9948
9949 >>> rm = RNE()
9950 >>> is_fprm(rm)
9951 True
9952 >>> rm = 1.0
9953 >>> is_fprm(rm)
9954 False
9955 """
9956 return isinstance(a, FPRMRef)
9957
9958
9959def is_fprm_value(a):
9960 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
9961 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
9962
9963# FP Numerals
9964
9965
9966class FPNumRef(FPRef):
9967 """The sign of the numeral.
9968
9969 >>> x = FPVal(+1.0, FPSort(8, 24))
9970 >>> x.sign()
9971 False
9972 >>> x = FPVal(-1.0, FPSort(8, 24))
9973 >>> x.sign()
9974 True
9975 """
9976
9977 def sign(self):
9978 num = (ctypes.c_int)()
9979 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
9980 if nsign is False:
9981 raise Z3Exception("error retrieving the sign of a numeral.")
9982 return num.value != 0
9983
9984 """The sign of a floating-point numeral as a bit-vector expression.
9985
9986 Remark: NaN's are invalid arguments.
9987 """
9988
9989 def sign_as_bv(self):
9990 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
9991
9992 """The significand of the numeral.
9993
9994 >>> x = FPVal(2.5, FPSort(8, 24))
9995 >>> x.significand()
9996 1.25
9997 """
9998
9999 def significand(self):
10000 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10001
10002 """The significand of the numeral as a long.
10003
10004 >>> x = FPVal(2.5, FPSort(8, 24))
10005 >>> x.significand_as_long()
10006 1.25
10007 """
10008
10009 def significand_as_long(self):
10010 ptr = (ctypes.c_ulonglong * 1)()
10011 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10012 raise Z3Exception("error retrieving the significand of a numeral.")
10013 return ptr[0]
10014
10015 """The significand of the numeral as a bit-vector expression.
10016
10017 Remark: NaN are invalid arguments.
10018 """
10019
10020 def significand_as_bv(self):
10021 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10022
10023 """The exponent of the numeral.
10024
10025 >>> x = FPVal(2.5, FPSort(8, 24))
10026 >>> x.exponent()
10027 1
10028 """
10029
10030 def exponent(self, biased=True):
10031 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10032
10033 """The exponent of the numeral as a long.
10034
10035 >>> x = FPVal(2.5, FPSort(8, 24))
10036 >>> x.exponent_as_long()
10037 1
10038 """
10039
10040 def exponent_as_long(self, biased=True):
10041 ptr = (ctypes.c_longlong * 1)()
10042 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10043 raise Z3Exception("error retrieving the exponent of a numeral.")
10044 return ptr[0]
10045
10046 """The exponent of the numeral as a bit-vector expression.
10047
10048 Remark: NaNs are invalid arguments.
10049 """
10050
10051 def exponent_as_bv(self, biased=True):
10052 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10053
10054 """Indicates whether the numeral is a NaN."""
10055
10056 def isNaN(self):
10057 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10058
10059 """Indicates whether the numeral is +oo or -oo."""
10060
10061 def isInf(self):
10062 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10063
10064 """Indicates whether the numeral is +zero or -zero."""
10065
10066 def isZero(self):
10067 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10068
10069 """Indicates whether the numeral is normal."""
10070
10071 def isNormal(self):
10072 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10073
10074 """Indicates whether the numeral is subnormal."""
10075
10076 def isSubnormal(self):
10077 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10078
10079 """Indicates whether the numeral is positive."""
10080
10081 def isPositive(self):
10082 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10083
10084 """Indicates whether the numeral is negative."""
10085
10086 def isNegative(self):
10087 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10088
10089 """
10090 The string representation of the numeral.
10091
10092 >>> x = FPVal(20, FPSort(8, 24))
10093 >>> x.as_string()
10094 1.25*(2**4)
10095 """
10096
10097 def as_string(self):
10098 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10099 return ("FPVal(%s, %s)" % (s, self.sort()))
10100
10101 def py_value(self):
10102 bv = simplify(fpToIEEEBV(self))
10103 binary = bv.py_value()
10104 if not isinstance(binary, int):
10105 return None
10106 # Decode the IEEE 754 binary representation
10107 import struct
10108 bytes_rep = binary.to_bytes(8, byteorder='big')
10109 return struct.unpack('>d', bytes_rep)[0]
10110
10111
10112def is_fp(a):
10113 """Return `True` if `a` is a Z3 floating-point expression.
10114
10115 >>> b = FP('b', FPSort(8, 24))
10116 >>> is_fp(b)
10117 True
10118 >>> is_fp(b + 1.0)
10119 True
10120 >>> is_fp(Int('x'))
10121 False
10122 """
10123 return isinstance(a, FPRef)
10124
10125
10126def is_fp_value(a):
10127 """Return `True` if `a` is a Z3 floating-point numeral value.
10128
10129 >>> b = FP('b', FPSort(8, 24))
10130 >>> is_fp_value(b)
10131 False
10132 >>> b = FPVal(1.0, FPSort(8, 24))
10133 >>> b
10134 1
10135 >>> is_fp_value(b)
10136 True
10137 """
10138 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10139
10140
10141def FPSort(ebits, sbits, ctx=None):
10142 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10143
10144 >>> Single = FPSort(8, 24)
10145 >>> Double = FPSort(11, 53)
10146 >>> Single
10147 FPSort(8, 24)
10148 >>> x = Const('x', Single)
10149 >>> eq(x, FP('x', FPSort(8, 24)))
10150 True
10151 """
10152 ctx = _get_ctx(ctx)
10153 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10154
10155
10156def _to_float_str(val, exp=0):
10157 if isinstance(val, float):
10158 if math.isnan(val):
10159 res = "NaN"
10160 elif val == 0.0:
10161 sone = math.copysign(1.0, val)
10162 if sone < 0.0:
10163 return "-0.0"
10164 else:
10165 return "+0.0"
10166 elif val == float("+inf"):
10167 res = "+oo"
10168 elif val == float("-inf"):
10169 res = "-oo"
10170 else:
10171 v = val.as_integer_ratio()
10172 num = v[0]
10173 den = v[1]
10174 rvs = str(num) + "/" + str(den)
10175 res = rvs + "p" + _to_int_str(exp)
10176 elif isinstance(val, bool):
10177 if val:
10178 res = "1.0"
10179 else:
10180 res = "0.0"
10181 elif _is_int(val):
10182 res = str(val)
10183 elif isinstance(val, str):
10184 inx = val.find("*(2**")
10185 if inx == -1:
10186 res = val
10187 elif val[-1] == ")":
10188 res = val[0:inx]
10189 exp = str(int(val[inx + 5:-1]) + int(exp))
10190 else:
10191 _z3_assert(False, "String does not have floating-point numeral form.")
10192 elif z3_debug():
10193 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10194 if exp == 0:
10195 return res
10196 else:
10197 return res + "p" + exp
10198
10199
10200def fpNaN(s):
10201 """Create a Z3 floating-point NaN term.
10202
10203 >>> s = FPSort(8, 24)
10204 >>> set_fpa_pretty(True)
10205 >>> fpNaN(s)
10206 NaN
10207 >>> pb = get_fpa_pretty()
10208 >>> set_fpa_pretty(False)
10209 >>> fpNaN(s)
10210 fpNaN(FPSort(8, 24))
10211 >>> set_fpa_pretty(pb)
10212 """
10213 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10214 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10215
10216
10217def fpPlusInfinity(s):
10218 """Create a Z3 floating-point +oo term.
10219
10220 >>> s = FPSort(8, 24)
10221 >>> pb = get_fpa_pretty()
10222 >>> set_fpa_pretty(True)
10223 >>> fpPlusInfinity(s)
10224 +oo
10225 >>> set_fpa_pretty(False)
10226 >>> fpPlusInfinity(s)
10227 fpPlusInfinity(FPSort(8, 24))
10228 >>> set_fpa_pretty(pb)
10229 """
10230 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10231 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10232
10233
10234def fpMinusInfinity(s):
10235 """Create a Z3 floating-point -oo term."""
10236 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10237 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10238
10239
10240def fpInfinity(s, negative):
10241 """Create a Z3 floating-point +oo or -oo term."""
10242 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10243 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10244 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10245
10246
10247def fpPlusZero(s):
10248 """Create a Z3 floating-point +0.0 term."""
10249 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10250 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10251
10252
10253def fpMinusZero(s):
10254 """Create a Z3 floating-point -0.0 term."""
10255 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10256 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10257
10258
10259def fpZero(s, negative):
10260 """Create a Z3 floating-point +0.0 or -0.0 term."""
10261 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10262 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10263 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10264
10265
10266def FPVal(sig, exp=None, fps=None, ctx=None):
10267 """Return a floating-point value of value `val` and sort `fps`.
10268 If `ctx=None`, then the global context is used.
10269
10270 >>> v = FPVal(20.0, FPSort(8, 24))
10271 >>> v
10272 1.25*(2**4)
10273 >>> print("0x%.8x" % v.exponent_as_long(False))
10274 0x00000004
10275 >>> v = FPVal(2.25, FPSort(8, 24))
10276 >>> v
10277 1.125*(2**1)
10278 >>> v = FPVal(-2.25, FPSort(8, 24))
10279 >>> v
10280 -1.125*(2**1)
10281 >>> FPVal(-0.0, FPSort(8, 24))
10282 -0.0
10283 >>> FPVal(0.0, FPSort(8, 24))
10284 +0.0
10285 >>> FPVal(+0.0, FPSort(8, 24))
10286 +0.0
10287 """
10288 ctx = _get_ctx(ctx)
10289 if is_fp_sort(exp):
10290 fps = exp
10291 exp = None
10292 elif fps is None:
10293 fps = _dflt_fps(ctx)
10294 _z3_assert(is_fp_sort(fps), "sort mismatch")
10295 if exp is None:
10296 exp = 0
10297 val = _to_float_str(sig)
10298 if val == "NaN" or val == "nan":
10299 return fpNaN(fps)
10300 elif val == "-0.0":
10301 return fpMinusZero(fps)
10302 elif val == "0.0" or val == "+0.0":
10303 return fpPlusZero(fps)
10304 elif val == "+oo" or val == "+inf" or val == "+Inf":
10305 return fpPlusInfinity(fps)
10306 elif val == "-oo" or val == "-inf" or val == "-Inf":
10307 return fpMinusInfinity(fps)
10308 else:
10309 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10310
10311
10312def FP(name, fpsort, ctx=None):
10313 """Return a floating-point constant named `name`.
10314 `fpsort` is the floating-point sort.
10315 If `ctx=None`, then the global context is used.
10316
10317 >>> x = FP('x', FPSort(8, 24))
10318 >>> is_fp(x)
10319 True
10320 >>> x.ebits()
10321 8
10322 >>> x.sort()
10323 FPSort(8, 24)
10324 >>> word = FPSort(8, 24)
10325 >>> x2 = FP('x', word)
10326 >>> eq(x, x2)
10327 True
10328 """
10329 if isinstance(fpsort, FPSortRef) and ctx is None:
10330 ctx = fpsort.ctx
10331 else:
10332 ctx = _get_ctx(ctx)
10333 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10334
10335
10336def FPs(names, fpsort, ctx=None):
10337 """Return an array of floating-point constants.
10338
10339 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10340 >>> x.sort()
10341 FPSort(8, 24)
10342 >>> x.sbits()
10343 24
10344 >>> x.ebits()
10345 8
10346 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10347 (x + y) * z
10348 """
10349 ctx = _get_ctx(ctx)
10350 if isinstance(names, str):
10351 names = names.split(" ")
10352 return [FP(name, fpsort, ctx) for name in names]
10353
10354
10355def fpAbs(a, ctx=None):
10356 """Create a Z3 floating-point absolute value expression.
10357
10358 >>> s = FPSort(8, 24)
10359 >>> rm = RNE()
10360 >>> x = FPVal(1.0, s)
10361 >>> fpAbs(x)
10362 fpAbs(1)
10363 >>> y = FPVal(-20.0, s)
10364 >>> y
10365 -1.25*(2**4)
10366 >>> fpAbs(y)
10367 fpAbs(-1.25*(2**4))
10368 >>> fpAbs(-1.25*(2**4))
10369 fpAbs(-1.25*(2**4))
10370 >>> fpAbs(x).sort()
10371 FPSort(8, 24)
10372 """
10373 ctx = _get_ctx(ctx)
10374 [a] = _coerce_fp_expr_list([a], ctx)
10375 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10376
10377
10378def fpNeg(a, ctx=None):
10379 """Create a Z3 floating-point addition expression.
10380
10381 >>> s = FPSort(8, 24)
10382 >>> rm = RNE()
10383 >>> x = FP('x', s)
10384 >>> fpNeg(x)
10385 -x
10386 >>> fpNeg(x).sort()
10387 FPSort(8, 24)
10388 """
10389 ctx = _get_ctx(ctx)
10390 [a] = _coerce_fp_expr_list([a], ctx)
10391 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10392
10393
10394def _mk_fp_unary(f, rm, a, ctx):
10395 ctx = _get_ctx(ctx)
10396 [a] = _coerce_fp_expr_list([a], ctx)
10397 if z3_debug():
10398 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10399 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10400 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10401
10402
10403def _mk_fp_unary_pred(f, a, ctx):
10404 ctx = _get_ctx(ctx)
10405 [a] = _coerce_fp_expr_list([a], ctx)
10406 if z3_debug():
10407 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10408 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10409
10410
10411def _mk_fp_bin(f, rm, a, b, ctx):
10412 ctx = _get_ctx(ctx)
10413 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10414 if z3_debug():
10415 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10416 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10417 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10418
10419
10420def _mk_fp_bin_norm(f, a, b, ctx):
10421 ctx = _get_ctx(ctx)
10422 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10423 if z3_debug():
10424 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10425 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10426
10427
10428def _mk_fp_bin_pred(f, a, b, ctx):
10429 ctx = _get_ctx(ctx)
10430 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10431 if z3_debug():
10432 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10433 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10434
10435
10436def _mk_fp_tern(f, rm, a, b, c, ctx):
10437 ctx = _get_ctx(ctx)
10438 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10439 if z3_debug():
10440 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10441 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10442 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10443 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10444
10445
10446def fpAdd(rm, a, b, ctx=None):
10447 """Create a Z3 floating-point addition expression.
10448
10449 >>> s = FPSort(8, 24)
10450 >>> rm = RNE()
10451 >>> x = FP('x', s)
10452 >>> y = FP('y', s)
10453 >>> fpAdd(rm, x, y)
10454 x + y
10455 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10456 fpAdd(RTZ(), x, y)
10457 >>> fpAdd(rm, x, y).sort()
10458 FPSort(8, 24)
10459 """
10460 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10461
10462
10463def fpSub(rm, a, b, ctx=None):
10464 """Create a Z3 floating-point subtraction expression.
10465
10466 >>> s = FPSort(8, 24)
10467 >>> rm = RNE()
10468 >>> x = FP('x', s)
10469 >>> y = FP('y', s)
10470 >>> fpSub(rm, x, y)
10471 x - y
10472 >>> fpSub(rm, x, y).sort()
10473 FPSort(8, 24)
10474 """
10475 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10476
10477
10478def fpMul(rm, a, b, ctx=None):
10479 """Create a Z3 floating-point multiplication expression.
10480
10481 >>> s = FPSort(8, 24)
10482 >>> rm = RNE()
10483 >>> x = FP('x', s)
10484 >>> y = FP('y', s)
10485 >>> fpMul(rm, x, y)
10486 x * y
10487 >>> fpMul(rm, x, y).sort()
10488 FPSort(8, 24)
10489 """
10490 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10491
10492
10493def fpDiv(rm, a, b, ctx=None):
10494 """Create a Z3 floating-point division expression.
10495
10496 >>> s = FPSort(8, 24)
10497 >>> rm = RNE()
10498 >>> x = FP('x', s)
10499 >>> y = FP('y', s)
10500 >>> fpDiv(rm, x, y)
10501 x / y
10502 >>> fpDiv(rm, x, y).sort()
10503 FPSort(8, 24)
10504 """
10505 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10506
10507
10508def fpRem(a, b, ctx=None):
10509 """Create a Z3 floating-point remainder expression.
10510
10511 >>> s = FPSort(8, 24)
10512 >>> x = FP('x', s)
10513 >>> y = FP('y', s)
10514 >>> fpRem(x, y)
10515 fpRem(x, y)
10516 >>> fpRem(x, y).sort()
10517 FPSort(8, 24)
10518 """
10519 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10520
10521
10522def fpMin(a, b, ctx=None):
10523 """Create a Z3 floating-point minimum expression.
10524
10525 >>> s = FPSort(8, 24)
10526 >>> rm = RNE()
10527 >>> x = FP('x', s)
10528 >>> y = FP('y', s)
10529 >>> fpMin(x, y)
10530 fpMin(x, y)
10531 >>> fpMin(x, y).sort()
10532 FPSort(8, 24)
10533 """
10534 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10535
10536
10537def fpMax(a, b, ctx=None):
10538 """Create a Z3 floating-point maximum expression.
10539
10540 >>> s = FPSort(8, 24)
10541 >>> rm = RNE()
10542 >>> x = FP('x', s)
10543 >>> y = FP('y', s)
10544 >>> fpMax(x, y)
10545 fpMax(x, y)
10546 >>> fpMax(x, y).sort()
10547 FPSort(8, 24)
10548 """
10549 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10550
10551
10552def fpFMA(rm, a, b, c, ctx=None):
10553 """Create a Z3 floating-point fused multiply-add expression.
10554 """
10555 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10556
10557
10558def fpSqrt(rm, a, ctx=None):
10559 """Create a Z3 floating-point square root expression.
10560 """
10561 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10562
10563
10564def fpRoundToIntegral(rm, a, ctx=None):
10565 """Create a Z3 floating-point roundToIntegral expression.
10566 """
10567 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10568
10569
10570def fpIsNaN(a, ctx=None):
10571 """Create a Z3 floating-point isNaN expression.
10572
10573 >>> s = FPSort(8, 24)
10574 >>> x = FP('x', s)
10575 >>> y = FP('y', s)
10576 >>> fpIsNaN(x)
10577 fpIsNaN(x)
10578 """
10579 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10580
10581
10582def fpIsInf(a, ctx=None):
10583 """Create a Z3 floating-point isInfinite expression.
10584
10585 >>> s = FPSort(8, 24)
10586 >>> x = FP('x', s)
10587 >>> fpIsInf(x)
10588 fpIsInf(x)
10589 """
10590 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10591
10592
10593def fpIsZero(a, ctx=None):
10594 """Create a Z3 floating-point isZero expression.
10595 """
10596 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10597
10598
10599def fpIsNormal(a, ctx=None):
10600 """Create a Z3 floating-point isNormal expression.
10601 """
10602 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10603
10604
10605def fpIsSubnormal(a, ctx=None):
10606 """Create a Z3 floating-point isSubnormal expression.
10607 """
10608 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10609
10610
10611def fpIsNegative(a, ctx=None):
10612 """Create a Z3 floating-point isNegative expression.
10613 """
10614 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10615
10616
10617def fpIsPositive(a, ctx=None):
10618 """Create a Z3 floating-point isPositive expression.
10619 """
10620 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10621
10622
10623def _check_fp_args(a, b):
10624 if z3_debug():
10625 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10626
10627
10628def fpLT(a, b, ctx=None):
10629 """Create the Z3 floating-point expression `other < self`.
10630
10631 >>> x, y = FPs('x y', FPSort(8, 24))
10632 >>> fpLT(x, y)
10633 x < y
10634 >>> (x < y).sexpr()
10635 '(fp.lt x y)'
10636 """
10637 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10638
10639
10640def fpLEQ(a, b, ctx=None):
10641 """Create the Z3 floating-point expression `other <= self`.
10642
10643 >>> x, y = FPs('x y', FPSort(8, 24))
10644 >>> fpLEQ(x, y)
10645 x <= y
10646 >>> (x <= y).sexpr()
10647 '(fp.leq x y)'
10648 """
10649 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10650
10651
10652def fpGT(a, b, ctx=None):
10653 """Create the Z3 floating-point expression `other > self`.
10654
10655 >>> x, y = FPs('x y', FPSort(8, 24))
10656 >>> fpGT(x, y)
10657 x > y
10658 >>> (x > y).sexpr()
10659 '(fp.gt x y)'
10660 """
10661 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10662
10663
10664def fpGEQ(a, b, ctx=None):
10665 """Create the Z3 floating-point expression `other >= self`.
10666
10667 >>> x, y = FPs('x y', FPSort(8, 24))
10668 >>> fpGEQ(x, y)
10669 x >= y
10670 >>> (x >= y).sexpr()
10671 '(fp.geq x y)'
10672 """
10673 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10674
10675
10676def fpEQ(a, b, ctx=None):
10677 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10678
10679 >>> x, y = FPs('x y', FPSort(8, 24))
10680 >>> fpEQ(x, y)
10681 fpEQ(x, y)
10682 >>> fpEQ(x, y).sexpr()
10683 '(fp.eq x y)'
10684 """
10685 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10686
10687
10688def fpNEQ(a, b, ctx=None):
10689 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10690
10691 >>> x, y = FPs('x y', FPSort(8, 24))
10692 >>> fpNEQ(x, y)
10693 Not(fpEQ(x, y))
10694 >>> (x != y).sexpr()
10695 '(distinct x y)'
10696 """
10697 return Not(fpEQ(a, b, ctx))
10698
10699
10700def fpFP(sgn, exp, sig, ctx=None):
10701 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10702
10703 >>> s = FPSort(8, 24)
10704 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10705 >>> print(x)
10706 fpFP(1, 127, 4194304)
10707 >>> xv = FPVal(-1.5, s)
10708 >>> print(xv)
10709 -1.5
10710 >>> slvr = Solver()
10711 >>> slvr.add(fpEQ(x, xv))
10712 >>> slvr.check()
10713 sat
10714 >>> xv = FPVal(+1.5, s)
10715 >>> print(xv)
10716 1.5
10717 >>> slvr = Solver()
10718 >>> slvr.add(fpEQ(x, xv))
10719 >>> slvr.check()
10720 unsat
10721 """
10722 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10723 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10724 ctx = _get_ctx(ctx)
10725 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10726 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10727
10728
10729def fpToFP(a1, a2=None, a3=None, ctx=None):
10730 """Create a Z3 floating-point conversion expression from other term sorts
10731 to floating-point.
10732
10733 From a bit-vector term in IEEE 754-2008 format:
10734 >>> x = FPVal(1.0, Float32())
10735 >>> x_bv = fpToIEEEBV(x)
10736 >>> simplify(fpToFP(x_bv, Float32()))
10737 1
10738
10739 From a floating-point term with different precision:
10740 >>> x = FPVal(1.0, Float32())
10741 >>> x_db = fpToFP(RNE(), x, Float64())
10742 >>> x_db.sort()
10743 FPSort(11, 53)
10744
10745 From a real term:
10746 >>> x_r = RealVal(1.5)
10747 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10748 1.5
10749
10750 From a signed bit-vector term:
10751 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10752 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10753 -1.25*(2**2)
10754 """
10755 ctx = _get_ctx(ctx)
10756 if is_bv(a1) and is_fp_sort(a2):
10757 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10758 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10759 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10760 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10761 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10762 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10763 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10764 else:
10765 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10766
10767
10768def fpBVToFP(v, sort, ctx=None):
10769 """Create a Z3 floating-point conversion expression that represents the
10770 conversion from a bit-vector term to a floating-point term.
10771
10772 >>> x_bv = BitVecVal(0x3F800000, 32)
10773 >>> x_fp = fpBVToFP(x_bv, Float32())
10774 >>> x_fp
10775 fpToFP(1065353216)
10776 >>> simplify(x_fp)
10777 1
10778 """
10779 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10780 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10781 ctx = _get_ctx(ctx)
10782 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10783
10784
10785def fpFPToFP(rm, v, sort, ctx=None):
10786 """Create a Z3 floating-point conversion expression that represents the
10787 conversion from a floating-point term to a floating-point term of different precision.
10788
10789 >>> x_sgl = FPVal(1.0, Float32())
10790 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10791 >>> x_dbl
10792 fpToFP(RNE(), 1)
10793 >>> simplify(x_dbl)
10794 1
10795 >>> x_dbl.sort()
10796 FPSort(11, 53)
10797 """
10798 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10799 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10800 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10801 ctx = _get_ctx(ctx)
10802 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10803
10804
10805def fpRealToFP(rm, v, sort, ctx=None):
10806 """Create a Z3 floating-point conversion expression that represents the
10807 conversion from a real term to a floating-point term.
10808
10809 >>> x_r = RealVal(1.5)
10810 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10811 >>> x_fp
10812 fpToFP(RNE(), 3/2)
10813 >>> simplify(x_fp)
10814 1.5
10815 """
10816 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10817 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10818 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10819 ctx = _get_ctx(ctx)
10820 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10821
10822
10823def fpSignedToFP(rm, v, sort, ctx=None):
10824 """Create a Z3 floating-point conversion expression that represents the
10825 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10826
10827 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10828 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10829 >>> x_fp
10830 fpToFP(RNE(), 4294967291)
10831 >>> simplify(x_fp)
10832 -1.25*(2**2)
10833 """
10834 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10835 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10836 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10837 ctx = _get_ctx(ctx)
10838 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10839
10840
10841def fpUnsignedToFP(rm, v, sort, ctx=None):
10842 """Create a Z3 floating-point conversion expression that represents the
10843 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10844
10845 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10846 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10847 >>> x_fp
10848 fpToFPUnsigned(RNE(), 4294967291)
10849 >>> simplify(x_fp)
10850 1*(2**32)
10851 """
10852 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10853 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10854 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10855 ctx = _get_ctx(ctx)
10856 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10857
10858
10859def fpToFPUnsigned(rm, x, s, ctx=None):
10860 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10861 if z3_debug():
10862 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10863 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10864 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10865 ctx = _get_ctx(ctx)
10866 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10867
10868
10869def fpToSBV(rm, x, s, ctx=None):
10870 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10871
10872 >>> x = FP('x', FPSort(8, 24))
10873 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10874 >>> print(is_fp(x))
10875 True
10876 >>> print(is_bv(y))
10877 True
10878 >>> print(is_fp(y))
10879 False
10880 >>> print(is_bv(x))
10881 False
10882 """
10883 if z3_debug():
10884 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10885 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10886 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10887 ctx = _get_ctx(ctx)
10888 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10889
10890
10891def fpToUBV(rm, x, s, ctx=None):
10892 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10893
10894 >>> x = FP('x', FPSort(8, 24))
10895 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10896 >>> print(is_fp(x))
10897 True
10898 >>> print(is_bv(y))
10899 True
10900 >>> print(is_fp(y))
10901 False
10902 >>> print(is_bv(x))
10903 False
10904 """
10905 if z3_debug():
10906 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10907 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10908 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10909 ctx = _get_ctx(ctx)
10910 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10911
10912
10913def fpToReal(x, ctx=None):
10914 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
10915
10916 >>> x = FP('x', FPSort(8, 24))
10917 >>> y = fpToReal(x)
10918 >>> print(is_fp(x))
10919 True
10920 >>> print(is_real(y))
10921 True
10922 >>> print(is_fp(y))
10923 False
10924 >>> print(is_real(x))
10925 False
10926 """
10927 if z3_debug():
10928 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10929 ctx = _get_ctx(ctx)
10930 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
10931
10932
10933def fpToIEEEBV(x, ctx=None):
10934 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
10935
10936 The size of the resulting bit-vector is automatically determined.
10937
10938 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
10939 knows only one NaN and it will always produce the same bit-vector representation of
10940 that NaN.
10941
10942 >>> x = FP('x', FPSort(8, 24))
10943 >>> y = fpToIEEEBV(x)
10944 >>> print(is_fp(x))
10945 True
10946 >>> print(is_bv(y))
10947 True
10948 >>> print(is_fp(y))
10949 False
10950 >>> print(is_bv(x))
10951 False
10952 """
10953 if z3_debug():
10954 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10955 ctx = _get_ctx(ctx)
10956 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
10957
10958
10959#########################################
10960#
10961# Strings, Sequences and Regular expressions
10962#
10963#########################################
10964
10965class SeqSortRef(SortRef):
10966 """Sequence sort."""
10967
10968 def is_string(self):
10969 """Determine if sort is a string
10970 >>> s = StringSort()
10971 >>> s.is_string()
10972 True
10973 >>> s = SeqSort(IntSort())
10974 >>> s.is_string()
10975 False
10976 """
10977 return Z3_is_string_sort(self.ctx_ref(), self.ast)
10978
10979 def basis(self):
10980 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
10981
10982class CharSortRef(SortRef):
10983 """Character sort."""
10984
10985
10986def StringSort(ctx=None):
10987 """Create a string sort
10988 >>> s = StringSort()
10989 >>> print(s)
10990 String
10991 """
10992 ctx = _get_ctx(ctx)
10993 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
10994
10995def CharSort(ctx=None):
10996 """Create a character sort
10997 >>> ch = CharSort()
10998 >>> print(ch)
10999 Char
11000 """
11001 ctx = _get_ctx(ctx)
11002 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11003
11004
11005def SeqSort(s):
11006 """Create a sequence sort over elements provided in the argument
11007 >>> s = SeqSort(IntSort())
11008 >>> s == Unit(IntVal(1)).sort()
11009 True
11010 """
11011 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11012
11013
11014class SeqRef(ExprRef):
11015 """Sequence expression."""
11016
11017 def sort(self):
11018 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11019
11020 def __add__(self, other):
11021 return Concat(self, other)
11022
11023 def __radd__(self, other):
11024 return Concat(other, self)
11025
11026 def __getitem__(self, i):
11027 if _is_int(i):
11028 i = IntVal(i, self.ctx)
11029 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11030
11031 def at(self, i):
11032 if _is_int(i):
11033 i = IntVal(i, self.ctx)
11034 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11035
11036 def is_string(self):
11037 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11038
11039 def is_string_value(self):
11040 return Z3_is_string(self.ctx_ref(), self.as_ast())
11041
11042 def as_string(self):
11043 """Return a string representation of sequence expression."""
11044 if self.is_string_value():
11045 string_length = ctypes.c_uint()
11046 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11047 return string_at(chars, size=string_length.value).decode("latin-1")
11048 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11049
11050 def py_value(self):
11051 return self.as_string()
11052
11053 def __le__(self, other):
11054 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11055
11056 def __lt__(self, other):
11057 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11058
11059 def __ge__(self, other):
11060 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11061
11062 def __gt__(self, other):
11063 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11064
11065
11066def _coerce_char(ch, ctx=None):
11067 if isinstance(ch, str):
11068 ctx = _get_ctx(ctx)
11069 ch = CharVal(ch, ctx)
11070 if not is_expr(ch):
11071 raise Z3Exception("Character expression expected")
11072 return ch
11073
11074class CharRef(ExprRef):
11075 """Character expression."""
11076
11077 def __le__(self, other):
11078 other = _coerce_char(other, self.ctx)
11079 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11080
11081 def to_int(self):
11082 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11083
11084 def to_bv(self):
11085 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11086
11087 def is_digit(self):
11088 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11089
11090
11091def CharVal(ch, ctx=None):
11092 ctx = _get_ctx(ctx)
11093 if isinstance(ch, str):
11094 ch = ord(ch)
11095 if not isinstance(ch, int):
11096 raise Z3Exception("character value should be an ordinal")
11097 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11098
11099def CharFromBv(bv):
11100 if not is_expr(bv):
11101 raise Z3Exception("Bit-vector expression needed")
11102 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11103
11104def CharToBv(ch, ctx=None):
11105 ch = _coerce_char(ch, ctx)
11106 return ch.to_bv()
11107
11108def CharToInt(ch, ctx=None):
11109 ch = _coerce_char(ch, ctx)
11110 return ch.to_int()
11111
11112def CharIsDigit(ch, ctx=None):
11113 ch = _coerce_char(ch, ctx)
11114 return ch.is_digit()
11115
11116def _coerce_seq(s, ctx=None):
11117 if isinstance(s, str):
11118 ctx = _get_ctx(ctx)
11119 s = StringVal(s, ctx)
11120 if not is_expr(s):
11121 raise Z3Exception("Non-expression passed as a sequence")
11122 if not is_seq(s):
11123 raise Z3Exception("Non-sequence passed as a sequence")
11124 return s
11125
11126
11127def _get_ctx2(a, b, ctx=None):
11128 if is_expr(a):
11129 return a.ctx
11130 if is_expr(b):
11131 return b.ctx
11132 if ctx is None:
11133 ctx = main_ctx()
11134 return ctx
11135
11136
11137def is_seq(a):
11138 """Return `True` if `a` is a Z3 sequence expression.
11139 >>> print (is_seq(Unit(IntVal(0))))
11140 True
11141 >>> print (is_seq(StringVal("abc")))
11142 True
11143 """
11144 return isinstance(a, SeqRef)
11145
11146
11147def is_string(a: Any) -> bool:
11148 """Return `True` if `a` is a Z3 string expression.
11149 >>> print (is_string(StringVal("ab")))
11150 True
11151 """
11152 return isinstance(a, SeqRef) and a.is_string()
11153
11154
11155def is_string_value(a: Any) -> bool:
11156 """return 'True' if 'a' is a Z3 string constant expression.
11157 >>> print (is_string_value(StringVal("a")))
11158 True
11159 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11160 False
11161 """
11162 return isinstance(a, SeqRef) and a.is_string_value()
11163
11164def StringVal(s, ctx=None):
11165 """create a string expression"""
11166 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11167 ctx = _get_ctx(ctx)
11168 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11169
11170
11171def String(name, ctx=None):
11172 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11173
11174 >>> x = String('x')
11175 """
11176 ctx = _get_ctx(ctx)
11177 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11178
11179
11180def Strings(names, ctx=None):
11181 """Return a tuple of String constants. """
11182 ctx = _get_ctx(ctx)
11183 if isinstance(names, str):
11184 names = names.split(" ")
11185 return [String(name, ctx) for name in names]
11186
11187
11188def SubString(s, offset, length):
11189 """Extract substring or subsequence starting at offset"""
11190 return Extract(s, offset, length)
11191
11192
11193def SubSeq(s, offset, length):
11194 """Extract substring or subsequence starting at offset"""
11195 return Extract(s, offset, length)
11196
11197
11198def Empty(s):
11199 """Create the empty sequence of the given sort
11200 >>> e = Empty(StringSort())
11201 >>> e2 = StringVal("")
11202 >>> print(e.eq(e2))
11203 True
11204 >>> e3 = Empty(SeqSort(IntSort()))
11205 >>> print(e3)
11206 Empty(Seq(Int))
11207 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11208 >>> print(e4)
11209 Empty(ReSort(Seq(Int)))
11210 """
11211 if isinstance(s, SeqSortRef):
11212 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11213 if isinstance(s, ReSortRef):
11214 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11215 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11216
11217
11218def Full(s):
11219 """Create the regular expression that accepts the universal language
11220 >>> e = Full(ReSort(SeqSort(IntSort())))
11221 >>> print(e)
11222 Full(ReSort(Seq(Int)))
11223 >>> e1 = Full(ReSort(StringSort()))
11224 >>> print(e1)
11225 Full(ReSort(String))
11226 """
11227 if isinstance(s, ReSortRef):
11228 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11229 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11230
11231
11232
11233def Unit(a):
11234 """Create a singleton sequence"""
11235 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11236
11237
11238def PrefixOf(a, b):
11239 """Check if 'a' is a prefix of 'b'
11240 >>> s1 = PrefixOf("ab", "abc")
11241 >>> simplify(s1)
11242 True
11243 >>> s2 = PrefixOf("bc", "abc")
11244 >>> simplify(s2)
11245 False
11246 """
11247 ctx = _get_ctx2(a, b)
11248 a = _coerce_seq(a, ctx)
11249 b = _coerce_seq(b, ctx)
11250 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11251
11252
11253def SuffixOf(a, b):
11254 """Check if 'a' is a suffix of 'b'
11255 >>> s1 = SuffixOf("ab", "abc")
11256 >>> simplify(s1)
11257 False
11258 >>> s2 = SuffixOf("bc", "abc")
11259 >>> simplify(s2)
11260 True
11261 """
11262 ctx = _get_ctx2(a, b)
11263 a = _coerce_seq(a, ctx)
11264 b = _coerce_seq(b, ctx)
11265 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11266
11267
11268def Contains(a, b):
11269 """Check if 'a' contains 'b'
11270 >>> s1 = Contains("abc", "ab")
11271 >>> simplify(s1)
11272 True
11273 >>> s2 = Contains("abc", "bc")
11274 >>> simplify(s2)
11275 True
11276 >>> x, y, z = Strings('x y z')
11277 >>> s3 = Contains(Concat(x,y,z), y)
11278 >>> simplify(s3)
11279 True
11280 """
11281 ctx = _get_ctx2(a, b)
11282 a = _coerce_seq(a, ctx)
11283 b = _coerce_seq(b, ctx)
11284 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11285
11286
11287def Replace(s, src, dst):
11288 """Replace the first occurrence of 'src' by 'dst' in 's'
11289 >>> r = Replace("aaa", "a", "b")
11290 >>> simplify(r)
11291 "baa"
11292 """
11293 ctx = _get_ctx2(dst, s)
11294 if ctx is None and is_expr(src):
11295 ctx = src.ctx
11296 src = _coerce_seq(src, ctx)
11297 dst = _coerce_seq(dst, ctx)
11298 s = _coerce_seq(s, ctx)
11299 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11300
11301
11302def IndexOf(s, substr, offset=None):
11303 """Retrieve the index of substring within a string starting at a specified offset.
11304 >>> simplify(IndexOf("abcabc", "bc", 0))
11305 1
11306 >>> simplify(IndexOf("abcabc", "bc", 2))
11307 4
11308 """
11309 if offset is None:
11310 offset = IntVal(0)
11311 ctx = None
11312 if is_expr(offset):
11313 ctx = offset.ctx
11314 ctx = _get_ctx2(s, substr, ctx)
11315 s = _coerce_seq(s, ctx)
11316 substr = _coerce_seq(substr, ctx)
11317 if _is_int(offset):
11318 offset = IntVal(offset, ctx)
11319 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11320
11321
11322def LastIndexOf(s, substr):
11323 """Retrieve the last index of substring within a string"""
11324 ctx = None
11325 ctx = _get_ctx2(s, substr, ctx)
11326 s = _coerce_seq(s, ctx)
11327 substr = _coerce_seq(substr, ctx)
11328 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11329
11330
11331def Length(s):
11332 """Obtain the length of a sequence 's'
11333 >>> l = Length(StringVal("abc"))
11334 >>> simplify(l)
11335 3
11336 """
11337 s = _coerce_seq(s)
11338 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11339
11340def SeqMap(f, s):
11341 """Map function 'f' over sequence 's'"""
11342 ctx = _get_ctx2(f, s)
11343 s = _coerce_seq(s, ctx)
11344 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11345
11346def SeqMapI(f, i, s):
11347 """Map function 'f' over sequence 's' at index 'i'"""
11348 ctx = _get_ctx2(f, s)
11349 s = _coerce_seq(s, ctx)
11350 if not is_expr(i):
11351 i = _py2expr(i)
11352 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11353
11354def SeqFoldLeft(f, a, s):
11355 ctx = _get_ctx2(f, s)
11356 s = _coerce_seq(s, ctx)
11357 a = _py2expr(a)
11358 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11359
11360def SeqFoldLeftI(f, i, a, s):
11361 ctx = _get_ctx2(f, s)
11362 s = _coerce_seq(s, ctx)
11363 a = _py2expr(a)
11364 i = _py2expr(i)
11365 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11366
11367def StrToInt(s):
11368 """Convert string expression to integer
11369 >>> a = StrToInt("1")
11370 >>> simplify(1 == a)
11371 True
11372 >>> b = StrToInt("2")
11373 >>> simplify(1 == b)
11374 False
11375 >>> c = StrToInt(IntToStr(2))
11376 >>> simplify(1 == c)
11377 False
11378 """
11379 s = _coerce_seq(s)
11380 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11381
11382
11383def IntToStr(s):
11384 """Convert integer expression to string"""
11385 if not is_expr(s):
11386 s = _py2expr(s)
11387 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11388
11389
11390def StrToCode(s):
11391 """Convert a unit length string to integer code"""
11392 if not is_expr(s):
11393 s = _py2expr(s)
11394 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11395
11396def StrFromCode(c):
11397 """Convert code to a string"""
11398 if not is_expr(c):
11399 c = _py2expr(c)
11400 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11401
11402def Re(s, ctx=None):
11403 """The regular expression that accepts sequence 's'
11404 >>> s1 = Re("ab")
11405 >>> s2 = Re(StringVal("ab"))
11406 >>> s3 = Re(Unit(BoolVal(True)))
11407 """
11408 s = _coerce_seq(s, ctx)
11409 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11410
11411
11412# Regular expressions
11413
11414class ReSortRef(SortRef):
11415 """Regular expression sort."""
11416
11417 def basis(self):
11418 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11419
11420
11421def ReSort(s):
11422 if is_ast(s):
11423 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11424 if s is None or isinstance(s, Context):
11425 ctx = _get_ctx(s)
11426 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11427 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11428
11429
11430class ReRef(ExprRef):
11431 """Regular expressions."""
11432
11433 def __add__(self, other):
11434 return Union(self, other)
11435
11436
11437def is_re(s):
11438 return isinstance(s, ReRef)
11439
11440
11441def InRe(s, re):
11442 """Create regular expression membership test
11443 >>> re = Union(Re("a"),Re("b"))
11444 >>> print (simplify(InRe("a", re)))
11445 True
11446 >>> print (simplify(InRe("b", re)))
11447 True
11448 >>> print (simplify(InRe("c", re)))
11449 False
11450 """
11451 s = _coerce_seq(s, re.ctx)
11452 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11453
11454
11455def Union(*args):
11456 """Create union of regular expressions.
11457 >>> re = Union(Re("a"), Re("b"), Re("c"))
11458 >>> print (simplify(InRe("d", re)))
11459 False
11460 """
11461 args = _get_args(args)
11462 sz = len(args)
11463 if z3_debug():
11464 _z3_assert(sz > 0, "At least one argument expected.")
11465 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11466 if sz == 1:
11467 return args[0]
11468 ctx = args[0].ctx
11469 v = (Ast * sz)()
11470 for i in range(sz):
11471 v[i] = args[i].as_ast()
11472 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11473
11474
11475def Intersect(*args):
11476 """Create intersection of regular expressions.
11477 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11478 """
11479 args = _get_args(args)
11480 sz = len(args)
11481 if z3_debug():
11482 _z3_assert(sz > 0, "At least one argument expected.")
11483 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11484 if sz == 1:
11485 return args[0]
11486 ctx = args[0].ctx
11487 v = (Ast * sz)()
11488 for i in range(sz):
11489 v[i] = args[i].as_ast()
11490 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11491
11492
11493def Plus(re):
11494 """Create the regular expression accepting one or more repetitions of argument.
11495 >>> re = Plus(Re("a"))
11496 >>> print(simplify(InRe("aa", re)))
11497 True
11498 >>> print(simplify(InRe("ab", re)))
11499 False
11500 >>> print(simplify(InRe("", re)))
11501 False
11502 """
11503 if z3_debug():
11504 _z3_assert(is_expr(re), "expression expected")
11505 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11506
11507
11508def Option(re):
11509 """Create the regular expression that optionally accepts the argument.
11510 >>> re = Option(Re("a"))
11511 >>> print(simplify(InRe("a", re)))
11512 True
11513 >>> print(simplify(InRe("", re)))
11514 True
11515 >>> print(simplify(InRe("aa", re)))
11516 False
11517 """
11518 if z3_debug():
11519 _z3_assert(is_expr(re), "expression expected")
11520 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11521
11522
11523def Complement(re):
11524 """Create the complement regular expression."""
11525 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11526
11527
11528def Star(re):
11529 """Create the regular expression accepting zero or more repetitions of argument.
11530 >>> re = Star(Re("a"))
11531 >>> print(simplify(InRe("aa", re)))
11532 True
11533 >>> print(simplify(InRe("ab", re)))
11534 False
11535 >>> print(simplify(InRe("", re)))
11536 True
11537 """
11538 if z3_debug():
11539 _z3_assert(is_expr(re), "expression expected")
11540 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11541
11542
11543def Loop(re, lo, hi=0):
11544 """Create the regular expression accepting between a lower and upper bound repetitions
11545 >>> re = Loop(Re("a"), 1, 3)
11546 >>> print(simplify(InRe("aa", re)))
11547 True
11548 >>> print(simplify(InRe("aaaa", re)))
11549 False
11550 >>> print(simplify(InRe("", re)))
11551 False
11552 """
11553 if z3_debug():
11554 _z3_assert(is_expr(re), "expression expected")
11555 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11556
11557
11558def Range(lo, hi, ctx=None):
11559 """Create the range regular expression over two sequences of length 1
11560 >>> range = Range("a","z")
11561 >>> print(simplify(InRe("b", range)))
11562 True
11563 >>> print(simplify(InRe("bb", range)))
11564 False
11565 """
11566 lo = _coerce_seq(lo, ctx)
11567 hi = _coerce_seq(hi, ctx)
11568 if z3_debug():
11569 _z3_assert(is_expr(lo), "expression expected")
11570 _z3_assert(is_expr(hi), "expression expected")
11571 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11572
11573def Diff(a, b, ctx=None):
11574 """Create the difference regular expression
11575 """
11576 if z3_debug():
11577 _z3_assert(is_expr(a), "expression expected")
11578 _z3_assert(is_expr(b), "expression expected")
11579 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11580
11581def AllChar(regex_sort, ctx=None):
11582 """Create a regular expression that accepts all single character strings
11583 """
11584 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11585
11586# Special Relations
11587
11588
11589def PartialOrder(a, index):
11590 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11591
11592
11593def LinearOrder(a, index):
11594 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11595
11596
11597def TreeOrder(a, index):
11598 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11599
11600
11601def PiecewiseLinearOrder(a, index):
11602 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11603
11604
11605def TransitiveClosure(f):
11606 """Given a binary relation R, such that the two arguments have the same sort
11607 create the transitive closure relation R+.
11608 The transitive closure R+ is a new relation.
11609 """
11610 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11611
11612def to_Ast(ptr,):
11613 ast = Ast(ptr)
11614 super(ctypes.c_void_p, ast).__init__(ptr)
11615 return ast
11616
11617def to_ContextObj(ptr,):
11618 ctx = ContextObj(ptr)
11619 super(ctypes.c_void_p, ctx).__init__(ptr)
11620 return ctx
11621
11622def to_AstVectorObj(ptr,):
11623 v = AstVectorObj(ptr)
11624 super(ctypes.c_void_p, v).__init__(ptr)
11625 return v
11626
11627# NB. my-hacky-class only works for a single instance of OnClause
11628# it should be replaced with a proper correlation between OnClause
11629# and object references that can be passed over the FFI.
11630# for UserPropagator we use a global dictionary, which isn't great code.
11631
11632_my_hacky_class = None
11633def on_clause_eh(ctx, p, n, dep, clause):
11634 onc = _my_hacky_class
11635 p = _to_expr_ref(to_Ast(p), onc.ctx)
11636 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11637 deps = [dep[i] for i in range(n)]
11638 onc.on_clause(p, deps, clause)
11639
11640_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11641
11642class OnClause:
11643 def __init__(self, s, on_clause):
11644 self.s = s
11645 self.ctx = s.ctx
11646 self.on_clause = on_clause
11647 self.idx = 22
11648 global _my_hacky_class
11649 _my_hacky_class = self
11650 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11651
11652
11653class PropClosures:
11654 def __init__(self):
11655 self.bases = {}
11656 self.lock = None
11657
11658 def set_threaded(self):
11659 if self.lock is None:
11660 import threading
11661 self.lock = threading.Lock()
11662
11663 def get(self, ctx):
11664 if self.lock:
11665 with self.lock:
11666 r = self.bases[ctx]
11667 else:
11668 r = self.bases[ctx]
11669 return r
11670
11671 def set(self, ctx, r):
11672 if self.lock:
11673 with self.lock:
11674 self.bases[ctx] = r
11675 else:
11676 self.bases[ctx] = r
11677
11678 def insert(self, r):
11679 if self.lock:
11680 with self.lock:
11681 id = len(self.bases) + 3
11682 self.bases[id] = r
11683 else:
11684 id = len(self.bases) + 3
11685 self.bases[id] = r
11686 return id
11687
11688
11689_prop_closures = None
11690
11691
11692def ensure_prop_closures():
11693 global _prop_closures
11694 if _prop_closures is None:
11695 _prop_closures = PropClosures()
11696
11697
11698def user_prop_push(ctx, cb):
11699 prop = _prop_closures.get(ctx)
11700 prop.cb = cb
11701 prop.push()
11702
11703
11704def user_prop_pop(ctx, cb, num_scopes):
11705 prop = _prop_closures.get(ctx)
11706 prop.cb = cb
11707 prop.pop(num_scopes)
11708
11709
11710def user_prop_fresh(ctx, _new_ctx):
11711 _prop_closures.set_threaded()
11712 prop = _prop_closures.get(ctx)
11713 nctx = Context()
11714 Z3_del_context(nctx.ctx)
11715 new_ctx = to_ContextObj(_new_ctx)
11716 nctx.ctx = new_ctx
11717 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11718 nctx.owner = False
11719 new_prop = prop.fresh(nctx)
11720 _prop_closures.set(new_prop.id, new_prop)
11721 return new_prop.id
11722
11723
11724def user_prop_fixed(ctx, cb, id, value):
11725 prop = _prop_closures.get(ctx)
11726 old_cb = prop.cb
11727 prop.cb = cb
11728 id = _to_expr_ref(to_Ast(id), prop.ctx())
11729 value = _to_expr_ref(to_Ast(value), prop.ctx())
11730 prop.fixed(id, value)
11731 prop.cb = old_cb
11732
11733def user_prop_created(ctx, cb, id):
11734 prop = _prop_closures.get(ctx)
11735 old_cb = prop.cb
11736 prop.cb = cb
11737 id = _to_expr_ref(to_Ast(id), prop.ctx())
11738 prop.created(id)
11739 prop.cb = old_cb
11740
11741
11742def user_prop_final(ctx, cb):
11743 prop = _prop_closures.get(ctx)
11744 old_cb = prop.cb
11745 prop.cb = cb
11746 prop.final()
11747 prop.cb = old_cb
11748
11749def user_prop_eq(ctx, cb, x, y):
11750 prop = _prop_closures.get(ctx)
11751 old_cb = prop.cb
11752 prop.cb = cb
11753 x = _to_expr_ref(to_Ast(x), prop.ctx())
11754 y = _to_expr_ref(to_Ast(y), prop.ctx())
11755 prop.eq(x, y)
11756 prop.cb = old_cb
11757
11758def user_prop_diseq(ctx, cb, x, y):
11759 prop = _prop_closures.get(ctx)
11760 old_cb = prop.cb
11761 prop.cb = cb
11762 x = _to_expr_ref(to_Ast(x), prop.ctx())
11763 y = _to_expr_ref(to_Ast(y), prop.ctx())
11764 prop.diseq(x, y)
11765 prop.cb = old_cb
11766
11767def user_prop_decide(ctx, cb, t_ref, idx, phase):
11768 prop = _prop_closures.get(ctx)
11769 old_cb = prop.cb
11770 prop.cb = cb
11771 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11772 prop.decide(t, idx, phase)
11773 prop.cb = old_cb
11774
11775
11776_user_prop_push = Z3_push_eh(user_prop_push)
11777_user_prop_pop = Z3_pop_eh(user_prop_pop)
11778_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11779_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11780_user_prop_created = Z3_created_eh(user_prop_created)
11781_user_prop_final = Z3_final_eh(user_prop_final)
11782_user_prop_eq = Z3_eq_eh(user_prop_eq)
11783_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11784_user_prop_decide = Z3_decide_eh(user_prop_decide)
11785
11786
11787def PropagateFunction(name, *sig):
11788 """Create a function that gets tracked by user propagator.
11789 Every term headed by this function symbol is tracked.
11790 If a term is fixed and the fixed callback is registered a
11791 callback is invoked that the term headed by this function is fixed.
11792 """
11793 sig = _get_args(sig)
11794 if z3_debug():
11795 _z3_assert(len(sig) > 0, "At least two arguments expected")
11796 arity = len(sig) - 1
11797 rng = sig[arity]
11798 if z3_debug():
11799 _z3_assert(is_sort(rng), "Z3 sort expected")
11800 dom = (Sort * arity)()
11801 for i in range(arity):
11802 if z3_debug():
11803 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11804 dom[i] = sig[i].ast
11805 ctx = rng.ctx
11806 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11807
11808
11809
11810class UserPropagateBase:
11811
11812 #
11813 # Either solver is set or ctx is set.
11814 # Propagators that are created through callbacks
11815 # to "fresh" inherit the context of that is supplied
11816 # as argument to the callback.
11817 # This context should not be deleted. It is owned by the solver.
11818 #
11819 def __init__(self, s, ctx=None):
11820 assert s is None or ctx is None
11821 ensure_prop_closures()
11822 self.solver = s
11823 self._ctx = None
11824 self.fresh_ctx = None
11825 self.cb = None
11826 self.id = _prop_closures.insert(self)
11827 self.fixed = None
11828 self.final = None
11829 self.eq = None
11830 self.diseq = None
11831 self.decide = None
11832 self.created = None
11833 if ctx:
11834 self.fresh_ctx = ctx
11835 if s:
11836 Z3_solver_propagate_init(self.ctx_ref(),
11837 s.solver,
11838 ctypes.c_void_p(self.id),
11839 _user_prop_push,
11840 _user_prop_pop,
11841 _user_prop_fresh)
11842
11843 def __del__(self):
11844 if self._ctx:
11845 self._ctx.ctx = None
11846
11847 def ctx(self):
11848 if self.fresh_ctx:
11849 return self.fresh_ctx
11850 else:
11851 return self.solver.ctx
11852
11853 def ctx_ref(self):
11854 return self.ctx().ref()
11855
11856 def add_fixed(self, fixed):
11857 assert not self.fixed
11858 assert not self._ctx
11859 if self.solver:
11860 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11861 self.fixed = fixed
11862
11863 def add_created(self, created):
11864 assert not self.created
11865 assert not self._ctx
11866 if self.solver:
11867 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
11868 self.created = created
11869
11870 def add_final(self, final):
11871 assert not self.final
11872 assert not self._ctx
11873 if self.solver:
11874 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
11875 self.final = final
11876
11877 def add_eq(self, eq):
11878 assert not self.eq
11879 assert not self._ctx
11880 if self.solver:
11881 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
11882 self.eq = eq
11883
11884 def add_diseq(self, diseq):
11885 assert not self.diseq
11886 assert not self._ctx
11887 if self.solver:
11888 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
11889 self.diseq = diseq
11890
11891 def add_decide(self, decide):
11892 assert not self.decide
11893 assert not self._ctx
11894 if self.solver:
11895 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
11896 self.decide = decide
11897
11898 def push(self):
11899 raise Z3Exception("push needs to be overwritten")
11900
11901 def pop(self, num_scopes):
11902 raise Z3Exception("pop needs to be overwritten")
11903
11904 def fresh(self, new_ctx):
11905 raise Z3Exception("fresh needs to be overwritten")
11906
11907 def add(self, e):
11908 assert not self._ctx
11909 if self.solver:
11910 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
11911 else:
11912 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
11913
11914 #
11915 # Tell the solver to perform the next split on a given term
11916 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
11917 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
11918 #
11919 def next_split(self, t, idx, phase):
11920 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
11921
11922 #
11923 # Propagation can only be invoked as during a fixed or final callback.
11924 #
11925 def propagate(self, e, ids, eqs=[]):
11926 _ids, num_fixed = _to_ast_array(ids)
11927 num_eqs = len(eqs)
11928 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
11929 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
11930 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
11931 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
11932
11933 def conflict(self, deps = [], eqs = []):
11934 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:10965
__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:8867
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:8934
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:9001
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:11437
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:8984
_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:11116
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:8938
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:11137
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:11164
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