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 def set_ast_print_mode(self, mode):
245 """Set the pretty printing mode for ASTs.
246
247 The following modes are available:
248 - Z3_PRINT_SMTLIB_FULL (0): Print AST nodes in SMTLIB verbose format.
249 - Z3_PRINT_LOW_LEVEL (1): Print AST nodes using a low-level format.
250 - Z3_PRINT_SMTLIB2_COMPLIANT (2): Print AST nodes in SMTLIB 2.x compliant format.
251
252 Example:
253 >>> c = Context()
254 >>> x = Int('x', c)
255 >>> c.set_ast_print_mode(Z3_PRINT_SMTLIB2_COMPLIANT)
256 >>> print(x)
257 x
258 """
259 Z3_set_ast_print_mode(self.ref(), mode)
260
261
262# Global Z3 context
263_main_ctx = None
264
265
266def main_ctx() -> Context:
267 """Return a reference to the global Z3 context.
268
269 >>> x = Real('x')
270 >>> x.ctx == main_ctx()
271 True
272 >>> c = Context()
273 >>> c == main_ctx()
274 False
275 >>> x2 = Real('x', c)
276 >>> x2.ctx == c
277 True
278 >>> eq(x, x2)
279 False
280 """
281 global _main_ctx
282 if _main_ctx is None:
283 _main_ctx = Context()
284 return _main_ctx
285
286
287def _get_ctx(ctx) -> Context:
288 if ctx is None:
289 return main_ctx()
290 else:
291 return ctx
292
293
294def get_ctx(ctx) -> Context:
295 return _get_ctx(ctx)
296
297
298def set_param(*args, **kws):
299 """Set Z3 global (or module) parameters.
300
301 >>> set_param(precision=10)
302 """
303 if z3_debug():
304 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
305 new_kws = {}
306 for k in kws:
307 v = kws[k]
308 if not set_pp_option(k, v):
309 new_kws[k] = v
310 for key in new_kws:
311 value = new_kws[key]
312 Z3_global_param_set(str(key).upper(), _to_param_value(value))
313 prev = None
314 for a in args:
315 if prev is None:
316 prev = a
317 else:
319 prev = None
320
321
322def reset_params() -> None:
323 """Reset all global (or module) parameters.
324 """
326
327
328def set_option(*args, **kws):
329 """Alias for 'set_param' for backward compatibility.
330 """
331 return set_param(*args, **kws)
332
333
334def get_param(name):
335 """Return the value of a Z3 global (or module) parameter
336
337 >>> get_param('nlsat.reorder')
338 'true'
339 """
340 ptr = (ctypes.c_char_p * 1)()
341 if Z3_global_param_get(str(name), ptr):
342 r = z3core._to_pystr(ptr[0])
343 return r
344 raise Z3Exception("failed to retrieve value for '%s'" % name)
345
346
351
352# Mark objects that use pretty printer
353
354
356 """Superclass for all Z3 objects that have support for pretty printing."""
357
358 def use_pp(self):
359 return True
360
361 def _repr_html_(self):
362 in_html = in_html_mode()
363 set_html_mode(True)
364 res = repr(self)
365 set_html_mode(in_html)
366 return res
367
368
370 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
371
372 def __init__(self, ast, ctx=None):
373 self.ast = ast
374 self.ctx = _get_ctx(ctx)
375 Z3_inc_ref(self.ctx.ref(), self.as_ast())
376
377 def __del__(self):
378 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
379 Z3_dec_ref(self.ctx.ref(), self.as_ast())
380 self.ast = None
381
382 def __deepcopy__(self, memo={}):
383 return _to_ast_ref(self.ast, self.ctx)
384
385 def __str__(self):
386 return obj_to_string(self)
387
388 def __repr__(self):
389 return obj_to_string(self)
390
391 def __eq__(self, other):
392 return self.eq(other)
393
394 def __hash__(self):
395 return self.hash()
396
397 def __nonzero__(self):
398 return self.__bool__()
399
400 def __bool__(self):
401 if is_true(self):
402 return True
403 elif is_false(self):
404 return False
405 elif is_eq(self) and self.num_args() == 2:
406 return self.arg(0).eq(self.arg(1))
407 else:
408 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
409
410 def sexpr(self):
411 """Return a string representing the AST node in s-expression notation.
412
413 >>> x = Int('x')
414 >>> ((x + 1)*x).sexpr()
415 '(* (+ x 1) x)'
416 """
417 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
418
419 def as_ast(self):
420 """Return a pointer to the corresponding C Z3_ast object."""
421 return self.ast
422
423 def get_id(self):
424 """Return unique identifier for object. It can be used for hash-tables and maps."""
425 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
426
427 def ctx_ref(self):
428 """Return a reference to the C context where this AST node is stored."""
429 return self.ctx.ref()
430
431 def eq(self, other):
432 """Return `True` if `self` and `other` are structurally identical.
433
434 >>> x = Int('x')
435 >>> n1 = x + 1
436 >>> n2 = 1 + x
437 >>> n1.eq(n2)
438 False
439 >>> n1 = simplify(n1)
440 >>> n2 = simplify(n2)
441 >>> n1.eq(n2)
442 True
443 """
444 if z3_debug():
445 _z3_assert(is_ast(other), "Z3 AST expected")
446 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
447
448 def translate(self, target):
449 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
450
451 >>> c1 = Context()
452 >>> c2 = Context()
453 >>> x = Int('x', c1)
454 >>> y = Int('y', c2)
455 >>> # Nodes in different contexts can't be mixed.
456 >>> # However, we can translate nodes from one context to another.
457 >>> x.translate(c2) + y
458 x + y
459 """
460 if z3_debug():
461 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
462 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
463
464 def __copy__(self):
465 return self.translate(self.ctx)
466
467 def hash(self):
468 """Return a hashcode for the `self`.
469
470 >>> n1 = simplify(Int('x') + 1)
471 >>> n2 = simplify(2 + Int('x') - 1)
472 >>> n1.hash() == n2.hash()
473 True
474 """
475 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
476
477 def py_value(self):
478 """Return a Python value that is equivalent to `self`."""
479 return None
480
481
482def is_ast(a : Any) -> bool:
483 """Return `True` if `a` is an AST node.
484
485 >>> is_ast(10)
486 False
487 >>> is_ast(IntVal(10))
488 True
489 >>> is_ast(Int('x'))
490 True
491 >>> is_ast(BoolSort())
492 True
493 >>> is_ast(Function('f', IntSort(), IntSort()))
494 True
495 >>> is_ast("x")
496 False
497 >>> is_ast(Solver())
498 False
499 """
500 return isinstance(a, AstRef)
501
502
503def eq(a : AstRef, b : AstRef) -> bool:
504 """Return `True` if `a` and `b` are structurally identical AST nodes.
505
506 >>> x = Int('x')
507 >>> y = Int('y')
508 >>> eq(x, y)
509 False
510 >>> eq(x + 1, x + 1)
511 True
512 >>> eq(x + 1, 1 + x)
513 False
514 >>> eq(simplify(x + 1), simplify(1 + x))
515 True
516 """
517 if z3_debug():
518 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
519 return a.eq(b)
520
521
522def _ast_kind(ctx : Context, a : Any) -> int:
523 if is_ast(a):
524 a = a.as_ast()
525 return Z3_get_ast_kind(ctx.ref(), a)
526
527
528def _ctx_from_ast_arg_list(args, default_ctx=None):
529 ctx = None
530 for a in args:
531 if is_ast(a) or is_probe(a):
532 if ctx is None:
533 ctx = a.ctx
534 else:
535 if z3_debug():
536 _z3_assert(ctx == a.ctx, "Context mismatch")
537 if ctx is None:
538 ctx = default_ctx
539 return ctx
540
541
543 return _ctx_from_ast_arg_list(args)
544
545
547 sz = len(args)
548 _args = (FuncDecl * sz)()
549 for i in range(sz):
550 _args[i] = args[i].as_func_decl()
551 return _args, sz
552
553
555 sz = len(args)
556 _args = (Ast * sz)()
557 for i in range(sz):
558 _args[i] = args[i].as_ast()
559 return _args, sz
560
561
562def _to_ref_array(ref, args):
563 sz = len(args)
564 _args = (ref * sz)()
565 for i in range(sz):
566 _args[i] = args[i].as_ast()
567 return _args, sz
568
569
570def _to_ast_ref(a, ctx):
571 k = _ast_kind(ctx, a)
572 if k == Z3_SORT_AST:
573 return _to_sort_ref(Sort.from_buffer_copy(a), ctx)
574 elif k == Z3_FUNC_DECL_AST:
575 return _to_func_decl_ref(a, ctx)
576 else:
577 return _to_expr_ref(a, ctx)
578
579
580
585
586def _sort_kind(ctx, s):
587 return Z3_get_sort_kind(ctx.ref(), s)
588
589
591 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
592
593 def as_ast(self):
594 # Z3_sort_to_ast is only a pointer cast, so do it here instead of calling into Z3.
595 return Ast.from_buffer_copy(self.ast)
596
597 def get_id(self):
598 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
599
600 def kind(self):
601 """Return the Z3 internal kind of a sort.
602 This method can be used to test if `self` is one of the Z3 builtin sorts.
603
604 >>> b = BoolSort()
605 >>> b.kind() == Z3_BOOL_SORT
606 True
607 >>> b.kind() == Z3_INT_SORT
608 False
609 >>> A = ArraySort(IntSort(), IntSort())
610 >>> A.kind() == Z3_ARRAY_SORT
611 True
612 >>> A.kind() == Z3_INT_SORT
613 False
614 """
615 return _sort_kind(self.ctx, self.ast)
616
617 def subsort(self, other):
618 """Return `True` if `self` is a subsort of `other`.
619
620 >>> IntSort().subsort(RealSort())
621 True
622 """
623 return False
624
625 def cast(self, val):
626 """Try to cast `val` as an element of sort `self`.
627
628 This method is used in Z3Py to convert Python objects such as integers,
629 floats, longs and strings into Z3 expressions.
630
631 >>> x = Int('x')
632 >>> RealSort().cast(x)
633 ToReal(x)
634 """
635 if z3_debug():
636 _z3_assert(is_expr(val), "Z3 expression expected")
637 _z3_assert(self.eq(val.sort()), "Sort mismatch")
638 return val
639
640 def name(self):
641 """Return the name (string) of sort `self`.
642
643 >>> BoolSort().name()
644 'Bool'
645 >>> ArraySort(IntSort(), IntSort()).name()
646 'Array'
647 """
648 return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
649
650 def __eq__(self, other):
651 """Return `True` if `self` and `other` are the same Z3 sort.
652
653 >>> p = Bool('p')
654 >>> p.sort() == BoolSort()
655 True
656 >>> p.sort() == IntSort()
657 False
658 """
659 if other is None:
660 return False
661 return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
662
663 def __ne__(self, other):
664 """Return `True` if `self` and `other` are not the same Z3 sort.
665
666 >>> p = Bool('p')
667 >>> p.sort() != BoolSort()
668 False
669 >>> p.sort() != IntSort()
670 True
671 """
672 return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
673
674 def __gt__(self, other):
675 """Create the function space Array(self, other)"""
676 return ArraySort(self, other)
677
678 def __hash__(self):
679 """ Hash code. """
680 return AstRef.__hash__(self)
681
682
683def is_sort(s : Any) -> bool:
684 """Return `True` if `s` is a Z3 sort.
685
686 >>> is_sort(IntSort())
687 True
688 >>> is_sort(Int('x'))
689 False
690 >>> is_expr(Int('x'))
691 True
692 """
693 return isinstance(s, SortRef)
694
695
696def _to_sort_ref(s, ctx):
697 if z3_debug():
698 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
699 if Z3_is_finite_set_sort(ctx.ref(), s):
700 return FiniteSetSortRef(s, ctx)
701 k = _sort_kind(ctx, s)
702 if k == Z3_BOOL_SORT:
703 return BoolSortRef(s, ctx)
704 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
705 return ArithSortRef(s, ctx)
706 elif k == Z3_COMPLEX_SORT:
707 return ComplexSortRef(s, ctx)
708 elif k == Z3_BV_SORT:
709 return BitVecSortRef(s, ctx)
710 elif k == Z3_ARRAY_SORT:
711 return ArraySortRef(s, ctx)
712 elif k == Z3_DATATYPE_SORT:
713 return DatatypeSortRef(s, ctx)
714 elif k == Z3_FINITE_FIELD_SORT:
715 return FiniteFieldSortRef(s, ctx)
716 elif k == Z3_FINITE_DOMAIN_SORT:
717 return FiniteDomainSortRef(s, ctx)
718 elif k == Z3_FLOATING_POINT_SORT:
719 return FPSortRef(s, ctx)
720 elif k == Z3_ROUNDING_MODE_SORT:
721 return FPRMSortRef(s, ctx)
722 elif k == Z3_RE_SORT:
723 return ReSortRef(s, ctx)
724 elif k == Z3_SEQ_SORT:
725 return SeqSortRef(s, ctx)
726 elif k == Z3_CHAR_SORT:
727 return CharSortRef(s, ctx)
728 elif k == Z3_TYPE_VAR:
729 return TypeVarRef(s, ctx)
730 return SortRef(s, ctx)
731
732
733def _sort(ctx : Context, a : Any) -> SortRef:
734 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
735
736
737def DeclareSort(name, ctx= None) -> SortRef:
738 """Create a new uninterpreted sort named `name`.
739
740 If `ctx=None`, then the new sort is declared in the global Z3Py context.
741
742 >>> A = DeclareSort('A')
743 >>> a = Const('a', A)
744 >>> b = Const('b', A)
745 >>> a.sort() == A
746 True
747 >>> b.sort() == A
748 True
749 >>> a == b
750 a == b
751 """
752 ctx = _get_ctx(ctx)
753 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
754
756 """Type variable reference"""
757
758 def subsort(self, other):
759 return True
760
761 def cast(self, val):
762 return val
763
764
765def DeclareTypeVar(name, ctx=None):
766 """Create a new type variable named `name`.
767
768 If `ctx=None`, then the new sort is declared in the global Z3Py context.
769
770 """
771 ctx = _get_ctx(ctx)
772 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
773
774
775
780
781
783 """Function declaration. Every constant and function have an associated declaration.
784
785 The declaration assigns a name, a sort (i.e., type), and for function
786 the sort (i.e., type) of each of its arguments. Note that, in Z3,
787 a constant is a function with 0 arguments.
788 """
789
790 def as_ast(self):
791 # Z3_func_decl_to_ast is only a pointer cast, so do it here instead of calling into Z3.
792 return Ast.from_buffer_copy(self.ast)
793
794 def get_id(self):
795 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
796
797 def as_func_decl(self):
798 return self.ast
799
800 def name(self):
801 """Return the name of the function declaration `self`.
802
803 >>> f = Function('f', IntSort(), IntSort())
804 >>> f.name()
805 'f'
806 >>> isinstance(f.name(), str)
807 True
808 """
809 return _symbol2py(self.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
810
811 def arity(self):
812 """Return the number of arguments of a function declaration.
813 If `self` is a constant, then `self.arity()` is 0.
814
815 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
816 >>> f.arity()
817 2
818 """
819 return int(Z3_get_arity(self.ctx_ref(), self.ast))
820
821 def domain(self, i):
822 """Return the sort of the argument `i` of a function declaration.
823 This method assumes that `0 <= i < self.arity()`.
824
825 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
826 >>> f.domain(0)
827 Int
828 >>> f.domain(1)
829 Real
830 """
831 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
832
833 def range(self):
834 """Return the sort of the range of a function declaration.
835 For constants, this is the sort of the constant.
836
837 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
838 >>> f.range()
839 Bool
840 """
841 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.ast), self.ctx)
842
843 def kind(self):
844 """Return the internal kind of a function declaration.
845 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
846
847 >>> x = Int('x')
848 >>> d = (x + 1).decl()
849 >>> d.kind() == Z3_OP_ADD
850 True
851 >>> d.kind() == Z3_OP_MUL
852 False
853 """
854 return Z3_get_decl_kind(self.ctx_ref(), self.ast)
855
856 def params(self):
857 ctx = self.ctx
858 n = Z3_get_decl_num_parameters(self.ctx_ref(), self.ast)
859 result = [None for i in range(n)]
860 for i in range(n):
861 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.ast, i)
862 if k == Z3_PARAMETER_INT:
863 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.ast, i)
864 elif k == Z3_PARAMETER_DOUBLE:
865 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.ast, i)
866 elif k == Z3_PARAMETER_RATIONAL:
867 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.ast, i)
868 elif k == Z3_PARAMETER_SYMBOL:
869 result[i] = _symbol2py(ctx, Z3_get_decl_symbol_parameter(self.ctx_ref(), self.ast, i))
870 elif k == Z3_PARAMETER_SORT:
871 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.ast, i), ctx)
872 elif k == Z3_PARAMETER_AST:
873 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.ast, i), ctx)
874 elif k == Z3_PARAMETER_FUNC_DECL:
875 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.ast, i), ctx)
876 elif k == Z3_PARAMETER_INTERNAL:
877 result[i] = "internal parameter"
878 elif k == Z3_PARAMETER_ZSTRING:
879 result[i] = "internal string"
880 else:
881 raise Z3Exception("Unexpected parameter kind")
882 return result
883
884 def __call__(self, *args):
885 """Create a Z3 application expression using the function `self`, and the given arguments.
886
887 The arguments must be Z3 expressions. This method assumes that
888 the sorts of the elements in `args` match the sorts of the
889 domain. Limited coercion is supported. For example, if
890 args[0] is a Python integer, and the function expects a Z3
891 integer, then the argument is automatically converted into a
892 Z3 integer.
893
894 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
895 >>> x = Int('x')
896 >>> y = Real('y')
897 >>> f(x, y)
898 f(x, y)
899 >>> f(x, x)
900 f(x, ToReal(x))
901 """
902 args = _get_args(args)
903 num = len(args)
904 _args = (Ast * num)()
905 saved = []
906 for i in range(num):
907 # self.domain(i).cast(args[i]) may create a new Z3 expression,
908 # then we must save in 'saved' to prevent it from being garbage collected.
909 tmp = self.domain(i).cast(args[i])
910 saved.append(tmp)
911 _args[i] = tmp.as_ast()
912 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
913
914
916 """Return `True` if `a` is a Z3 function declaration.
917
918 >>> f = Function('f', IntSort(), IntSort())
919 >>> is_func_decl(f)
920 True
921 >>> x = Real('x')
922 >>> is_func_decl(x)
923 False
924 """
925 return isinstance(a, FuncDeclRef)
926
927
928def Function(name, *sig):
929 """Create a new Z3 uninterpreted function with the given sorts.
930
931 >>> f = Function('f', IntSort(), IntSort())
932 >>> f(f(0))
933 f(f(0))
934 """
935 sig = _get_args(sig)
936 if z3_debug():
937 _z3_assert(len(sig) > 0, "At least two arguments expected")
938 arity = len(sig) - 1
939 rng = sig[arity]
940 if z3_debug():
941 _z3_assert(is_sort(rng), "Z3 sort expected")
942 dom = (Sort * arity)()
943 for i in range(arity):
944 if z3_debug():
945 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
946 dom[i] = sig[i].ast
947 ctx = rng.ctx
948 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
949
950
952 """Create a new fresh Z3 uninterpreted function with the given sorts.
953 """
954 sig = _get_args(sig)
955 if z3_debug():
956 _z3_assert(len(sig) > 0, "At least two arguments expected")
957 arity = len(sig) - 1
958 rng = sig[arity]
959 if z3_debug():
960 _z3_assert(is_sort(rng), "Z3 sort expected")
961 dom = (z3.Sort * arity)()
962 for i in range(arity):
963 if z3_debug():
964 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
965 dom[i] = sig[i].ast
966 ctx = rng.ctx
967 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
968
969
971 return FuncDeclRef(a, ctx)
972
973
974def RecFunction(name, *sig):
975 """Create a new Z3 recursive with the given sorts."""
976 sig = _get_args(sig)
977 if z3_debug():
978 _z3_assert(len(sig) > 0, "At least two arguments expected")
979 arity = len(sig) - 1
980 rng = sig[arity]
981 if z3_debug():
982 _z3_assert(is_sort(rng), "Z3 sort expected")
983 dom = (Sort * arity)()
984 for i in range(arity):
985 if z3_debug():
986 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
987 dom[i] = sig[i].ast
988 ctx = rng.ctx
989 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
990
991
992def RecAddDefinition(f, args, body):
993 """Set the body of a recursive function.
994 Recursive definitions can be simplified if they are applied to ground
995 arguments.
996 >>> ctx = Context()
997 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
998 >>> n = Int('n', ctx)
999 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
1000 >>> simplify(fac(5))
1001 120
1002 >>> s = Solver(ctx=ctx)
1003 >>> s.add(fac(n) < 3)
1004 >>> s.check()
1005 sat
1006 >>> s.model().eval(fac(5))
1007 120
1008 """
1009 if is_app(args):
1010 args = [args]
1011 ctx = body.ctx
1012 args = _get_args(args)
1013 n = len(args)
1014 _args = (Ast * n)()
1015 for i in range(n):
1016 _args[i] = args[i].ast
1017 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
1018
1019
1024
1025
1027 """Constraints, formulas and terms are expressions in Z3.
1028
1029 Expressions are ASTs. Every expression has a sort.
1030 There are three main kinds of expressions:
1031 function applications, quantifiers and bounded variables.
1032 A constant is a function application with 0 arguments.
1033 For quantifier free problems, all expressions are
1034 function applications.
1035 """
1036
1037 def as_ast(self):
1038 return self.ast
1039
1040 def get_id(self):
1041 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1042
1043 def sort(self):
1044 """Return the sort of expression `self`.
1045
1046 >>> x = Int('x')
1047 >>> (x + 1).sort()
1048 Int
1049 >>> y = Real('y')
1050 >>> (x + y).sort()
1051 Real
1052 """
1053 return _sort(self.ctx, self.as_ast())
1054
1055 def sort_kind(self):
1056 """Shorthand for `self.sort().kind()`.
1057
1058 >>> a = Array('a', IntSort(), IntSort())
1059 >>> a.sort_kind() == Z3_ARRAY_SORT
1060 True
1061 >>> a.sort_kind() == Z3_INT_SORT
1062 False
1063 """
1064 return self.sort().kind()
1065
1066 def __eq__(self, other):
1067 """Return a Z3 expression that represents the constraint `self == other`.
1068
1069 If `other` is `None`, then this method simply returns `False`.
1070
1071 >>> a = Int('a')
1072 >>> b = Int('b')
1073 >>> a == b
1074 a == b
1075 >>> a is None
1076 False
1077 """
1078 if other is None:
1079 return False
1080 a, b = _coerce_exprs(self, other)
1081 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
1082
1083 def __hash__(self):
1084 """ Hash code. """
1085 return AstRef.__hash__(self)
1086
1087 def __ne__(self, other):
1088 """Return a Z3 expression that represents the constraint `self != other`.
1089
1090 If `other` is `None`, then this method simply returns `True`.
1091
1092 >>> a = Int('a')
1093 >>> b = Int('b')
1094 >>> a != b
1095 a != b
1096 >>> a is not None
1097 True
1098 """
1099 if other is None:
1100 return True
1101 a, b = _coerce_exprs(self, other)
1102 _args, sz = _to_ast_array((a, b))
1103 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
1104
1105 def params(self):
1106 return self.decl().params()
1107
1108 def decl(self):
1109 """Return the Z3 function declaration associated with a Z3 application.
1110
1111 >>> f = Function('f', IntSort(), IntSort())
1112 >>> a = Int('a')
1113 >>> t = f(a)
1114 >>> eq(t.decl(), f)
1115 True
1116 >>> (a + 1).decl()
1117 +
1118 """
1119 if z3_debug():
1120 _z3_assert(is_app(self), "Z3 application expected")
1121 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_ast()), self.ctx)
1122
1123 def kind(self):
1124 """Return the Z3 internal kind of a function application."""
1125 if z3_debug():
1126 _z3_assert(is_app(self), "Z3 application expected")
1128
1129
1130 def num_args(self):
1131 """Return the number of arguments of a Z3 application.
1132
1133 >>> a = Int('a')
1134 >>> b = Int('b')
1135 >>> (a + b).num_args()
1136 2
1137 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1138 >>> t = f(a, b, 0)
1139 >>> t.num_args()
1140 3
1141 """
1142 if z3_debug():
1143 _z3_assert(is_app(self), "Z3 application expected")
1144 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_ast()))
1145
1146 def arg(self, idx):
1147 """Return argument `idx` of the application `self`.
1148
1149 This method assumes that `self` is a function application with at least `idx+1` arguments.
1150
1151 >>> a = Int('a')
1152 >>> b = Int('b')
1153 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1154 >>> t = f(a, b, 0)
1155 >>> t.arg(0)
1156 a
1157 >>> t.arg(1)
1158 b
1159 >>> t.arg(2)
1160 0
1161 """
1162 if z3_debug():
1163 _z3_assert(is_app(self), "Z3 application expected")
1164 _z3_assert(idx < self.num_args(), "Invalid argument index")
1165 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_ast(), idx), self.ctx)
1166
1167 def children(self):
1168 """Return a list containing the children of the given expression
1169
1170 >>> a = Int('a')
1171 >>> b = Int('b')
1172 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1173 >>> t = f(a, b, 0)
1174 >>> t.children()
1175 [a, b, 0]
1176 """
1177 if is_app(self):
1178 return [self.arg(i) for i in range(self.num_args())]
1179 else:
1180 return []
1181
1182 def update(self, *args):
1183 """Update the arguments of the expression.
1184
1185 Return a new expression with the same function declaration and updated arguments.
1186 The number of new arguments must match the current number of arguments.
1187
1188 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1189 >>> a = Int('a')
1190 >>> b = Int('b')
1191 >>> c = Int('c')
1192 >>> t = f(a, b)
1193 >>> t.update(c, c)
1194 f(c, c)
1195 """
1196 if z3_debug():
1197 _z3_assert(is_app(self), "Z3 application expected")
1198 _z3_assert(len(args) == self.num_args(), "Number of arguments does not match")
1199 _z3_assert(all([is_expr(arg) for arg in args]), "Z3 expressions expected")
1200 num = len(args)
1201 _args = (Ast * num)()
1202 for i in range(num):
1203 _args[i] = args[i].as_ast()
1204 return _to_expr_ref(Z3_update_term(self.ctx_ref(), self.as_ast(), num, _args), self.ctx)
1205
1206 def from_string(self, s):
1207 pass
1208
1209 def serialize(self):
1210 s = Solver()
1211 f = Function('F', self.sort(), BoolSort(self.ctx))
1212 s.add(f(self))
1213 return s.sexpr()
1214
1216 """inverse function to the serialize method on ExprRef.
1217 It is made available to make it easier for users to serialize expressions back and forth between
1218 strings. Solvers can be serialized using the 'sexpr()' method.
1219 """
1220 s = Solver()
1221 s.from_string(st)
1222 if len(s.assertions()) != 1:
1223 raise Z3Exception("single assertion expected")
1224 fml = s.assertions()[0]
1225 if fml.num_args() != 1:
1226 raise Z3Exception("dummy function 'F' expected")
1227 return fml.arg(0)
1228
1229def _to_expr_ref(a, ctx):
1230 if isinstance(a, Pattern):
1231 return PatternRef(a, ctx)
1232 ctx_ref = ctx.ref()
1233 k = Z3_get_ast_kind(ctx_ref, a)
1234 if k == Z3_QUANTIFIER_AST:
1235 return QuantifierRef(a, ctx)
1236 # Check for finite set sort before checking sort kind
1237 s = Z3_get_sort(ctx_ref, a)
1238 if Z3_is_finite_set_sort(ctx_ref, s):
1239 return FiniteSetRef(a, ctx)
1240 sk = Z3_get_sort_kind(ctx_ref, s)
1241 if sk == Z3_BOOL_SORT:
1242 return BoolRef(a, ctx)
1243 if sk == Z3_INT_SORT:
1244 if k == Z3_NUMERAL_AST:
1245 return IntNumRef(a, ctx)
1246 return ArithRef(a, ctx)
1247 if sk == Z3_REAL_SORT:
1248 if k == Z3_NUMERAL_AST:
1249 return RatNumRef(a, ctx)
1250 if _is_algebraic(ctx, a):
1251 return AlgebraicNumRef(a, ctx)
1252 return ArithRef(a, ctx)
1253 if sk == Z3_COMPLEX_SORT:
1254 return ComplexRef(a, ctx)
1255 if sk == Z3_BV_SORT:
1256 if k == Z3_NUMERAL_AST:
1257 return BitVecNumRef(a, ctx)
1258 else:
1259 return BitVecRef(a, ctx)
1260 if sk == Z3_ARRAY_SORT:
1261 return ArrayRef(a, ctx)
1262 if sk == Z3_DATATYPE_SORT:
1263 return DatatypeRef(a, ctx)
1264 if sk == Z3_FLOATING_POINT_SORT:
1265 if k == Z3_APP_AST and _is_numeral(ctx, a):
1266 return FPNumRef(a, ctx)
1267 else:
1268 return FPRef(a, ctx)
1269 if sk == Z3_FINITE_FIELD_SORT:
1270 return FiniteFieldRef(a, ctx)
1271 if sk == Z3_FINITE_DOMAIN_SORT:
1272 if k == Z3_NUMERAL_AST:
1273 return FiniteDomainNumRef(a, ctx)
1274 else:
1275 return FiniteDomainRef(a, ctx)
1276 if sk == Z3_ROUNDING_MODE_SORT:
1277 return FPRMRef(a, ctx)
1278 if sk == Z3_SEQ_SORT:
1279 return SeqRef(a, ctx)
1280 if sk == Z3_CHAR_SORT:
1281 return CharRef(a, ctx)
1282 if sk == Z3_RE_SORT:
1283 return ReRef(a, ctx)
1284 return ExprRef(a, ctx)
1285
1286
1288 if is_expr(a):
1289 s1 = a.sort()
1290 if s is None:
1291 return s1
1292 if s1.eq(s):
1293 return s
1294 elif s.subsort(s1):
1295 return s1
1296 elif s1.subsort(s):
1297 return s
1298 else:
1299 if z3_debug():
1300 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1301 _z3_assert(False, "sort mismatch")
1302 else:
1303 return s
1304
1305def _check_same_sort(a, b, ctx=None):
1306 if not isinstance(a, ExprRef):
1307 return False
1308 if not isinstance(b, ExprRef):
1309 return False
1310 if ctx is None:
1311 ctx = a.ctx
1312
1313 a_sort = Z3_get_sort(ctx.ctx, a.ast)
1314 b_sort = Z3_get_sort(ctx.ctx, b.ast)
1315 return Z3_is_eq_sort(ctx.ctx, a_sort, b_sort)
1316
1317
1318def _coerce_exprs(a, b, ctx=None):
1319 if not is_expr(a) and not is_expr(b):
1320 a = _py2expr(a, ctx)
1321 b = _py2expr(b, ctx)
1322 if isinstance(a, str) and isinstance(b, SeqRef):
1323 a = StringVal(a, b.ctx)
1324 if isinstance(b, str) and isinstance(a, SeqRef):
1325 b = StringVal(b, a.ctx)
1326 if isinstance(a, float) and isinstance(b, ArithRef):
1327 a = RealVal(a, b.ctx)
1328 if isinstance(b, float) and isinstance(a, ArithRef):
1329 b = RealVal(b, a.ctx)
1330 if isinstance(a, complex) and is_expr(b):
1331 a = ComplexVal(a, ctx=b.ctx)
1332 if isinstance(b, complex) and is_expr(a):
1333 b = ComplexVal(b, ctx=a.ctx)
1334
1335 if _check_same_sort(a, b, ctx):
1336 return (a, b)
1337
1338 if z3_debug():
1339 _z3_assert(is_expr(a) or is_expr(b), "At least one of the arguments must be a Z3 expression")
1340 # In x + 1 only x is an expression: its sort is the result sort, so only the
1341 # Python value needs to be cast.
1342 if not is_expr(b):
1343 return (a, a.sort().cast(b))
1344 if not is_expr(a):
1345 return (b.sort().cast(a), b)
1346 s = _coerce_expr_merge(_coerce_expr_merge(None, a), b)
1347 return (s.cast(a), s.cast(b))
1348
1349
1350def _reduce(func, sequence, initial):
1351 result = initial
1352 for element in sequence:
1353 result = func(result, element)
1354 return result
1355
1356
1357def _coerce_expr_list(alist, ctx=None):
1358 has_expr = False
1359 for a in alist:
1360 if is_expr(a):
1361 has_expr = True
1362 break
1363 if not has_expr:
1364 alist = [_py2expr(a, ctx) for a in alist]
1365 else:
1366 ctx = ctx if ctx is not None else _ctx_from_ast_arg_list(alist)
1367 alist = [ComplexVal(a, ctx=ctx) if isinstance(a, complex) else a for a in alist]
1368 s = _reduce(_coerce_expr_merge, alist, None)
1369 return [s.cast(a) for a in alist]
1370
1371
1372def is_expr(a):
1373 """Return `True` if `a` is a Z3 expression.
1374
1375 >>> a = Int('a')
1376 >>> is_expr(a)
1377 True
1378 >>> is_expr(a + 1)
1379 True
1380 >>> is_expr(IntSort())
1381 False
1382 >>> is_expr(1)
1383 False
1384 >>> is_expr(IntVal(1))
1385 True
1386 >>> x = Int('x')
1387 >>> is_expr(ForAll(x, x >= 0))
1388 True
1389 >>> is_expr(FPVal(1.0))
1390 True
1391 """
1392 return isinstance(a, ExprRef)
1393
1394
1395def is_app(a):
1396 """Return `True` if `a` is a Z3 function application.
1397
1398 Note that, constants are function applications with 0 arguments.
1399
1400 >>> a = Int('a')
1401 >>> is_app(a)
1402 True
1403 >>> is_app(a + 1)
1404 True
1405 >>> is_app(IntSort())
1406 False
1407 >>> is_app(1)
1408 False
1409 >>> is_app(IntVal(1))
1410 True
1411 >>> x = Int('x')
1412 >>> is_app(ForAll(x, x >= 0))
1413 False
1414 """
1415 if not isinstance(a, ExprRef):
1416 return False
1417 k = _ast_kind(a.ctx, a)
1418 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1419
1420
1422 """Return `True` if `a` is Z3 constant/variable expression.
1423
1424 >>> a = Int('a')
1425 >>> is_const(a)
1426 True
1427 >>> is_const(a + 1)
1428 False
1429 >>> is_const(1)
1430 False
1431 >>> is_const(IntVal(1))
1432 True
1433 >>> x = Int('x')
1434 >>> is_const(ForAll(x, x >= 0))
1435 False
1436 """
1437 return is_app(a) and a.num_args() == 0
1438
1439
1440def is_var(a):
1441 """Return `True` if `a` is variable.
1442
1443 Z3 uses de-Bruijn indices for representing bound variables in
1444 quantifiers.
1445
1446 >>> x = Int('x')
1447 >>> is_var(x)
1448 False
1449 >>> is_const(x)
1450 True
1451 >>> f = Function('f', IntSort(), IntSort())
1452 >>> # Z3 replaces x with bound variables when ForAll is executed.
1453 >>> q = ForAll(x, f(x) == x)
1454 >>> b = q.body()
1455 >>> b
1456 f(Var(0)) == Var(0)
1457 >>> b.arg(1)
1458 Var(0)
1459 >>> is_var(b.arg(1))
1460 True
1461 """
1462 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1463
1464
1466 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1467
1468 >>> x = Int('x')
1469 >>> y = Int('y')
1470 >>> is_var(x)
1471 False
1472 >>> is_const(x)
1473 True
1474 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1475 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1476 >>> q = ForAll([x, y], f(x, y) == x + y)
1477 >>> q.body()
1478 f(Var(1), Var(0)) == Var(1) + Var(0)
1479 >>> b = q.body()
1480 >>> b.arg(0)
1481 f(Var(1), Var(0))
1482 >>> v1 = b.arg(0).arg(0)
1483 >>> v2 = b.arg(0).arg(1)
1484 >>> v1
1485 Var(1)
1486 >>> v2
1487 Var(0)
1488 >>> get_var_index(v1)
1489 1
1490 >>> get_var_index(v2)
1491 0
1492 """
1493 if z3_debug():
1494 _z3_assert(is_var(a), "Z3 bound variable expected")
1495 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1496
1497
1498def is_app_of(a, k):
1499 """Return `True` if `a` is an application of the given kind `k`.
1500
1501 >>> x = Int('x')
1502 >>> n = x + 1
1503 >>> is_app_of(n, Z3_OP_ADD)
1504 True
1505 >>> is_app_of(n, Z3_OP_MUL)
1506 False
1507 """
1508 return is_app(a) and a.kind() == k
1509
1510
1511def If(a, b, c, ctx=None):
1512 """Create a Z3 if-then-else expression.
1513
1514 >>> x = Int('x')
1515 >>> y = Int('y')
1516 >>> max = If(x > y, x, y)
1517 >>> max
1518 If(x > y, x, y)
1519 >>> simplify(max)
1520 If(x <= y, y, x)
1521 """
1522 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1523 return Cond(a, b, c, ctx)
1524 else:
1525 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1526 s = BoolSort(ctx)
1527 a = s.cast(a)
1528 b, c = _coerce_exprs(b, c, ctx)
1529 if z3_debug():
1530 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1531 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1532
1533
1534def Distinct(*args):
1535 """Create a Z3 distinct expression.
1536
1537 >>> x = Int('x')
1538 >>> y = Int('y')
1539 >>> Distinct(x, y)
1540 x != y
1541 >>> z = Int('z')
1542 >>> Distinct(x, y, z)
1543 Distinct(x, y, z)
1544 >>> simplify(Distinct(x, y, z))
1545 Distinct(x, y, z)
1546 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1547 And(Not(x == y), Not(x == z), Not(y == z))
1548 """
1549 args = _get_args(args)
1550 ctx = _ctx_from_ast_arg_list(args)
1551 if z3_debug():
1552 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1553 args = _coerce_expr_list(args, ctx)
1554 _args, sz = _to_ast_array(args)
1555 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1556
1557
1558def _mk_bin(f, a, b):
1559 args = (Ast * 2)()
1560 if z3_debug():
1561 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1562 args[0] = a.as_ast()
1563 args[1] = b.as_ast()
1564 return f(a.ctx.ref(), 2, args)
1565
1566
1567def Const(name, sort):
1568 """Create a constant of the given sort.
1569
1570 >>> Const('x', IntSort())
1571 x
1572 """
1573 if z3_debug():
1574 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1575 ctx = sort.ctx
1576 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1577
1578
1579def Consts(names, sort):
1580 """Create several constants of the given sort.
1581
1582 `names` is a string containing the names of all constants to be created.
1583 Blank spaces separate the names of different constants.
1584
1585 >>> x, y, z = Consts('x y z', IntSort())
1586 >>> x + y + z
1587 x + y + z
1588 """
1589 if isinstance(names, str):
1590 names = names.split(" ")
1591 return [Const(name, sort) for name in names]
1592
1593
1594def FreshConst(sort, prefix="c"):
1595 """Create a fresh constant of a specified sort"""
1596 if z3_debug():
1597 _z3_assert(is_sort(sort), f"Z3 sort expected, got {type(sort)}")
1598 ctx = _get_ctx(sort.ctx)
1599 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1600
1601
1602def Var(idx : int, s : SortRef) -> ExprRef:
1603 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1604 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1605 declarations.
1606
1607 >>> Var(0, IntSort())
1608 Var(0)
1609 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1610 False
1611 """
1612 if z3_debug():
1613 _z3_assert(is_sort(s), "Z3 sort expected")
1614 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1615
1616
1617def RealVar(idx: int, ctx=None) -> ExprRef:
1618 """
1619 Create a real free variable. Free variables are used to create quantified formulas.
1620 They are also used to create polynomials.
1621
1622 >>> RealVar(0)
1623 Var(0)
1624 """
1625 return Var(idx, RealSort(ctx))
1626
1627def RealVarVector(n: int, ctx= None):
1628 """
1629 Create a list of Real free variables.
1630 The variables have ids: 0, 1, ..., n-1
1631
1632 >>> x0, x1, x2, x3 = RealVarVector(4)
1633 >>> x2
1634 Var(2)
1635 """
1636 return [RealVar(i, ctx) for i in range(n)]
1637
1638
1643
1644
1646 """Boolean sort."""
1647
1648 def cast(self, val):
1649 """Try to cast `val` as a Boolean.
1650
1651 >>> x = BoolSort().cast(True)
1652 >>> x
1653 True
1654 >>> is_expr(x)
1655 True
1656 >>> is_expr(True)
1657 False
1658 >>> x.sort()
1659 Bool
1660 """
1661 if isinstance(val, bool):
1662 return BoolVal(val, self.ctx)
1663 if z3_debug():
1664 if not is_expr(val):
1665 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1666 _z3_assert(is_expr(val), msg % (val, type(val)))
1667 if not self.eq(val.sort()):
1668 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1669 return val
1670
1671 def subsort(self, other):
1672 return isinstance(other, ArithSortRef)
1673
1674 def is_int(self):
1675 return True
1676
1677 def is_bool(self):
1678 return True
1679
1680
1682 """All Boolean expressions are instances of this class."""
1683
1684 def sort(self):
1685 return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
1686
1687 def __add__(self, other):
1688 if isinstance(other, BoolRef):
1689 other = If(other, 1, 0)
1690 return If(self, 1, 0) + other
1691
1692 def __radd__(self, other):
1693 return self + other
1694
1695 def __rmul__(self, other):
1696 return self * other
1697
1698 def __mul__(self, other):
1699 """Create the Z3 expression `self * other`.
1700 """
1701 if isinstance(other, int) and other == 1:
1702 return If(self, 1, 0)
1703 if isinstance(other, int) and other == 0:
1704 return IntVal(0, self.ctx)
1705 if isinstance(other, BoolRef):
1706 other = If(other, 1, 0)
1707 return If(self, other, 0)
1708
1709 def __and__(self, other):
1710 return And(self, other)
1711
1712 def __or__(self, other):
1713 return Or(self, other)
1714
1715 def __xor__(self, other):
1716 return Xor(self, other)
1717
1718 def __invert__(self):
1719 return Not(self)
1720
1721 def py_value(self):
1722 if is_true(self):
1723 return True
1724 if is_false(self):
1725 return False
1726 return None
1727
1728
1729
1730
1731def is_bool(a : Any) -> bool:
1732 """Return `True` if `a` is a Z3 Boolean expression.
1733
1734 >>> p = Bool('p')
1735 >>> is_bool(p)
1736 True
1737 >>> q = Bool('q')
1738 >>> is_bool(And(p, q))
1739 True
1740 >>> x = Real('x')
1741 >>> is_bool(x)
1742 False
1743 >>> is_bool(x == 0)
1744 True
1745 """
1746 return isinstance(a, BoolRef)
1747
1748
1749def is_true(a : Any) -> bool:
1750 """Return `True` if `a` is the Z3 true expression.
1751
1752 >>> p = Bool('p')
1753 >>> is_true(p)
1754 False
1755 >>> is_true(simplify(p == p))
1756 True
1757 >>> x = Real('x')
1758 >>> is_true(x == 0)
1759 False
1760 >>> # True is a Python Boolean expression
1761 >>> is_true(True)
1762 False
1763 """
1764 return is_app_of(a, Z3_OP_TRUE)
1765
1766
1767def is_false(a : Any) -> bool:
1768 """Return `True` if `a` is the Z3 false expression.
1769
1770 >>> p = Bool('p')
1771 >>> is_false(p)
1772 False
1773 >>> is_false(False)
1774 False
1775 >>> is_false(BoolVal(False))
1776 True
1777 """
1778 return is_app_of(a, Z3_OP_FALSE)
1779
1780
1781def is_and(a : Any) -> bool:
1782 """Return `True` if `a` is a Z3 and expression.
1783
1784 >>> p, q = Bools('p q')
1785 >>> is_and(And(p, q))
1786 True
1787 >>> is_and(Or(p, q))
1788 False
1789 """
1790 return is_app_of(a, Z3_OP_AND)
1791
1792
1793def is_or(a : Any) -> bool:
1794 """Return `True` if `a` is a Z3 or expression.
1795
1796 >>> p, q = Bools('p q')
1797 >>> is_or(Or(p, q))
1798 True
1799 >>> is_or(And(p, q))
1800 False
1801 """
1802 return is_app_of(a, Z3_OP_OR)
1803
1804
1805def is_implies(a : Any) -> bool:
1806 """Return `True` if `a` is a Z3 implication expression.
1807
1808 >>> p, q = Bools('p q')
1809 >>> is_implies(Implies(p, q))
1810 True
1811 >>> is_implies(And(p, q))
1812 False
1813 """
1814 return is_app_of(a, Z3_OP_IMPLIES)
1815
1816
1817def is_not(a : Any) -> bool:
1818 """Return `True` if `a` is a Z3 not expression.
1819
1820 >>> p = Bool('p')
1821 >>> is_not(p)
1822 False
1823 >>> is_not(Not(p))
1824 True
1825 """
1826 return is_app_of(a, Z3_OP_NOT)
1827
1828
1829def is_eq(a : Any) -> bool:
1830 """Return `True` if `a` is a Z3 equality expression.
1831
1832 >>> x, y = Ints('x y')
1833 >>> is_eq(x == y)
1834 True
1835 """
1836 return is_app_of(a, Z3_OP_EQ)
1837
1838
1839def is_distinct(a : Any) -> bool:
1840 """Return `True` if `a` is a Z3 distinct expression.
1841
1842 >>> x, y, z = Ints('x y z')
1843 >>> is_distinct(x == y)
1844 False
1845 >>> is_distinct(Distinct(x, y, z))
1846 True
1847 """
1848 return is_app_of(a, Z3_OP_DISTINCT)
1849
1850
1851def BoolSort(ctx=None):
1852 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1853
1854 >>> BoolSort()
1855 Bool
1856 >>> p = Const('p', BoolSort())
1857 >>> is_bool(p)
1858 True
1859 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1860 >>> r(0, 1)
1861 r(0, 1)
1862 >>> is_bool(r(0, 1))
1863 True
1864 """
1865 ctx = _get_ctx(ctx)
1866 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1867
1868
1869def BoolVal(val, ctx=None):
1870 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1871
1872 >>> BoolVal(True)
1873 True
1874 >>> is_true(BoolVal(True))
1875 True
1876 >>> is_true(True)
1877 False
1878 >>> is_false(BoolVal(False))
1879 True
1880 """
1881 ctx = _get_ctx(ctx)
1882 if val:
1883 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1884 else:
1885 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1886
1887
1888def Bool(name, ctx=None):
1889 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1890
1891 >>> p = Bool('p')
1892 >>> q = Bool('q')
1893 >>> And(p, q)
1894 And(p, q)
1895 """
1896 ctx = _get_ctx(ctx)
1897 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1898
1899
1900def Bools(names, ctx=None):
1901 """Return a tuple of Boolean constants.
1902
1903 `names` is a single string containing all names separated by blank spaces.
1904 If `ctx=None`, then the global context is used.
1905
1906 >>> p, q, r = Bools('p q r')
1907 >>> And(p, Or(q, r))
1908 And(p, Or(q, r))
1909 """
1910 ctx = _get_ctx(ctx)
1911 if isinstance(names, str):
1912 names = names.split(" ")
1913 return [Bool(name, ctx) for name in names]
1914
1915
1916def BoolVector(prefix, sz, ctx=None):
1917 """Return a list of Boolean constants of size `sz`.
1918
1919 The constants are named using the given prefix.
1920 If `ctx=None`, then the global context is used.
1921
1922 >>> P = BoolVector('p', 3)
1923 >>> P
1924 [p__0, p__1, p__2]
1925 >>> And(P)
1926 And(p__0, p__1, p__2)
1927 """
1928 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1929
1930
1931def FreshBool(prefix="b", ctx=None):
1932 """Return a fresh Boolean constant in the given context using the given prefix.
1933
1934 If `ctx=None`, then the global context is used.
1935
1936 >>> b1 = FreshBool()
1937 >>> b2 = FreshBool()
1938 >>> eq(b1, b2)
1939 False
1940 """
1941 ctx = _get_ctx(ctx)
1942 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1943
1944
1945def Implies(a, b, ctx=None):
1946 """Create a Z3 implies expression.
1947
1948 >>> p, q = Bools('p q')
1949 >>> Implies(p, q)
1950 Implies(p, q)
1951 """
1952 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1953 s = BoolSort(ctx)
1954 a = s.cast(a)
1955 b = s.cast(b)
1956 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1957
1958
1959def Xor(a, b, ctx=None):
1960 """Create a Z3 Xor expression.
1961
1962 >>> p, q = Bools('p q')
1963 >>> Xor(p, q)
1964 Xor(p, q)
1965 >>> simplify(Xor(p, q))
1966 Not(p == q)
1967 """
1968 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1969 s = BoolSort(ctx)
1970 a = s.cast(a)
1971 b = s.cast(b)
1972 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1973
1974
1975def Not(a, ctx=None):
1976 """Create a Z3 not expression or probe.
1977
1978 >>> p = Bool('p')
1979 >>> Not(Not(p))
1980 Not(Not(p))
1981 >>> simplify(Not(Not(p)))
1982 p
1983 """
1984 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1985 if is_probe(a):
1986 # Not is also used to build probes
1987 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1988 else:
1989 s = BoolSort(ctx)
1990 a = s.cast(a)
1991 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1992
1993
1994def mk_not(a):
1995 if is_not(a):
1996 return a.arg(0)
1997 else:
1998 return Not(a)
1999
2000
2001def _has_probe(args):
2002 """Return `True` if one of the elements of the given collection is a Z3 probe."""
2003 for arg in args:
2004 if is_probe(arg):
2005 return True
2006 return False
2007
2008
2009def And(*args):
2010 """Create a Z3 and-expression or and-probe.
2011
2012 >>> p, q, r = Bools('p q r')
2013 >>> And(p, q, r)
2014 And(p, q, r)
2015 >>> P = BoolVector('p', 5)
2016 >>> And(P)
2017 And(p__0, p__1, p__2, p__3, p__4)
2018 """
2019 last_arg = None
2020 if len(args) > 0:
2021 last_arg = args[len(args) - 1]
2022 if isinstance(last_arg, Context):
2023 ctx = args[len(args) - 1]
2024 args = args[:len(args) - 1]
2025 elif len(args) == 1 and isinstance(args[0], AstVector):
2026 ctx = args[0].ctx
2027 args = [a for a in args[0]]
2028 else:
2029 ctx = None
2030 args = _get_args(args)
2031 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2032 if z3_debug():
2033 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2034 if _has_probe(args):
2035 return _probe_and(args, ctx)
2036 else:
2037 args = _coerce_expr_list(args, ctx)
2038 _args, sz = _to_ast_array(args)
2039 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
2040
2041
2042def Or(*args):
2043 """Create a Z3 or-expression or or-probe.
2044
2045 >>> p, q, r = Bools('p q r')
2046 >>> Or(p, q, r)
2047 Or(p, q, r)
2048 >>> P = BoolVector('p', 5)
2049 >>> Or(P)
2050 Or(p__0, p__1, p__2, p__3, p__4)
2051 """
2052 last_arg = None
2053 if len(args) > 0:
2054 last_arg = args[len(args) - 1]
2055 if isinstance(last_arg, Context):
2056 ctx = args[len(args) - 1]
2057 args = args[:len(args) - 1]
2058 elif len(args) == 1 and isinstance(args[0], AstVector):
2059 ctx = args[0].ctx
2060 args = [a for a in args[0]]
2061 else:
2062 ctx = None
2063 args = _get_args(args)
2064 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2065 if z3_debug():
2066 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2067 if _has_probe(args):
2068 return _probe_or(args, ctx)
2069 else:
2070 args = _coerce_expr_list(args, ctx)
2071 _args, sz = _to_ast_array(args)
2072 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
2073
2074
2079
2080
2082 """Patterns are hints for quantifier instantiation.
2083
2084 """
2085
2086 def as_ast(self):
2087 # Z3_pattern_to_ast is only a pointer cast, so do it here instead of calling into Z3.
2088 return Ast.from_buffer_copy(self.ast)
2089
2090 def get_id(self):
2091 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2092
2093
2095 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
2096
2097 >>> f = Function('f', IntSort(), IntSort())
2098 >>> x = Int('x')
2099 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
2100 >>> q
2101 ForAll(x, f(x) == 0)
2102 >>> q.num_patterns()
2103 1
2104 >>> is_pattern(q.pattern(0))
2105 True
2106 >>> q.pattern(0)
2107 f(Var(0))
2108 """
2109 return isinstance(a, PatternRef)
2110
2111
2112def MultiPattern(*args):
2113 """Create a Z3 multi-pattern using the given expressions `*args`
2114
2115 >>> f = Function('f', IntSort(), IntSort())
2116 >>> g = Function('g', IntSort(), IntSort())
2117 >>> x = Int('x')
2118 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2119 >>> q
2120 ForAll(x, f(x) != g(x))
2121 >>> q.num_patterns()
2122 1
2123 >>> is_pattern(q.pattern(0))
2124 True
2125 >>> q.pattern(0)
2126 MultiPattern(f(Var(0)), g(Var(0)))
2127 """
2128 if z3_debug():
2129 _z3_assert(len(args) > 0, "At least one argument expected")
2130 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2131 ctx = args[0].ctx
2132 args, sz = _to_ast_array(args)
2133 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2134
2135
2137 if is_pattern(arg):
2138 return arg
2139 else:
2140 return MultiPattern(arg)
2141
2142
2147
2148
2150 """Universally and Existentially quantified formulas."""
2151
2152 def as_ast(self):
2153 return self.ast
2154
2155 def get_id(self):
2156 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2157
2158 def sort(self):
2159 """Return the Boolean sort or sort of Lambda."""
2160 if self.is_lambda():
2161 return _sort(self.ctx, self.as_ast())
2162 return BoolSort(self.ctx)
2163
2164 def is_forall(self):
2165 """Return `True` if `self` is a universal quantifier.
2166
2167 >>> f = Function('f', IntSort(), IntSort())
2168 >>> x = Int('x')
2169 >>> q = ForAll(x, f(x) == 0)
2170 >>> q.is_forall()
2171 True
2172 >>> q = Exists(x, f(x) != 0)
2173 >>> q.is_forall()
2174 False
2175 """
2177
2178 def is_exists(self):
2179 """Return `True` if `self` is an existential quantifier.
2180
2181 >>> f = Function('f', IntSort(), IntSort())
2182 >>> x = Int('x')
2183 >>> q = ForAll(x, f(x) == 0)
2184 >>> q.is_exists()
2185 False
2186 >>> q = Exists(x, f(x) != 0)
2187 >>> q.is_exists()
2188 True
2189 """
2190 return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
2191
2192 def is_lambda(self):
2193 """Return `True` if `self` is a lambda expression.
2194
2195 >>> f = Function('f', IntSort(), IntSort())
2196 >>> x = Int('x')
2197 >>> q = Lambda(x, f(x))
2198 >>> q.is_lambda()
2199 True
2200 >>> q = Exists(x, f(x) != 0)
2201 >>> q.is_lambda()
2202 False
2203 """
2204 return Z3_is_lambda(self.ctx_ref(), self.ast)
2205
2206 def __getitem__(self, arg):
2207 """Return the Z3 expression `self[arg]`.
2208 """
2209 if z3_debug():
2210 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2211 return _array_select(self, arg)
2212
2213 def weight(self):
2214 """Return the weight annotation of `self`.
2215
2216 >>> f = Function('f', IntSort(), IntSort())
2217 >>> x = Int('x')
2218 >>> q = ForAll(x, f(x) == 0)
2219 >>> q.weight()
2220 1
2221 >>> q = ForAll(x, f(x) == 0, weight=10)
2222 >>> q.weight()
2223 10
2224 """
2225 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
2226
2227 def skolem_id(self):
2228 """Return the skolem id of `self`.
2229 """
2230 return _symbol2py(self.ctx, Z3_get_quantifier_skolem_id(self.ctx_ref(), self.ast))
2231
2232 def qid(self):
2233 """Return the quantifier id of `self`.
2234 """
2235 return _symbol2py(self.ctx, Z3_get_quantifier_id(self.ctx_ref(), self.ast))
2236
2237 def num_patterns(self):
2238 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2239
2240 >>> f = Function('f', IntSort(), IntSort())
2241 >>> g = Function('g', IntSort(), IntSort())
2242 >>> x = Int('x')
2243 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2244 >>> q.num_patterns()
2245 2
2246 """
2247 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
2248
2249 def pattern(self, idx):
2250 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2251
2252 >>> f = Function('f', IntSort(), IntSort())
2253 >>> g = Function('g', IntSort(), IntSort())
2254 >>> x = Int('x')
2255 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2256 >>> q.num_patterns()
2257 2
2258 >>> q.pattern(0)
2259 f(Var(0))
2260 >>> q.pattern(1)
2261 g(Var(0))
2262 """
2263 if z3_debug():
2264 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2265 return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2266
2268 """Return the number of no-patterns."""
2269 return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
2270
2271 def no_pattern(self, idx):
2272 """Return a no-pattern."""
2273 if z3_debug():
2274 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2275 return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2276
2277 def body(self):
2278 """Return the expression being quantified.
2279
2280 >>> f = Function('f', IntSort(), IntSort())
2281 >>> x = Int('x')
2282 >>> q = ForAll(x, f(x) == 0)
2283 >>> q.body()
2284 f(Var(0)) == 0
2285 """
2286 return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
2287
2288 def num_vars(self):
2289 """Return the number of variables bounded by this quantifier.
2290
2291 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2292 >>> x = Int('x')
2293 >>> y = Int('y')
2294 >>> q = ForAll([x, y], f(x, y) >= x)
2295 >>> q.num_vars()
2296 2
2297 """
2298 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
2299
2300 def var_name(self, idx):
2301 """Return a string representing a name used when displaying the quantifier.
2302
2303 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2304 >>> x = Int('x')
2305 >>> y = Int('y')
2306 >>> q = ForAll([x, y], f(x, y) >= x)
2307 >>> q.var_name(0)
2308 'x'
2309 >>> q.var_name(1)
2310 'y'
2311 """
2312 if z3_debug():
2313 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2314 return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
2315
2316 def var_sort(self, idx):
2317 """Return the sort of a bound variable.
2318
2319 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2320 >>> x = Int('x')
2321 >>> y = Real('y')
2322 >>> q = ForAll([x, y], f(x, y) >= x)
2323 >>> q.var_sort(0)
2324 Int
2325 >>> q.var_sort(1)
2326 Real
2327 """
2328 if z3_debug():
2329 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2330 return _to_sort_ref(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
2331
2332 def children(self):
2333 """Return a list containing a single element self.body()
2334
2335 >>> f = Function('f', IntSort(), IntSort())
2336 >>> x = Int('x')
2337 >>> q = ForAll(x, f(x) == 0)
2338 >>> q.children()
2339 [f(Var(0)) == 0]
2340 """
2341 return [self.body()]
2342
2343
2345 """Return `True` if `a` is a Z3 quantifier.
2346
2347 >>> f = Function('f', IntSort(), IntSort())
2348 >>> x = Int('x')
2349 >>> q = ForAll(x, f(x) == 0)
2350 >>> is_quantifier(q)
2351 True
2352 >>> is_quantifier(f(x))
2353 False
2354 """
2355 return isinstance(a, QuantifierRef)
2356
2357
2358def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2359 if z3_debug():
2360 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2361 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2362 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2363 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2364 if is_app(vs):
2365 ctx = vs.ctx
2366 vs = [vs]
2367 else:
2368 ctx = vs[0].ctx
2369 if not is_expr(body):
2370 body = BoolVal(body, ctx)
2371 num_vars = len(vs)
2372 if num_vars == 0:
2373 return body
2374 _vs = (Ast * num_vars)()
2375 for i in range(num_vars):
2376 # TODO: Check if is constant
2377 _vs[i] = vs[i].as_ast()
2378 patterns = [_to_pattern(p) for p in patterns]
2379 num_pats = len(patterns)
2380 _pats = (Pattern * num_pats)()
2381 for i in range(num_pats):
2382 _pats[i] = patterns[i].ast
2383 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2384 qid = to_symbol(qid, ctx)
2385 skid = to_symbol(skid, ctx)
2386 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2387 num_vars, _vs,
2388 num_pats, _pats,
2389 num_no_pats, _no_pats,
2390 body.as_ast()), ctx)
2391
2392
2393def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2394 """Create a Z3 forall formula.
2395
2396 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2397
2398 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2399 >>> x = Int('x')
2400 >>> y = Int('y')
2401 >>> ForAll([x, y], f(x, y) >= x)
2402 ForAll([x, y], f(x, y) >= x)
2403 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2404 ForAll([x, y], f(x, y) >= x)
2405 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2406 ForAll([x, y], f(x, y) >= x)
2407 """
2408 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2409
2410
2411def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2412 """Create a Z3 exists formula.
2413
2414 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2415
2416
2417 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2418 >>> x = Int('x')
2419 >>> y = Int('y')
2420 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2421 >>> q
2422 Exists([x, y], f(x, y) >= x)
2423 >>> is_quantifier(q)
2424 True
2425 >>> r = Tactic('nnf')(q).as_expr()
2426 >>> is_quantifier(r)
2427 False
2428 """
2429 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2430
2431
2432def Lambda(vs, body):
2433 """Create a Z3 lambda expression.
2434
2435 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2436 >>> mem0 = Array('mem0', IntSort(), IntSort())
2437 >>> lo, hi, e, i = Ints('lo hi e i')
2438 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2439 >>> mem1
2440 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2441 """
2442 ctx = body.ctx
2443 if is_app(vs):
2444 vs = [vs]
2445 num_vars = len(vs)
2446 _vs = (Ast * num_vars)()
2447 for i in range(num_vars):
2448 # TODO: Check if is constant
2449 _vs[i] = vs[i].as_ast()
2450 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2451
2452
2457
2458
2460 """Real and Integer sorts."""
2461
2462 def is_real(self):
2463 """Return `True` if `self` is of the sort Real.
2464
2465 >>> x = Real('x')
2466 >>> x.is_real()
2467 True
2468 >>> (x + 1).is_real()
2469 True
2470 >>> x = Int('x')
2471 >>> x.is_real()
2472 False
2473 """
2474 return self.kind() == Z3_REAL_SORT
2475
2476 def is_int(self):
2477 """Return `True` if `self` is of the sort Integer.
2478
2479 >>> x = Int('x')
2480 >>> x.is_int()
2481 True
2482 >>> (x + 1).is_int()
2483 True
2484 >>> x = Real('x')
2485 >>> x.is_int()
2486 False
2487 """
2488 return self.kind() == Z3_INT_SORT
2489
2490 def is_bool(self):
2491 return False
2492
2493 def subsort(self, other):
2494 """Return `True` if `self` is a subsort of `other`."""
2495 return is_complex_sort(other) or (self.is_int() and is_arith_sort(other) and other.is_real())
2496
2497 def cast(self, val):
2498 """Try to cast `val` as an Integer or Real.
2499
2500 >>> IntSort().cast(10)
2501 10
2502 >>> is_int(IntSort().cast(10))
2503 True
2504 >>> is_int(10)
2505 False
2506 >>> RealSort().cast(10)
2507 10
2508 >>> is_real(RealSort().cast(10))
2509 True
2510 """
2511 if is_expr(val):
2512 if z3_debug():
2513 _z3_assert(self.ctx == val.ctx, "Context mismatch")
2514 val_s = val.sort()
2515 if self.eq(val_s):
2516 return val
2517 if val_s.is_int() and self.is_real():
2518 return ToReal(val)
2519 if val_s.is_bool() and self.is_int():
2520 return If(val, 1, 0)
2521 if val_s.is_bool() and self.is_real():
2522 return ToReal(If(val, 1, 0))
2523 if z3_debug():
2524 _z3_assert(False, "Z3 Integer/Real expression expected")
2525 else:
2526 if self.is_int():
2527 return IntVal(val, self.ctx)
2528 if self.is_real():
2529 return RealVal(val, self.ctx)
2530 if z3_debug():
2531 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2532 _z3_assert(False, msg % self)
2533
2534
2535def is_arith_sort(s : Any) -> bool:
2536 """Return `True` if s is an arithmetical sort (type).
2537
2538 >>> is_arith_sort(IntSort())
2539 True
2540 >>> is_arith_sort(RealSort())
2541 True
2542 >>> is_arith_sort(BoolSort())
2543 False
2544 >>> n = Int('x') + 1
2545 >>> is_arith_sort(n.sort())
2546 True
2547 """
2548 return isinstance(s, ArithSortRef)
2549
2550
2552 """Integer, Real, and Complex expressions."""
2553
2554 def sort(self):
2555 """Return the sort (type) of the arithmetical expression `self`.
2556
2557 >>> Int('x').sort()
2558 Int
2559 >>> (Real('x') + 1).sort()
2560 Real
2561 """
2562 return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
2563
2564 def is_int(self):
2565 """Return `True` if `self` is an integer expression.
2566
2567 >>> x = Int('x')
2568 >>> x.is_int()
2569 True
2570 >>> (x + 1).is_int()
2571 True
2572 >>> y = Real('y')
2573 >>> (x + y).is_int()
2574 False
2575 """
2576 return self.sort().is_int()
2577
2578 def is_real(self):
2579 """Return `True` if `self` is an real expression.
2580
2581 >>> x = Real('x')
2582 >>> x.is_real()
2583 True
2584 >>> (x + 1).is_real()
2585 True
2586 """
2587 return self.sort().is_real()
2588
2589 def __add__(self, other):
2590 """Create the Z3 expression `self + other`.
2591
2592 >>> x = Int('x')
2593 >>> y = Int('y')
2594 >>> x + y
2595 x + y
2596 >>> (x + y).sort()
2597 Int
2598 """
2599 a, b = _coerce_exprs(self, other)
2600 return _to_expr_ref(_mk_bin(Z3_mk_add, a, b), self.ctx)
2601
2602 def __radd__(self, other):
2603 """Create the Z3 expression `other + self`.
2604
2605 >>> x = Int('x')
2606 >>> 10 + x
2607 10 + x
2608 """
2609 a, b = _coerce_exprs(self, other)
2610 return _to_expr_ref(_mk_bin(Z3_mk_add, b, a), self.ctx)
2611
2612 def __mul__(self, other):
2613 """Create the Z3 expression `self * other`.
2614
2615 >>> x = Real('x')
2616 >>> y = Real('y')
2617 >>> x * y
2618 x*y
2619 >>> (x * y).sort()
2620 Real
2621 """
2622 if isinstance(other, BoolRef):
2623 return If(other, self, 0)
2624 a, b = _coerce_exprs(self, other)
2625 return _to_expr_ref(_mk_bin(Z3_mk_mul, a, b), self.ctx)
2626
2627 def __rmul__(self, other):
2628 """Create the Z3 expression `other * self`.
2629
2630 >>> x = Real('x')
2631 >>> 10 * x
2632 10*x
2633 """
2634 a, b = _coerce_exprs(self, other)
2635 return _to_expr_ref(_mk_bin(Z3_mk_mul, b, a), self.ctx)
2636
2637 def __sub__(self, other):
2638 """Create the Z3 expression `self - other`.
2639
2640 >>> x = Int('x')
2641 >>> y = Int('y')
2642 >>> x - y
2643 x - y
2644 >>> (x - y).sort()
2645 Int
2646 """
2647 a, b = _coerce_exprs(self, other)
2648 return _to_expr_ref(_mk_bin(Z3_mk_sub, a, b), self.ctx)
2649
2650 def __rsub__(self, other):
2651 """Create the Z3 expression `other - self`.
2652
2653 >>> x = Int('x')
2654 >>> 10 - x
2655 10 - x
2656 """
2657 a, b = _coerce_exprs(self, other)
2658 return _to_expr_ref(_mk_bin(Z3_mk_sub, b, a), self.ctx)
2659
2660 def __pow__(self, other):
2661 """Create the Z3 expression `self**other` (** is the power operator).
2662
2663 >>> x = Real('x')
2664 >>> x**3
2665 x**3
2666 >>> (x**3).sort()
2667 Real
2668 >>> simplify(IntVal(2)**8)
2669 256
2670 """
2671 a, b = _coerce_exprs(self, other)
2672 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2673
2674 def __rpow__(self, other):
2675 """Create the Z3 expression `other**self` (** is the power operator).
2676
2677 >>> x = Real('x')
2678 >>> 2**x
2679 2**x
2680 >>> (2**x).sort()
2681 Real
2682 >>> simplify(2**IntVal(8))
2683 256
2684 """
2685 a, b = _coerce_exprs(self, other)
2686 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2687
2688 def __div__(self, other):
2689 """Create the Z3 expression `other/self`.
2690
2691 >>> x = Int('x')
2692 >>> y = Int('y')
2693 >>> x/y
2694 x/y
2695 >>> (x/y).sort()
2696 Int
2697 >>> (x/y).sexpr()
2698 '(div x y)'
2699 >>> x = Real('x')
2700 >>> y = Real('y')
2701 >>> x/y
2702 x/y
2703 >>> (x/y).sort()
2704 Real
2705 >>> (x/y).sexpr()
2706 '(/ x y)'
2707 """
2708 a, b = _coerce_exprs(self, other)
2709 return _to_expr_ref(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2710
2711 def __truediv__(self, other):
2712 """Create the Z3 expression `other/self`."""
2713 return self.__div__(other)
2714
2715 def __rdiv__(self, other):
2716 """Create the Z3 expression `other/self`.
2717
2718 >>> x = Int('x')
2719 >>> 10/x
2720 10/x
2721 >>> (10/x).sexpr()
2722 '(div 10 x)'
2723 >>> x = Real('x')
2724 >>> 10/x
2725 10/x
2726 >>> (10/x).sexpr()
2727 '(/ 10.0 x)'
2728 """
2729 a, b = _coerce_exprs(self, other)
2730 return _to_expr_ref(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2731
2732 def __rtruediv__(self, other):
2733 """Create the Z3 expression `other/self`."""
2734 return self.__rdiv__(other)
2735
2736 def __mod__(self, other):
2737 """Create the Z3 expression `other%self`.
2738
2739 >>> x = Int('x')
2740 >>> y = Int('y')
2741 >>> x % y
2742 x%y
2743 >>> simplify(IntVal(10) % IntVal(3))
2744 1
2745 """
2746 a, b = _coerce_exprs(self, other)
2747 if z3_debug():
2748 _z3_assert(a.is_int(), "Z3 integer expression expected")
2749 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2750
2751 def __rmod__(self, other):
2752 """Create the Z3 expression `other%self`.
2753
2754 >>> x = Int('x')
2755 >>> 10 % x
2756 10%x
2757 """
2758 a, b = _coerce_exprs(self, other)
2759 if z3_debug():
2760 _z3_assert(a.is_int(), "Z3 integer expression expected")
2761 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2762
2763 def __neg__(self):
2764 """Return an expression representing `-self`.
2765
2766 >>> x = Int('x')
2767 >>> -x
2768 -x
2769 >>> simplify(-(-x))
2770 x
2771 """
2772 return _to_expr_ref(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
2773
2774 def __pos__(self):
2775 """Return `self`.
2776
2777 >>> x = Int('x')
2778 >>> +x
2779 x
2780 """
2781 return self
2782
2783 def __le__(self, other):
2784 """Create the Z3 expression `other <= self`.
2785
2786 >>> x, y = Ints('x y')
2787 >>> x <= y
2788 x <= y
2789 >>> y = Real('y')
2790 >>> x <= y
2791 ToReal(x) <= y
2792 """
2793 a, b = _coerce_exprs(self, other)
2794 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2795
2796 def __lt__(self, other):
2797 """Create the Z3 expression `other < self`.
2798
2799 >>> x, y = Ints('x y')
2800 >>> x < y
2801 x < y
2802 >>> y = Real('y')
2803 >>> x < y
2804 ToReal(x) < y
2805 """
2806 a, b = _coerce_exprs(self, other)
2807 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2808
2809 def __gt__(self, other):
2810 """Create the Z3 expression `other > self`.
2811
2812 >>> x, y = Ints('x y')
2813 >>> x > y
2814 x > y
2815 >>> y = Real('y')
2816 >>> x > y
2817 ToReal(x) > y
2818 """
2819 a, b = _coerce_exprs(self, other)
2820 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2821
2822 def __ge__(self, other):
2823 """Create the Z3 expression `other >= self`.
2824
2825 >>> x, y = Ints('x y')
2826 >>> x >= y
2827 x >= y
2828 >>> y = Real('y')
2829 >>> x >= y
2830 ToReal(x) >= y
2831 """
2832 a, b = _coerce_exprs(self, other)
2833 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2834
2835 def __abs__(self):
2836 """Return an expression representing `abs(self)`.
2837
2838 >>> x = Int('x')
2839 >>> abs(x)
2840 If(x > 0, x, -x)
2841 >>> eq(abs(x), Abs(x))
2842 True
2843 """
2844 return Abs(self)
2845
2846
2848 """Return `True` if `a` is an arithmetical expression.
2849
2850 >>> x = Int('x')
2851 >>> is_arith(x)
2852 True
2853 >>> is_arith(x + 1)
2854 True
2855 >>> is_arith(1)
2856 False
2857 >>> is_arith(IntVal(1))
2858 True
2859 >>> y = Real('y')
2860 >>> is_arith(y)
2861 True
2862 >>> is_arith(y + 1)
2863 True
2864 """
2865 return isinstance(a, ArithRef)
2866
2867
2868def is_int(a) -> bool:
2869 """Return `True` if `a` is an integer expression.
2870
2871 >>> x = Int('x')
2872 >>> is_int(x + 1)
2873 True
2874 >>> is_int(1)
2875 False
2876 >>> is_int(IntVal(1))
2877 True
2878 >>> y = Real('y')
2879 >>> is_int(y)
2880 False
2881 >>> is_int(y + 1)
2882 False
2883 """
2884 return is_arith(a) and a.is_int()
2885
2886
2887def is_real(a):
2888 """Return `True` if `a` is a real expression.
2889
2890 >>> x = Int('x')
2891 >>> is_real(x + 1)
2892 False
2893 >>> y = Real('y')
2894 >>> is_real(y)
2895 True
2896 >>> is_real(y + 1)
2897 True
2898 >>> is_real(1)
2899 False
2900 >>> is_real(RealVal(1))
2901 True
2902 """
2903 return is_arith(a) and a.is_real()
2904
2905
2906def _is_numeral(ctx, a):
2907 return Z3_is_numeral_ast(ctx.ref(), a)
2908
2909
2910def _is_algebraic(ctx, a):
2911 return Z3_is_algebraic_number(ctx.ref(), a)
2912
2913
2915 """Return `True` if `a` is an integer value of sort Int.
2916
2917 >>> is_int_value(IntVal(1))
2918 True
2919 >>> is_int_value(1)
2920 False
2921 >>> is_int_value(Int('x'))
2922 False
2923 >>> n = Int('x') + 1
2924 >>> n
2925 x + 1
2926 >>> n.arg(1)
2927 1
2928 >>> is_int_value(n.arg(1))
2929 True
2930 >>> is_int_value(RealVal("1/3"))
2931 False
2932 >>> is_int_value(RealVal(1))
2933 False
2934 """
2935 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2936
2937
2939 """Return `True` if `a` is rational value of sort Real.
2940
2941 >>> is_rational_value(RealVal(1))
2942 True
2943 >>> is_rational_value(RealVal("3/5"))
2944 True
2945 >>> is_rational_value(IntVal(1))
2946 False
2947 >>> is_rational_value(1)
2948 False
2949 >>> n = Real('x') + 1
2950 >>> n.arg(1)
2951 1
2952 >>> is_rational_value(n.arg(1))
2953 True
2954 >>> is_rational_value(Real('x'))
2955 False
2956 """
2957 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2958
2959
2961 """Return `True` if `a` is an algebraic value of sort Real.
2962
2963 >>> is_algebraic_value(RealVal("3/5"))
2964 False
2965 >>> n = simplify(Sqrt(2))
2966 >>> n
2967 1.4142135623?
2968 >>> is_algebraic_value(n)
2969 True
2970 """
2971 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2972
2973
2974def is_add(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_add(x + y)
2979 True
2980 >>> is_add(x - y)
2981 False
2982 """
2983 return is_app_of(a, Z3_OP_ADD)
2984
2985
2986def is_mul(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_mul(x * y)
2991 True
2992 >>> is_mul(x - y)
2993 False
2994 """
2995 return is_app_of(a, Z3_OP_MUL)
2996
2997
2998def is_sub(a : Any) -> bool:
2999 """Return `True` if `a` is an expression of the form b - c.
3000
3001 >>> x, y = Ints('x y')
3002 >>> is_sub(x - y)
3003 True
3004 >>> is_sub(x + y)
3005 False
3006 """
3007 return is_app_of(a, Z3_OP_SUB)
3008
3009
3010def is_div(a : Any) -> bool:
3011 """Return `True` if `a` is an expression of the form b / c.
3012
3013 >>> x, y = Reals('x y')
3014 >>> is_div(x / y)
3015 True
3016 >>> is_div(x + y)
3017 False
3018 >>> x, y = Ints('x y')
3019 >>> is_div(x / y)
3020 False
3021 >>> is_idiv(x / y)
3022 True
3023 """
3024 return is_app_of(a, Z3_OP_DIV)
3025
3026
3027def is_idiv(a : Any) -> bool:
3028 """Return `True` if `a` is an expression of the form b div c.
3029
3030 >>> x, y = Ints('x y')
3031 >>> is_idiv(x / y)
3032 True
3033 >>> is_idiv(x + y)
3034 False
3035 """
3036 return is_app_of(a, Z3_OP_IDIV)
3037
3038
3039def is_mod(a : Any) -> bool:
3040 """Return `True` if `a` is an expression of the form b % c.
3041
3042 >>> x, y = Ints('x y')
3043 >>> is_mod(x % y)
3044 True
3045 >>> is_mod(x + y)
3046 False
3047 """
3048 return is_app_of(a, Z3_OP_MOD)
3049
3050
3051def is_le(a : Any) -> bool:
3052 """Return `True` if `a` is an expression of the form b <= c.
3053
3054 >>> x, y = Ints('x y')
3055 >>> is_le(x <= y)
3056 True
3057 >>> is_le(x < y)
3058 False
3059 """
3060 return is_app_of(a, Z3_OP_LE)
3061
3062
3063def is_lt(a : Any) -> bool:
3064 """Return `True` if `a` is an expression of the form b < c.
3065
3066 >>> x, y = Ints('x y')
3067 >>> is_lt(x < y)
3068 True
3069 >>> is_lt(x == y)
3070 False
3071 """
3072 return is_app_of(a, Z3_OP_LT)
3073
3074
3075def is_ge(a : Any) -> bool:
3076 """Return `True` if `a` is an expression of the form b >= c.
3077
3078 >>> x, y = Ints('x y')
3079 >>> is_ge(x >= y)
3080 True
3081 >>> is_ge(x == y)
3082 False
3083 """
3084 return is_app_of(a, Z3_OP_GE)
3085
3086
3087def is_gt(a : Any) -> bool:
3088 """Return `True` if `a` is an expression of the form b > c.
3089
3090 >>> x, y = Ints('x y')
3091 >>> is_gt(x > y)
3092 True
3093 >>> is_gt(x == y)
3094 False
3095 """
3096 return is_app_of(a, Z3_OP_GT)
3097
3098
3099def is_is_int(a : Any) -> bool:
3100 """Return `True` if `a` is an expression of the form IsInt(b).
3101
3102 >>> x = Real('x')
3103 >>> is_is_int(IsInt(x))
3104 True
3105 >>> is_is_int(x)
3106 False
3107 """
3108 return is_app_of(a, Z3_OP_IS_INT)
3109
3110
3111def is_to_real(a : Any) -> bool:
3112 """Return `True` if `a` is an expression of the form ToReal(b).
3113
3114 >>> x = Int('x')
3115 >>> n = ToReal(x)
3116 >>> n
3117 ToReal(x)
3118 >>> is_to_real(n)
3119 True
3120 >>> is_to_real(x)
3121 False
3122 """
3123 return is_app_of(a, Z3_OP_TO_REAL)
3124
3125
3126def is_to_int(a : Any) -> bool:
3127 """Return `True` if `a` is an expression of the form ToInt(b).
3128
3129 >>> x = Real('x')
3130 >>> n = ToInt(x)
3131 >>> n
3132 ToInt(x)
3133 >>> is_to_int(n)
3134 True
3135 >>> is_to_int(x)
3136 False
3137 """
3138 return is_app_of(a, Z3_OP_TO_INT)
3139
3140
3142 """Integer values."""
3143
3144 def as_long(self):
3145 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3146
3147 >>> v = IntVal(1)
3148 >>> v + 1
3149 1 + 1
3150 >>> v.as_long() + 1
3151 2
3152 """
3153 if z3_debug():
3154 _z3_assert(self.is_int(), "Integer value expected")
3155 return int(self.as_string())
3156
3157 def as_string(self):
3158 """Return a Z3 integer numeral as a Python string.
3159 >>> v = IntVal(100)
3160 >>> v.as_string()
3161 '100'
3162 """
3163 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3164
3166 """Return a Z3 integer numeral as a Python binary string.
3167 >>> v = IntVal(10)
3168 >>> v.as_binary_string()
3169 '1010'
3170 """
3171 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3172
3173 def py_value(self):
3174 return self.as_long()
3175
3176
3178 """Rational values."""
3179
3180 def numerator(self):
3181 """ Return the numerator of a Z3 rational numeral.
3182
3183 >>> is_rational_value(RealVal("3/5"))
3184 True
3185 >>> n = RealVal("3/5")
3186 >>> n.numerator()
3187 3
3188 >>> is_rational_value(Q(3,5))
3189 True
3190 >>> Q(3,5).numerator()
3191 3
3192 """
3193 return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
3194
3195 def denominator(self):
3196 """ Return the denominator of a Z3 rational numeral.
3197
3198 >>> is_rational_value(Q(3,5))
3199 True
3200 >>> n = Q(3,5)
3201 >>> n.denominator()
3202 5
3203 """
3204 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
3205
3207 """ Return the numerator as a Python long.
3208
3209 >>> v = RealVal(10000000000)
3210 >>> v
3211 10000000000
3212 >>> v + 1
3213 10000000000 + 1
3214 >>> v.numerator_as_long() + 1 == 10000000001
3215 True
3216 """
3217 return self.numerator().as_long()
3218
3220 """ Return the denominator as a Python long.
3221
3222 >>> v = RealVal("1/3")
3223 >>> v
3224 1/3
3225 >>> v.denominator_as_long()
3226 3
3227 """
3228 return self.denominator().as_long()
3229
3230 def is_int(self):
3231 return False
3232
3233 def is_real(self):
3234 return True
3235
3236 def is_int_value(self):
3237 return self.denominator().is_int() and self.denominator_as_long() == 1
3238
3239 def as_long(self):
3240 _z3_assert(self.is_int_value(), "Expected integer fraction")
3241 return self.numerator_as_long()
3242
3243 def as_decimal(self, prec):
3244 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3245
3246 >>> v = RealVal("1/5")
3247 >>> v.as_decimal(3)
3248 '0.2'
3249 >>> v = RealVal("1/3")
3250 >>> v.as_decimal(3)
3251 '0.333?'
3252 """
3253 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3254
3255 def as_string(self):
3256 """Return a Z3 rational numeral as a Python string.
3257
3258 >>> v = Q(3,6)
3259 >>> v.as_string()
3260 '1/2'
3261 """
3262 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3263
3264 def as_fraction(self):
3265 """Return a Z3 rational as a Python Fraction object.
3266
3267 >>> v = RealVal("1/5")
3268 >>> v.as_fraction()
3269 Fraction(1, 5)
3270 """
3271 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3272
3273 def py_value(self):
3274 return Z3_get_numeral_double(self.ctx_ref(), self.as_ast())
3275
3276
3278 """Algebraic irrational values."""
3279
3280 def approx(self, precision=10):
3281 """Return a Z3 rational number that approximates the algebraic number `self`.
3282 The result `r` is such that |r - self| <= 1/10^precision
3283
3284 >>> x = simplify(Sqrt(2))
3285 >>> x.approx(20)
3286 6838717160008073720548335/4835703278458516698824704
3287 >>> x.approx(5)
3288 2965821/2097152
3289 """
3290 return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
3291
3292 def as_decimal(self, prec):
3293 """Return a string representation of the algebraic number `self` in decimal notation
3294 using `prec` decimal places.
3295
3296 >>> x = simplify(Sqrt(2))
3297 >>> x.as_decimal(10)
3298 '1.4142135623?'
3299 >>> x.as_decimal(20)
3300 '1.41421356237309504880?'
3301 """
3302 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3303
3304 def poly(self):
3305 return AstVector(Z3_algebraic_get_poly(self.ctx_ref(), self.as_ast()), self.ctx)
3306
3307 def index(self):
3308 return Z3_algebraic_get_i(self.ctx_ref(), self.as_ast())
3309
3310
3312 """The Complex sort, represented by pairs of Reals."""
3313
3314 def subsort(self, other):
3315 return False
3316
3317 def cast(self, val):
3318 if is_expr(val):
3319 _z3_assert(self.ctx == val.ctx, "Context mismatch")
3320 if self.eq(val.sort()):
3321 return val
3322 return ComplexVal(val, ctx=self.ctx)
3323
3324
3326 """A Complex expression supporting arithmetic, equality, and projections.
3327
3328 Complex numbers do not support ordering or exponentiation.
3329 """
3330
3331 def sort(self):
3332 return ComplexSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3333
3334 def real_part(self):
3335 return RealPart(self)
3336
3337 def imag_part(self):
3338 return ImagPart(self)
3339
3340
3342 """Return whether `s` is a Complex sort."""
3343 return isinstance(s, ComplexSortRef)
3344
3345
3347 """Return whether `a` is a Complex expression."""
3348 return isinstance(a, ComplexRef)
3349
3350
3351def ComplexSort(ctx=None):
3352 """Return the Complex sort in the given context."""
3353 ctx = _get_ctx(ctx)
3354 return ComplexSortRef(Z3_mk_complex_sort(ctx.ref()), ctx)
3355
3356
3357def Complex(name, ctx=None):
3358 """Create a named Complex constant."""
3359 ctx = _get_ctx(ctx)
3360 return ComplexRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), ComplexSort(ctx).ast), ctx)
3361
3362
3363def Complexes(names, ctx=None):
3364 """Create Complex constants from a space-separated string or list of names."""
3365 if isinstance(names, str):
3366 names = names.split(" ")
3367 return [Complex(name, ctx) for name in names]
3368
3369
3370def ComplexVal(real, imag=0, ctx=None):
3371 """Construct a Complex value or expression from Int or Real components.
3372
3373 A Python complex value may be passed as the sole component argument.
3374
3375 >>> z = ComplexVal("1/2", 2)
3376 >>> simplify(RealPart(z))
3377 1/2
3378 >>> simplify(ImagPart(z))
3379 2
3380 """
3381 if isinstance(real, complex):
3382 _z3_assert(imag == 0, "A Python complex value cannot have an additional imaginary component")
3383 real, imag = real.real, real.imag
3384 ctx = _get_ctx(ctx if ctx is not None else _ctx_from_ast_arg_list([real, imag]))
3385 sort = RealSort(ctx)
3386 real, imag = sort.cast(real), sort.cast(imag)
3387 return ComplexRef(Z3_mk_complex(ctx.ref(), real.as_ast(), imag.as_ast()), ctx)
3388
3389
3390def RealPart(value):
3391 """Return the Real-valued real component of a Complex expression."""
3392 _z3_assert(is_complex(value), "Complex expression expected")
3393 return _to_expr_ref(Z3_mk_real_part(value.ctx_ref(), value.as_ast()), value.ctx)
3394
3395
3396def ImagPart(value):
3397 """Return the Real-valued imaginary component of a Complex expression."""
3398 _z3_assert(is_complex(value), "Complex expression expected")
3399 return _to_expr_ref(Z3_mk_imag_part(value.ctx_ref(), value.as_ast()), value.ctx)
3400
3401
3402def _py2expr(a, ctx=None):
3403 if isinstance(a, bool):
3404 return BoolVal(a, ctx)
3405 if _is_int(a):
3406 return IntVal(a, ctx)
3407 if isinstance(a, float):
3408 return RealVal(a, ctx)
3409 if isinstance(a, complex):
3410 return ComplexVal(a, ctx=ctx)
3411 if isinstance(a, str):
3412 return StringVal(a, ctx)
3413 if is_expr(a):
3414 return a
3415 if z3_debug():
3416 _z3_assert(False, "Python bool, int, long or float expected")
3417
3418
3419def IntSort(ctx=None):
3420 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3421
3422 >>> IntSort()
3423 Int
3424 >>> x = Const('x', IntSort())
3425 >>> is_int(x)
3426 True
3427 >>> x.sort() == IntSort()
3428 True
3429 >>> x.sort() == BoolSort()
3430 False
3431 """
3432 ctx = _get_ctx(ctx)
3433 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3434
3435
3436def RealSort(ctx=None):
3437 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3438
3439 >>> RealSort()
3440 Real
3441 >>> x = Const('x', RealSort())
3442 >>> is_real(x)
3443 True
3444 >>> is_int(x)
3445 False
3446 >>> x.sort() == RealSort()
3447 True
3448 """
3449 ctx = _get_ctx(ctx)
3450 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3451
3452
3454 if isinstance(val, float):
3455 return str(int(val))
3456 elif isinstance(val, bool):
3457 if val:
3458 return "1"
3459 else:
3460 return "0"
3461 else:
3462 return str(val)
3463
3464
3465def IntVal(val, ctx=None):
3466 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3467
3468 >>> IntVal(1)
3469 1
3470 >>> IntVal("100")
3471 100
3472 """
3473 ctx = _get_ctx(ctx)
3474 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), Z3_mk_int_sort(ctx.ref())), ctx)
3475
3476
3477def RealVal(val, ctx=None):
3478 """Return a Z3 real value.
3479
3480 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3481 If `ctx=None`, then the global context is used.
3482
3483 >>> RealVal(1)
3484 1
3485 >>> RealVal(1).sort()
3486 Real
3487 >>> RealVal("3/5")
3488 3/5
3489 >>> RealVal("1.5")
3490 3/2
3491 """
3492 ctx = _get_ctx(ctx)
3493 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), Z3_mk_real_sort(ctx.ref())), ctx)
3494
3495
3496def RatVal(a, b, ctx=None):
3497 """Return a Z3 rational a/b.
3498
3499 If `ctx=None`, then the global context is used.
3500
3501 Note: Division by zero (b == 0) is allowed in Z3 symbolic expressions.
3502 Z3 can reason about such expressions symbolically.
3503
3504 >>> RatVal(3,5)
3505 3/5
3506 >>> RatVal(3,5).sort()
3507 Real
3508 """
3509 if z3_debug():
3510 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3511 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3512 # Division by 0 is intentionally allowed - Z3 handles it symbolically
3513 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3514
3515
3516def Q(a, b, ctx=None):
3517 """Return a Z3 rational a/b.
3518
3519 If `ctx=None`, then the global context is used.
3520
3521 >>> Q(3,5)
3522 3/5
3523 >>> Q(3,5).sort()
3524 Real
3525 """
3526 return simplify(RatVal(a, b, ctx=ctx))
3527
3528
3529def Int(name, ctx=None):
3530 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3531
3532 >>> x = Int('x')
3533 >>> is_int(x)
3534 True
3535 >>> is_int(x + 1)
3536 True
3537 """
3538 ctx = _get_ctx(ctx)
3539 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3540
3541
3542def Ints(names, ctx=None):
3543 """Return a tuple of Integer constants.
3544
3545 >>> x, y, z = Ints('x y z')
3546 >>> Sum(x, y, z)
3547 x + y + z
3548 """
3549 ctx = _get_ctx(ctx)
3550 if isinstance(names, str):
3551 names = names.split(" ")
3552 return [Int(name, ctx) for name in names]
3553
3554
3555def IntVector(prefix, sz, ctx=None):
3556 """Return a list of integer constants of size `sz`.
3557
3558 >>> X = IntVector('x', 3)
3559 >>> X
3560 [x__0, x__1, x__2]
3561 >>> Sum(X)
3562 x__0 + x__1 + x__2
3563 """
3564 ctx = _get_ctx(ctx)
3565 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3566
3567
3568def FreshInt(prefix="x", ctx=None):
3569 """Return a fresh integer constant in the given context using the given prefix.
3570
3571 >>> x = FreshInt()
3572 >>> y = FreshInt()
3573 >>> eq(x, y)
3574 False
3575 >>> x.sort()
3576 Int
3577 """
3578 ctx = _get_ctx(ctx)
3579 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3580
3581
3582def Real(name, ctx=None):
3583 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3584
3585 >>> x = Real('x')
3586 >>> is_real(x)
3587 True
3588 >>> is_real(x + 1)
3589 True
3590 """
3591 ctx = _get_ctx(ctx)
3592 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3593
3594
3595def Reals(names, ctx=None):
3596 """Return a tuple of real constants.
3597
3598 >>> x, y, z = Reals('x y z')
3599 >>> Sum(x, y, z)
3600 x + y + z
3601 >>> Sum(x, y, z).sort()
3602 Real
3603 """
3604 ctx = _get_ctx(ctx)
3605 if isinstance(names, str):
3606 names = names.split(" ")
3607 return [Real(name, ctx) for name in names]
3608
3609
3610def RealVector(prefix, sz, ctx=None):
3611 """Return a list of real constants of size `sz`.
3612
3613 >>> X = RealVector('x', 3)
3614 >>> X
3615 [x__0, x__1, x__2]
3616 >>> Sum(X)
3617 x__0 + x__1 + x__2
3618 >>> Sum(X).sort()
3619 Real
3620 """
3621 ctx = _get_ctx(ctx)
3622 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3623
3624
3625def FreshReal(prefix="b", ctx=None):
3626 """Return a fresh real constant in the given context using the given prefix.
3627
3628 >>> x = FreshReal()
3629 >>> y = FreshReal()
3630 >>> eq(x, y)
3631 False
3632 >>> x.sort()
3633 Real
3634 """
3635 ctx = _get_ctx(ctx)
3636 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3637
3638
3639def ToReal(a):
3640 """ Return the Z3 expression ToReal(a).
3641
3642 >>> x = Int('x')
3643 >>> x.sort()
3644 Int
3645 >>> n = ToReal(x)
3646 >>> n
3647 ToReal(x)
3648 >>> n.sort()
3649 Real
3650 """
3651 ctx = a.ctx
3652 if isinstance(a, BoolRef):
3653 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3654 if z3_debug():
3655 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3656 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3657
3658
3659def ToInt(a):
3660 """ Return the Z3 expression ToInt(a).
3661
3662 >>> x = Real('x')
3663 >>> x.sort()
3664 Real
3665 >>> n = ToInt(x)
3666 >>> n
3667 ToInt(x)
3668 >>> n.sort()
3669 Int
3670 """
3671 if z3_debug():
3672 _z3_assert(a.is_real(), "Z3 real expression expected.")
3673 ctx = a.ctx
3674 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3675
3676
3677def IsInt(a):
3678 """ Return the Z3 predicate IsInt(a).
3679
3680 >>> x = Real('x')
3681 >>> IsInt(x + "1/2")
3682 IsInt(x + 1/2)
3683 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3684 [x = 1/2]
3685 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3686 no solution
3687 """
3688 if z3_debug():
3689 _z3_assert(a.is_real(), "Z3 real expression expected.")
3690 ctx = a.ctx
3691 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3692
3693
3694def Sqrt(a, ctx=None):
3695 """ Return a Z3 expression which represents the square root of a.
3696
3697 >>> x = Real('x')
3698 >>> Sqrt(x)
3699 x**(1/2)
3700 """
3701 if not is_expr(a):
3702 ctx = _get_ctx(ctx)
3703 a = RealVal(a, ctx)
3704 return a ** "1/2"
3705
3706
3707def Cbrt(a, ctx=None):
3708 """ Return a Z3 expression which represents the cubic root of a.
3709
3710 >>> x = Real('x')
3711 >>> Cbrt(x)
3712 x**(1/3)
3713 """
3714 if not is_expr(a):
3715 ctx = _get_ctx(ctx)
3716 a = RealVal(a, ctx)
3717 return a ** "1/3"
3718
3719
3724
3725
3727 """Bit-vector sort."""
3728
3729 def size(self):
3730 """Return the size (number of bits) of the bit-vector sort `self`.
3731
3732 >>> b = BitVecSort(32)
3733 >>> b.size()
3734 32
3735 """
3736 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
3737
3738 def subsort(self, other):
3739 return is_bv_sort(other) and self.size() < other.size()
3740
3741 def cast(self, val):
3742 """Try to cast `val` as a Bit-Vector.
3743
3744 >>> b = BitVecSort(32)
3745 >>> b.cast(10)
3746 10
3747 >>> b.cast(10).sexpr()
3748 '#x0000000a'
3749 """
3750 if is_expr(val):
3751 if z3_debug():
3752 _z3_assert(self.ctx == val.ctx, "Context mismatch")
3753 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3754 return val
3755 else:
3756 return BitVecVal(val, self)
3757
3758
3760 """Return True if `s` is a Z3 bit-vector sort.
3761
3762 >>> is_bv_sort(BitVecSort(32))
3763 True
3764 >>> is_bv_sort(IntSort())
3765 False
3766 """
3767 return isinstance(s, BitVecSortRef)
3768
3769
3771 """Bit-vector expressions."""
3772
3773 def sort(self):
3774 """Return the sort of the bit-vector expression `self`.
3775
3776 >>> x = BitVec('x', 32)
3777 >>> x.sort()
3778 BitVec(32)
3779 >>> x.sort() == BitVecSort(32)
3780 True
3781 """
3782 return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3783
3784 def size(self):
3785 """Return the number of bits of the bit-vector expression `self`.
3786
3787 >>> x = BitVec('x', 32)
3788 >>> (x + 1).size()
3789 32
3790 >>> Concat(x, x).size()
3791 64
3792 """
3793 return self.sort().size()
3794
3795 def __add__(self, other):
3796 """Create the Z3 expression `self + other`.
3797
3798 >>> x = BitVec('x', 32)
3799 >>> y = BitVec('y', 32)
3800 >>> x + y
3801 x + y
3802 >>> (x + y).sort()
3803 BitVec(32)
3804 """
3805 a, b = _coerce_exprs(self, other)
3806 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3807
3808 def __radd__(self, other):
3809 """Create the Z3 expression `other + self`.
3810
3811 >>> x = BitVec('x', 32)
3812 >>> 10 + x
3813 10 + x
3814 """
3815 a, b = _coerce_exprs(self, other)
3816 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3817
3818 def __mul__(self, other):
3819 """Create the Z3 expression `self * other`.
3820
3821 >>> x = BitVec('x', 32)
3822 >>> y = BitVec('y', 32)
3823 >>> x * y
3824 x*y
3825 >>> (x * y).sort()
3826 BitVec(32)
3827 """
3828 a, b = _coerce_exprs(self, other)
3829 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3830
3831 def __rmul__(self, other):
3832 """Create the Z3 expression `other * self`.
3833
3834 >>> x = BitVec('x', 32)
3835 >>> 10 * x
3836 10*x
3837 """
3838 a, b = _coerce_exprs(self, other)
3839 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3840
3841 def __sub__(self, other):
3842 """Create the Z3 expression `self - other`.
3843
3844 >>> x = BitVec('x', 32)
3845 >>> y = BitVec('y', 32)
3846 >>> x - y
3847 x - y
3848 >>> (x - y).sort()
3849 BitVec(32)
3850 """
3851 a, b = _coerce_exprs(self, other)
3852 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3853
3854 def __rsub__(self, other):
3855 """Create the Z3 expression `other - self`.
3856
3857 >>> x = BitVec('x', 32)
3858 >>> 10 - x
3859 10 - x
3860 """
3861 a, b = _coerce_exprs(self, other)
3862 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3863
3864 def __or__(self, other):
3865 """Create the Z3 expression bitwise-or `self | other`.
3866
3867 >>> x = BitVec('x', 32)
3868 >>> y = BitVec('y', 32)
3869 >>> x | y
3870 x | y
3871 >>> (x | y).sort()
3872 BitVec(32)
3873 """
3874 a, b = _coerce_exprs(self, other)
3875 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3876
3877 def __ror__(self, other):
3878 """Create the Z3 expression bitwise-or `other | self`.
3879
3880 >>> x = BitVec('x', 32)
3881 >>> 10 | x
3882 10 | x
3883 """
3884 a, b = _coerce_exprs(self, other)
3885 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3886
3887 def __and__(self, other):
3888 """Create the Z3 expression bitwise-and `self & other`.
3889
3890 >>> x = BitVec('x', 32)
3891 >>> y = BitVec('y', 32)
3892 >>> x & y
3893 x & y
3894 >>> (x & y).sort()
3895 BitVec(32)
3896 """
3897 a, b = _coerce_exprs(self, other)
3898 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3899
3900 def __rand__(self, other):
3901 """Create the Z3 expression bitwise-or `other & self`.
3902
3903 >>> x = BitVec('x', 32)
3904 >>> 10 & x
3905 10 & x
3906 """
3907 a, b = _coerce_exprs(self, other)
3908 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3909
3910 def __xor__(self, other):
3911 """Create the Z3 expression bitwise-xor `self ^ other`.
3912
3913 >>> x = BitVec('x', 32)
3914 >>> y = BitVec('y', 32)
3915 >>> x ^ y
3916 x ^ y
3917 >>> (x ^ y).sort()
3918 BitVec(32)
3919 """
3920 a, b = _coerce_exprs(self, other)
3921 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3922
3923 def __rxor__(self, other):
3924 """Create the Z3 expression bitwise-xor `other ^ self`.
3925
3926 >>> x = BitVec('x', 32)
3927 >>> 10 ^ x
3928 10 ^ x
3929 """
3930 a, b = _coerce_exprs(self, other)
3931 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3932
3933 def __pos__(self):
3934 """Return `self`.
3935
3936 >>> x = BitVec('x', 32)
3937 >>> +x
3938 x
3939 """
3940 return self
3941
3942 def __neg__(self):
3943 """Return an expression representing `-self`.
3944
3945 >>> x = BitVec('x', 32)
3946 >>> -x
3947 -x
3948 >>> simplify(-(-x))
3949 x
3950 """
3951 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3952
3953 def __invert__(self):
3954 """Create the Z3 expression bitwise-not `~self`.
3955
3956 >>> x = BitVec('x', 32)
3957 >>> ~x
3958 ~x
3959 >>> simplify(~(~x))
3960 x
3961 """
3962 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3963
3964 def __div__(self, other):
3965 """Create the Z3 expression (signed) division `self / other`.
3966
3967 Use the function UDiv() for unsigned division.
3968
3969 >>> x = BitVec('x', 32)
3970 >>> y = BitVec('y', 32)
3971 >>> x / y
3972 x/y
3973 >>> (x / y).sort()
3974 BitVec(32)
3975 >>> (x / y).sexpr()
3976 '(bvsdiv x y)'
3977 >>> UDiv(x, y).sexpr()
3978 '(bvudiv x y)'
3979 """
3980 a, b = _coerce_exprs(self, other)
3981 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3982
3983 def __truediv__(self, other):
3984 """Create the Z3 expression (signed) division `self / other`."""
3985 return self.__div__(other)
3986
3987 def __rdiv__(self, other):
3988 """Create the Z3 expression (signed) division `other / self`.
3989
3990 Use the function UDiv() for unsigned division.
3991
3992 >>> x = BitVec('x', 32)
3993 >>> 10 / x
3994 10/x
3995 >>> (10 / x).sexpr()
3996 '(bvsdiv #x0000000a x)'
3997 >>> UDiv(10, x).sexpr()
3998 '(bvudiv #x0000000a x)'
3999 """
4000 a, b = _coerce_exprs(self, other)
4001 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
4002
4003 def __rtruediv__(self, other):
4004 """Create the Z3 expression (signed) division `other / self`."""
4005 return self.__rdiv__(other)
4006
4007 def __mod__(self, other):
4008 """Create the Z3 expression (signed) mod `self % other`.
4009
4010 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
4011
4012 >>> x = BitVec('x', 32)
4013 >>> y = BitVec('y', 32)
4014 >>> x % y
4015 x%y
4016 >>> (x % y).sort()
4017 BitVec(32)
4018 >>> (x % y).sexpr()
4019 '(bvsmod x y)'
4020 >>> URem(x, y).sexpr()
4021 '(bvurem x y)'
4022 >>> SRem(x, y).sexpr()
4023 '(bvsrem x y)'
4024 """
4025 a, b = _coerce_exprs(self, other)
4026 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4027
4028 def __rmod__(self, other):
4029 """Create the Z3 expression (signed) mod `other % self`.
4030
4031 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
4032
4033 >>> x = BitVec('x', 32)
4034 >>> 10 % x
4035 10%x
4036 >>> (10 % x).sexpr()
4037 '(bvsmod #x0000000a x)'
4038 >>> URem(10, x).sexpr()
4039 '(bvurem #x0000000a x)'
4040 >>> SRem(10, x).sexpr()
4041 '(bvsrem #x0000000a x)'
4042 """
4043 a, b = _coerce_exprs(self, other)
4044 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
4045
4046 def __le__(self, other):
4047 """Create the Z3 expression (signed) `other <= self`.
4048
4049 Use the function ULE() for unsigned less than or equal to.
4050
4051 >>> x, y = BitVecs('x y', 32)
4052 >>> x <= y
4053 x <= y
4054 >>> (x <= y).sexpr()
4055 '(bvsle x y)'
4056 >>> ULE(x, y).sexpr()
4057 '(bvule x y)'
4058 """
4059 a, b = _coerce_exprs(self, other)
4060 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4061
4062 def __lt__(self, other):
4063 """Create the Z3 expression (signed) `other < self`.
4064
4065 Use the function ULT() for unsigned less than.
4066
4067 >>> x, y = BitVecs('x y', 32)
4068 >>> x < y
4069 x < y
4070 >>> (x < y).sexpr()
4071 '(bvslt x y)'
4072 >>> ULT(x, y).sexpr()
4073 '(bvult x y)'
4074 """
4075 a, b = _coerce_exprs(self, other)
4076 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4077
4078 def __gt__(self, other):
4079 """Create the Z3 expression (signed) `other > self`.
4080
4081 Use the function UGT() for unsigned greater than.
4082
4083 >>> x, y = BitVecs('x y', 32)
4084 >>> x > y
4085 x > y
4086 >>> (x > y).sexpr()
4087 '(bvsgt x y)'
4088 >>> UGT(x, y).sexpr()
4089 '(bvugt x y)'
4090 """
4091 a, b = _coerce_exprs(self, other)
4092 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4093
4094 def __ge__(self, other):
4095 """Create the Z3 expression (signed) `other >= self`.
4096
4097 Use the function UGE() for unsigned greater than or equal to.
4098
4099 >>> x, y = BitVecs('x y', 32)
4100 >>> x >= y
4101 x >= y
4102 >>> (x >= y).sexpr()
4103 '(bvsge x y)'
4104 >>> UGE(x, y).sexpr()
4105 '(bvuge x y)'
4106 """
4107 a, b = _coerce_exprs(self, other)
4108 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4109
4110 def __rshift__(self, other):
4111 """Create the Z3 expression (arithmetical) right shift `self >> other`
4112
4113 Use the function LShR() for the right logical shift
4114
4115 >>> x, y = BitVecs('x y', 32)
4116 >>> x >> y
4117 x >> y
4118 >>> (x >> y).sexpr()
4119 '(bvashr x y)'
4120 >>> LShR(x, y).sexpr()
4121 '(bvlshr x y)'
4122 >>> BitVecVal(4, 3)
4123 4
4124 >>> BitVecVal(4, 3).as_signed_long()
4125 -4
4126 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4127 -2
4128 >>> simplify(BitVecVal(4, 3) >> 1)
4129 6
4130 >>> simplify(LShR(BitVecVal(4, 3), 1))
4131 2
4132 >>> simplify(BitVecVal(2, 3) >> 1)
4133 1
4134 >>> simplify(LShR(BitVecVal(2, 3), 1))
4135 1
4136 """
4137 a, b = _coerce_exprs(self, other)
4138 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4139
4140 def __lshift__(self, other):
4141 """Create the Z3 expression left shift `self << other`
4142
4143 >>> x, y = BitVecs('x y', 32)
4144 >>> x << y
4145 x << y
4146 >>> (x << y).sexpr()
4147 '(bvshl x y)'
4148 >>> simplify(BitVecVal(2, 3) << 1)
4149 4
4150 """
4151 a, b = _coerce_exprs(self, other)
4152 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4153
4154 def __rrshift__(self, other):
4155 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
4156
4157 Use the function LShR() for the right logical shift
4158
4159 >>> x = BitVec('x', 32)
4160 >>> 10 >> x
4161 10 >> x
4162 >>> (10 >> x).sexpr()
4163 '(bvashr #x0000000a x)'
4164 """
4165 a, b = _coerce_exprs(self, other)
4166 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
4167
4168 def __rlshift__(self, other):
4169 """Create the Z3 expression left shift `other << self`.
4170
4171 Use the function LShR() for the right logical shift
4172
4173 >>> x = BitVec('x', 32)
4174 >>> 10 << x
4175 10 << x
4176 >>> (10 << x).sexpr()
4177 '(bvshl #x0000000a x)'
4178 """
4179 a, b = _coerce_exprs(self, other)
4180 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
4181
4182
4184 """Bit-vector values."""
4185
4186 def as_long(self):
4187 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4188
4189 >>> v = BitVecVal(0xbadc0de, 32)
4190 >>> v
4191 195936478
4192 >>> print("0x%.8x" % v.as_long())
4193 0x0badc0de
4194 """
4195 return int(self.as_string())
4196
4198 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4199 The most significant bit is assumed to be the sign.
4200
4201 >>> BitVecVal(4, 3).as_signed_long()
4202 -4
4203 >>> BitVecVal(7, 3).as_signed_long()
4204 -1
4205 >>> BitVecVal(3, 3).as_signed_long()
4206 3
4207 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4208 -1
4209 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4210 -1
4211 """
4212 sz = self.size()
4213 val = self.as_long()
4214 if val >= 2**(sz - 1):
4215 val = val - 2**sz
4216 if val < -2**(sz - 1):
4217 val = val + 2**sz
4218 return int(val)
4219
4220 def as_string(self):
4221 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
4222
4224 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
4225
4226 def py_value(self):
4227 """Return the Python value of a Z3 bit-vector numeral."""
4228 return self.as_long()
4229
4230
4231
4232def is_bv(a):
4233 """Return `True` if `a` is a Z3 bit-vector expression.
4234
4235 >>> b = BitVec('b', 32)
4236 >>> is_bv(b)
4237 True
4238 >>> is_bv(b + 10)
4239 True
4240 >>> is_bv(Int('x'))
4241 False
4242 """
4243 return isinstance(a, BitVecRef)
4244
4245
4247 """Return `True` if `a` is a Z3 bit-vector numeral value.
4248
4249 >>> b = BitVec('b', 32)
4250 >>> is_bv_value(b)
4251 False
4252 >>> b = BitVecVal(10, 32)
4253 >>> b
4254 10
4255 >>> is_bv_value(b)
4256 True
4257 """
4258 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4259
4260
4261def BV2Int(a, is_signed=False):
4262 """Return the Z3 expression BV2Int(a).
4263
4264 >>> b = BitVec('b', 3)
4265 >>> BV2Int(b).sort()
4266 Int
4267 >>> x = Int('x')
4268 >>> x > BV2Int(b)
4269 x > BV2Int(b)
4270 >>> x > BV2Int(b, is_signed=False)
4271 x > BV2Int(b)
4272 >>> x > BV2Int(b, is_signed=True)
4273 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4274 >>> solve(x > BV2Int(b), b == 1, x < 3)
4275 [x = 2, b = 1]
4276 """
4277 if z3_debug():
4278 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4279 ctx = a.ctx
4280 # investigate problem with bv2int
4281 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4282
4283
4284def Int2BV(a, num_bits):
4285 """Return the z3 expression Int2BV(a, num_bits).
4286 It is a bit-vector of width num_bits and represents the
4287 modulo of a by 2^num_bits
4288 """
4289 ctx = a.ctx
4290 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4291
4292
4293def BitVecSort(sz, ctx=None):
4294 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4295
4296 >>> Byte = BitVecSort(8)
4297 >>> Word = BitVecSort(16)
4298 >>> Byte
4299 BitVec(8)
4300 >>> x = Const('x', Byte)
4301 >>> eq(x, BitVec('x', 8))
4302 True
4303 """
4304 ctx = _get_ctx(ctx)
4305 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4306
4307
4308def BitVecVal(val, bv, ctx=None):
4309 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4310
4311 >>> v = BitVecVal(10, 32)
4312 >>> v
4313 10
4314 >>> print("0x%.8x" % v.as_long())
4315 0x0000000a
4316 """
4317 if is_bv_sort(bv):
4318 ctx = bv.ctx
4319 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4320 else:
4321 ctx = _get_ctx(ctx)
4322 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4323
4324
4325def BitVec(name, bv, ctx=None):
4326 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4327 If `ctx=None`, then the global context is used.
4328
4329 >>> x = BitVec('x', 16)
4330 >>> is_bv(x)
4331 True
4332 >>> x.size()
4333 16
4334 >>> x.sort()
4335 BitVec(16)
4336 >>> word = BitVecSort(16)
4337 >>> x2 = BitVec('x', word)
4338 >>> eq(x, x2)
4339 True
4340 """
4341 if isinstance(bv, BitVecSortRef):
4342 ctx = bv.ctx
4343 else:
4344 ctx = _get_ctx(ctx)
4345 bv = BitVecSort(bv, ctx)
4346 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4347
4348
4349def BitVecs(names, bv, ctx=None):
4350 """Return a tuple of bit-vector constants of size bv.
4351
4352 >>> x, y, z = BitVecs('x y z', 16)
4353 >>> x.size()
4354 16
4355 >>> x.sort()
4356 BitVec(16)
4357 >>> Sum(x, y, z)
4358 0 + x + y + z
4359 >>> Product(x, y, z)
4360 1*x*y*z
4361 >>> simplify(Product(x, y, z))
4362 x*y*z
4363 """
4364 ctx = _get_ctx(ctx)
4365 if isinstance(names, str):
4366 names = names.split(" ")
4367 return [BitVec(name, bv, ctx) for name in names]
4368
4369
4370def Concat(*args):
4371 """Create a Z3 bit-vector concatenation expression.
4372
4373 >>> v = BitVecVal(1, 4)
4374 >>> Concat(v, v+1, v)
4375 Concat(Concat(1, 1 + 1), 1)
4376 >>> simplify(Concat(v, v+1, v))
4377 289
4378 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4379 121
4380 """
4381 args = _get_args(args)
4382 sz = len(args)
4383 if z3_debug():
4384 _z3_assert(sz >= 2, "At least two arguments expected.")
4385
4386 ctx = None
4387 for a in args:
4388 if is_expr(a):
4389 ctx = a.ctx
4390 break
4391 if is_seq(args[0]) or isinstance(args[0], str):
4392 args = [_coerce_seq(s, ctx) for s in args]
4393 if z3_debug():
4394 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4395 v = (Ast * sz)()
4396 for i in range(sz):
4397 v[i] = args[i].as_ast()
4398 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4399
4400 if is_re(args[0]):
4401 if z3_debug():
4402 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4403 v = (Ast * sz)()
4404 for i in range(sz):
4405 v[i] = args[i].as_ast()
4406 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4407
4408 if z3_debug():
4409 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4410 r = args[0]
4411 for i in range(sz - 1):
4412 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4413 return r
4414
4415
4416def Extract(high, low, a):
4417 """Create a Z3 bit-vector extraction expression or sequence extraction expression.
4418
4419 Extract is overloaded to work with both bit-vectors and sequences:
4420
4421 **Bit-vector extraction**: Extract(high, low, bitvector)
4422 Extracts bits from position `high` down to position `low` (both inclusive).
4423 - high: int - the highest bit position to extract (0-indexed from right)
4424 - low: int - the lowest bit position to extract (0-indexed from right)
4425 - bitvector: BitVecRef - the bit-vector to extract from
4426 Returns a new bit-vector containing bits [high:low]
4427
4428 **Sequence extraction**: Extract(sequence, offset, length)
4429 Extracts a subsequence starting at the given offset with the specified length.
4430 The functions SubString and SubSeq are redirected to this form of Extract.
4431 - sequence: SeqRef or str - the sequence to extract from
4432 - offset: int - the starting position (0-indexed)
4433 - length: int - the number of elements to extract
4434 Returns a new sequence containing the extracted subsequence
4435
4436 >>> # Bit-vector extraction examples
4437 >>> x = BitVec('x', 8)
4438 >>> Extract(6, 2, x) # Extract bits 6 down to 2 (5 bits total)
4439 Extract(6, 2, x)
4440 >>> Extract(6, 2, x).sort() # Result is a 5-bit vector
4441 BitVec(5)
4442 >>> Extract(7, 0, x) # Extract all 8 bits
4443 Extract(7, 0, x)
4444 >>> Extract(3, 3, x) # Extract single bit at position 3
4445 Extract(3, 3, x)
4446
4447 >>> # Sequence extraction examples
4448 >>> s = StringVal("hello")
4449 >>> Extract(s, 1, 3) # Extract 3 characters starting at position 1
4450 str.substr("hello", 1, 3)
4451 >>> simplify(Extract(StringVal("abcd"), 2, 1)) # Extract 1 character at position 2
4452 "c"
4453 >>> simplify(Extract(StringVal("abcd"), 0, 2)) # Extract first 2 characters
4454 "ab"
4455 """
4456 if isinstance(high, str):
4457 high = StringVal(high)
4458 if is_seq(high):
4459 s = high
4460 offset, length = _coerce_exprs(low, a, s.ctx)
4461 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4462 if z3_debug():
4463 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4464 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4465 "First and second arguments must be non negative integers")
4466 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4467 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4468
4469
4471 if z3_debug():
4472 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4473
4474
4475def ULE(a, b):
4476 """Create the Z3 expression (unsigned) `other <= self`.
4477
4478 Use the operator <= for signed less than or equal to.
4479
4480 >>> x, y = BitVecs('x y', 32)
4481 >>> ULE(x, y)
4482 ULE(x, y)
4483 >>> (x <= y).sexpr()
4484 '(bvsle x y)'
4485 >>> ULE(x, y).sexpr()
4486 '(bvule x y)'
4487 """
4488 _check_bv_args(a, b)
4489 a, b = _coerce_exprs(a, b)
4490 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4491
4492
4493def ULT(a, b):
4494 """Create the Z3 expression (unsigned) `other < self`.
4495
4496 Use the operator < for signed less than.
4497
4498 >>> x, y = BitVecs('x y', 32)
4499 >>> ULT(x, y)
4500 ULT(x, y)
4501 >>> (x < y).sexpr()
4502 '(bvslt x y)'
4503 >>> ULT(x, y).sexpr()
4504 '(bvult x y)'
4505 """
4506 _check_bv_args(a, b)
4507 a, b = _coerce_exprs(a, b)
4508 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4509
4510
4511def UGE(a, b):
4512 """Create the Z3 expression (unsigned) `other >= self`.
4513
4514 Use the operator >= for signed greater than or equal to.
4515
4516 >>> x, y = BitVecs('x y', 32)
4517 >>> UGE(x, y)
4518 UGE(x, y)
4519 >>> (x >= y).sexpr()
4520 '(bvsge x y)'
4521 >>> UGE(x, y).sexpr()
4522 '(bvuge x y)'
4523 """
4524 _check_bv_args(a, b)
4525 a, b = _coerce_exprs(a, b)
4526 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4527
4528
4529def UGT(a, b):
4530 """Create the Z3 expression (unsigned) `other > self`.
4531
4532 Use the operator > for signed greater than.
4533
4534 >>> x, y = BitVecs('x y', 32)
4535 >>> UGT(x, y)
4536 UGT(x, y)
4537 >>> (x > y).sexpr()
4538 '(bvsgt x y)'
4539 >>> UGT(x, y).sexpr()
4540 '(bvugt x y)'
4541 """
4542 _check_bv_args(a, b)
4543 a, b = _coerce_exprs(a, b)
4544 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4545
4546
4547def UDiv(a, b):
4548 """Create the Z3 expression (unsigned) division `self / other`.
4549
4550 Use the operator / for signed division.
4551
4552 >>> x = BitVec('x', 32)
4553 >>> y = BitVec('y', 32)
4554 >>> UDiv(x, y)
4555 UDiv(x, y)
4556 >>> UDiv(x, y).sort()
4557 BitVec(32)
4558 >>> (x / y).sexpr()
4559 '(bvsdiv x y)'
4560 >>> UDiv(x, y).sexpr()
4561 '(bvudiv x y)'
4562 """
4563 _check_bv_args(a, b)
4564 a, b = _coerce_exprs(a, b)
4565 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4566
4567
4568def URem(a, b):
4569 """Create the Z3 expression (unsigned) remainder `self % other`.
4570
4571 Use the operator % for signed modulus, and SRem() for signed remainder.
4572
4573 >>> x = BitVec('x', 32)
4574 >>> y = BitVec('y', 32)
4575 >>> URem(x, y)
4576 URem(x, y)
4577 >>> URem(x, y).sort()
4578 BitVec(32)
4579 >>> (x % y).sexpr()
4580 '(bvsmod x y)'
4581 >>> URem(x, y).sexpr()
4582 '(bvurem x y)'
4583 """
4584 _check_bv_args(a, b)
4585 a, b = _coerce_exprs(a, b)
4586 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4587
4588
4589def SRem(a, b):
4590 """Create the Z3 expression signed remainder.
4591
4592 Use the operator % for signed modulus, and URem() for unsigned remainder.
4593
4594 >>> x = BitVec('x', 32)
4595 >>> y = BitVec('y', 32)
4596 >>> SRem(x, y)
4597 SRem(x, y)
4598 >>> SRem(x, y).sort()
4599 BitVec(32)
4600 >>> (x % y).sexpr()
4601 '(bvsmod x y)'
4602 >>> SRem(x, y).sexpr()
4603 '(bvsrem x y)'
4604 """
4605 _check_bv_args(a, b)
4606 a, b = _coerce_exprs(a, b)
4607 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4608
4609
4610def LShR(a, b):
4611 """Create the Z3 expression logical right shift.
4612
4613 Use the operator >> for the arithmetical right shift.
4614
4615 >>> x, y = BitVecs('x y', 32)
4616 >>> LShR(x, y)
4617 LShR(x, y)
4618 >>> (x >> y).sexpr()
4619 '(bvashr x y)'
4620 >>> LShR(x, y).sexpr()
4621 '(bvlshr x y)'
4622 >>> BitVecVal(4, 3)
4623 4
4624 >>> BitVecVal(4, 3).as_signed_long()
4625 -4
4626 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4627 -2
4628 >>> simplify(BitVecVal(4, 3) >> 1)
4629 6
4630 >>> simplify(LShR(BitVecVal(4, 3), 1))
4631 2
4632 >>> simplify(BitVecVal(2, 3) >> 1)
4633 1
4634 >>> simplify(LShR(BitVecVal(2, 3), 1))
4635 1
4636 """
4637 _check_bv_args(a, b)
4638 a, b = _coerce_exprs(a, b)
4639 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4640
4641
4642def RotateLeft(a, b):
4643 """Return an expression representing `a` rotated to the left `b` times.
4644
4645 >>> a, b = BitVecs('a b', 16)
4646 >>> RotateLeft(a, b)
4647 RotateLeft(a, b)
4648 >>> simplify(RotateLeft(a, 0))
4649 a
4650 >>> simplify(RotateLeft(a, 16))
4651 a
4652 """
4653 _check_bv_args(a, b)
4654 a, b = _coerce_exprs(a, b)
4655 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4656
4657
4658def RotateRight(a, b):
4659 """Return an expression representing `a` rotated to the right `b` times.
4660
4661 >>> a, b = BitVecs('a b', 16)
4662 >>> RotateRight(a, b)
4663 RotateRight(a, b)
4664 >>> simplify(RotateRight(a, 0))
4665 a
4666 >>> simplify(RotateRight(a, 16))
4667 a
4668 """
4669 _check_bv_args(a, b)
4670 a, b = _coerce_exprs(a, b)
4671 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4672
4673
4674def SignExt(n, a):
4675 """Return a bit-vector expression with `n` extra sign-bits.
4676
4677 >>> x = BitVec('x', 16)
4678 >>> n = SignExt(8, x)
4679 >>> n.size()
4680 24
4681 >>> n
4682 SignExt(8, x)
4683 >>> n.sort()
4684 BitVec(24)
4685 >>> v0 = BitVecVal(2, 2)
4686 >>> v0
4687 2
4688 >>> v0.size()
4689 2
4690 >>> v = simplify(SignExt(6, v0))
4691 >>> v
4692 254
4693 >>> v.size()
4694 8
4695 >>> print("%.x" % v.as_long())
4696 fe
4697 """
4698 if z3_debug():
4699 _z3_assert(_is_int(n), "First argument must be an integer")
4700 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4701 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4702
4703
4704def ZeroExt(n, a):
4705 """Return a bit-vector expression with `n` extra zero-bits.
4706
4707 >>> x = BitVec('x', 16)
4708 >>> n = ZeroExt(8, x)
4709 >>> n.size()
4710 24
4711 >>> n
4712 ZeroExt(8, x)
4713 >>> n.sort()
4714 BitVec(24)
4715 >>> v0 = BitVecVal(2, 2)
4716 >>> v0
4717 2
4718 >>> v0.size()
4719 2
4720 >>> v = simplify(ZeroExt(6, v0))
4721 >>> v
4722 2
4723 >>> v.size()
4724 8
4725 """
4726 if z3_debug():
4727 _z3_assert(_is_int(n), "First argument must be an integer")
4728 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4729 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4730
4731
4733 """Return an expression representing `n` copies of `a`.
4734
4735 >>> x = BitVec('x', 8)
4736 >>> n = RepeatBitVec(4, x)
4737 >>> n
4738 RepeatBitVec(4, x)
4739 >>> n.size()
4740 32
4741 >>> v0 = BitVecVal(10, 4)
4742 >>> print("%.x" % v0.as_long())
4743 a
4744 >>> v = simplify(RepeatBitVec(4, v0))
4745 >>> v.size()
4746 16
4747 >>> print("%.x" % v.as_long())
4748 aaaa
4749 """
4750 if z3_debug():
4751 _z3_assert(_is_int(n), "First argument must be an integer")
4752 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4753 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4754
4755
4757 """Return the reduction-and expression of `a`."""
4758 if z3_debug():
4759 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4760 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4761
4762
4763def BVRedOr(a):
4764 """Return the reduction-or expression of `a`."""
4765 if z3_debug():
4766 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4767 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4768
4769
4770def BvNand(a, b):
4771 """Return the bitwise NAND of `a` and `b`.
4772
4773 >>> x = BitVec('x', 8)
4774 >>> y = BitVec('y', 8)
4775 >>> BvNand(x, y)
4776 bvnand(x, y)
4777 """
4778 _check_bv_args(a, b)
4779 a, b = _coerce_exprs(a, b)
4780 return BitVecRef(Z3_mk_bvnand(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4781
4782
4783def BvNor(a, b):
4784 """Return the bitwise NOR of `a` and `b`.
4785
4786 >>> x = BitVec('x', 8)
4787 >>> y = BitVec('y', 8)
4788 >>> BvNor(x, y)
4789 bvnor(x, y)
4790 """
4791 _check_bv_args(a, b)
4792 a, b = _coerce_exprs(a, b)
4793 return BitVecRef(Z3_mk_bvnor(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4794
4795
4796def BvXnor(a, b):
4797 """Return the bitwise XNOR of `a` and `b`.
4798
4799 >>> x = BitVec('x', 8)
4800 >>> y = BitVec('y', 8)
4801 >>> BvXnor(x, y)
4802 bvxnor(x, y)
4803 """
4804 _check_bv_args(a, b)
4805 a, b = _coerce_exprs(a, b)
4806 return BitVecRef(Z3_mk_bvxnor(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4807
4808
4809def BVAddNoOverflow(a, b, signed):
4810 """A predicate the determines that bit-vector addition does not overflow"""
4811 _check_bv_args(a, b)
4812 a, b = _coerce_exprs(a, b)
4813 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4814
4815
4817 """A predicate the determines that signed bit-vector addition does not underflow"""
4818 _check_bv_args(a, b)
4819 a, b = _coerce_exprs(a, b)
4820 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4821
4822
4824 """A predicate the determines that bit-vector subtraction does not overflow"""
4825 _check_bv_args(a, b)
4826 a, b = _coerce_exprs(a, b)
4827 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4828
4829
4830def BVSubNoUnderflow(a, b, signed):
4831 """A predicate the determines that bit-vector subtraction does not underflow"""
4832 _check_bv_args(a, b)
4833 a, b = _coerce_exprs(a, b)
4834 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4835
4836
4838 """A predicate the determines that bit-vector signed division does not overflow"""
4839 _check_bv_args(a, b)
4840 a, b = _coerce_exprs(a, b)
4841 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4842
4843
4845 """A predicate the determines that bit-vector unary negation does not overflow"""
4846 if z3_debug():
4847 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4848 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4849
4850
4851def BVMulNoOverflow(a, b, signed):
4852 """A predicate the determines that bit-vector multiplication does not overflow"""
4853 _check_bv_args(a, b)
4854 a, b = _coerce_exprs(a, b)
4855 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4856
4857
4859 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4860 _check_bv_args(a, b)
4861 a, b = _coerce_exprs(a, b)
4862 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4863
4864
4865
4870
4872 """Array sorts."""
4873
4874 def domain(self):
4875 """Return the domain of the array sort `self`.
4876
4877 >>> A = ArraySort(IntSort(), BoolSort())
4878 >>> A.domain()
4879 Int
4880 """
4882
4883 def domain_n(self, i):
4884 """Return the domain of the array sort `self`.
4885 """
4886 return _to_sort_ref(Z3_get_array_sort_domain_n(self.ctx_ref(), self.ast, i), self.ctx)
4887
4888 def range(self):
4889 """Return the range of the array sort `self`.
4890
4891 >>> A = ArraySort(IntSort(), BoolSort())
4892 >>> A.range()
4893 Bool
4894 """
4895 return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
4896
4897
4899 """Array expressions. """
4900
4901 def sort(self):
4902 """Return the array sort of the array expression `self`.
4903
4904 >>> a = Array('a', IntSort(), BoolSort())
4905 >>> a.sort()
4906 Array(Int, Bool)
4907 """
4908 return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4909
4910 def domain(self):
4911 """Shorthand for `self.sort().domain()`.
4912
4913 >>> a = Array('a', IntSort(), BoolSort())
4914 >>> a.domain()
4915 Int
4916 """
4917 return self.sort().domain()
4918
4919 def domain_n(self, i):
4920 """Shorthand for self.sort().domain_n(i)`."""
4921 return self.sort().domain_n(i)
4922
4923 def range(self):
4924 """Shorthand for `self.sort().range()`.
4925
4926 >>> a = Array('a', IntSort(), BoolSort())
4927 >>> a.range()
4928 Bool
4929 """
4930 return self.sort().range()
4931
4932 def __getitem__(self, arg):
4933 """Return the Z3 expression `self[arg]`.
4934
4935 >>> a = Array('a', IntSort(), BoolSort())
4936 >>> i = Int('i')
4937 >>> a[i]
4938 a[i]
4939 >>> a[i].sexpr()
4940 '(select a i)'
4941 """
4942 return _array_select(self, arg)
4943
4944 def default(self):
4945 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)
4946
4947
4948def _array_select(ar, arg):
4949 if isinstance(arg, tuple):
4950 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4951 _args, sz = _to_ast_array(args)
4952 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4953 arg = ar.sort().domain().cast(arg)
4954 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4955
4956
4958 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4959
4960
4961def is_array(a : Any) -> bool:
4962 """Return `True` if `a` is a Z3 array expression.
4963
4964 >>> a = Array('a', IntSort(), IntSort())
4965 >>> is_array(a)
4966 True
4967 >>> is_array(Store(a, 0, 1))
4968 True
4969 >>> is_array(a[0])
4970 False
4971 """
4972 return isinstance(a, ArrayRef)
4973
4974
4976 """Return `True` if `a` is a Z3 constant array.
4977
4978 >>> a = K(IntSort(), 10)
4979 >>> is_const_array(a)
4980 True
4981 >>> a = Array('a', IntSort(), IntSort())
4982 >>> is_const_array(a)
4983 False
4984 """
4985 return is_app_of(a, Z3_OP_CONST_ARRAY)
4986
4987
4988def is_K(a):
4989 """Return `True` if `a` is a Z3 constant array.
4990
4991 >>> a = K(IntSort(), 10)
4992 >>> is_K(a)
4993 True
4994 >>> a = Array('a', IntSort(), IntSort())
4995 >>> is_K(a)
4996 False
4997 """
4998 return is_app_of(a, Z3_OP_CONST_ARRAY)
4999
5000
5001def is_map(a):
5002 """Return `True` if `a` is a Z3 map array expression.
5003
5004 >>> f = Function('f', IntSort(), IntSort())
5005 >>> b = Array('b', IntSort(), IntSort())
5006 >>> a = Map(f, b)
5007 >>> a
5008 Map(f, b)
5009 >>> is_map(a)
5010 True
5011 >>> is_map(b)
5012 False
5013 """
5014 return is_app_of(a, Z3_OP_ARRAY_MAP)
5015
5016
5018 """Return `True` if `a` is a Z3 default array expression.
5019 >>> d = Default(K(IntSort(), 10))
5020 >>> is_default(d)
5021 True
5022 """
5023 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
5024
5025
5027 """Return the function declaration associated with a Z3 map array expression.
5028
5029 >>> f = Function('f', IntSort(), IntSort())
5030 >>> b = Array('b', IntSort(), IntSort())
5031 >>> a = Map(f, b)
5032 >>> eq(f, get_map_func(a))
5033 True
5034 >>> get_map_func(a)
5035 f
5036 >>> get_map_func(a)(0)
5037 f(0)
5038 """
5039 if z3_debug():
5040 _z3_assert(is_map(a), "Z3 array map expression expected.")
5041 return FuncDeclRef(
5043 a.ctx_ref(),
5044 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
5045 ),
5046 ctx=a.ctx,
5047 )
5048
5049
5050def ArraySort(*sig):
5051 """Return the Z3 array sort with the given domain and range sorts.
5052
5053 >>> A = ArraySort(IntSort(), BoolSort())
5054 >>> A
5055 Array(Int, Bool)
5056 >>> A.domain()
5057 Int
5058 >>> A.range()
5059 Bool
5060 >>> AA = ArraySort(IntSort(), A)
5061 >>> AA
5062 Array(Int, Array(Int, Bool))
5063 >>> ArraySort(IntSort(), BoolSort(), RealSort())
5064 Array(Int, Bool, Real)
5065 """
5066 sig = _get_args(sig)
5067 if z3_debug():
5068 _z3_assert(len(sig) > 1, "At least two arguments expected")
5069 arity = len(sig) - 1
5070 r = sig[arity]
5071 d = sig[0]
5072 if z3_debug():
5073 for s in sig:
5074 _z3_assert(is_sort(s), "Z3 sort expected")
5075 _z3_assert(s.ctx == r.ctx, "Context mismatch")
5076 ctx = d.ctx
5077 if len(sig) == 2:
5078 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
5079 dom = (Sort * arity)()
5080 for i in range(arity):
5081 dom[i] = sig[i].ast
5082 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
5083
5084
5085def Array(name, *sorts):
5086 """Return an array constant named `name` with the given domain and range sorts.
5087
5088 >>> a = Array('a', IntSort(), IntSort())
5089 >>> a.sort()
5090 Array(Int, Int)
5091 >>> a[0]
5092 a[0]
5093 """
5094 s = ArraySort(sorts)
5095 ctx = s.ctx
5096 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
5097
5098
5099def Update(a, *args):
5100 """Return a Z3 store array expression.
5101
5102 >>> a = Array('a', IntSort(), IntSort())
5103 >>> i, v = Ints('i v')
5104 >>> s = Update(a, i, v)
5105 >>> s.sort()
5106 Array(Int, Int)
5107 >>> prove(s[i] == v)
5108 proved
5109 >>> j = Int('j')
5110 >>> prove(Implies(i != j, s[j] == a[j]))
5111 proved
5112 """
5113 if z3_debug():
5114 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
5115 args = _get_args(args)
5116 ctx = a.ctx
5117 if len(args) <= 1:
5118 raise Z3Exception("array update requires index and value arguments")
5119 if len(args) == 2:
5120 i = args[0]
5121 v = args[1]
5122 i = a.sort().domain().cast(i)
5123 v = a.sort().range().cast(v)
5124 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
5125 v = a.sort().range().cast(args[-1])
5126 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
5127 _args, sz = _to_ast_array(idxs)
5128 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
5129
5130
5131def Default(a):
5132 """ Return a default value for array expression.
5133 >>> b = K(IntSort(), 1)
5134 >>> prove(Default(b) == 1)
5135 proved
5136 """
5137 if z3_debug():
5138 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
5139 return a.default()
5140
5141
5142def Store(a, *args):
5143 """Return a Z3 store array expression.
5144
5145 >>> a = Array('a', IntSort(), IntSort())
5146 >>> i, v = Ints('i v')
5147 >>> s = Store(a, i, v)
5148 >>> s.sort()
5149 Array(Int, Int)
5150 >>> prove(s[i] == v)
5151 proved
5152 >>> j = Int('j')
5153 >>> prove(Implies(i != j, s[j] == a[j]))
5154 proved
5155 """
5156 return Update(a, args)
5157
5158
5159def Select(a, *args):
5160 """Return a Z3 select array expression.
5161
5162 >>> a = Array('a', IntSort(), IntSort())
5163 >>> i = Int('i')
5164 >>> Select(a, i)
5165 a[i]
5166 >>> eq(Select(a, i), a[i])
5167 True
5168 """
5169 args = _get_args(args)
5170 if z3_debug():
5171 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
5172 return a[args]
5173
5174
5175def Map(f, *args):
5176 """Return a Z3 map array expression.
5177
5178 >>> f = Function('f', IntSort(), IntSort(), IntSort())
5179 >>> a1 = Array('a1', IntSort(), IntSort())
5180 >>> a2 = Array('a2', IntSort(), IntSort())
5181 >>> b = Map(f, a1, a2)
5182 >>> b
5183 Map(f, a1, a2)
5184 >>> prove(b[0] == f(a1[0], a2[0]))
5185 proved
5186 """
5187 args = _get_args(args)
5188 if z3_debug():
5189 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
5190 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
5191 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
5192 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
5193 _args, sz = _to_ast_array(args)
5194 ctx = f.ctx
5195 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
5196
5197
5198def K(dom, v):
5199 """Return a Z3 constant array expression.
5200
5201 >>> a = K(IntSort(), 10)
5202 >>> a
5203 K(Int, 10)
5204 >>> a.sort()
5205 Array(Int, Int)
5206 >>> i = Int('i')
5207 >>> a[i]
5208 K(Int, 10)[i]
5209 >>> simplify(a[i])
5210 10
5211 """
5212 if z3_debug():
5213 _z3_assert(is_sort(dom), "Z3 sort expected")
5214 ctx = dom.ctx
5215 if not is_expr(v):
5216 v = _py2expr(v, ctx)
5217 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
5218
5219
5220def Ext(a, b):
5221 """Return extensionality index for one-dimensional arrays.
5222 >> a, b = Consts('a b', SetSort(IntSort()))
5223 >> Ext(a, b)
5224 Ext(a, b)
5225 """
5226 ctx = a.ctx
5227 if z3_debug():
5228 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
5229 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5230
5231
5232def AsArray(f):
5233 """Return a Z3 as-array expression for the given function declaration.
5234
5235 >>> f = Function('f', IntSort(), IntSort())
5236 >>> a = AsArray(f)
5237 >>> a.sort()
5238 Array(Int, Int)
5239 >>> is_as_array(a)
5240 True
5241 >>> get_as_array_func(a) == f
5242 True
5243 """
5244 if z3_debug():
5245 _z3_assert(isinstance(f, FuncDeclRef), "function declaration expected")
5246 ctx = f.ctx
5247 return ArrayRef(Z3_mk_as_array(ctx.ref(), f.ast), ctx)
5248
5249
5251 """Return `True` if `a` is a Z3 array select application.
5252
5253 >>> a = Array('a', IntSort(), IntSort())
5254 >>> is_select(a)
5255 False
5256 >>> i = Int('i')
5257 >>> is_select(a[i])
5258 True
5259 """
5260 return is_app_of(a, Z3_OP_SELECT)
5261
5262
5264 """Return `True` if `a` is a Z3 array store application.
5265
5266 >>> a = Array('a', IntSort(), IntSort())
5267 >>> is_store(a)
5268 False
5269 >>> is_store(Store(a, 0, 1))
5270 True
5271 """
5272 return is_app_of(a, Z3_OP_STORE)
5273
5274
5279
5280
5281def SetSort(s):
5282 """ Create a set sort over element sort s"""
5283 return ArraySort(s, BoolSort())
5284
5285
5287 """Create the empty set
5288 >>> EmptySet(IntSort())
5289 K(Int, False)
5290 """
5291 ctx = s.ctx
5292 if is_finite_set_sort(s):
5293 return FiniteSetEmpty(s)
5294 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5295
5296
5297def FullSet(s):
5298 """Create the full set
5299 >>> FullSet(IntSort())
5300 K(Int, True)
5301 """
5302 ctx = s.ctx
5303 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5304
5305
5306def SetUnion(*args):
5307 """ Take the union of sets
5308 >>> a = Const('a', SetSort(IntSort()))
5309 >>> b = Const('b', SetSort(IntSort()))
5310 >>> SetUnion(a, b)
5311 union(a, b)
5312 """
5313 args = _get_args(args)
5314 if len(args) > 0 and is_finite_set(args[0]):
5315 from functools import reduce
5316 return reduce(FiniteSetUnion, args)
5317 ctx = _ctx_from_ast_arg_list(args)
5318 _args, sz = _to_ast_array(args)
5319 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5320
5321
5322def SetIntersect(*args):
5323 """ Take the union of sets
5324 >>> a = Const('a', SetSort(IntSort()))
5325 >>> b = Const('b', SetSort(IntSort()))
5326 >>> SetIntersect(a, b)
5327 intersection(a, b)
5328 """
5329 args = _get_args(args)
5330 ctx = _ctx_from_ast_arg_list(args)
5331 if len(args) > 0 and is_finite_set(args[0]):
5332 from functools import reduce
5333 return reduce(FiniteSetIntersect, args)
5334 _args, sz = _to_ast_array(args)
5335 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5336
5337
5338def SetAdd(s, e):
5339 """ Add element e to set s
5340 >>> a = Const('a', SetSort(IntSort()))
5341 >>> SetAdd(a, 1)
5342 Store(a, 1, True)
5343 """
5344 ctx = _ctx_from_ast_arg_list([s, e])
5345 e = _py2expr(e, ctx)
5346 if is_finite_set(s):
5347 return FiniteSetSingleton(e) | s
5348 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5349
5350
5351def SetDel(s, e):
5352 """ Remove element e to set s
5353 >>> a = Const('a', SetSort(IntSort()))
5354 >>> SetDel(a, 1)
5355 Store(a, 1, False)
5356 """
5357 ctx = _ctx_from_ast_arg_list([s, e])
5358 e = _py2expr(e, ctx)
5359 if is_finite_set(s):
5360 return s - FiniteSetSingleton(e)
5361 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5362
5363
5365 """ The complement of set s
5366 >>> a = Const('a', SetSort(IntSort()))
5367 >>> SetComplement(a)
5368 complement(a)
5369 """
5370 ctx = s.ctx
5371 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5372
5373
5375 """ The set difference of a and b
5376 >>> a = Const('a', SetSort(IntSort()))
5377 >>> b = Const('b', SetSort(IntSort()))
5378 >>> SetDifference(a, b)
5379 setminus(a, b)
5380 """
5381 ctx = _ctx_from_ast_arg_list([a, b])
5382 if is_finite_set(a):
5383 return FiniteSetDifference(a, b)
5384 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5385
5386
5387def IsMember(e, s):
5388 """ Check if e is a member of set s
5389 >>> a = Const('a', SetSort(IntSort()))
5390 >>> IsMember(1, a)
5391 a[1]
5392 """
5393 ctx = _ctx_from_ast_arg_list([s, e])
5394 e = _py2expr(e, ctx)
5395 if is_finite_set(s):
5396 return FiniteSetIsMember(e, s)
5397 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5398
5399
5400def IsSubset(a, b):
5401 """ Check if a is a subset of b
5402 >>> a = Const('a', SetSort(IntSort()))
5403 >>> b = Const('b', SetSort(IntSort()))
5404 >>> IsSubset(a, b)
5405 subset(a, b)
5406 """
5407 ctx = _ctx_from_ast_arg_list([a, b])
5408 if is_finite_set(a):
5409 return FiniteSetIsSubset(a, b)
5410 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5411
5412
5413
5418
5419
5421 """Finite set sort."""
5422
5423 def element_sort(self):
5424 """Return the element sort of this finite set sort."""
5426
5427 def cast(self, val):
5428 """Try to cast val as a finite set expression."""
5429 if is_expr(val):
5430 if self.eq(val.sort()):
5431 return val
5432 else:
5433 _z3_assert(False, "Cannot cast to finite set sort")
5434 if isinstance(val, set):
5435 elem_sort = self.element_sort()
5436 result = FiniteSetEmpty(self)
5437 for e in val:
5438 result = FiniteSetUnion(result, Singleton(_py2expr(e, self.ctx, elem_sort)))
5439 return result
5440 _z3_assert(False, "Cannot cast to finite set sort")
5441
5442 def subsort(self, other):
5443 return False
5444
5445 def is_int(self):
5446 return False
5447
5448 def is_bool(self):
5449 return False
5450
5451 def is_datatype(self):
5452 return False
5453
5454 def is_array(self):
5455 return False
5456
5457 def is_bv(self):
5458 return False
5459
5460
5462 """Return True if a is a Z3 finite set expression.
5463 >>> s = FiniteSetSort(IntSort())
5464 >>> is_finite_set(FiniteSetEmpty(s))
5465 True
5466 >>> is_finite_set(IntVal(1))
5467 False
5468 """
5469 return isinstance(a, FiniteSetRef)
5470
5471
5473 """Return True if s is a Z3 finite set sort.
5474 >>> is_finite_set_sort(FiniteSetSort(IntSort()))
5475 True
5476 >>> is_finite_set_sort(IntSort())
5477 False
5478 """
5479 return isinstance(s, FiniteSetSortRef)
5480
5481
5483 """Finite set expression."""
5484
5485 def sort(self):
5486 return FiniteSetSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5487
5488 def __or__(self, other):
5489 """Return the union of self and other."""
5490 return FiniteSetUnion(self, other)
5491
5492 def __and__(self, other):
5493 """Return the intersection of self and other."""
5494 return FiniteSetIntersect(self, other)
5495
5496 def __sub__(self, other):
5497 """Return the set difference of self and other."""
5498 return FiniteSetDifference(self, other)
5499
5500
5501def FiniteSetSort(elem_sort):
5502 """Create a finite set sort over element sort elem_sort.
5503 >>> s = FiniteSetSort(IntSort())
5504 >>> s
5505 FiniteSet(Int)
5506 """
5507 return FiniteSetSortRef(Z3_mk_finite_set_sort(elem_sort.ctx_ref(), elem_sort.ast), elem_sort.ctx)
5508
5509
5510def FiniteSetEmpty(set_sort):
5511 """Create an empty finite set of the given sort.
5512 >>> s = FiniteSetSort(IntSort())
5513 >>> FiniteSetEmpty(s)
5514 set.empty
5515 """
5516 ctx = set_sort.ctx
5517 return FiniteSetRef(Z3_mk_finite_set_empty(ctx.ref(), set_sort.ast), ctx)
5518
5519
5520def Singleton(elem):
5521 """Create a singleton finite set containing elem.
5522 >>> Singleton(IntVal(1))
5523 set.singleton(1)
5524 """
5525 ctx = elem.ctx
5526 return FiniteSetRef(Z3_mk_finite_set_singleton(ctx.ref(), elem.as_ast()), ctx)
5527
5528
5529def FiniteSetUnion(s1, s2):
5530 """Create the union of two finite sets.
5531 >>> a = Const('a', FiniteSetSort(IntSort()))
5532 >>> b = Const('b', FiniteSetSort(IntSort()))
5533 >>> FiniteSetUnion(a, b)
5534 set.union(a, b)
5535 """
5536 ctx = _ctx_from_ast_arg_list([s1, s2])
5537 return FiniteSetRef(Z3_mk_finite_set_union(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx)
5538
5539
5541 """Create the intersection of two finite sets.
5542 >>> a = Const('a', FiniteSetSort(IntSort()))
5543 >>> b = Const('b', FiniteSetSort(IntSort()))
5544 >>> FiniteSetIntersect(a, b)
5545 set.intersect(a, b)
5546 """
5547 ctx = _ctx_from_ast_arg_list([s1, s2])
5548 return FiniteSetRef(Z3_mk_finite_set_intersect(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx)
5549
5550
5552 """Create the set difference of two finite sets.
5553 >>> a = Const('a', FiniteSetSort(IntSort()))
5554 >>> b = Const('b', FiniteSetSort(IntSort()))
5555 >>> FiniteSetDifference(a, b)
5556 set.difference(a, b)
5557 """
5558 ctx = _ctx_from_ast_arg_list([s1, s2])
5559 return FiniteSetRef(Z3_mk_finite_set_difference(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx)
5560
5561
5562def FiniteSetMember(elem, set):
5563 """Check if elem is a member of the finite set.
5564 >>> a = Const('a', FiniteSetSort(IntSort()))
5565 >>> FiniteSetMember(IntVal(1), a)
5566 set.in(1, a)
5567 """
5568 ctx = _ctx_from_ast_arg_list([elem, set])
5569 return BoolRef(Z3_mk_finite_set_member(ctx.ref(), elem.as_ast(), set.as_ast()), ctx)
5570
5571def In(elem, set):
5572 return FiniteSetMember(elem, set)
5573
5575 """Get the size (cardinality) of a finite set.
5576 >>> a = Const('a', FiniteSetSort(IntSort()))
5577 >>> FiniteSetSize(a)
5578 set.size(a)
5579 """
5580 ctx = set.ctx
5581 return ArithRef(Z3_mk_finite_set_size(ctx.ref(), set.as_ast()), ctx)
5582
5583
5585 """Check if s1 is a subset of s2.
5586 >>> a = Const('a', FiniteSetSort(IntSort()))
5587 >>> b = Const('b', FiniteSetSort(IntSort()))
5588 >>> FiniteSetSubset(a, b)
5589 set.subset(a, b)
5590 """
5591 ctx = _ctx_from_ast_arg_list([s1, s2])
5592 return BoolRef(Z3_mk_finite_set_subset(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx)
5593
5594
5595def FiniteSetMap(f, set):
5596 """Apply function f to all elements of the finite set.
5597 >>> f = Array('f', IntSort(), IntSort())
5598 >>> a = Const('a', FiniteSetSort(IntSort()))
5599 >>> FiniteSetMap(f, a)
5600 set.map(f, a)
5601 """
5602 if isinstance(f, FuncDeclRef):
5603 f = AsArray(f)
5604 ctx = _ctx_from_ast_arg_list([f, set])
5605 return FiniteSetRef(Z3_mk_finite_set_map(ctx.ref(), f.as_ast(), set.as_ast()), ctx)
5606
5607
5609 """Filter a finite set using predicate f.
5610 >>> f = Array('f', IntSort(), BoolSort())
5611 >>> a = Const('a', FiniteSetSort(IntSort()))
5612 >>> FiniteSetFilter(f, a)
5613 set.filter(f, a)
5614 """
5615 if isinstance(f, FuncDeclRef):
5616 f = AsArray(f)
5617 ctx = _ctx_from_ast_arg_list([f, set])
5618 return FiniteSetRef(Z3_mk_finite_set_filter(ctx.ref(), f.as_ast(), set.as_ast()), ctx)
5619
5620
5621def FiniteSetRange(low, high):
5622 """Create a finite set of integers in the range [low, high).
5623 >>> FiniteSetRange(IntVal(0), IntVal(5))
5624 set.range(0, 5)
5625 """
5626 ctx = _ctx_from_ast_arg_list([low, high])
5627 return FiniteSetRef(Z3_mk_finite_set_range(ctx.ref(), low.as_ast(), high.as_ast()), ctx)
5628
5629
5630
5635
5637 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5638 if not isinstance(acc, tuple):
5639 return False
5640 if len(acc) != 2:
5641 return False
5642 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5643
5644
5646 """Helper class for declaring Z3 datatypes.
5647
5648 >>> List = Datatype('List')
5649 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5650 >>> List.declare('nil')
5651 >>> List = List.create()
5652 >>> # List is now a Z3 declaration
5653 >>> List.nil
5654 nil
5655 >>> List.cons(10, List.nil)
5656 cons(10, nil)
5657 >>> List.cons(10, List.nil).sort()
5658 List
5659 >>> cons = List.cons
5660 >>> nil = List.nil
5661 >>> car = List.car
5662 >>> cdr = List.cdr
5663 >>> n = cons(1, cons(0, nil))
5664 >>> n
5665 cons(1, cons(0, nil))
5666 >>> simplify(cdr(n))
5667 cons(0, nil)
5668 >>> simplify(car(n))
5669 1
5670 """
5671
5672 def __init__(self, name, ctx=None):
5673 self.ctx = _get_ctx(ctx)
5674 self.name = name
5676
5677 def __deepcopy__(self, memo={}):
5678 r = Datatype(self.name, self.ctx)
5679 r.constructors = copy.deepcopy(self.constructors)
5680 return r
5681
5682 def declare_core(self, name, rec_name, *args):
5683 if z3_debug():
5684 _z3_assert(isinstance(name, str), "String expected")
5685 _z3_assert(isinstance(rec_name, str), "String expected")
5686 _z3_assert(
5687 all([_valid_accessor(a) for a in args]),
5688 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5689 )
5690 self.constructors.append((name, rec_name, args))
5691
5692 def declare(self, name, *args):
5693 """Declare constructor named `name` with the given accessors `args`.
5694 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5695 or a reference to the datatypes being declared.
5696
5697 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5698 declares the constructor named `cons` that builds a new List using an integer and a List.
5699 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5700 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5701 we use the method create() to create the actual datatype in Z3.
5702
5703 >>> List = Datatype('List')
5704 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5705 >>> List.declare('nil')
5706 >>> List = List.create()
5707 """
5708 if z3_debug():
5709 _z3_assert(isinstance(name, str), "String expected")
5710 _z3_assert(name != "", "Constructor name cannot be empty")
5711 return self.declare_core(name, "is-" + name, *args)
5712
5713 def __repr__(self):
5714 return "Datatype(%s, %s)" % (self.name, self.constructors)
5715
5716 def create(self):
5717 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5718
5719 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5720
5721 >>> List = Datatype('List')
5722 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5723 >>> List.declare('nil')
5724 >>> List = List.create()
5725 >>> List.nil
5726 nil
5727 >>> List.cons(10, List.nil)
5728 cons(10, nil)
5729 """
5730 return CreateDatatypes([self])[0]
5731
5732 def create_polymorphic(self, type_params):
5733 """Create a polymorphic Z3 datatype with explicit type variables.
5734
5735 `type_params` is a list of type variables created with `DeclareTypeVar`.
5736 Constructor field sorts may reference these type variables.
5737 Self-recursive fields may reference this datatype directly.
5738
5739 >>> A = DeclareTypeVar('A')
5740 >>> Pair = Datatype('Pair')
5741 >>> Pair.declare('pair', ('fst', A), ('snd', A))
5742 >>> Pair = Pair.create_polymorphic([A])
5743 """
5744 return CreatePolymorphicDatatype(self, type_params)
5745
5746
5748 """Auxiliary object used to create Z3 datatypes."""
5749
5750 def __init__(self, c, ctx):
5751 self.c = c
5752 self.ctx = ctx
5753
5754 def __del__(self):
5755 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5756 Z3_del_constructor(self.ctx.ref(), self.c)
5757
5758
5760 """Auxiliary object used to create Z3 datatypes."""
5761
5762 def __init__(self, c, ctx):
5763 self.c = c
5764 self.ctx = ctx
5765
5766 def __del__(self):
5767 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5768 Z3_del_constructor_list(self.ctx.ref(), self.c)
5769
5770
5772 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5773
5774 In the following example we define a Tree-List using two mutually recursive datatypes.
5775
5776 >>> TreeList = Datatype('TreeList')
5777 >>> Tree = Datatype('Tree')
5778 >>> # Tree has two constructors: leaf and node
5779 >>> Tree.declare('leaf', ('val', IntSort()))
5780 >>> # a node contains a list of trees
5781 >>> Tree.declare('node', ('children', TreeList))
5782 >>> TreeList.declare('nil')
5783 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5784 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5785 >>> Tree.val(Tree.leaf(10))
5786 val(leaf(10))
5787 >>> simplify(Tree.val(Tree.leaf(10)))
5788 10
5789 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5790 >>> n1
5791 node(cons(leaf(10), cons(leaf(20), nil)))
5792 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5793 >>> simplify(n2 == n1)
5794 False
5795 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5796 True
5797 """
5798 ds = _get_args(ds)
5799 if z3_debug():
5800 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5801 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5802 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5803 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5804 ctx = ds[0].ctx
5805 num = len(ds)
5806 names = (Symbol * num)()
5807 out = (Sort * num)()
5808 clists = (ConstructorList * num)()
5809 to_delete = []
5810 for i in range(num):
5811 d = ds[i]
5812 names[i] = to_symbol(d.name, ctx)
5813 num_cs = len(d.constructors)
5814 cs = (Constructor * num_cs)()
5815 for j in range(num_cs):
5816 c = d.constructors[j]
5817 cname = to_symbol(c[0], ctx)
5818 rname = to_symbol(c[1], ctx)
5819 fs = c[2]
5820 num_fs = len(fs)
5821 fnames = (Symbol * num_fs)()
5822 sorts = (Sort * num_fs)()
5823 refs = (ctypes.c_uint * num_fs)()
5824 for k in range(num_fs):
5825 fname = fs[k][0]
5826 ftype = fs[k][1]
5827 fnames[k] = to_symbol(fname, ctx)
5828 if isinstance(ftype, Datatype):
5829 if z3_debug():
5830 _z3_assert(
5831 ds.count(ftype) == 1,
5832 "One and only one occurrence of each datatype is expected",
5833 )
5834 sorts[k] = None
5835 refs[k] = ds.index(ftype)
5836 else:
5837 if z3_debug():
5838 _z3_assert(is_sort(ftype), "Z3 sort expected")
5839 sorts[k] = ftype.ast
5840 refs[k] = 0
5841 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5842 to_delete.append(ScopedConstructor(cs[j], ctx))
5843 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5844 to_delete.append(ScopedConstructorList(clists[i], ctx))
5845 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5846 result = []
5847 # Create a field for every constructor, recognizer and accessor
5848 for i in range(num):
5849 dref = DatatypeSortRef(out[i], ctx)
5850 num_cs = dref.num_constructors()
5851 for j in range(num_cs):
5852 cref = dref.constructor(j)
5853 cref_name = cref.name()
5854 cref_arity = cref.arity()
5855 if cref.arity() == 0:
5856 cref = cref()
5857 setattr(dref, cref_name, cref)
5858 rref = dref.recognizer(j)
5859 setattr(dref, "is_" + cref_name, rref)
5860 for k in range(cref_arity):
5861 aref = dref.accessor(j, k)
5862 setattr(dref, aref.name(), aref)
5863 result.append(dref)
5864 return tuple(result)
5865
5866
5867def CreatePolymorphicDatatype(d, type_params):
5868 """Create a single polymorphic Z3 datatype with explicit type parameters.
5869
5870 `d` is a `Datatype` helper object whose constructors have been declared.
5871 `type_params` is a list of type variables created with `DeclareTypeVar`.
5872 Constructor field sorts may reference these type variables, and self-recursive
5873 fields may reference `d` directly.
5874
5875 >>> A = DeclareTypeVar('A')
5876 >>> Pair = Datatype('Pair')
5877 >>> Pair.declare('pair', ('fst', A), ('snd', A))
5878 >>> Pair = CreatePolymorphicDatatype(Pair, [A])
5879 """
5880 if z3_debug():
5881 _z3_assert(isinstance(d, Datatype), "Datatype expected")
5882 _z3_assert(d.constructors != [], "Non-empty Datatype expected")
5883 ctx = d.ctx
5884 name = to_symbol(d.name, ctx)
5885 num_params = len(type_params)
5886 params_arr = (Sort * num_params)()
5887 for i, p in enumerate(type_params):
5888 if z3_debug():
5889 _z3_assert(is_sort(p), "Z3 sort expected for type parameter")
5890 params_arr[i] = p.ast
5891 num_cs = len(d.constructors)
5892 cs = (Constructor * num_cs)()
5893 to_delete = []
5894 for j in range(num_cs):
5895 c = d.constructors[j]
5896 cname = to_symbol(c[0], ctx)
5897 rname = to_symbol(c[1], ctx)
5898 fs = c[2]
5899 num_fs = len(fs)
5900 fnames = (Symbol * num_fs)()
5901 sorts = (Sort * num_fs)()
5902 refs = (ctypes.c_uint * num_fs)()
5903 for k in range(num_fs):
5904 fname = fs[k][0]
5905 ftype = fs[k][1]
5906 fnames[k] = to_symbol(fname, ctx)
5907 if isinstance(ftype, Datatype):
5908 if z3_debug():
5909 _z3_assert(ftype is d, "Only self-recursive references are supported in polymorphic datatypes. Use CreateDatatypes for mutually recursive datatypes.")
5910 sorts[k] = None
5911 refs[k] = 0
5912 else:
5913 if z3_debug():
5914 _z3_assert(is_sort(ftype), "Z3 sort expected")
5915 sorts[k] = ftype.ast
5916 refs[k] = 0
5917 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5918 to_delete.append(ScopedConstructor(cs[j], ctx))
5919 out = Z3_mk_polymorphic_datatype(ctx.ref(), name, num_params, params_arr, num_cs, cs)
5920 dref = DatatypeSortRef(out, ctx)
5921 num_cs_actual = dref.num_constructors()
5922 for j in range(num_cs_actual):
5923 cref = dref.constructor(j)
5924 cref_name = cref.name()
5925 cref_arity = cref.arity()
5926 if cref_arity == 0:
5927 cref = cref()
5928 setattr(dref, cref_name, cref)
5929 rref = dref.recognizer(j)
5930 setattr(dref, "is_" + cref_name, rref)
5931 for k in range(cref_arity):
5932 aref = dref.accessor(j, k)
5933 setattr(dref, aref.name(), aref)
5934 return dref
5935
5936
5938 """Datatype sorts."""
5939
5941 """Return the number of constructors in the given Z3 datatype.
5942
5943 >>> List = Datatype('List')
5944 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5945 >>> List.declare('nil')
5946 >>> List = List.create()
5947 >>> # List is now a Z3 declaration
5948 >>> List.num_constructors()
5949 2
5950 """
5952
5953 def constructor(self, idx):
5954 """Return a constructor of the datatype `self`.
5955
5956 >>> List = Datatype('List')
5957 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5958 >>> List.declare('nil')
5959 >>> List = List.create()
5960 >>> # List is now a Z3 declaration
5961 >>> List.num_constructors()
5962 2
5963 >>> List.constructor(0)
5964 cons
5965 >>> List.constructor(1)
5966 nil
5967 """
5968 if z3_debug():
5969 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5971
5972 def recognizer(self, idx):
5973 """In Z3, each constructor has an associated recognizer predicate.
5974
5975 If the constructor is named `name`, then the recognizer `is_name`.
5976
5977 >>> List = Datatype('List')
5978 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5979 >>> List.declare('nil')
5980 >>> List = List.create()
5981 >>> # List is now a Z3 declaration
5982 >>> List.num_constructors()
5983 2
5984 >>> List.recognizer(0)
5985 is(cons)
5986 >>> List.recognizer(1)
5987 is(nil)
5988 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5989 False
5990 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5991 True
5992 >>> l = Const('l', List)
5993 >>> simplify(List.is_cons(l))
5994 is(cons, l)
5995 """
5996 if z3_debug():
5997 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5998 return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
5999
6000 def accessor(self, i, j):
6001 """In Z3, each constructor has 0 or more accessor.
6002 The number of accessors is equal to the arity of the constructor.
6003
6004 >>> List = Datatype('List')
6005 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
6006 >>> List.declare('nil')
6007 >>> List = List.create()
6008 >>> List.num_constructors()
6009 2
6010 >>> List.constructor(0)
6011 cons
6012 >>> num_accs = List.constructor(0).arity()
6013 >>> num_accs
6014 2
6015 >>> List.accessor(0, 0)
6016 car
6017 >>> List.accessor(0, 1)
6018 cdr
6019 >>> List.constructor(1)
6020 nil
6021 >>> num_accs = List.constructor(1).arity()
6022 >>> num_accs
6023 0
6024 """
6025 if z3_debug():
6026 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
6027 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
6028 return FuncDeclRef(
6030 ctx=self.ctx,
6031 )
6032
6033
6035 """Datatype expressions."""
6036
6037 def sort(self):
6038 """Return the datatype sort of the datatype expression `self`."""
6039 return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
6040
6041 def update_field(self, field_accessor, new_value):
6042 """Return a new datatype expression with the specified field updated.
6043
6044 Args:
6045 field_accessor: The accessor function declaration for the field to update
6046 new_value: The new value for the field
6047
6048 Returns:
6049 A new datatype expression with the field updated, other fields unchanged
6050
6051 Example:
6052 >>> Person = Datatype('Person')
6053 >>> Person.declare('person', ('name', StringSort()), ('age', IntSort()))
6054 >>> Person = Person.create()
6055 >>> person_age = Person.accessor(0, 1) # age accessor
6056 >>> p = Const('p', Person)
6057 >>> p2 = p.update_field(person_age, IntVal(30))
6058 """
6059 if z3_debug():
6060 _z3_assert(is_func_decl(field_accessor), "Z3 function declaration expected")
6061 _z3_assert(is_expr(new_value), "Z3 expression expected")
6062 return _to_expr_ref(
6063 Z3_datatype_update_field(self.ctx_ref(), field_accessor.ast, self.as_ast(), new_value.as_ast()),
6064 self.ctx
6065 )
6066
6067def DatatypeSort(name, params=None, ctx=None):
6068 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype.
6069
6070 Args:
6071 name: name of the datatype sort
6072 params: optional list/tuple of sort parameters for parametric datatypes
6073 ctx: Z3 context (optional)
6074
6075 Example:
6076 >>> # Non-parametric datatype
6077 >>> TreeRef = DatatypeSort('Tree')
6078 >>> # Parametric datatype with one parameter
6079 >>> ListIntRef = DatatypeSort('List', [IntSort()])
6080 >>> # Parametric datatype with multiple parameters
6081 >>> PairRef = DatatypeSort('Pair', [IntSort(), BoolSort()])
6082 """
6083 ctx = _get_ctx(ctx)
6084 if params is None or len(params) == 0:
6085 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), 0, (Sort * 0)()), ctx)
6086 else:
6087 _params = (Sort * len(params))()
6088 for i in range(len(params)):
6089 _params[i] = params[i].ast
6090 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), len(params), _params), ctx)
6091
6092def TupleSort(name, sorts, ctx=None):
6093 """Create a named tuple sort base on a set of underlying sorts
6094 Example:
6095 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
6096 """
6097 tuple = Datatype(name, ctx)
6098 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
6099 tuple.declare(name, *projects)
6100 tuple = tuple.create()
6101 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
6102
6103
6104def DisjointSum(name, sorts, ctx=None):
6105 """Create a named tagged union sort base on a set of underlying sorts
6106 Example:
6107 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
6108 """
6109 sum = Datatype(name, ctx)
6110 for i in range(len(sorts)):
6111 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
6112 sum = sum.create()
6113 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
6114
6115
6116def EnumSort(name, values, ctx=None):
6117 """Return a new enumeration sort named `name` containing the given values.
6118
6119 The result is a pair (sort, list of constants).
6120 Example:
6121 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
6122 """
6123 if z3_debug():
6124 _z3_assert(isinstance(name, str), "Name must be a string")
6125 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
6126 _z3_assert(len(values) > 0, "At least one value expected")
6127 ctx = _get_ctx(ctx)
6128 num = len(values)
6129 _val_names = (Symbol * num)()
6130 for i in range(num):
6131 _val_names[i] = to_symbol(values[i], ctx)
6132 _values = (FuncDecl * num)()
6133 _testers = (FuncDecl * num)()
6134 name = to_symbol(name, ctx)
6135 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
6136 V = []
6137 for i in range(num):
6138 V.append(FuncDeclRef(_values[i], ctx))
6139 V = [a() for a in V]
6140 return S, V
6141
6142
6147
6148
6150 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
6151
6152 Consider using the function `args2params` to create instances of this object.
6153 """
6154
6155 def __init__(self, ctx=None, params=None):
6156 self.ctx = _get_ctx(ctx)
6157 if params is None:
6158 self.params = Z3_mk_params(self.ctx.ref())
6159 else:
6160 self.params = params
6161 Z3_params_inc_ref(self.ctx.ref(), self.params)
6162
6163 def __deepcopy__(self, memo={}):
6164 return ParamsRef(self.ctx, self.params)
6165
6166 def __del__(self):
6167 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
6168 Z3_params_dec_ref(self.ctx.ref(), self.params)
6169
6170 def set(self, name, val):
6171 """Set parameter name with value val."""
6172 if z3_debug():
6173 _z3_assert(isinstance(name, str), "parameter name must be a string")
6174 name_sym = to_symbol(name, self.ctx)
6175 if isinstance(val, bool):
6176 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
6177 elif _is_int(val):
6178 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
6179 elif isinstance(val, float):
6180 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
6181 elif isinstance(val, str):
6182 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
6183 else:
6184 if z3_debug():
6185 _z3_assert(False, "invalid parameter value")
6186
6187 def __repr__(self):
6188 return Z3_params_to_string(self.ctx.ref(), self.params)
6189
6190 def validate(self, ds):
6191 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
6192 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
6193
6194
6195def args2params(arguments, keywords, ctx=None):
6196 """Convert python arguments into a Z3_params object.
6197 A ':' is added to the keywords, and '_' is replaced with '-'
6198
6199 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
6200 (params model true relevancy 2 elim_and true)
6201 """
6202 if z3_debug():
6203 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
6204 prev = None
6205 r = ParamsRef(ctx)
6206 for a in arguments:
6207 if prev is None:
6208 prev = a
6209 else:
6210 r.set(prev, a)
6211 prev = None
6212 for k in keywords:
6213 v = keywords[k]
6214 r.set(k, v)
6215 return r
6216
6217
6219 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
6220 """
6221
6222 def __init__(self, descr, ctx=None):
6223 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
6224 self.ctx = _get_ctx(ctx)
6225 self.descr = descr
6226 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
6227
6228 def __deepcopy__(self, memo={}):
6229 return ParamsDescrsRef(self.descr, self.ctx)
6230
6231 def __del__(self):
6232 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
6233 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
6234
6235 def size(self):
6236 """Return the size of in the parameter description `self`.
6237 """
6238 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
6239
6240 def __len__(self):
6241 """Return the size of in the parameter description `self`.
6242 """
6243 return self.size()
6244
6245 def get_name(self, i):
6246 """Return the i-th parameter name in the parameter description `self`.
6247 """
6248 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
6249
6250 def get_kind(self, n):
6251 """Return the kind of the parameter named `n`.
6252 """
6253 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
6254
6255 def get_documentation(self, n):
6256 """Return the documentation string of the parameter named `n`.
6257 """
6258 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
6259
6260 def __getitem__(self, arg):
6261 if _is_int(arg):
6262 return self.get_name(arg)
6263 else:
6264 return self.get_kind(arg)
6265
6266 def __repr__(self):
6267 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
6268
6269
6274
6275
6277 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
6278
6279 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
6280 A goal has a solution if one of its subgoals has a solution.
6281 A goal is unsatisfiable if all subgoals are unsatisfiable.
6282 """
6283
6284 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
6285 if z3_debug():
6286 _z3_assert(goal is None or ctx is not None,
6287 "If goal is different from None, then ctx must be also different from None")
6288 self.ctx = _get_ctx(ctx)
6289 self.goal = goal
6290 if self.goal is None:
6291 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
6292 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
6293
6294 def __del__(self):
6295 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
6296 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
6297
6298 def depth(self):
6299 """Return the depth of the goal `self`.
6300 The depth corresponds to the number of tactics applied to `self`.
6301
6302 >>> x, y = Ints('x y')
6303 >>> g = Goal()
6304 >>> g.add(x == 0, y >= x + 1)
6305 >>> g.depth()
6306 0
6307 >>> r = Then('simplify', 'solve-eqs')(g)
6308 >>> # r has 1 subgoal
6309 >>> len(r)
6310 1
6311 >>> r[0].depth()
6312 2
6313 """
6314 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
6315
6316 def inconsistent(self):
6317 """Return `True` if `self` contains the `False` constraints.
6318
6319 >>> x, y = Ints('x y')
6320 >>> g = Goal()
6321 >>> g.inconsistent()
6322 False
6323 >>> g.add(x == 0, x == 1)
6324 >>> g
6325 [x == 0, x == 1]
6326 >>> g.inconsistent()
6327 False
6328 >>> g2 = Tactic('propagate-values')(g)[0]
6329 >>> g2.inconsistent()
6330 True
6331 """
6332 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
6333
6334 def prec(self):
6335 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
6336
6337 >>> g = Goal()
6338 >>> g.prec() == Z3_GOAL_PRECISE
6339 True
6340 >>> x, y = Ints('x y')
6341 >>> g.add(x == y + 1)
6342 >>> g.prec() == Z3_GOAL_PRECISE
6343 True
6344 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
6345 >>> g2 = t(g)[0]
6346 >>> g2
6347 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
6348 >>> g2.prec() == Z3_GOAL_PRECISE
6349 False
6350 >>> g2.prec() == Z3_GOAL_UNDER
6351 True
6352 """
6353 return Z3_goal_precision(self.ctx.ref(), self.goal)
6354
6355 def precision(self):
6356 """Alias for `prec()`.
6357
6358 >>> g = Goal()
6359 >>> g.precision() == Z3_GOAL_PRECISE
6360 True
6361 """
6362 return self.prec()
6363
6364 def size(self):
6365 """Return the number of constraints in the goal `self`.
6366
6367 >>> g = Goal()
6368 >>> g.size()
6369 0
6370 >>> x, y = Ints('x y')
6371 >>> g.add(x == 0, y > x)
6372 >>> g.size()
6373 2
6374 """
6375 return int(Z3_goal_size(self.ctx.ref(), self.goal))
6376
6377 def __len__(self):
6378 """Return the number of constraints in the goal `self`.
6379
6380 >>> g = Goal()
6381 >>> len(g)
6382 0
6383 >>> x, y = Ints('x y')
6384 >>> g.add(x == 0, y > x)
6385 >>> len(g)
6386 2
6387 """
6388 return self.size()
6389
6390 def get(self, i):
6391 """Return a constraint in the goal `self`.
6392
6393 >>> g = Goal()
6394 >>> x, y = Ints('x y')
6395 >>> g.add(x == 0, y > x)
6396 >>> g.get(0)
6397 x == 0
6398 >>> g.get(1)
6399 y > x
6400 """
6401 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
6402
6403 def __getitem__(self, arg):
6404 """Return a constraint in the goal `self`.
6405
6406 >>> g = Goal()
6407 >>> x, y = Ints('x y')
6408 >>> g.add(x == 0, y > x)
6409 >>> g[0]
6410 x == 0
6411 >>> g[1]
6412 y > x
6413 """
6414 if arg < 0:
6415 arg += len(self)
6416 if arg < 0 or arg >= len(self):
6417 raise IndexError
6418 return self.get(arg)
6419
6420 def assert_exprs(self, *args):
6421 """Assert constraints into the goal.
6422
6423 >>> x = Int('x')
6424 >>> g = Goal()
6425 >>> g.assert_exprs(x > 0, x < 2)
6426 >>> g
6427 [x > 0, x < 2]
6428 """
6429 args = _get_args(args)
6430 s = BoolSort(self.ctx)
6431 for arg in args:
6432 arg = s.cast(arg)
6433 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
6434
6435 def append(self, *args):
6436 """Add constraints.
6437
6438 >>> x = Int('x')
6439 >>> g = Goal()
6440 >>> g.append(x > 0, x < 2)
6441 >>> g
6442 [x > 0, x < 2]
6443 """
6444 self.assert_exprs(*args)
6445
6446 def insert(self, *args):
6447 """Add constraints.
6448
6449 >>> x = Int('x')
6450 >>> g = Goal()
6451 >>> g.insert(x > 0, x < 2)
6452 >>> g
6453 [x > 0, x < 2]
6454 """
6455 self.assert_exprs(*args)
6456
6457 def add(self, *args):
6458 """Add constraints.
6459
6460 >>> x = Int('x')
6461 >>> g = Goal()
6462 >>> g.add(x > 0, x < 2)
6463 >>> g
6464 [x > 0, x < 2]
6465 """
6466 self.assert_exprs(*args)
6467
6468 def convert_model(self, model):
6469 """Retrieve model from a satisfiable goal
6470 >>> a, b = Ints('a b')
6471 >>> g = Goal()
6472 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
6473 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
6474 >>> r = t(g)
6475 >>> r[0]
6476 [Or(b == 0, b == 1), Not(0 <= b)]
6477 >>> r[1]
6478 [Or(b == 0, b == 1), Not(1 <= b)]
6479 >>> # Remark: the subgoal r[0] is unsatisfiable
6480 >>> # Creating a solver for solving the second subgoal
6481 >>> s = Solver()
6482 >>> s.add(r[1])
6483 >>> s.check()
6484 sat
6485 >>> s.model()
6486 [b = 0]
6487 >>> # Model s.model() does not assign a value to `a`
6488 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
6489 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
6490 >>> r[1].convert_model(s.model())
6491 [b = 0, a = 1]
6492 """
6493 if z3_debug():
6494 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
6495 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
6496
6497 def __repr__(self):
6498 return obj_to_string(self)
6499
6500 def sexpr(self):
6501 """Return a textual representation of the s-expression representing the goal."""
6502 return Z3_goal_to_string(self.ctx.ref(), self.goal)
6503
6504 def dimacs(self, include_names=True):
6505 """Return a textual representation of the goal in DIMACS format."""
6506 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
6507
6508 def translate(self, target):
6509 """Copy goal `self` to context `target`.
6510
6511 >>> x = Int('x')
6512 >>> g = Goal()
6513 >>> g.add(x > 10)
6514 >>> g
6515 [x > 10]
6516 >>> c2 = Context()
6517 >>> g2 = g.translate(c2)
6518 >>> g2
6519 [x > 10]
6520 >>> g.ctx == main_ctx()
6521 True
6522 >>> g2.ctx == c2
6523 True
6524 >>> g2.ctx == main_ctx()
6525 False
6526 """
6527 if z3_debug():
6528 _z3_assert(isinstance(target, Context), "target must be a context")
6529 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
6530
6531 def __copy__(self):
6532 return self.translate(self.ctx)
6533
6534 def __deepcopy__(self, memo={}):
6535 return self.translate(self.ctx)
6536
6537 def simplify(self, *arguments, **keywords):
6538 """Return a new simplified goal.
6539
6540 This method is essentially invoking the simplify tactic.
6541
6542 >>> g = Goal()
6543 >>> x = Int('x')
6544 >>> g.add(x + 1 >= 2)
6545 >>> g
6546 [x + 1 >= 2]
6547 >>> g2 = g.simplify()
6548 >>> g2
6549 [x >= 1]
6550 >>> # g was not modified
6551 >>> g
6552 [x + 1 >= 2]
6553 """
6554 t = Tactic("simplify")
6555 return t.apply(self, *arguments, **keywords)[0]
6556
6557 def as_expr(self):
6558 """Return goal `self` as a single Z3 expression.
6559
6560 >>> x = Int('x')
6561 >>> g = Goal()
6562 >>> g.as_expr()
6563 True
6564 >>> g.add(x > 1)
6565 >>> g.as_expr()
6566 x > 1
6567 >>> g.add(x < 10)
6568 >>> g.as_expr()
6569 And(x > 1, x < 10)
6570 """
6571 sz = len(self)
6572 if sz == 0:
6573 return BoolVal(True, self.ctx)
6574 elif sz == 1:
6575 return self.get(0)
6576 else:
6577 return And([self.get(i) for i in range(len(self))], self.ctx)
6578
6579
6584
6585
6587 """A collection (vector) of ASTs."""
6588
6589 def __init__(self, v=None, ctx=None):
6590 self.vector = None
6591 if v is None:
6592 self.ctx = _get_ctx(ctx)
6593 self.vector = Z3_mk_ast_vector(self.ctx.ref())
6594 else:
6595 self.vector = v
6596 assert ctx is not None
6597 self.ctx = ctx
6598 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
6599
6600 def __del__(self):
6601 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
6602 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
6603
6604 def __len__(self):
6605 """Return the size of the vector `self`.
6606
6607 >>> A = AstVector()
6608 >>> len(A)
6609 0
6610 >>> A.push(Int('x'))
6611 >>> A.push(Int('x'))
6612 >>> len(A)
6613 2
6614 """
6615 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
6616
6617 def __getitem__(self, i):
6618 """Return the AST at position `i`.
6619
6620 >>> A = AstVector()
6621 >>> A.push(Int('x') + 1)
6622 >>> A.push(Int('y'))
6623 >>> A[0]
6624 x + 1
6625 >>> A[1]
6626 y
6627 >>> ctx = Context()
6628 >>> A = AstVector(ctx=ctx)
6629 >>> sorts = [BoolSort(ctx), IntSort(ctx), RealSort(ctx), BitVecSort(8, ctx),
6630 ... ArraySort(IntSort(ctx), BoolSort(ctx)), DeclareSort('S', ctx)]
6631 >>> for s in sorts: A.push(s)
6632 >>> all(isinstance(A[i], type(s)) and A[i].eq(s)
6633 ... for i, s in enumerate(sorts))
6634 True
6635 >>> A[-1].eq(sorts[-1])
6636 True
6637 >>> all(a.eq(s) for a, s in zip(A[:], sorts))
6638 True
6639 >>> A.push(Int('z', ctx))
6640 >>> A.push(Function('f', IntSort(ctx), IntSort(ctx)))
6641 >>> is_func_decl(A[-1])
6642 True
6643 >>> [is_expr(a) for a in A]
6644 [False, False, False, False, False, False, True, False]
6645 >>> ctx = Context()
6646 >>> B = A.translate(ctx)
6647 >>> all(B[i].eq(s.translate(ctx)) for i, s in enumerate(sorts))
6648 True
6649 """
6650
6651 if isinstance(i, int):
6652 if i < 0:
6653 i += self.__len__()
6654
6655 if i >= self.__len__():
6656 raise IndexError
6657 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
6658
6659 elif isinstance(i, slice):
6660 result = []
6661 for ii in range(*i.indices(self.__len__())):
6662 result.append(_to_ast_ref(
6663 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6664 self.ctx,
6665 ))
6666 return result
6667
6668 def __setitem__(self, i, v):
6669 """Update AST at position `i`.
6670
6671 >>> A = AstVector()
6672 >>> A.push(Int('x') + 1)
6673 >>> A.push(Int('y'))
6674 >>> A[0]
6675 x + 1
6676 >>> A[0] = Int('x')
6677 >>> A[0]
6678 x
6679 """
6680 if i < 0:
6681 i += self.__len__()
6682 if i < 0 or i >= self.__len__():
6683 raise IndexError
6684 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6685
6686 def push(self, v):
6687 """Add `v` in the end of the vector.
6688
6689 >>> A = AstVector()
6690 >>> len(A)
6691 0
6692 >>> A.push(Int('x'))
6693 >>> len(A)
6694 1
6695 """
6696 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6697
6698 def resize(self, sz):
6699 """Resize the vector to `sz` elements.
6700
6701 >>> A = AstVector()
6702 >>> A.resize(10)
6703 >>> len(A)
6704 10
6705 >>> for i in range(10): A[i] = Int('x')
6706 >>> A[5]
6707 x
6708 """
6709 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6710
6711 def __contains__(self, item):
6712 """Return `True` if the vector contains `item`.
6713
6714 >>> x = Int('x')
6715 >>> A = AstVector()
6716 >>> x in A
6717 False
6718 >>> A.push(x)
6719 >>> x in A
6720 True
6721 >>> (x+1) in A
6722 False
6723 >>> A.push(x+1)
6724 >>> (x+1) in A
6725 True
6726 >>> A
6727 [x, x + 1]
6728 """
6729 for elem in self:
6730 if elem.eq(item):
6731 return True
6732 return False
6733
6734 def translate(self, other_ctx):
6735 """Copy vector `self` to context `other_ctx`.
6736
6737 >>> x = Int('x')
6738 >>> A = AstVector()
6739 >>> A.push(x)
6740 >>> c2 = Context()
6741 >>> B = A.translate(c2)
6742 >>> B
6743 [x]
6744 """
6745 return AstVector(
6746 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6747 ctx=other_ctx,
6748 )
6749
6750 def __copy__(self):
6751 return self.translate(self.ctx)
6752
6753 def __deepcopy__(self, memo={}):
6754 return self.translate(self.ctx)
6755
6756 def __repr__(self):
6757 return obj_to_string(self)
6758
6759 def sexpr(self):
6760 """Return a textual representation of the s-expression representing the vector."""
6761 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6762
6763
6768
6769
6771 """A mapping from ASTs to ASTs."""
6772
6773 def __init__(self, m=None, ctx=None):
6774 self.map = None
6775 if m is None:
6776 self.ctx = _get_ctx(ctx)
6777 self.map = Z3_mk_ast_map(self.ctx.ref())
6778 else:
6779 self.map = m
6780 assert ctx is not None
6781 self.ctx = ctx
6782 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6783
6784 def __deepcopy__(self, memo={}):
6785 return AstMap(self.map, self.ctx)
6786
6787 def __del__(self):
6788 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6789 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6790
6791 def __len__(self):
6792 """Return the size of the map.
6793
6794 >>> M = AstMap()
6795 >>> len(M)
6796 0
6797 >>> x = Int('x')
6798 >>> M[x] = IntVal(1)
6799 >>> len(M)
6800 1
6801 """
6802 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6803
6804 def __contains__(self, key):
6805 """Return `True` if the map contains key `key`.
6806
6807 >>> M = AstMap()
6808 >>> x = Int('x')
6809 >>> M[x] = x + 1
6810 >>> x in M
6811 True
6812 >>> x+1 in M
6813 False
6814 """
6815 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6816
6817 def __getitem__(self, key):
6818 """Retrieve the value associated with key `key`.
6819
6820 >>> M = AstMap()
6821 >>> x = Int('x')
6822 >>> M[x] = x + 1
6823 >>> M[x]
6824 x + 1
6825 """
6826 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6827
6828 def __setitem__(self, k, v):
6829 """Add/Update key `k` with value `v`.
6830
6831 >>> M = AstMap()
6832 >>> x = Int('x')
6833 >>> M[x] = x + 1
6834 >>> len(M)
6835 1
6836 >>> M[x]
6837 x + 1
6838 >>> M[x] = IntVal(1)
6839 >>> M[x]
6840 1
6841 """
6842 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6843
6844 def __repr__(self):
6845 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6846
6847 def erase(self, k):
6848 """Remove the entry associated with key `k`.
6849
6850 >>> M = AstMap()
6851 >>> x = Int('x')
6852 >>> M[x] = x + 1
6853 >>> len(M)
6854 1
6855 >>> M.erase(x)
6856 >>> len(M)
6857 0
6858 """
6859 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6860
6861 def reset(self):
6862 """Remove all entries from the map.
6863
6864 >>> M = AstMap()
6865 >>> x = Int('x')
6866 >>> M[x] = x + 1
6867 >>> M[x+x] = IntVal(1)
6868 >>> len(M)
6869 2
6870 >>> M.reset()
6871 >>> len(M)
6872 0
6873 """
6874 Z3_ast_map_reset(self.ctx.ref(), self.map)
6875
6876 def keys(self):
6877 """Return an AstVector containing all keys in the map.
6878
6879 >>> M = AstMap()
6880 >>> x = Int('x')
6881 >>> M[x] = x + 1
6882 >>> M[x+x] = IntVal(1)
6883 >>> M.keys()
6884 [x + x, x]
6885 """
6886 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6887
6888
6893
6894
6896 """Store the value of the interpretation of a function in a particular point."""
6897
6898 def __init__(self, entry, ctx):
6899 self.entry = entry
6900 self.ctx = ctx
6901 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6902
6903 def __deepcopy__(self, memo={}):
6904 return FuncEntry(self.entry, self.ctx)
6905
6906 def __del__(self):
6907 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6908 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6909
6910 def num_args(self):
6911 """Return the number of arguments in the given entry.
6912
6913 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6914 >>> s = Solver()
6915 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6916 >>> s.check()
6917 sat
6918 >>> m = s.model()
6919 >>> f_i = m[f]
6920 >>> f_i.num_entries()
6921 1
6922 >>> e = f_i.entry(0)
6923 >>> e.num_args()
6924 2
6925 """
6926 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6927
6928 def arg_value(self, idx):
6929 """Return the value of argument `idx`.
6930
6931 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6932 >>> s = Solver()
6933 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6934 >>> s.check()
6935 sat
6936 >>> m = s.model()
6937 >>> f_i = m[f]
6938 >>> f_i.num_entries()
6939 1
6940 >>> e = f_i.entry(0)
6941 >>> e
6942 [1, 2, 20]
6943 >>> e.num_args()
6944 2
6945 >>> e.arg_value(0)
6946 1
6947 >>> e.arg_value(1)
6948 2
6949 >>> try:
6950 ... e.arg_value(2)
6951 ... except IndexError:
6952 ... print("index error")
6953 index error
6954 """
6955 if idx >= self.num_args():
6956 raise IndexError
6957 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6958
6959 def value(self):
6960 """Return the value of the function at point `self`.
6961
6962 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6963 >>> s = Solver()
6964 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6965 >>> s.check()
6966 sat
6967 >>> m = s.model()
6968 >>> f_i = m[f]
6969 >>> f_i.num_entries()
6970 1
6971 >>> e = f_i.entry(0)
6972 >>> e
6973 [1, 2, 20]
6974 >>> e.num_args()
6975 2
6976 >>> e.value()
6977 20
6978 """
6979 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6980
6981 def as_list(self):
6982 """Return entry `self` as a Python list.
6983 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6984 >>> s = Solver()
6985 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6986 >>> s.check()
6987 sat
6988 >>> m = s.model()
6989 >>> f_i = m[f]
6990 >>> f_i.num_entries()
6991 1
6992 >>> e = f_i.entry(0)
6993 >>> e.as_list()
6994 [1, 2, 20]
6995 """
6996 args = [self.arg_value(i) for i in range(self.num_args())]
6997 args.append(self.value())
6998 return args
6999
7000 def __repr__(self):
7001 return repr(self.as_list())
7002
7003
7005 """Stores the interpretation of a function in a Z3 model."""
7006
7007 def __init__(self, f, ctx):
7008 self.f = f
7009 self.ctx = ctx
7010 if self.f is not None:
7011 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
7012
7013 def __del__(self):
7014 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
7015 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
7016
7017 def else_value(self):
7018 """
7019 Return the `else` value for a function interpretation.
7020 Return None if Z3 did not specify the `else` value for
7021 this object.
7022
7023 >>> f = Function('f', IntSort(), IntSort())
7024 >>> s = Solver()
7025 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
7026 >>> s.check()
7027 sat
7028 >>> m = s.model()
7029 >>> m[f]
7030 [2 -> 0, else -> 1]
7031 >>> m[f].else_value()
7032 1
7033 """
7034 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
7035 if r:
7036 return _to_expr_ref(r, self.ctx)
7037 else:
7038 return None
7039
7040 def num_entries(self):
7041 """Return the number of entries/points in the function interpretation `self`.
7042
7043 >>> f = Function('f', IntSort(), IntSort())
7044 >>> s = Solver()
7045 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
7046 >>> s.check()
7047 sat
7048 >>> m = s.model()
7049 >>> m[f]
7050 [2 -> 0, else -> 1]
7051 >>> m[f].num_entries()
7052 1
7053 """
7054 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
7055
7056 def arity(self):
7057 """Return the number of arguments for each entry in the function interpretation `self`.
7058
7059 >>> f = Function('f', IntSort(), IntSort())
7060 >>> s = Solver()
7061 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
7062 >>> s.check()
7063 sat
7064 >>> m = s.model()
7065 >>> m[f].arity()
7066 1
7067 """
7068 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
7069
7070 def entry(self, idx):
7071 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
7072
7073 >>> f = Function('f', IntSort(), IntSort())
7074 >>> s = Solver()
7075 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
7076 >>> s.check()
7077 sat
7078 >>> m = s.model()
7079 >>> m[f]
7080 [2 -> 0, else -> 1]
7081 >>> m[f].num_entries()
7082 1
7083 >>> m[f].entry(0)
7084 [2, 0]
7085 """
7086 if idx >= self.num_entries():
7087 raise IndexError
7088 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
7089
7090 def translate(self, other_ctx):
7091 """Copy model 'self' to context 'other_ctx'.
7092 """
7093 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
7094
7095 def __copy__(self):
7096 return self.translate(self.ctx)
7097
7098 def __deepcopy__(self, memo={}):
7099 return self.translate(self.ctx)
7100
7101 def as_list(self):
7102 """Return the function interpretation as a Python list.
7103 >>> f = Function('f', IntSort(), IntSort())
7104 >>> s = Solver()
7105 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
7106 >>> s.check()
7107 sat
7108 >>> m = s.model()
7109 >>> m[f]
7110 [2 -> 0, else -> 1]
7111 >>> m[f].as_list()
7112 [[2, 0], 1]
7113 """
7114 r = [self.entry(i).as_list() for i in range(self.num_entries())]
7115 r.append(self.else_value())
7116 return r
7117
7118 def __repr__(self):
7119 return obj_to_string(self)
7120
7121
7123 """Model/Solution of a satisfiability problem (aka system of constraints)."""
7124
7125 def __init__(self, m, ctx):
7126 assert ctx is not None
7127 self.model = m
7128 self.ctx = ctx
7129 Z3_model_inc_ref(self.ctx.ref(), self.model)
7130
7131 def __del__(self):
7132 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
7133 Z3_model_dec_ref(self.ctx.ref(), self.model)
7134
7135 def __repr__(self):
7136 return obj_to_string(self)
7137
7138 def sexpr(self):
7139 """Return a textual representation of the s-expression representing the model."""
7140 return Z3_model_to_string(self.ctx.ref(), self.model)
7141
7142 def eval(self, t, model_completion=False):
7143 """Evaluate the expression `t` in the model `self`.
7144 If `model_completion` is enabled, then a default interpretation is automatically added
7145 for symbols that do not have an interpretation in the model `self`.
7146
7147 >>> x = Int('x')
7148 >>> s = Solver()
7149 >>> s.add(x > 0, x < 2)
7150 >>> s.check()
7151 sat
7152 >>> m = s.model()
7153 >>> m.eval(x + 1)
7154 2
7155 >>> m.eval(x == 1)
7156 True
7157 >>> y = Int('y')
7158 >>> m.eval(y + x)
7159 1 + y
7160 >>> m.eval(y)
7161 y
7162 >>> m.eval(y, model_completion=True)
7163 0
7164 >>> # Now, m contains an interpretation for y
7165 >>> m.eval(y + x)
7166 1
7167 """
7168 r = (Ast * 1)()
7169 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
7170 return _to_expr_ref(r[0], self.ctx)
7171 raise Z3Exception("failed to evaluate expression in the model")
7172
7173 def evaluate(self, t, model_completion=False):
7174 """Alias for `eval`.
7175
7176 >>> x = Int('x')
7177 >>> s = Solver()
7178 >>> s.add(x > 0, x < 2)
7179 >>> s.check()
7180 sat
7181 >>> m = s.model()
7182 >>> m.evaluate(x + 1)
7183 2
7184 >>> m.evaluate(x == 1)
7185 True
7186 >>> y = Int('y')
7187 >>> m.evaluate(y + x)
7188 1 + y
7189 >>> m.evaluate(y)
7190 y
7191 >>> m.evaluate(y, model_completion=True)
7192 0
7193 >>> # Now, m contains an interpretation for y
7194 >>> m.evaluate(y + x)
7195 1
7196 """
7197 return self.eval(t, model_completion)
7198
7199 def __len__(self):
7200 """Return the number of constant and function declarations in the model `self`.
7201
7202 >>> f = Function('f', IntSort(), IntSort())
7203 >>> x = Int('x')
7204 >>> s = Solver()
7205 >>> s.add(x > 0, f(x) != x)
7206 >>> s.check()
7207 sat
7208 >>> m = s.model()
7209 >>> len(m)
7210 2
7211 """
7212 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
7213 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
7214 return num_consts + num_funcs
7215
7216 def get_interp(self, decl):
7217 """Return the interpretation for a given declaration or constant.
7218
7219 >>> f = Function('f', IntSort(), IntSort())
7220 >>> x = Int('x')
7221 >>> s = Solver()
7222 >>> s.add(x > 0, x < 2, f(x) == 0)
7223 >>> s.check()
7224 sat
7225 >>> m = s.model()
7226 >>> m[x]
7227 1
7228 >>> m[f]
7229 [else -> 0]
7230 """
7231 if z3_debug():
7232 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
7233 if is_const(decl):
7234 decl = decl.decl()
7235 try:
7236 if decl.arity() == 0:
7237 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
7238 if _r.value is None:
7239 return None
7240 r = _to_expr_ref(_r, self.ctx)
7241 if is_as_array(r):
7242 fi = self.get_interp(get_as_array_func(r))
7243 if fi is None:
7244 return fi
7245 e = fi.else_value()
7246 if e is None:
7247 return fi
7248 if fi.arity() != 1:
7249 return fi
7250 srt = decl.range()
7251 dom = srt.domain()
7252 e = K(dom, e)
7253 i = 0
7254 sz = fi.num_entries()
7255 n = fi.arity()
7256 while i < sz:
7257 fe = fi.entry(i)
7258 e = Store(e, fe.arg_value(0), fe.value())
7259 i += 1
7260 return e
7261 else:
7262 return r
7263 else:
7264 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
7265 except Z3Exception:
7266 return None
7267
7268 def num_sorts(self):
7269 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
7270
7271 >>> A = DeclareSort('A')
7272 >>> a, b = Consts('a b', A)
7273 >>> s = Solver()
7274 >>> s.add(a != b)
7275 >>> s.check()
7276 sat
7277 >>> m = s.model()
7278 >>> m.num_sorts()
7279 1
7280 """
7281 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
7282
7283 def get_sort(self, idx):
7284 """Return the uninterpreted sort at position `idx` < self.num_sorts().
7285
7286 >>> A = DeclareSort('A')
7287 >>> B = DeclareSort('B')
7288 >>> a1, a2 = Consts('a1 a2', A)
7289 >>> b1, b2 = Consts('b1 b2', B)
7290 >>> s = Solver()
7291 >>> s.add(a1 != a2, b1 != b2)
7292 >>> s.check()
7293 sat
7294 >>> m = s.model()
7295 >>> m.num_sorts()
7296 2
7297 >>> m.get_sort(0)
7298 A
7299 >>> m.get_sort(1)
7300 B
7301 """
7302 if idx >= self.num_sorts():
7303 raise IndexError
7304 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
7305
7306 def sorts(self):
7307 """Return all uninterpreted sorts that have an interpretation in the model `self`.
7308
7309 >>> A = DeclareSort('A')
7310 >>> B = DeclareSort('B')
7311 >>> a1, a2 = Consts('a1 a2', A)
7312 >>> b1, b2 = Consts('b1 b2', B)
7313 >>> s = Solver()
7314 >>> s.add(a1 != a2, b1 != b2)
7315 >>> s.check()
7316 sat
7317 >>> m = s.model()
7318 >>> m.sorts()
7319 [A, B]
7320 """
7321 return [self.get_sort(i) for i in range(self.num_sorts())]
7322
7323 def get_universe(self, s):
7324 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
7325
7326 >>> A = DeclareSort('A')
7327 >>> a, b = Consts('a b', A)
7328 >>> s = Solver()
7329 >>> s.add(a != b)
7330 >>> s.check()
7331 sat
7332 >>> m = s.model()
7333 >>> m.get_universe(A)
7334 [A!val!0, A!val!1]
7335 """
7336 if z3_debug():
7337 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
7338 try:
7339 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
7340 except Z3Exception:
7341 return None
7342
7343 def __getitem__(self, idx):
7344 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
7345 If `idx` is a declaration, then the actual interpretation is returned.
7346
7347 The elements can be retrieved using position or the actual declaration.
7348
7349 >>> f = Function('f', IntSort(), IntSort())
7350 >>> x = Int('x')
7351 >>> s = Solver()
7352 >>> s.add(x > 0, x < 2, f(x) == 0)
7353 >>> s.check()
7354 sat
7355 >>> m = s.model()
7356 >>> len(m)
7357 2
7358 >>> m[0]
7359 x
7360 >>> m[1]
7361 f
7362 >>> m[x]
7363 1
7364 >>> m[f]
7365 [else -> 0]
7366 >>> for d in m: print("%s -> %s" % (d, m[d]))
7367 x -> 1
7368 f -> [else -> 0]
7369 """
7370 if _is_int(idx):
7371 if idx < 0:
7372 idx += len(self)
7373 if idx < 0 or idx >= len(self):
7374 raise IndexError
7375 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
7376 if (idx < num_consts):
7377 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
7378 else:
7379 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
7380 if isinstance(idx, FuncDeclRef):
7381 return self.get_interp(idx)
7382 if is_const(idx):
7383 return self.get_interp(idx.decl())
7384 if isinstance(idx, SortRef):
7385 return self.get_universe(idx)
7386 if z3_debug():
7387 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected. Use model.eval instead for complicated expressions")
7388 return None
7389
7390 def decls(self):
7391 """Return a list with all symbols that have an interpretation in the model `self`.
7392 >>> f = Function('f', IntSort(), IntSort())
7393 >>> x = Int('x')
7394 >>> s = Solver()
7395 >>> s.add(x > 0, x < 2, f(x) == 0)
7396 >>> s.check()
7397 sat
7398 >>> m = s.model()
7399 >>> m.decls()
7400 [x, f]
7401 """
7402 r = []
7403 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
7404 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
7405 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
7406 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
7407 return r
7408
7409 def update_value(self, x, value):
7410 """Update the interpretation of a constant"""
7411 if is_expr(x):
7412 x = x.decl()
7413 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
7414 fi1 = value.f
7415 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
7416 fi2 = FuncInterp(fi2, x.ctx)
7417 for i in range(value.num_entries()):
7418 e = value.entry(i)
7419 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
7420 v = AstVector()
7421 for j in range(n):
7422 v.push(e.arg_value(j))
7423 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
7424 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
7425 return
7426 if not is_func_decl(x) or x.arity() != 0:
7427 raise Z3Exception("Expecting 0-ary function or constant expression")
7428 value = _py2expr(value)
7429 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
7430
7431 def translate(self, target):
7432 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7433 """
7434 if z3_debug():
7435 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7436 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
7437 return ModelRef(model, target)
7438
7439 def project(self, vars, fml):
7440 """Perform model-based projection on fml with respect to vars.
7441 Assume that the model satisfies fml. Then compute a projection fml_p, such
7442 that vars do not occur free in fml_p, fml_p is true in the model and
7443 fml_p => exists vars . fml
7444 """
7445 ctx = self.ctx.ref()
7446 _vars = (Ast * len(vars))()
7447 for i in range(len(vars)):
7448 _vars[i] = vars[i].as_ast()
7449 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
7450
7451 def project_with_witness(self, vars, fml):
7452 """Perform model-based projection, but also include realizer terms for the projected variables"""
7453 ctx = self.ctx.ref()
7454 _vars = (Ast * len(vars))()
7455 for i in range(len(vars)):
7456 _vars[i] = vars[i].as_ast()
7457 defs = AstMap()
7458 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
7459 result = _to_expr_ref(result, self.ctx)
7460 return result, defs
7461
7462
7463 def __copy__(self):
7464 return self.translate(self.ctx)
7465
7466 def __deepcopy__(self, memo={}):
7467 return self.translate(self.ctx)
7468
7469
7470def Model(ctx=None, eval = {}):
7471 ctx = _get_ctx(ctx)
7472 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
7473 for k, v in eval.items():
7474 mdl.update_value(k, v)
7475 return mdl
7476
7477
7479 """Return true if n is a Z3 expression of the form (_ as-array f)."""
7480 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
7481
7482
7484 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
7485 if z3_debug():
7486 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
7487 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
7488
7489
7494
7495
7497 """Statistics for `Solver.check()`."""
7498
7499 def __init__(self, stats, ctx):
7500 self.stats = stats
7501 self.ctx = ctx
7502 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
7503
7504 def __deepcopy__(self, memo={}):
7505 return Statistics(self.stats, self.ctx)
7506
7507 def __del__(self):
7508 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
7509 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
7510
7511 def __repr__(self):
7512 if in_html_mode():
7513 out = io.StringIO()
7514 even = True
7515 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
7516 for k, v in self:
7517 if even:
7518 out.write(u('<tr style="background-color:#CFCFCF">'))
7519 even = False
7520 else:
7521 out.write(u("<tr>"))
7522 even = True
7523 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
7524 out.write(u("</table>"))
7525 return out.getvalue()
7526 else:
7527 return Z3_stats_to_string(self.ctx.ref(), self.stats)
7528
7529 def __len__(self):
7530 """Return the number of statistical counters.
7531
7532 >>> x = Int('x')
7533 >>> s = Then('simplify', 'nlsat').solver()
7534 >>> s.add(x > 0)
7535 >>> s.check()
7536 sat
7537 >>> st = s.statistics()
7538 >>> len(st) > 0
7539 True
7540 """
7541 return int(Z3_stats_size(self.ctx.ref(), self.stats))
7542
7543 def __getitem__(self, idx):
7544 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
7545
7546 >>> x = Int('x')
7547 >>> s = Then('simplify', 'nlsat').solver()
7548 >>> s.add(x > 0)
7549 >>> s.check()
7550 sat
7551 >>> st = s.statistics()
7552 >>> len(st) > 0
7553 True
7554 >>> st[0]
7555 ('nlsat propagations', 2)
7556 >>> st[1]
7557 ('nlsat restarts', 1)
7558 """
7559 if idx >= len(self):
7560 raise IndexError
7561 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7562 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7563 else:
7564 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7565 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
7566
7567 def keys(self):
7568 """Return the list of statistical counters.
7569
7570 >>> x = Int('x')
7571 >>> s = Then('simplify', 'nlsat').solver()
7572 >>> s.add(x > 0)
7573 >>> s.check()
7574 sat
7575 >>> st = s.statistics()
7576 """
7577 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
7578
7579 def get_key_value(self, key):
7580 """Return the value of a particular statistical counter.
7581
7582 >>> x = Int('x')
7583 >>> s = Then('simplify', 'nlsat').solver()
7584 >>> s.add(x > 0)
7585 >>> s.check()
7586 sat
7587 >>> st = s.statistics()
7588 >>> st.get_key_value('nlsat propagations')
7589 2
7590 """
7591 for idx in range(len(self)):
7592 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
7593 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7594 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7595 else:
7596 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7597 raise Z3Exception("unknown key")
7598
7599 def __getattr__(self, name):
7600 """Access the value of statistical using attributes.
7601
7602 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
7603 we should use '_' (e.g., 'nlsat_propagations').
7604
7605 >>> x = Int('x')
7606 >>> s = Then('simplify', 'nlsat').solver()
7607 >>> s.add(x > 0)
7608 >>> s.check()
7609 sat
7610 >>> st = s.statistics()
7611 >>> st.nlsat_propagations
7612 2
7613 >>> st.nlsat_stages
7614 2
7615 """
7616 key = name.replace("_", " ")
7617 try:
7618 return self.get_key_value(key)
7619 except Z3Exception:
7620 raise AttributeError
7621
7622
7627
7628
7630 """Represents the result of a satisfiability check: sat, unsat, unknown.
7631
7632 >>> s = Solver()
7633 >>> s.check()
7634 sat
7635 >>> r = s.check()
7636 >>> isinstance(r, CheckSatResult)
7637 True
7638 """
7639
7640 def __init__(self, r):
7641 self.r = r
7642
7643 def __deepcopy__(self, memo={}):
7644 return CheckSatResult(self.r)
7645
7646 def __eq__(self, other):
7647 return isinstance(other, CheckSatResult) and self.r == other.r
7648
7649 def __ne__(self, other):
7650 return not self.__eq__(other)
7651
7652 def __repr__(self):
7653 if in_html_mode():
7654 if self.r == Z3_L_TRUE:
7655 return "<b>sat</b>"
7656 elif self.r == Z3_L_FALSE:
7657 return "<b>unsat</b>"
7658 else:
7659 return "<b>unknown</b>"
7660 else:
7661 if self.r == Z3_L_TRUE:
7662 return "sat"
7663 elif self.r == Z3_L_FALSE:
7664 return "unsat"
7665 else:
7666 return "unknown"
7667
7668 def _repr_html_(self):
7669 in_html = in_html_mode()
7670 set_html_mode(True)
7671 res = repr(self)
7672 set_html_mode(in_html)
7673 return res
7674
7675
7676sat = CheckSatResult(Z3_L_TRUE)
7677unsat = CheckSatResult(Z3_L_FALSE)
7678unknown = CheckSatResult(Z3_L_UNDEF)
7679
7680
7682 """
7683 Solver API provides methods for implementing the main SMT 2.0 commands:
7684 push, pop, check, get-model, etc.
7685 """
7686
7687 def __init__(self, solver=None, ctx=None, logFile=None):
7688 assert solver is None or ctx is not None
7689 self.ctx = _get_ctx(ctx)
7690 self.backtrack_level = 4000000000
7691 self.solver = None
7692 if solver is None:
7693 self.solver = Z3_mk_solver(self.ctx.ref())
7694 else:
7695 self.solver = solver
7696 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7697 if logFile is not None:
7698 self.set("smtlib2_log", logFile)
7699
7700 def __del__(self):
7701 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7702 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7703
7704 def __enter__(self):
7705 self.push()
7706 return self
7707
7708 def __exit__(self, *exc_info):
7709 self.pop()
7710
7711 def set(self, *args, **keys):
7712 """Set a configuration option.
7713 The method `help()` return a string containing all available options.
7714
7715 >>> s = Solver()
7716 >>> # The option MBQI can be set using three different approaches.
7717 >>> s.set(mbqi=True)
7718 >>> s.set('MBQI', True)
7719 >>> s.set(':mbqi', True)
7720 """
7721 p = args2params(args, keys, self.ctx)
7722 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7723
7724 def push(self):
7725 """Create a backtracking point.
7726
7727 >>> x = Int('x')
7728 >>> s = Solver()
7729 >>> s.add(x > 0)
7730 >>> s
7731 [x > 0]
7732 >>> s.push()
7733 >>> s.add(x < 1)
7734 >>> s
7735 [x > 0, x < 1]
7736 >>> s.check()
7737 unsat
7738 >>> s.pop()
7739 >>> s.check()
7740 sat
7741 >>> s
7742 [x > 0]
7743 """
7744 Z3_solver_push(self.ctx.ref(), self.solver)
7745
7746 def pop(self, num=1):
7747 """Backtrack \\c num backtracking points.
7748
7749 >>> x = Int('x')
7750 >>> s = Solver()
7751 >>> s.add(x > 0)
7752 >>> s
7753 [x > 0]
7754 >>> s.push()
7755 >>> s.add(x < 1)
7756 >>> s
7757 [x > 0, x < 1]
7758 >>> s.check()
7759 unsat
7760 >>> s.pop()
7761 >>> s.check()
7762 sat
7763 >>> s
7764 [x > 0]
7765 """
7766 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7767
7768 def num_scopes(self):
7769 """Return the current number of backtracking points.
7770
7771 >>> s = Solver()
7772 >>> s.num_scopes()
7773 0
7774 >>> s.push()
7775 >>> s.num_scopes()
7776 1
7777 >>> s.push()
7778 >>> s.num_scopes()
7779 2
7780 >>> s.pop()
7781 >>> s.num_scopes()
7782 1
7783 """
7784 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7785
7786 def reset(self):
7787 """Remove all asserted constraints and backtracking points created using `push()`.
7788
7789 >>> x = Int('x')
7790 >>> s = Solver()
7791 >>> s.add(x > 0)
7792 >>> s
7793 [x > 0]
7794 >>> s.reset()
7795 >>> s
7796 []
7797 """
7798 Z3_solver_reset(self.ctx.ref(), self.solver)
7799
7800 def assert_exprs(self, *args):
7801 """Assert constraints into the solver.
7802
7803 >>> x = Int('x')
7804 >>> s = Solver()
7805 >>> s.assert_exprs(x > 0, x < 2)
7806 >>> s
7807 [x > 0, x < 2]
7808 """
7809 args = _get_args(args)
7810 s = BoolSort(self.ctx)
7811 for arg in args:
7812 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7813 for f in arg:
7814 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7815 else:
7816 arg = s.cast(arg)
7817 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7818
7819 def add(self, *args):
7820 """Assert constraints into the solver.
7821
7822 >>> x = Int('x')
7823 >>> s = Solver()
7824 >>> s.add(x > 0, x < 2)
7825 >>> s
7826 [x > 0, x < 2]
7827 """
7828 self.assert_exprs(*args)
7829
7830 def __iadd__(self, fml):
7831 self.add(fml)
7832 return self
7833
7834 def append(self, *args):
7835 """Assert constraints into the solver.
7836
7837 >>> x = Int('x')
7838 >>> s = Solver()
7839 >>> s.append(x > 0, x < 2)
7840 >>> s
7841 [x > 0, x < 2]
7842 """
7843 self.assert_exprs(*args)
7844
7845 def insert(self, *args):
7846 """Assert constraints into the solver.
7847
7848 >>> x = Int('x')
7849 >>> s = Solver()
7850 >>> s.insert(x > 0, x < 2)
7851 >>> s
7852 [x > 0, x < 2]
7853 """
7854 self.assert_exprs(*args)
7855
7856 def assert_and_track(self, a, p):
7857 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7858
7859 If `p` is a string, it will be automatically converted into a Boolean constant.
7860
7861 >>> x = Int('x')
7862 >>> p3 = Bool('p3')
7863 >>> s = Solver()
7864 >>> s.set(unsat_core=True)
7865 >>> s.assert_and_track(x > 0, 'p1')
7866 >>> s.assert_and_track(x != 1, 'p2')
7867 >>> s.assert_and_track(x < 0, p3)
7868 >>> print(s.check())
7869 unsat
7870 >>> c = s.unsat_core()
7871 >>> len(c)
7872 2
7873 >>> Bool('p1') in c
7874 True
7875 >>> Bool('p2') in c
7876 False
7877 >>> p3 in c
7878 True
7879 """
7880 if isinstance(p, str):
7881 p = Bool(p, self.ctx)
7882 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7883 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7884 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7885
7886 def check(self, *assumptions):
7887 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7888
7889 >>> x = Int('x')
7890 >>> s = Solver()
7891 >>> s.check()
7892 sat
7893 >>> s.add(x > 0, x < 2)
7894 >>> s.check()
7895 sat
7896 >>> s.model().eval(x)
7897 1
7898 >>> s.add(x < 1)
7899 >>> s.check()
7900 unsat
7901 >>> s.reset()
7902 >>> s.add(2**x == 4)
7903 >>> s.check()
7904 sat
7905 """
7906 s = BoolSort(self.ctx)
7907 assumptions = _get_args(assumptions)
7908 num = len(assumptions)
7909 _assumptions = (Ast * num)()
7910 for i in range(num):
7911 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7912 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7913 return CheckSatResult(r)
7914
7915 def model(self):
7916 """Return a model for the last `check()`.
7917
7918 This function raises an exception if
7919 a model is not available (e.g., last `check()` returned unsat).
7920
7921 >>> s = Solver()
7922 >>> a = Int('a')
7923 >>> s.add(a + 2 == 0)
7924 >>> s.check()
7925 sat
7926 >>> s.model()
7927 [a = -2]
7928 """
7929 try:
7930 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7931 except Z3Exception:
7932 raise Z3Exception("model is not available")
7933
7934 def import_model_converter(self, other):
7935 """Import model converter from other into the current solver"""
7936 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7937
7938 def interrupt(self):
7939 """Interrupt the execution of the solver object.
7940 Remarks: This ensures that the interrupt applies only
7941 to the given solver object and it applies only if it is running.
7942 """
7943 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7944
7945 def unsat_core(self):
7946 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7947
7948 These are the assumptions Z3 used in the unsatisfiability proof.
7949 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7950 They may be also used to "retract" assumptions. Note that, assumptions are not really
7951 "soft constraints", but they can be used to implement them.
7952
7953 >>> p1, p2, p3 = Bools('p1 p2 p3')
7954 >>> x, y = Ints('x y')
7955 >>> s = Solver()
7956 >>> s.add(Implies(p1, x > 0))
7957 >>> s.add(Implies(p2, y > x))
7958 >>> s.add(Implies(p2, y < 1))
7959 >>> s.add(Implies(p3, y > -3))
7960 >>> s.check(p1, p2, p3)
7961 unsat
7962 >>> core = s.unsat_core()
7963 >>> len(core)
7964 2
7965 >>> p1 in core
7966 True
7967 >>> p2 in core
7968 True
7969 >>> p3 in core
7970 False
7971 >>> # "Retracting" p2
7972 >>> s.check(p1, p3)
7973 sat
7974 """
7975 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7976
7977 def consequences(self, assumptions, variables):
7978 """Determine fixed values for the variables based on the solver state and assumptions.
7979 >>> s = Solver()
7980 >>> a, b, c, d = Bools('a b c d')
7981 >>> s.add(Implies(a,b), Implies(b, c))
7982 >>> s.consequences([a],[b,c,d])
7983 (sat, [Implies(a, b), Implies(a, c)])
7984 >>> s.consequences([Not(c),d],[a,b,c,d])
7985 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7986 """
7987 if isinstance(assumptions, list):
7988 _asms = AstVector(None, self.ctx)
7989 for a in assumptions:
7990 _asms.push(a)
7991 assumptions = _asms
7992 if isinstance(variables, list):
7993 _vars = AstVector(None, self.ctx)
7994 for a in variables:
7995 _vars.push(a)
7996 variables = _vars
7997 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7998 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7999 consequences = AstVector(None, self.ctx)
8000 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
8001 variables.vector, consequences.vector)
8002 sz = len(consequences)
8003 consequences = [consequences[i] for i in range(sz)]
8004 return CheckSatResult(r), consequences
8005
8006 def from_file(self, filename):
8007 """Parse assertions from a file"""
8008 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
8009
8010 def from_string(self, s):
8011 """Parse assertions from a string"""
8012 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
8013
8014 def cube(self, vars=None):
8015 """Get set of cubes
8016 The method takes an optional set of variables that restrict which
8017 variables may be used as a starting point for cubing.
8018 If vars is not None, then the first case split is based on a variable in
8019 this set.
8020 """
8021 self.cube_vs = AstVector(None, self.ctx)
8022 if vars is not None:
8023 for v in vars:
8024 self.cube_vs.push(v)
8025 while True:
8026 lvl = self.backtrack_level
8027 self.backtrack_level = 4000000000
8028 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
8029 if (len(r) == 1 and is_false(r[0])):
8030 return
8031 yield r
8032 if (len(r) == 0):
8033 return
8034
8035 def cube_vars(self):
8036 """Access the set of variables that were touched by the most recently generated cube.
8037 This set of variables can be used as a starting point for additional cubes.
8038 The idea is that variables that appear in clauses that are reduced by the most recent
8039 cube are likely more useful to cube on."""
8040 return self.cube_vs
8041
8042 def congruence_root(self, t):
8043 """Retrieve congruence closure root of the term t relative to the current search state
8044 The function primarily works for SimpleSolver. Terms and variables that are
8045 eliminated during pre-processing are not visible to the congruence closure.
8046 """
8047 t = _py2expr(t, self.ctx)
8048 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
8049
8050 def congruence_next(self, t):
8051 """Retrieve congruence closure sibling of the term t relative to the current search state
8052 The function primarily works for SimpleSolver. Terms and variables that are
8053 eliminated during pre-processing are not visible to the congruence closure.
8054 """
8055 t = _py2expr(t, self.ctx)
8056 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
8057
8058 def congruence_explain(self, a, b):
8059 """Explain congruence of a and b relative to the current search state"""
8060 a = _py2expr(a, self.ctx)
8061 b = _py2expr(b, self.ctx)
8062 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
8063
8064
8065 def solve_for(self, ts):
8066 """Retrieve a solution for t relative to linear equations maintained in the current state."""
8067 vars = AstVector(ctx=self.ctx);
8068 terms = AstVector(ctx=self.ctx);
8069 guards = AstVector(ctx=self.ctx);
8070 for t in ts:
8071 t = _py2expr(t, self.ctx)
8072 vars.push(t)
8073 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
8074 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
8075
8076
8077 def proof(self):
8078 """Return a proof for the last `check()`. Proof construction must be enabled."""
8079 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
8080
8081 def assertions(self):
8082 """Return an AST vector containing all added constraints.
8083
8084 >>> s = Solver()
8085 >>> s.assertions()
8086 []
8087 >>> a = Int('a')
8088 >>> s.add(a > 0)
8089 >>> s.add(a < 10)
8090 >>> s.assertions()
8091 [a > 0, a < 10]
8092 """
8093 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
8094
8095 def units(self):
8096 """Return an AST vector containing all currently inferred units.
8097 """
8098 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
8099
8100 def non_units(self):
8101 """Return an AST vector containing all atomic formulas in solver state that are not units.
8102 """
8103 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
8104
8105 def trail_levels(self):
8106 """Return trail and decision levels of the solver state after a check() call.
8107 """
8108 trail = self.trail()
8109 levels = (ctypes.c_uint * len(trail))()
8110 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
8111 return trail, levels
8112
8113 def set_initial_value(self, var, value):
8114 """initialize the solver's state by setting the initial value of var to value
8115 """
8116 s = var.sort()
8117 value = s.cast(value)
8118 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
8119
8120 def trail(self):
8121 """Return trail of the solver state after a check() call.
8122 """
8123 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
8124
8125 def statistics(self):
8126 """Return statistics for the last `check()`.
8127
8128 >>> s = SimpleSolver()
8129 >>> x = Int('x')
8130 >>> s.add(x > 0)
8131 >>> s.check()
8132 sat
8133 >>> st = s.statistics()
8134 >>> st.get_key_value('final checks')
8135 1
8136 >>> len(st) > 0
8137 True
8138 >>> st[0] != 0
8139 True
8140 """
8141 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
8142
8143 def reason_unknown(self):
8144 """Return a string describing why the last `check()` returned `unknown`.
8145
8146 >>> x = Int('x')
8147 >>> s = SimpleSolver()
8148 >>> s.add(x == 2**x)
8149 >>> s.check()
8150 unknown
8151 >>> s.reason_unknown()
8152 '(incomplete (theory arithmetic))'
8153 """
8154 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
8155
8156 def help(self):
8157 """Display a string describing all available options."""
8158 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
8159
8160 def param_descrs(self):
8161 """Return the parameter description set."""
8162 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
8163
8164 def __repr__(self):
8165 """Return a formatted string with all added constraints."""
8166 return obj_to_string(self)
8167
8168 def translate(self, target):
8169 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
8170
8171 >>> c1 = Context()
8172 >>> c2 = Context()
8173 >>> s1 = Solver(ctx=c1)
8174 >>> s2 = s1.translate(c2)
8175 """
8176 if z3_debug():
8177 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
8178 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
8179 return Solver(solver, target)
8180
8181 def __copy__(self):
8182 return self.translate(self.ctx)
8183
8184 def __deepcopy__(self, memo={}):
8185 return self.translate(self.ctx)
8186
8187 def sexpr(self):
8188 """Return a formatted string (in Lisp-like format) with all added constraints.
8189 """
8190 return Z3_solver_to_string(self.ctx.ref(), self.solver)
8191
8192 def dimacs(self, include_names=True):
8193 """Return a textual representation of the solver in DIMACS format."""
8194 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
8195
8196 def to_smt2(self):
8197 """return SMTLIB2 formatted benchmark for solver's assertions"""
8198 es = self.assertions()
8199 sz = len(es)
8200 sz1 = sz
8201 if sz1 > 0:
8202 sz1 -= 1
8203 v = (Ast * sz1)()
8204 for i in range(sz1):
8205 v[i] = es[i].as_ast()
8206 if sz > 0:
8207 e = es[sz1].as_ast()
8208 else:
8209 e = BoolVal(True, self.ctx).as_ast()
8210 return Z3_benchmark_to_smtlib_string(
8211 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
8212 )
8213
8214 def solutions(self, t):
8215 """Returns an iterator over solutions that satisfy the constraints.
8216
8217 The parameter `t` is an expression whose values should be returned.
8218
8219 >>> s = Solver()
8220 >>> x, y, z = Ints("x y z")
8221 >>> s.add(x * x == 4)
8222 >>> print(list(s.solutions(x)))
8223 [-2, 2]
8224 >>> s.reset()
8225 >>> s.add(x >= 0, x < 10)
8226 >>> print(list(s.solutions(x)))
8227 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8228 >>> s.reset()
8229 >>> s.add(x >= 0, y < 10, y == 2*x)
8230 >>> print(list(s.solutions([x, y])))
8231 [[0, 0], [1, 2], [2, 4], [3, 6], [4, 8]]
8232 """
8233 s = Solver()
8234 s.add(self.assertions())
8235 t = _get_args(t)
8236 if isinstance(t, (list, tuple)):
8237 while s.check() == sat:
8238 result = [s.model().eval(t_, model_completion=True) for t_ in t]
8239 yield result
8240 s.add(Or(t_ != result_ for t_, result_ in zip(t, result)))
8241 else:
8242 while s.check() == sat:
8243 result = s.model().eval(t, model_completion=True)
8244 yield result
8245 s.add(t != result)
8246
8247
8248def SolverFor(logic, ctx=None, logFile=None):
8249 """Create a solver customized for the given logic.
8250
8251 The parameter `logic` is a string. It should be contains
8252 the name of a SMT-LIB logic.
8253 See http://www.smtlib.org/ for the name of all available logics.
8254
8255 >>> s = SolverFor("QF_LIA")
8256 >>> x = Int('x')
8257 >>> s.add(x > 0)
8258 >>> s.add(x < 2)
8259 >>> s.check()
8260 sat
8261 >>> s.model()
8262 [x = 1]
8263 """
8264 ctx = _get_ctx(ctx)
8265 logic = to_symbol(logic)
8266 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
8267
8268
8269def SimpleSolver(ctx=None, logFile=None):
8270 """Return a simple general purpose solver with limited amount of preprocessing.
8271
8272 >>> s = SimpleSolver()
8273 >>> x = Int('x')
8274 >>> s.add(x > 0)
8275 >>> s.check()
8276 sat
8277 """
8278 ctx = _get_ctx(ctx)
8279 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
8280
8281#########################################
8282#
8283# Fixedpoint
8284#
8285#########################################
8286
8287
8288class Fixedpoint(Z3PPObject):
8289 """Fixedpoint API provides methods for solving with recursive predicates"""
8290
8291 def __init__(self, fixedpoint=None, ctx=None):
8292 assert fixedpoint is None or ctx is not None
8293 self.ctx = _get_ctx(ctx)
8294 self.fixedpoint = None
8295 if fixedpoint is None:
8296 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
8297 else:
8298 self.fixedpoint = fixedpoint
8299 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
8300 self.vars = []
8301
8302 def __deepcopy__(self, memo={}):
8303 return FixedPoint(self.fixedpoint, self.ctx)
8304
8305 def __del__(self):
8306 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
8307 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
8308
8309 def set(self, *args, **keys):
8310 """Set a configuration option. The method `help()` return a string containing all available options.
8311 """
8312 p = args2params(args, keys, self.ctx)
8313 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
8314
8315 def help(self):
8316 """Display a string describing all available options."""
8317 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
8318
8319 def param_descrs(self):
8320 """Return the parameter description set."""
8321 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
8322
8323 def assert_exprs(self, *args):
8324 """Assert constraints as background axioms for the fixedpoint solver."""
8325 args = _get_args(args)
8326 s = BoolSort(self.ctx)
8327 for arg in args:
8328 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8329 for f in arg:
8330 f = self.abstract(f)
8331 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
8332 else:
8333 arg = s.cast(arg)
8334 arg = self.abstract(arg)
8335 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
8336
8337 def add(self, *args):
8338 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
8339 self.assert_exprs(*args)
8340
8341 def __iadd__(self, fml):
8342 self.add(fml)
8343 return self
8344
8345 def append(self, *args):
8346 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
8347 self.assert_exprs(*args)
8348
8349 def insert(self, *args):
8350 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
8351 self.assert_exprs(*args)
8352
8353 def add_rule(self, head, body=None, name=None):
8354 """Assert rules defining recursive predicates to the fixedpoint solver.
8355 >>> a = Bool('a')
8356 >>> b = Bool('b')
8357 >>> s = Fixedpoint()
8358 >>> s.register_relation(a.decl())
8359 >>> s.register_relation(b.decl())
8360 >>> s.fact(a)
8361 >>> s.rule(b, a)
8362 >>> s.query(b)
8363 sat
8364 """
8365 if name is None:
8366 name = ""
8367 name = to_symbol(name, self.ctx)
8368 if body is None:
8369 head = self.abstract(head)
8370 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
8371 else:
8372 body = _get_args(body)
8373 f = self.abstract(Implies(And(body, self.ctx), head))
8374 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
8375
8376 def rule(self, head, body=None, name=None):
8377 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
8378 self.add_rule(head, body, name)
8379
8380 def fact(self, head, name=None):
8381 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
8382 self.add_rule(head, None, name)
8383
8384 def query(self, *query):
8385 """Query the fixedpoint engine whether formula is derivable.
8386 You can also pass an tuple or list of recursive predicates.
8387 """
8388 query = _get_args(query)
8389 sz = len(query)
8390 if sz >= 1 and isinstance(query[0], FuncDeclRef):
8391 _decls = (FuncDecl * sz)()
8392 i = 0
8393 for q in query:
8394 _decls[i] = q.ast
8395 i = i + 1
8396 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
8397 else:
8398 if sz == 1:
8399 query = query[0]
8400 else:
8401 query = And(query, self.ctx)
8402 query = self.abstract(query, False)
8403 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
8404 return CheckSatResult(r)
8405
8406 def query_from_lvl(self, lvl, *query):
8407 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
8408 """
8409 query = _get_args(query)
8410 sz = len(query)
8411 if sz >= 1 and isinstance(query[0], FuncDecl):
8412 _z3_assert(False, "unsupported")
8413 else:
8414 if sz == 1:
8415 query = query[0]
8416 else:
8417 query = And(query)
8418 query = self.abstract(query, False)
8419 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
8420 return CheckSatResult(r)
8421
8422 def update_rule(self, head, body, name):
8423 """update rule"""
8424 if name is None:
8425 name = ""
8426 name = to_symbol(name, self.ctx)
8427 body = _get_args(body)
8428 f = self.abstract(Implies(And(body, self.ctx), head))
8429 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
8430
8431 def get_answer(self):
8432 """Retrieve answer from last query call."""
8433 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
8434 return _to_expr_ref(r, self.ctx)
8435
8436 def get_ground_sat_answer(self):
8437 """Retrieve a ground cex from last query call."""
8438 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
8439 return _to_expr_ref(r, self.ctx)
8440
8441 def get_rules_along_trace(self):
8442 """retrieve rules along the counterexample trace"""
8443 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
8444
8445 def get_rule_names_along_trace(self):
8446 """retrieve rule names along the counterexample trace"""
8447 # this is a hack as I don't know how to return a list of symbols from C++;
8448 # obtain names as a single string separated by semicolons
8449 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
8450 # split into individual names
8451 return names.split(";")
8452
8453 def get_num_levels(self, predicate):
8454 """Retrieve number of levels used for predicate in PDR engine"""
8455 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
8456
8457 def get_cover_delta(self, level, predicate):
8458 """Retrieve properties known about predicate for the level'th unfolding.
8459 -1 is treated as the limit (infinity)
8460 """
8461 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
8462 return _to_expr_ref(r, self.ctx)
8463
8464 def add_cover(self, level, predicate, property):
8465 """Add property to predicate for the level'th unfolding.
8466 -1 is treated as infinity (infinity)
8467 """
8468 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
8469
8470 def register_relation(self, *relations):
8471 """Register relation as recursive"""
8472 relations = _get_args(relations)
8473 for f in relations:
8474 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
8475
8476 def set_predicate_representation(self, f, *representations):
8477 """Control how relation is represented"""
8478 representations = _get_args(representations)
8479 representations = [to_symbol(s) for s in representations]
8480 sz = len(representations)
8481 args = (Symbol * sz)()
8482 for i in range(sz):
8483 args[i] = representations[i]
8484 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
8485
8486 def parse_string(self, s):
8487 """Parse rules and queries from a string"""
8488 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
8489
8490 def parse_file(self, f):
8491 """Parse rules and queries from a file"""
8492 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
8493
8494 def get_rules(self):
8495 """retrieve rules that have been added to fixedpoint context"""
8496 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
8497
8498 def get_assertions(self):
8499 """retrieve assertions that have been added to fixedpoint context"""
8500 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
8501
8502 def __repr__(self):
8503 """Return a formatted string with all added rules and constraints."""
8504 return self.sexpr()
8505
8506 def sexpr(self):
8507 """Return a formatted string (in Lisp-like format) with all added constraints.
8508 We say the string is in s-expression format.
8509 """
8510 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
8511
8512 def to_string(self, queries):
8513 """Return a formatted string (in Lisp-like format) with all added constraints.
8514 We say the string is in s-expression format.
8515 Include also queries.
8516 """
8517 args, len = _to_ast_array(queries)
8518 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
8519
8520 def statistics(self):
8521 """Return statistics for the last `query()`.
8522 """
8523 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
8524
8525 def reason_unknown(self):
8526 """Return a string describing why the last `query()` returned `unknown`.
8527 """
8528 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
8529
8530 def declare_var(self, *vars):
8531 """Add variable or several variables.
8532 The added variable or variables will be bound in the rules
8533 and queries
8534 """
8535 vars = _get_args(vars)
8536 for v in vars:
8537 self.vars += [v]
8538
8539 def abstract(self, fml, is_forall=True):
8540 if self.vars == []:
8541 return fml
8542 if is_forall:
8543 return ForAll(self.vars, fml)
8544 else:
8545 return Exists(self.vars, fml)
8546
8547
8548#########################################
8549#
8550# Finite domains
8551#
8552#########################################
8553
8554class FiniteDomainSortRef(SortRef):
8555 """Finite domain sort."""
8556
8557 def size(self):
8558 """Return the size of the finite domain sort"""
8559 r = (ctypes.c_ulonglong * 1)()
8560 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
8561 return r[0]
8562 else:
8563 raise Z3Exception("Failed to retrieve finite domain sort size")
8564
8565
8566def FiniteDomainSort(name, sz, ctx=None):
8567 """Create a named finite domain sort of a given size sz"""
8568 if not isinstance(name, Symbol):
8569 name = to_symbol(name)
8570 ctx = _get_ctx(ctx)
8571 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
8572
8573
8574def is_finite_domain_sort(s):
8575 """Return True if `s` is a Z3 finite-domain sort.
8576
8577 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
8578 True
8579 >>> is_finite_domain_sort(IntSort())
8580 False
8581 """
8582 return isinstance(s, FiniteDomainSortRef)
8583
8584
8585class FiniteDomainRef(ExprRef):
8586 """Finite-domain expressions."""
8587
8588 def sort(self):
8589 """Return the sort of the finite-domain expression `self`."""
8590 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
8591
8592 def as_string(self):
8593 """Return a Z3 floating point expression as a Python string."""
8594 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
8595
8596
8597def is_finite_domain(a):
8598 """Return `True` if `a` is a Z3 finite-domain expression.
8599
8600 >>> s = FiniteDomainSort('S', 100)
8601 >>> b = Const('b', s)
8602 >>> is_finite_domain(b)
8603 True
8604 >>> is_finite_domain(Int('x'))
8605 False
8606 """
8607 return isinstance(a, FiniteDomainRef)
8608
8609
8610class FiniteDomainNumRef(FiniteDomainRef):
8611 """Integer values."""
8612
8613 def as_long(self):
8614 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
8615
8616 >>> s = FiniteDomainSort('S', 100)
8617 >>> v = FiniteDomainVal(3, s)
8618 >>> v
8619 3
8620 >>> v.as_long() + 1
8621 4
8622 """
8623 return int(self.as_string())
8624
8625 def as_string(self):
8626 """Return a Z3 finite-domain numeral as a Python string.
8627
8628 >>> s = FiniteDomainSort('S', 100)
8629 >>> v = FiniteDomainVal(42, s)
8630 >>> v.as_string()
8631 '42'
8632 """
8633 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
8634
8635
8636def FiniteDomainVal(val, sort, ctx=None):
8637 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
8638
8639 >>> s = FiniteDomainSort('S', 256)
8640 >>> FiniteDomainVal(255, s)
8641 255
8642 >>> FiniteDomainVal('100', s)
8643 100
8644 """
8645 if z3_debug():
8646 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
8647 ctx = sort.ctx
8648 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
8649
8650
8651def is_finite_domain_value(a):
8652 """Return `True` if `a` is a Z3 finite-domain value.
8653
8654 >>> s = FiniteDomainSort('S', 100)
8655 >>> b = Const('b', s)
8656 >>> is_finite_domain_value(b)
8657 False
8658 >>> b = FiniteDomainVal(10, s)
8659 >>> b
8660 10
8661 >>> is_finite_domain_value(b)
8662 True
8663 """
8664 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
8665
8666
8667#########################################
8668#
8669# Optimize
8670#
8671#########################################
8672
8673class OptimizeObjective:
8674 def __init__(self, opt, value, is_max):
8675 self._opt = opt
8676 self._value = value
8677 self._is_max = is_max
8678
8679 def lower(self):
8680 opt = self._opt
8681 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8682
8683 def upper(self):
8684 opt = self._opt
8685 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8686
8687 def lower_values(self):
8688 opt = self._opt
8689 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8690
8691 def upper_values(self):
8692 opt = self._opt
8693 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8694
8695 def value(self):
8696 if self._is_max:
8697 return self.upper()
8698 else:
8699 return self.lower()
8700
8701 def __str__(self):
8702 return "%s:%s" % (self._value, self._is_max)
8703
8704
8705_on_models = {}
8706
8707
8708def _global_on_model(ctx):
8709 (fn, mdl) = _on_models[ctx]
8710 fn(mdl)
8711
8712
8713_on_model_eh = on_model_eh_type(_global_on_model)
8714
8715
8716class Optimize(Z3PPObject):
8717 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8718
8719 def __init__(self, optimize=None, ctx=None):
8720 self.ctx = _get_ctx(ctx)
8721 if optimize is None:
8722 self.optimize = Z3_mk_optimize(self.ctx.ref())
8723 else:
8724 self.optimize = optimize
8725 self._on_models_id = None
8726 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8727
8728 def __copy__(self):
8729 return self.translate(self.ctx)
8730
8731 def __deepcopy__(self, memo={}):
8732 return self.translate(self.ctx)
8733
8734 def __del__(self):
8735 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8736 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8737 if self._on_models_id is not None:
8738 del _on_models[self._on_models_id]
8739
8740 def __enter__(self):
8741 self.push()
8742 return self
8743
8744 def __exit__(self, *exc_info):
8745 self.pop()
8746
8747 def set(self, *args, **keys):
8748 """Set a configuration option.
8749 The method `help()` return a string containing all available options.
8750 """
8751 p = args2params(args, keys, self.ctx)
8752 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8753
8754 def help(self):
8755 """Display a string describing all available options."""
8756 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8757
8758 def param_descrs(self):
8759 """Return the parameter description set."""
8760 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8761
8762 def assert_exprs(self, *args):
8763 """Assert constraints as background axioms for the optimize solver."""
8764 args = _get_args(args)
8765 s = BoolSort(self.ctx)
8766 for arg in args:
8767 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8768 for f in arg:
8769 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8770 else:
8771 arg = s.cast(arg)
8772 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8773
8774 def add(self, *args):
8775 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8776 self.assert_exprs(*args)
8777
8778 def __iadd__(self, fml):
8779 self.add(fml)
8780 return self
8781
8782 def assert_and_track(self, a, p):
8783 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8784
8785 If `p` is a string, it will be automatically converted into a Boolean constant.
8786
8787 >>> x = Int('x')
8788 >>> p3 = Bool('p3')
8789 >>> s = Optimize()
8790 >>> s.assert_and_track(x > 0, 'p1')
8791 >>> s.assert_and_track(x != 1, 'p2')
8792 >>> s.assert_and_track(x < 0, p3)
8793 >>> print(s.check())
8794 unsat
8795 >>> c = s.unsat_core()
8796 >>> len(c)
8797 2
8798 >>> Bool('p1') in c
8799 True
8800 >>> Bool('p2') in c
8801 False
8802 >>> p3 in c
8803 True
8804 """
8805 if isinstance(p, str):
8806 p = Bool(p, self.ctx)
8807 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8808 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8809 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8810
8811 def add_soft(self, arg, weight="1", id=None):
8812 """Add soft constraint with optional weight and optional identifier.
8813 If no weight is supplied, then the penalty for violating the soft constraint
8814 is 1.
8815 Soft constraints are grouped by identifiers. Soft constraints that are
8816 added without identifiers are grouped by default.
8817 """
8818 if _is_int(weight):
8819 weight = "%d" % weight
8820 elif isinstance(weight, float):
8821 weight = "%f" % weight
8822 if not isinstance(weight, str):
8823 raise Z3Exception("weight should be a string or an integer")
8824 if id is None:
8825 id = ""
8826 id = to_symbol(id, self.ctx)
8827
8828 def asoft(a):
8829 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8830 return OptimizeObjective(self, v, False)
8831 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8832 return [asoft(a) for a in arg]
8833 return asoft(arg)
8834
8835 def set_initial_value(self, var, value):
8836 """initialize the solver's state by setting the initial value of var to value
8837 """
8838 s = var.sort()
8839 value = s.cast(value)
8840 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8841
8842 def maximize(self, arg):
8843 """Add objective function to maximize."""
8844 return OptimizeObjective(
8845 self,
8846 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8847 is_max=True,
8848 )
8849
8850 def minimize(self, arg):
8851 """Add objective function to minimize."""
8852 return OptimizeObjective(
8853 self,
8854 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8855 is_max=False,
8856 )
8857
8858 def push(self):
8859 """create a backtracking point for added rules, facts and assertions"""
8860 Z3_optimize_push(self.ctx.ref(), self.optimize)
8861
8862 def pop(self):
8863 """restore to previously created backtracking point"""
8864 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8865
8866 def check(self, *assumptions):
8867 """Check consistency and produce optimal values."""
8868 assumptions = _get_args(assumptions)
8869 num = len(assumptions)
8870 _assumptions = (Ast * num)()
8871 for i in range(num):
8872 _assumptions[i] = assumptions[i].as_ast()
8873 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8874
8875 def reason_unknown(self):
8876 """Return a string that describes why the last `check()` returned `unknown`."""
8877 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8878
8879 def model(self):
8880 """Return a model for the last check()."""
8881 try:
8882 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8883 except Z3Exception:
8884 raise Z3Exception("model is not available")
8885
8886 def unsat_core(self):
8887 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8888
8889 def lower(self, obj):
8890 if not isinstance(obj, OptimizeObjective):
8891 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8892 return obj.lower()
8893
8894 def upper(self, obj):
8895 if not isinstance(obj, OptimizeObjective):
8896 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8897 return obj.upper()
8898
8899 def lower_values(self, obj):
8900 if not isinstance(obj, OptimizeObjective):
8901 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8902 return obj.lower_values()
8903
8904 def upper_values(self, obj):
8905 if not isinstance(obj, OptimizeObjective):
8906 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8907 return obj.upper_values()
8908
8909 def from_file(self, filename):
8910 """Parse assertions and objectives from a file"""
8911 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8912
8913 def from_string(self, s):
8914 """Parse assertions and objectives from a string"""
8915 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8916
8917 def assertions(self):
8918 """Return an AST vector containing all added constraints."""
8919 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8920
8921 def objectives(self):
8922 """returns set of objective functions"""
8923 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8924
8925 def __repr__(self):
8926 """Return a formatted string with all added rules and constraints."""
8927 return self.sexpr()
8928
8929 def sexpr(self):
8930 """Return a formatted string (in Lisp-like format) with all added constraints.
8931 We say the string is in s-expression format.
8932 """
8933 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8934
8935 def statistics(self):
8936 """Return statistics for the last check`.
8937 """
8938 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8939
8940 def translate(self, target):
8941 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
8942
8943 >>> c1 = Context()
8944 >>> c2 = Context()
8945 >>> o1 = Optimize(ctx=c1)
8946 >>> o2 = o1.translate(c2)
8947 """
8948 if z3_debug():
8949 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
8950 opt = Z3_optimize_translate(self.ctx.ref(), self.optimize, target.ref())
8951 return Optimize(opt, target)
8952
8953 def set_on_model(self, on_model):
8954 """Register a callback that is invoked with every incremental improvement to
8955 objective values. The callback takes a model as argument.
8956 The life-time of the model is limited to the callback so the
8957 model has to be (deep) copied if it is to be used after the callback
8958 """
8959 id = len(_on_models) + 41
8960 mdl = Model(self.ctx)
8961 _on_models[id] = (on_model, mdl)
8962 self._on_models_id = id
8963 Z3_optimize_register_model_eh(
8964 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8965 )
8966
8967
8968#########################################
8969#
8970# ApplyResult
8971#
8972#########################################
8973class ApplyResult(Z3PPObject):
8974 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8975 It also contains model and proof converters.
8976 """
8977
8978 def __init__(self, result, ctx):
8979 self.result = result
8980 self.ctx = ctx
8981 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8982
8983 def __deepcopy__(self, memo={}):
8984 return ApplyResult(self.result, self.ctx)
8985
8986 def __del__(self):
8987 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8988 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8989
8990 def __len__(self):
8991 """Return the number of subgoals in `self`.
8992
8993 >>> a, b = Ints('a b')
8994 >>> g = Goal()
8995 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8996 >>> t = Tactic('split-clause')
8997 >>> r = t(g)
8998 >>> len(r)
8999 2
9000 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
9001 >>> len(t(g))
9002 4
9003 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
9004 >>> len(t(g))
9005 1
9006 """
9007 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
9008
9009 def __getitem__(self, idx):
9010 """Return one of the subgoals stored in ApplyResult object `self`.
9011
9012 >>> a, b = Ints('a b')
9013 >>> g = Goal()
9014 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
9015 >>> t = Tactic('split-clause')
9016 >>> r = t(g)
9017 >>> r[0]
9018 [a == 0, Or(b == 0, b == 1), a > b]
9019 >>> r[1]
9020 [a == 1, Or(b == 0, b == 1), a > b]
9021 """
9022 if idx < 0:
9023 idx += len(self)
9024 if idx < 0 or idx >= len(self):
9025 raise IndexError
9026 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
9027
9028 def __repr__(self):
9029 return obj_to_string(self)
9030
9031 def sexpr(self):
9032 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
9033 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
9034
9035 def as_expr(self):
9036 """Return a Z3 expression consisting of all subgoals.
9037
9038 >>> x = Int('x')
9039 >>> g = Goal()
9040 >>> g.add(x > 1)
9041 >>> g.add(Or(x == 2, x == 3))
9042 >>> r = Tactic('simplify')(g)
9043 >>> r
9044 [[Not(x <= 1), Or(x == 2, x == 3)]]
9045 >>> r.as_expr()
9046 And(Not(x <= 1), Or(x == 2, x == 3))
9047 >>> r = Tactic('split-clause')(g)
9048 >>> r
9049 [[x > 1, x == 2], [x > 1, x == 3]]
9050 >>> r.as_expr()
9051 Or(And(x > 1, x == 2), And(x > 1, x == 3))
9052 """
9053 sz = len(self)
9054 if sz == 0:
9055 return BoolVal(False, self.ctx)
9056 elif sz == 1:
9057 return self[0].as_expr()
9058 else:
9059 return Or([self[i].as_expr() for i in range(len(self))])
9060
9061#########################################
9062#
9063# Simplifiers
9064#
9065#########################################
9066
9067def num_simplifiers(ctx=None):
9068 """Return the number of simplifiers supported by the given context."""
9069 return Z3_get_num_simplifiers(_get_ctx(ctx).ref())
9070
9071
9072def simplifier_name(i, ctx=None):
9073 """Return the name of the i-th simplifier supported by the given context."""
9074 return Z3_get_simplifier_name(_get_ctx(ctx).ref(), i)
9075
9076
9077def simplifier_description(name, ctx=None):
9078 """Return the description of the simplifier identified by name."""
9079 return Z3_simplifier_get_descr(_get_ctx(ctx).ref(), name)
9080
9081
9082class Simplifier:
9083 """Simplifiers act as pre-processing utilities for solvers.
9084 Build a custom simplifier and add it to a solver"""
9085
9086 def __init__(self, simplifier, ctx=None):
9087 self.ctx = _get_ctx(ctx)
9088 self.simplifier = None
9089 if isinstance(simplifier, SimplifierObj):
9090 self.simplifier = simplifier
9091 elif isinstance(simplifier, list):
9092 simps = [Simplifier(s, ctx) for s in simplifier]
9093 self.simplifier = simps[0].simplifier
9094 for i in range(1, len(simps)):
9095 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
9096 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
9097 return
9098 else:
9099 if z3_debug():
9100 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
9101 try:
9102 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
9103 except Z3Exception:
9104 raise Z3Exception("unknown simplifier '%s'" % simplifier)
9105 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
9106
9107 def __deepcopy__(self, memo={}):
9108 return Simplifier(self.simplifier, self.ctx)
9109
9110 def __del__(self):
9111 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
9112 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
9113
9114 def using_params(self, *args, **keys):
9115 """Return a simplifier that uses the given configuration options"""
9116 p = args2params(args, keys, self.ctx)
9117 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
9118
9119 def add(self, solver):
9120 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
9121 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
9122
9123 def help(self):
9124 """Display a string containing a description of the available options for the `self` simplifier."""
9125 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
9126
9127 def param_descrs(self):
9128 """Return the parameter description set."""
9129 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
9130
9131
9132#########################################
9133#
9134# Tactics
9135#
9136#########################################
9137
9138
9139class Tactic:
9140 """Tactics transform, solver and/or simplify sets of constraints (Goal).
9141 A Tactic can be converted into a Solver using the method solver().
9142
9143 Several combinators are available for creating new tactics using the built-in ones:
9144 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
9145 """
9146
9147 def __init__(self, tactic, ctx=None):
9148 self.ctx = _get_ctx(ctx)
9149 self.tactic = None
9150 if isinstance(tactic, TacticObj):
9151 self.tactic = tactic
9152 else:
9153 if z3_debug():
9154 _z3_assert(isinstance(tactic, str), "tactic name expected")
9155 try:
9156 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
9157 except Z3Exception:
9158 raise Z3Exception("unknown tactic '%s'" % tactic)
9159 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
9160
9161 def __deepcopy__(self, memo={}):
9162 return Tactic(self.tactic, self.ctx)
9163
9164 def __del__(self):
9165 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
9166 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
9167
9168 def solver(self, logFile=None):
9169 """Create a solver using the tactic `self`.
9170
9171 The solver supports the methods `push()` and `pop()`, but it
9172 will always solve each `check()` from scratch.
9173
9174 >>> t = Then('simplify', 'nlsat')
9175 >>> s = t.solver()
9176 >>> x = Real('x')
9177 >>> s.add(x**2 == 2, x > 0)
9178 >>> s.check()
9179 sat
9180 >>> s.model()
9181 [x = 1.4142135623?]
9182 """
9183 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
9184
9185 def apply(self, goal, *arguments, **keywords):
9186 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
9187
9188 >>> x, y = Ints('x y')
9189 >>> t = Tactic('solve-eqs')
9190 >>> t.apply(And(x == 0, y >= x + 1))
9191 [[y >= 1]]
9192 """
9193 if z3_debug():
9194 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
9195 goal = _to_goal(goal)
9196 if len(arguments) > 0 or len(keywords) > 0:
9197 p = args2params(arguments, keywords, self.ctx)
9198 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
9199 else:
9200 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
9201
9202 def __call__(self, goal, *arguments, **keywords):
9203 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
9204
9205 >>> x, y = Ints('x y')
9206 >>> t = Tactic('solve-eqs')
9207 >>> t(And(x == 0, y >= x + 1))
9208 [[y >= 1]]
9209 """
9210 return self.apply(goal, *arguments, **keywords)
9211
9212 def help(self):
9213 """Display a string containing a description of the available options for the `self` tactic."""
9214 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
9215
9216 def param_descrs(self):
9217 """Return the parameter description set."""
9218 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
9219
9220
9221def _to_goal(a):
9222 if isinstance(a, BoolRef):
9223 goal = Goal(ctx=a.ctx)
9224 goal.add(a)
9225 return goal
9226 else:
9227 return a
9228
9229
9230def _to_tactic(t, ctx=None):
9231 if isinstance(t, Tactic):
9232 return t
9233 else:
9234 return Tactic(t, ctx)
9235
9236
9237def _and_then(t1, t2, ctx=None):
9238 t1 = _to_tactic(t1, ctx)
9239 t2 = _to_tactic(t2, ctx)
9240 if z3_debug():
9241 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
9242 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
9243
9244
9245def _or_else(t1, t2, ctx=None):
9246 t1 = _to_tactic(t1, ctx)
9247 t2 = _to_tactic(t2, ctx)
9248 if z3_debug():
9249 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
9250 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
9251
9252
9253def AndThen(*ts, **ks):
9254 """Return a tactic that applies the tactics in `*ts` in sequence.
9255
9256 >>> x, y = Ints('x y')
9257 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
9258 >>> t(And(x == 0, y > x + 1))
9259 [[Not(y <= 1)]]
9260 >>> t(And(x == 0, y > x + 1)).as_expr()
9261 Not(y <= 1)
9262 """
9263 if z3_debug():
9264 _z3_assert(len(ts) >= 2, "At least two arguments expected")
9265 ctx = ks.get("ctx", None)
9266 num = len(ts)
9267 r = ts[0]
9268 for i in range(num - 1):
9269 r = _and_then(r, ts[i + 1], ctx)
9270 return r
9271
9272
9273def Then(*ts, **ks):
9274 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
9275
9276 >>> x, y = Ints('x y')
9277 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
9278 >>> t(And(x == 0, y > x + 1))
9279 [[Not(y <= 1)]]
9280 >>> t(And(x == 0, y > x + 1)).as_expr()
9281 Not(y <= 1)
9282 """
9283 return AndThen(*ts, **ks)
9284
9285
9286def OrElse(*ts, **ks):
9287 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
9288
9289 >>> x = Int('x')
9290 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
9291 >>> # Tactic split-clause fails if there is no clause in the given goal.
9292 >>> t(x == 0)
9293 [[x == 0]]
9294 >>> t(Or(x == 0, x == 1))
9295 [[x == 0], [x == 1]]
9296 """
9297 if z3_debug():
9298 _z3_assert(len(ts) >= 2, "At least two arguments expected")
9299 ctx = ks.get("ctx", None)
9300 num = len(ts)
9301 r = ts[0]
9302 for i in range(num - 1):
9303 r = _or_else(r, ts[i + 1], ctx)
9304 return r
9305
9306
9307def ParOr(*ts, **ks):
9308 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
9309
9310 >>> x = Int('x')
9311 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
9312 >>> t(x + 1 == 2)
9313 [[x == 1]]
9314 """
9315 if z3_debug():
9316 _z3_assert(len(ts) >= 2, "At least two arguments expected")
9317 ctx = _get_ctx(ks.get("ctx", None))
9318 ts = [_to_tactic(t, ctx) for t in ts]
9319 sz = len(ts)
9320 _args = (TacticObj * sz)()
9321 for i in range(sz):
9322 _args[i] = ts[i].tactic
9323 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
9324
9325
9326def ParThen(t1, t2, ctx=None):
9327 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
9328 The subgoals are processed in parallel.
9329
9330 >>> x, y = Ints('x y')
9331 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
9332 >>> t(And(Or(x == 1, x == 2), y == x + 1))
9333 [[x == 1, y == 2], [x == 2, y == 3]]
9334 """
9335 t1 = _to_tactic(t1, ctx)
9336 t2 = _to_tactic(t2, ctx)
9337 if z3_debug():
9338 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
9339 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
9340
9341
9342def ParAndThen(t1, t2, ctx=None):
9343 """Alias for ParThen(t1, t2, ctx)."""
9344 return ParThen(t1, t2, ctx)
9345
9346
9347def With(t, *args, **keys):
9348 """Return a tactic that applies tactic `t` using the given configuration options.
9349
9350 >>> x, y = Ints('x y')
9351 >>> t = With(Tactic('simplify'), som=True)
9352 >>> t((x + 1)*(y + 2) == 0)
9353 [[2*x + y + x*y == -2]]
9354 """
9355 ctx = keys.pop("ctx", None)
9356 t = _to_tactic(t, ctx)
9357 p = args2params(args, keys, t.ctx)
9358 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
9359
9360
9361def WithParams(t, p):
9362 """Return a tactic that applies tactic `t` using the given configuration options.
9363
9364 >>> x, y = Ints('x y')
9365 >>> p = ParamsRef()
9366 >>> p.set("som", True)
9367 >>> t = WithParams(Tactic('simplify'), p)
9368 >>> t((x + 1)*(y + 2) == 0)
9369 [[2*x + y + x*y == -2]]
9370 """
9371 t = _to_tactic(t, None)
9372 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
9373
9374
9375def Repeat(t, max=4294967295, ctx=None):
9376 """Return a tactic that keeps applying `t` until the goal is not modified anymore
9377 or the maximum number of iterations `max` is reached.
9378
9379 >>> x, y = Ints('x y')
9380 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
9381 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
9382 >>> r = t(c)
9383 >>> for subgoal in r: print(subgoal)
9384 [x == 0, y == 0, x > y]
9385 [x == 0, y == 1, x > y]
9386 [x == 1, y == 0, x > y]
9387 [x == 1, y == 1, x > y]
9388 >>> t = Then(t, Tactic('propagate-values'))
9389 >>> t(c)
9390 [[x == 1, y == 0]]
9391 """
9392 t = _to_tactic(t, ctx)
9393 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
9394
9395
9396def TryFor(t, ms, ctx=None):
9397 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
9398
9399 If `t` does not terminate in `ms` milliseconds, then it fails.
9400 """
9401 t = _to_tactic(t, ctx)
9402 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
9403
9404
9405def tactics(ctx=None):
9406 """Return a list of all available tactics in Z3.
9407
9408 >>> l = tactics()
9409 >>> l.count('simplify') == 1
9410 True
9411 """
9412 ctx = _get_ctx(ctx)
9413 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
9414
9415
9416def tactic_description(name, ctx=None):
9417 """Return a short description for the tactic named `name`.
9418
9419 >>> d = tactic_description('simplify')
9420 """
9421 ctx = _get_ctx(ctx)
9422 return Z3_tactic_get_descr(ctx.ref(), name)
9423
9424
9425def describe_tactics():
9426 """Display a (tabular) description of all available tactics in Z3."""
9427 if in_html_mode():
9428 even = True
9429 print('<table border="1" cellpadding="2" cellspacing="0">')
9430 for t in tactics():
9431 if even:
9432 print('<tr style="background-color:#CFCFCF">')
9433 even = False
9434 else:
9435 print("<tr>")
9436 even = True
9437 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
9438 print("</table>")
9439 else:
9440 for t in tactics():
9441 print("%s : %s" % (t, tactic_description(t)))
9442
9443
9444class Probe:
9445 """Probes are used to inspect a goal (aka problem) and collect information that may be used
9446 to decide which solver and/or preprocessing step will be used.
9447 """
9448
9449 def __init__(self, probe, ctx=None):
9450 self.ctx = _get_ctx(ctx)
9451 self.probe = None
9452 if isinstance(probe, ProbeObj):
9453 self.probe = probe
9454 elif isinstance(probe, float):
9455 self.probe = Z3_probe_const(self.ctx.ref(), probe)
9456 elif _is_int(probe):
9457 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
9458 elif isinstance(probe, bool):
9459 if probe:
9460 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
9461 else:
9462 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
9463 else:
9464 if z3_debug():
9465 _z3_assert(isinstance(probe, str), "probe name expected")
9466 try:
9467 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
9468 except Z3Exception:
9469 raise Z3Exception("unknown probe '%s'" % probe)
9470 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
9471
9472 def __deepcopy__(self, memo={}):
9473 return Probe(self.probe, self.ctx)
9474
9475 def __del__(self):
9476 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
9477 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
9478
9479 def __lt__(self, other):
9480 """Return a probe that evaluates to "true" when the value returned by `self`
9481 is less than the value returned by `other`.
9482
9483 >>> p = Probe('size') < 10
9484 >>> x = Int('x')
9485 >>> g = Goal()
9486 >>> g.add(x > 0)
9487 >>> g.add(x < 10)
9488 >>> p(g)
9489 1.0
9490 """
9491 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9492
9493 def __gt__(self, other):
9494 """Return a probe that evaluates to "true" when the value returned by `self`
9495 is greater than the value returned by `other`.
9496
9497 >>> p = Probe('size') > 10
9498 >>> x = Int('x')
9499 >>> g = Goal()
9500 >>> g.add(x > 0)
9501 >>> g.add(x < 10)
9502 >>> p(g)
9503 0.0
9504 """
9505 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9506
9507 def __le__(self, other):
9508 """Return a probe that evaluates to "true" when the value returned by `self`
9509 is less than or equal to the value returned by `other`.
9510
9511 >>> p = Probe('size') <= 2
9512 >>> x = Int('x')
9513 >>> g = Goal()
9514 >>> g.add(x > 0)
9515 >>> g.add(x < 10)
9516 >>> p(g)
9517 1.0
9518 """
9519 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9520
9521 def __ge__(self, other):
9522 """Return a probe that evaluates to "true" when the value returned by `self`
9523 is greater than or equal to the value returned by `other`.
9524
9525 >>> p = Probe('size') >= 2
9526 >>> x = Int('x')
9527 >>> g = Goal()
9528 >>> g.add(x > 0)
9529 >>> g.add(x < 10)
9530 >>> p(g)
9531 1.0
9532 """
9533 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9534
9535 def __eq__(self, other):
9536 """Return a probe that evaluates to "true" when the value returned by `self`
9537 is equal to the value returned by `other`.
9538
9539 >>> p = Probe('size') == 2
9540 >>> x = Int('x')
9541 >>> g = Goal()
9542 >>> g.add(x > 0)
9543 >>> g.add(x < 10)
9544 >>> p(g)
9545 1.0
9546 """
9547 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9548
9549 def __ne__(self, other):
9550 """Return a probe that evaluates to "true" when the value returned by `self`
9551 is not equal to the value returned by `other`.
9552
9553 >>> p = Probe('size') != 2
9554 >>> x = Int('x')
9555 >>> g = Goal()
9556 >>> g.add(x > 0)
9557 >>> g.add(x < 10)
9558 >>> p(g)
9559 0.0
9560 """
9561 p = self.__eq__(other)
9562 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
9563
9564 def __call__(self, goal):
9565 """Evaluate the probe `self` in the given goal.
9566
9567 >>> p = Probe('size')
9568 >>> x = Int('x')
9569 >>> g = Goal()
9570 >>> g.add(x > 0)
9571 >>> g.add(x < 10)
9572 >>> p(g)
9573 2.0
9574 >>> g.add(x < 20)
9575 >>> p(g)
9576 3.0
9577 >>> p = Probe('num-consts')
9578 >>> p(g)
9579 1.0
9580 >>> p = Probe('is-propositional')
9581 >>> p(g)
9582 0.0
9583 >>> p = Probe('is-qflia')
9584 >>> p(g)
9585 1.0
9586 """
9587 if z3_debug():
9588 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
9589 goal = _to_goal(goal)
9590 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
9591
9592
9593def is_probe(p):
9594 """Return `True` if `p` is a Z3 probe.
9595
9596 >>> is_probe(Int('x'))
9597 False
9598 >>> is_probe(Probe('memory'))
9599 True
9600 """
9601 return isinstance(p, Probe)
9602
9603
9604def _to_probe(p, ctx=None):
9605 if is_probe(p):
9606 return p
9607 else:
9608 return Probe(p, ctx)
9609
9610
9611def probes(ctx=None):
9612 """Return a list of all available probes in Z3.
9613
9614 >>> l = probes()
9615 >>> l.count('memory') == 1
9616 True
9617 """
9618 ctx = _get_ctx(ctx)
9619 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
9620
9621
9622def probe_description(name, ctx=None):
9623 """Return a short description for the probe named `name`.
9624
9625 >>> d = probe_description('memory')
9626 """
9627 ctx = _get_ctx(ctx)
9628 return Z3_probe_get_descr(ctx.ref(), name)
9629
9630
9631def describe_probes():
9632 """Display a (tabular) description of all available probes in Z3."""
9633 if in_html_mode():
9634 even = True
9635 print('<table border="1" cellpadding="2" cellspacing="0">')
9636 for p in probes():
9637 if even:
9638 print('<tr style="background-color:#CFCFCF">')
9639 even = False
9640 else:
9641 print("<tr>")
9642 even = True
9643 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
9644 print("</table>")
9645 else:
9646 for p in probes():
9647 print("%s : %s" % (p, probe_description(p)))
9648
9649
9650def _probe_nary(f, args, ctx):
9651 if z3_debug():
9652 _z3_assert(len(args) > 0, "At least one argument expected")
9653 num = len(args)
9654 r = _to_probe(args[0], ctx)
9655 for i in range(num - 1):
9656 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
9657 return r
9658
9659
9660def _probe_and(args, ctx):
9661 return _probe_nary(Z3_probe_and, args, ctx)
9662
9663
9664def _probe_or(args, ctx):
9665 return _probe_nary(Z3_probe_or, args, ctx)
9666
9667
9668def FailIf(p, ctx=None):
9669 """Return a tactic that fails if the probe `p` evaluates to true.
9670 Otherwise, it returns the input goal unmodified.
9671
9672 In the following example, the tactic applies 'simplify' if and only if there are
9673 more than 2 constraints in the goal.
9674
9675 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
9676 >>> x, y = Ints('x y')
9677 >>> g = Goal()
9678 >>> g.add(x > 0)
9679 >>> g.add(y > 0)
9680 >>> t(g)
9681 [[x > 0, y > 0]]
9682 >>> g.add(x == y + 1)
9683 >>> t(g)
9684 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9685 """
9686 p = _to_probe(p, ctx)
9687 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
9688
9689
9690def When(p, t, ctx=None):
9691 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
9692 Otherwise, it returns the input goal unmodified.
9693
9694 >>> t = When(Probe('size') > 2, Tactic('simplify'))
9695 >>> x, y = Ints('x y')
9696 >>> g = Goal()
9697 >>> g.add(x > 0)
9698 >>> g.add(y > 0)
9699 >>> t(g)
9700 [[x > 0, y > 0]]
9701 >>> g.add(x == y + 1)
9702 >>> t(g)
9703 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9704 """
9705 p = _to_probe(p, ctx)
9706 t = _to_tactic(t, ctx)
9707 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
9708
9709
9710def Cond(p, t1, t2, ctx=None):
9711 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
9712
9713 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
9714 """
9715 p = _to_probe(p, ctx)
9716 t1 = _to_tactic(t1, ctx)
9717 t2 = _to_tactic(t2, ctx)
9718 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
9719
9720#########################################
9721#
9722# Utils
9723#
9724#########################################
9725
9726
9727def simplify(a, *arguments, **keywords):
9728 """Simplify the expression `a` using the given options.
9729
9730 This function has many options. Use `help_simplify` to obtain the complete list.
9731
9732 >>> x = Int('x')
9733 >>> y = Int('y')
9734 >>> simplify(x + 1 + y + x + 1)
9735 2 + 2*x + y
9736 >>> simplify((x + 1)*(y + 1), som=True)
9737 1 + x + y + x*y
9738 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9739 And(Not(x == y), Not(x == 1), Not(y == 1))
9740 >>> simplify(And(x == 0, y == 1), elim_and=True)
9741 Not(Or(Not(x == 0), Not(y == 1)))
9742 """
9743 if z3_debug():
9744 _z3_assert(is_expr(a), "Z3 expression expected")
9745 if len(arguments) > 0 or len(keywords) > 0:
9746 p = args2params(arguments, keywords, a.ctx)
9747 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9748 else:
9749 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9750
9751
9752def help_simplify():
9753 """Return a string describing all options available for Z3 `simplify` procedure."""
9754 print(Z3_simplify_get_help(main_ctx().ref()))
9755
9756
9757def simplify_param_descrs():
9758 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9759 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9760
9761
9762def substitute(t, *m):
9763 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9764 Every occurrence in t of from is replaced with to.
9765
9766 >>> x = Int('x')
9767 >>> y = Int('y')
9768 >>> substitute(x + 1, (x, y + 1))
9769 y + 1 + 1
9770 >>> f = Function('f', IntSort(), IntSort())
9771 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9772 1 + 1
9773 """
9774 if isinstance(m, tuple):
9775 m1 = _get_args(m)
9776 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9777 m = m1
9778 if z3_debug():
9779 _z3_assert(is_expr(t), "Z3 expression expected")
9780 _z3_assert(
9781 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9782 "Z3 invalid substitution, expression pairs expected.")
9783 _z3_assert(
9784 all([p[0].sort().eq(p[1].sort()) for p in m]),
9785 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9786 num = len(m)
9787 _from = (Ast * num)()
9788 _to = (Ast * num)()
9789 for i in range(num):
9790 _from[i] = m[i][0].as_ast()
9791 _to[i] = m[i][1].as_ast()
9792 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9793
9794
9795def substitute_vars(t, *m):
9796 """Substitute the free variables in t with the expression in m.
9797
9798 >>> v0 = Var(0, IntSort())
9799 >>> v1 = Var(1, IntSort())
9800 >>> x = Int('x')
9801 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9802 >>> # replace v0 with x+1 and v1 with x
9803 >>> substitute_vars(f(v0, v1), x + 1, x)
9804 f(x + 1, x)
9805 """
9806 if z3_debug():
9807 _z3_assert(is_expr(t), "Z3 expression expected")
9808 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9809 num = len(m)
9810 _to = (Ast * num)()
9811 for i in range(num):
9812 _to[i] = m[i].as_ast()
9813 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9814
9815def substitute_funs(t, *m):
9816 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9817 Every occurrence in to of the function from is replaced with the expression to.
9818 The expression to can have free variables, that refer to the arguments of from.
9819 For examples, see
9820 """
9821 if isinstance(m, tuple):
9822 m1 = _get_args(m)
9823 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9824 m = m1
9825 if z3_debug():
9826 _z3_assert(is_expr(t), "Z3 expression expected")
9827 _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.")
9828 num = len(m)
9829 _from = (FuncDecl * num)()
9830 _to = (Ast * num)()
9831 for i in range(num):
9832 _from[i] = m[i][0].as_func_decl()
9833 _to[i] = m[i][1].as_ast()
9834 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9835
9836
9837def Sum(*args):
9838 """Create the sum of the Z3 expressions.
9839
9840 >>> a, b, c = Ints('a b c')
9841 >>> Sum(a, b, c)
9842 a + b + c
9843 >>> Sum([a, b, c])
9844 a + b + c
9845 >>> A = IntVector('a', 5)
9846 >>> Sum(A)
9847 a__0 + a__1 + a__2 + a__3 + a__4
9848 """
9849 args = _get_args(args)
9850 if len(args) == 0:
9851 return 0
9852 ctx = _ctx_from_ast_arg_list(args)
9853 if ctx is None:
9854 return _reduce(lambda a, b: a + b, args, 0)
9855 args = _coerce_expr_list(args, ctx)
9856 if is_bv(args[0]) or isinstance(args[0], FiniteFieldRef):
9857 return _reduce(lambda a, b: a + b, args, 0)
9858 else:
9859 _args, sz = _to_ast_array(args)
9860 return _to_expr_ref(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9861
9862
9863def Product(*args):
9864 """Create the product of the Z3 expressions.
9865
9866 >>> a, b, c = Ints('a b c')
9867 >>> Product(a, b, c)
9868 a*b*c
9869 >>> Product([a, b, c])
9870 a*b*c
9871 >>> A = IntVector('a', 5)
9872 >>> Product(A)
9873 a__0*a__1*a__2*a__3*a__4
9874 """
9875 args = _get_args(args)
9876 if len(args) == 0:
9877 return 1
9878 ctx = _ctx_from_ast_arg_list(args)
9879 if ctx is None:
9880 return _reduce(lambda a, b: a * b, args, 1)
9881 args = _coerce_expr_list(args, ctx)
9882 if is_bv(args[0]) or isinstance(args[0], FiniteFieldRef):
9883 return _reduce(lambda a, b: a * b, args, 1)
9884 else:
9885 _args, sz = _to_ast_array(args)
9886 return _to_expr_ref(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9887
9888def Abs(arg):
9889 """Create the absolute value of an arithmetic expression"""
9890 return If(arg > 0, arg, -arg)
9891
9892
9893def AtMost(*args):
9894 """Create an at-most Pseudo-Boolean k constraint.
9895
9896 >>> a, b, c = Bools('a b c')
9897 >>> f = AtMost(a, b, c, 2)
9898 """
9899 args = _get_args(args)
9900 if z3_debug():
9901 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9902 ctx = _ctx_from_ast_arg_list(args)
9903 if z3_debug():
9904 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9905 args1 = _coerce_expr_list(args[:-1], ctx)
9906 k = args[-1]
9907 _args, sz = _to_ast_array(args1)
9908 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9909
9910
9911def AtLeast(*args):
9912 """Create an at-least Pseudo-Boolean k constraint.
9913
9914 >>> a, b, c = Bools('a b c')
9915 >>> f = AtLeast(a, b, c, 2)
9916 """
9917 args = _get_args(args)
9918 if z3_debug():
9919 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9920 ctx = _ctx_from_ast_arg_list(args)
9921 if z3_debug():
9922 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9923 args1 = _coerce_expr_list(args[:-1], ctx)
9924 k = args[-1]
9925 _args, sz = _to_ast_array(args1)
9926 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9927
9928
9929def _reorder_pb_arg(arg):
9930 a, b = arg
9931 if not _is_int(b) and _is_int(a):
9932 return b, a
9933 return arg
9934
9935
9936def _pb_args_coeffs(args, default_ctx=None):
9937 args = _get_args_ast_list(args)
9938 if len(args) == 0:
9939 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9940 args = [_reorder_pb_arg(arg) for arg in args]
9941 args, coeffs = zip(*args)
9942 if z3_debug():
9943 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9944 ctx = _ctx_from_ast_arg_list(args)
9945 if z3_debug():
9946 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9947 args = _coerce_expr_list(args, ctx)
9948 _args, sz = _to_ast_array(args)
9949 _coeffs = (ctypes.c_int * len(coeffs))()
9950 for i in range(len(coeffs)):
9951 _z3_check_cint_overflow(coeffs[i], "coefficient")
9952 _coeffs[i] = coeffs[i]
9953 return ctx, sz, _args, _coeffs, args
9954
9955
9956def PbLe(args, k):
9957 """Create a Pseudo-Boolean inequality k constraint.
9958
9959 >>> a, b, c = Bools('a b c')
9960 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9961 """
9962 _z3_check_cint_overflow(k, "k")
9963 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9964 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9965
9966
9967def PbGe(args, k):
9968 """Create a Pseudo-Boolean inequality k constraint.
9969
9970 >>> a, b, c = Bools('a b c')
9971 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9972 """
9973 _z3_check_cint_overflow(k, "k")
9974 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9975 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9976
9977
9978def PbEq(args, k, ctx=None):
9979 """Create a Pseudo-Boolean equality k constraint.
9980
9981 >>> a, b, c = Bools('a b c')
9982 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9983 """
9984 _z3_check_cint_overflow(k, "k")
9985 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9986 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9987
9988
9989def solve(*args, **keywords):
9990 """Solve the constraints `*args`.
9991
9992 This is a simple function for creating demonstrations. It creates a solver,
9993 configure it using the options in `keywords`, adds the constraints
9994 in `args`, and invokes check.
9995
9996 >>> a = Int('a')
9997 >>> solve(a > 0, a < 2)
9998 [a = 1]
9999 """
10000 show = keywords.pop("show", False)
10001 s = Solver()
10002 s.set(**keywords)
10003 s.add(*args)
10004 if show:
10005 print(s)
10006 r = s.check()
10007 if r == unsat:
10008 print("no solution")
10009 elif r == unknown:
10010 print("failed to solve")
10011 try:
10012 print(s.model())
10013 except Z3Exception:
10014 return
10015 else:
10016 print(s.model())
10017
10018
10019def solve_using(s, *args, **keywords):
10020 """Solve the constraints `*args` using solver `s`.
10021
10022 This is a simple function for creating demonstrations. It is similar to `solve`,
10023 but it uses the given solver `s`.
10024 It configures solver `s` using the options in `keywords`, adds the constraints
10025 in `args`, and invokes check.
10026 """
10027 show = keywords.pop("show", False)
10028 if z3_debug():
10029 _z3_assert(isinstance(s, Solver), "Solver object expected")
10030 s.set(**keywords)
10031 s.add(*args)
10032 if show:
10033 print("Problem:")
10034 print(s)
10035 r = s.check()
10036 if r == unsat:
10037 print("no solution")
10038 elif r == unknown:
10039 print("failed to solve")
10040 try:
10041 print(s.model())
10042 except Z3Exception:
10043 return
10044 else:
10045 if show:
10046 print("Solution:")
10047 print(s.model())
10048
10049
10050def prove(claim, show=False, **keywords):
10051 """Try to prove the given claim.
10052
10053 This is a simple function for creating demonstrations. It tries to prove
10054 `claim` by showing the negation is unsatisfiable.
10055
10056 >>> p, q = Bools('p q')
10057 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
10058 proved
10059 """
10060 if z3_debug():
10061 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
10062 s = Solver()
10063 s.set(**keywords)
10064 s.add(Not(claim))
10065 if show:
10066 print(s)
10067 r = s.check()
10068 if r == unsat:
10069 print("proved")
10070 elif r == unknown:
10071 print("failed to prove")
10072 print(s.model())
10073 else:
10074 print("counterexample")
10075 print(s.model())
10076
10077
10078def _solve_html(*args, **keywords):
10079 """Version of function `solve` that renders HTML output."""
10080 show = keywords.pop("show", False)
10081 s = Solver()
10082 s.set(**keywords)
10083 s.add(*args)
10084 if show:
10085 print("<b>Problem:</b>")
10086 print(s)
10087 r = s.check()
10088 if r == unsat:
10089 print("<b>no solution</b>")
10090 elif r == unknown:
10091 print("<b>failed to solve</b>")
10092 try:
10093 print(s.model())
10094 except Z3Exception:
10095 return
10096 else:
10097 if show:
10098 print("<b>Solution:</b>")
10099 print(s.model())
10100
10101
10102def _solve_using_html(s, *args, **keywords):
10103 """Version of function `solve_using` that renders HTML."""
10104 show = keywords.pop("show", False)
10105 if z3_debug():
10106 _z3_assert(isinstance(s, Solver), "Solver object expected")
10107 s.set(**keywords)
10108 s.add(*args)
10109 if show:
10110 print("<b>Problem:</b>")
10111 print(s)
10112 r = s.check()
10113 if r == unsat:
10114 print("<b>no solution</b>")
10115 elif r == unknown:
10116 print("<b>failed to solve</b>")
10117 try:
10118 print(s.model())
10119 except Z3Exception:
10120 return
10121 else:
10122 if show:
10123 print("<b>Solution:</b>")
10124 print(s.model())
10125
10126
10127def _prove_html(claim, show=False, **keywords):
10128 """Version of function `prove` that renders HTML."""
10129 if z3_debug():
10130 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
10131 s = Solver()
10132 s.set(**keywords)
10133 s.add(Not(claim))
10134 if show:
10135 print(s)
10136 r = s.check()
10137 if r == unsat:
10138 print("<b>proved</b>")
10139 elif r == unknown:
10140 print("<b>failed to prove</b>")
10141 print(s.model())
10142 else:
10143 print("<b>counterexample</b>")
10144 print(s.model())
10145
10146
10147def _dict2sarray(sorts, ctx):
10148 sz = len(sorts)
10149 _names = (Symbol * sz)()
10150 _sorts = (Sort * sz)()
10151 i = 0
10152 for k in sorts:
10153 v = sorts[k]
10154 if z3_debug():
10155 _z3_assert(isinstance(k, str), "String expected")
10156 _z3_assert(is_sort(v), "Z3 sort expected")
10157 _names[i] = to_symbol(k, ctx)
10158 _sorts[i] = v.ast
10159 i = i + 1
10160 return sz, _names, _sorts
10161
10162
10163def _dict2darray(decls, ctx):
10164 sz = len(decls)
10165 _names = (Symbol * sz)()
10166 _decls = (FuncDecl * sz)()
10167 i = 0
10168 for k in decls:
10169 v = decls[k]
10170 if z3_debug():
10171 _z3_assert(isinstance(k, str), "String expected")
10172 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
10173 _names[i] = to_symbol(k, ctx)
10174 if is_const(v):
10175 _decls[i] = v.decl().ast
10176 else:
10177 _decls[i] = v.ast
10178 i = i + 1
10179 return sz, _names, _decls
10180
10181class ParserContext:
10182 def __init__(self, ctx= None):
10183 self.ctx = _get_ctx(ctx)
10184 self.pctx = Z3_mk_parser_context(self.ctx.ref())
10185 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
10186
10187 def __del__(self):
10188 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
10189 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
10190 self.pctx = None
10191
10192 def add_sort(self, sort):
10193 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
10194
10195 def add_decl(self, decl):
10196 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
10197
10198 def from_string(self, s):
10199 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
10200
10201def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
10202 """Parse a string in SMT 2.0 format using the given sorts and decls.
10203
10204 The arguments sorts and decls are Python dictionaries used to initialize
10205 the symbol table used for the SMT 2.0 parser.
10206
10207 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
10208 [x > 0, x < 10]
10209 >>> x, y = Ints('x y')
10210 >>> f = Function('f', IntSort(), IntSort())
10211 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
10212 [x + f(y) > 0]
10213 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
10214 [a > 0]
10215 """
10216 ctx = _get_ctx(ctx)
10217 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
10218 dsz, dnames, ddecls = _dict2darray(decls, ctx)
10219 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
10220
10221
10222def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
10223 """Parse a file in SMT 2.0 format using the given sorts and decls.
10224
10225 This function is similar to parse_smt2_string().
10226 """
10227 ctx = _get_ctx(ctx)
10228 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
10229 dsz, dnames, ddecls = _dict2darray(decls, ctx)
10230 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
10231
10232
10233#########################################
10234#
10235# Floating-Point Arithmetic
10236#
10237#########################################
10238
10239
10240# Global default rounding mode
10241_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
10242_dflt_fpsort_ebits = 11
10243_dflt_fpsort_sbits = 53
10244
10245
10246def get_default_rounding_mode(ctx=None):
10247 """Retrieves the global default rounding mode."""
10248 global _dflt_rounding_mode
10249 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
10250 return RTZ(ctx)
10251 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
10252 return RTN(ctx)
10253 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
10254 return RTP(ctx)
10255 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
10256 return RNE(ctx)
10257 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
10258 return RNA(ctx)
10259
10260
10261_ROUNDING_MODES = frozenset({
10262 Z3_OP_FPA_RM_TOWARD_ZERO,
10263 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
10264 Z3_OP_FPA_RM_TOWARD_POSITIVE,
10265 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
10266 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
10267})
10268
10269
10270def set_default_rounding_mode(rm, ctx=None):
10271 global _dflt_rounding_mode
10272 if is_fprm_value(rm):
10273 _dflt_rounding_mode = rm.kind()
10274 else:
10275 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
10276 _dflt_rounding_mode = rm
10277
10278
10279def get_default_fp_sort(ctx=None):
10280 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
10281
10282
10283def set_default_fp_sort(ebits, sbits, ctx=None):
10284 global _dflt_fpsort_ebits
10285 global _dflt_fpsort_sbits
10286 _dflt_fpsort_ebits = ebits
10287 _dflt_fpsort_sbits = sbits
10288
10289
10290def _dflt_rm(ctx=None):
10291 return get_default_rounding_mode(ctx)
10292
10293
10294def _dflt_fps(ctx=None):
10295 return get_default_fp_sort(ctx)
10296
10297
10298def _coerce_fp_expr_list(alist, ctx):
10299 first_fp_sort = None
10300 for a in alist:
10301 if is_fp(a):
10302 if first_fp_sort is None:
10303 first_fp_sort = a.sort()
10304 elif first_fp_sort == a.sort():
10305 pass # OK, same as before
10306 else:
10307 # we saw at least 2 different float sorts; something will
10308 # throw a sort mismatch later, for now assume None.
10309 first_fp_sort = None
10310 break
10311
10312 r = []
10313 for i in range(len(alist)):
10314 a = alist[i]
10315 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
10316 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
10317 r.append(FPVal(a, None, first_fp_sort, ctx))
10318 else:
10319 r.append(a)
10320 return _coerce_expr_list(r, ctx)
10321
10322
10323# FP Sorts
10324
10325class FPSortRef(SortRef):
10326 """Floating-point sort."""
10327
10328 def ebits(self):
10329 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
10330 >>> b = FPSort(8, 24)
10331 >>> b.ebits()
10332 8
10333 """
10334 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
10335
10336 def sbits(self):
10337 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
10338 >>> b = FPSort(8, 24)
10339 >>> b.sbits()
10340 24
10341 """
10342 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
10343
10344 def cast(self, val):
10345 """Try to cast `val` as a floating-point expression.
10346 >>> b = FPSort(8, 24)
10347 >>> b.cast(1.0)
10348 1
10349 >>> b.cast(1.0).sexpr()
10350 '(fp #b0 #x7f #b00000000000000000000000)'
10351 """
10352 if is_expr(val):
10353 if z3_debug():
10354 _z3_assert(self.ctx == val.ctx, "Context mismatch")
10355 return val
10356 else:
10357 return FPVal(val, None, self, self.ctx)
10358
10359
10360def Float16(ctx=None):
10361 """Floating-point 16-bit (half) sort."""
10362 ctx = _get_ctx(ctx)
10363 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
10364
10365
10366def FloatHalf(ctx=None):
10367 """Floating-point 16-bit (half) sort."""
10368 ctx = _get_ctx(ctx)
10369 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
10370
10371
10372def Float32(ctx=None):
10373 """Floating-point 32-bit (single) sort."""
10374 ctx = _get_ctx(ctx)
10375 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
10376
10377
10378def FloatSingle(ctx=None):
10379 """Floating-point 32-bit (single) sort."""
10380 ctx = _get_ctx(ctx)
10381 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
10382
10383
10384def Float64(ctx=None):
10385 """Floating-point 64-bit (double) sort."""
10386 ctx = _get_ctx(ctx)
10387 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
10388
10389
10390def FloatDouble(ctx=None):
10391 """Floating-point 64-bit (double) sort."""
10392 ctx = _get_ctx(ctx)
10393 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
10394
10395
10396def Float128(ctx=None):
10397 """Floating-point 128-bit (quadruple) sort."""
10398 ctx = _get_ctx(ctx)
10399 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
10400
10401
10402def FloatQuadruple(ctx=None):
10403 """Floating-point 128-bit (quadruple) sort."""
10404 ctx = _get_ctx(ctx)
10405 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
10406
10407
10408class FPRMSortRef(SortRef):
10409 """"Floating-point rounding mode sort."""
10410
10411
10412def is_fp_sort(s):
10413 """Return True if `s` is a Z3 floating-point sort.
10414
10415 >>> is_fp_sort(FPSort(8, 24))
10416 True
10417 >>> is_fp_sort(IntSort())
10418 False
10419 """
10420 return isinstance(s, FPSortRef)
10421
10422
10423def is_fprm_sort(s):
10424 """Return True if `s` is a Z3 floating-point rounding mode sort.
10425
10426 >>> is_fprm_sort(FPSort(8, 24))
10427 False
10428 >>> is_fprm_sort(RNE().sort())
10429 True
10430 """
10431 return isinstance(s, FPRMSortRef)
10432
10433# FP Expressions
10434
10435
10436class FPRef(ExprRef):
10437 """Floating-point expressions."""
10438
10439 def sort(self):
10440 """Return the sort of the floating-point expression `self`.
10441
10442 >>> x = FP('1.0', FPSort(8, 24))
10443 >>> x.sort()
10444 FPSort(8, 24)
10445 >>> x.sort() == FPSort(8, 24)
10446 True
10447 """
10448 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
10449
10450 def ebits(self):
10451 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
10452 >>> b = FPSort(8, 24)
10453 >>> b.ebits()
10454 8
10455 """
10456 return self.sort().ebits()
10457
10458 def sbits(self):
10459 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
10460 >>> b = FPSort(8, 24)
10461 >>> b.sbits()
10462 24
10463 """
10464 return self.sort().sbits()
10465
10466 def as_string(self):
10467 """Return a Z3 floating point expression as a Python string."""
10468 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10469
10470 def __le__(self, other):
10471 return fpLEQ(self, other, self.ctx)
10472
10473 def __lt__(self, other):
10474 return fpLT(self, other, self.ctx)
10475
10476 def __ge__(self, other):
10477 return fpGEQ(self, other, self.ctx)
10478
10479 def __gt__(self, other):
10480 return fpGT(self, other, self.ctx)
10481
10482 def __add__(self, other):
10483 """Create the Z3 expression `self + other`.
10484
10485 >>> x = FP('x', FPSort(8, 24))
10486 >>> y = FP('y', FPSort(8, 24))
10487 >>> x + y
10488 x + y
10489 >>> (x + y).sort()
10490 FPSort(8, 24)
10491 """
10492 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10493 return fpAdd(_dflt_rm(), a, b, self.ctx)
10494
10495 def __radd__(self, other):
10496 """Create the Z3 expression `other + self`.
10497
10498 >>> x = FP('x', FPSort(8, 24))
10499 >>> 10 + x
10500 1.25*(2**3) + x
10501 """
10502 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10503 return fpAdd(_dflt_rm(), a, b, self.ctx)
10504
10505 def __sub__(self, other):
10506 """Create the Z3 expression `self - other`.
10507
10508 >>> x = FP('x', FPSort(8, 24))
10509 >>> y = FP('y', FPSort(8, 24))
10510 >>> x - y
10511 x - y
10512 >>> (x - y).sort()
10513 FPSort(8, 24)
10514 """
10515 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10516 return fpSub(_dflt_rm(), a, b, self.ctx)
10517
10518 def __rsub__(self, other):
10519 """Create the Z3 expression `other - self`.
10520
10521 >>> x = FP('x', FPSort(8, 24))
10522 >>> 10 - x
10523 1.25*(2**3) - x
10524 """
10525 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10526 return fpSub(_dflt_rm(), a, b, self.ctx)
10527
10528 def __mul__(self, other):
10529 """Create the Z3 expression `self * other`.
10530
10531 >>> x = FP('x', FPSort(8, 24))
10532 >>> y = FP('y', FPSort(8, 24))
10533 >>> x * y
10534 x * y
10535 >>> (x * y).sort()
10536 FPSort(8, 24)
10537 >>> 10 * y
10538 1.25*(2**3) * y
10539 """
10540 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10541 return fpMul(_dflt_rm(), a, b, self.ctx)
10542
10543 def __rmul__(self, other):
10544 """Create the Z3 expression `other * self`.
10545
10546 >>> x = FP('x', FPSort(8, 24))
10547 >>> y = FP('y', FPSort(8, 24))
10548 >>> x * y
10549 x * y
10550 >>> x * 10
10551 x * 1.25*(2**3)
10552 """
10553 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10554 return fpMul(_dflt_rm(), a, b, self.ctx)
10555
10556 def __pos__(self):
10557 """Create the Z3 expression `+self`."""
10558 return self
10559
10560 def __neg__(self):
10561 """Create the Z3 expression `-self`.
10562
10563 >>> x = FP('x', Float32())
10564 >>> -x
10565 -x
10566 """
10567 return fpNeg(self)
10568
10569 def __div__(self, other):
10570 """Create the Z3 expression `self / other`.
10571
10572 >>> x = FP('x', FPSort(8, 24))
10573 >>> y = FP('y', FPSort(8, 24))
10574 >>> x / y
10575 x / y
10576 >>> (x / y).sort()
10577 FPSort(8, 24)
10578 >>> 10 / y
10579 1.25*(2**3) / y
10580 """
10581 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10582 return fpDiv(_dflt_rm(), a, b, self.ctx)
10583
10584 def __rdiv__(self, other):
10585 """Create the Z3 expression `other / self`.
10586
10587 >>> x = FP('x', FPSort(8, 24))
10588 >>> y = FP('y', FPSort(8, 24))
10589 >>> x / y
10590 x / y
10591 >>> x / 10
10592 x / 1.25*(2**3)
10593 """
10594 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10595 return fpDiv(_dflt_rm(), a, b, self.ctx)
10596
10597 def __truediv__(self, other):
10598 """Create the Z3 expression division `self / other`."""
10599 return self.__div__(other)
10600
10601 def __rtruediv__(self, other):
10602 """Create the Z3 expression division `other / self`."""
10603 return self.__rdiv__(other)
10604
10605 def __mod__(self, other):
10606 """Create the Z3 expression mod `self % other`."""
10607 return fpRem(self, other)
10608
10609 def __rmod__(self, other):
10610 """Create the Z3 expression mod `other % self`."""
10611 return fpRem(other, self)
10612
10613
10614class FPRMRef(ExprRef):
10615 """Floating-point rounding mode expressions"""
10616
10617 def as_string(self):
10618 """Return a Z3 floating point expression as a Python string."""
10619 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10620
10621
10622def RoundNearestTiesToEven(ctx=None):
10623 ctx = _get_ctx(ctx)
10624 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10625
10626
10627def RNE(ctx=None):
10628 ctx = _get_ctx(ctx)
10629 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10630
10631
10632def RoundNearestTiesToAway(ctx=None):
10633 ctx = _get_ctx(ctx)
10634 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10635
10636
10637def RNA(ctx=None):
10638 ctx = _get_ctx(ctx)
10639 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10640
10641
10642def RoundTowardPositive(ctx=None):
10643 ctx = _get_ctx(ctx)
10644 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10645
10646
10647def RTP(ctx=None):
10648 ctx = _get_ctx(ctx)
10649 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10650
10651
10652def RoundTowardNegative(ctx=None):
10653 ctx = _get_ctx(ctx)
10654 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10655
10656
10657def RTN(ctx=None):
10658 ctx = _get_ctx(ctx)
10659 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10660
10661
10662def RoundTowardZero(ctx=None):
10663 ctx = _get_ctx(ctx)
10664 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10665
10666
10667def RTZ(ctx=None):
10668 ctx = _get_ctx(ctx)
10669 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10670
10671
10672def is_fprm(a):
10673 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
10674
10675 >>> rm = RNE()
10676 >>> is_fprm(rm)
10677 True
10678 >>> rm = 1.0
10679 >>> is_fprm(rm)
10680 False
10681 """
10682 return isinstance(a, FPRMRef)
10683
10684
10685def is_fprm_value(a):
10686 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
10687 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
10688
10689# FP Numerals
10690
10691
10692class FPNumRef(FPRef):
10693 """The sign of the numeral.
10694
10695 >>> x = FPVal(+1.0, FPSort(8, 24))
10696 >>> x.sign()
10697 False
10698 >>> x = FPVal(-1.0, FPSort(8, 24))
10699 >>> x.sign()
10700 True
10701 """
10702
10703 def sign(self):
10704 num = ctypes.c_bool()
10705 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
10706 if nsign is False:
10707 raise Z3Exception("error retrieving the sign of a numeral.")
10708 return num.value != 0
10709
10710 """The sign of a floating-point numeral as a bit-vector expression.
10711
10712 Remark: NaN's are invalid arguments.
10713 """
10714
10715 def sign_as_bv(self):
10716 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10717
10718 """The significand of the numeral.
10719
10720 >>> x = FPVal(2.5, FPSort(8, 24))
10721 >>> x.significand()
10722 1.25
10723 """
10724
10725 def significand(self):
10726 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10727
10728 """The significand of the numeral as a long.
10729
10730 >>> x = FPVal(2.5, FPSort(8, 24))
10731 >>> x.significand_as_long()
10732 1.25
10733 """
10734
10735 def significand_as_long(self):
10736 ptr = (ctypes.c_ulonglong * 1)()
10737 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10738 raise Z3Exception("error retrieving the significand of a numeral.")
10739 return ptr[0]
10740
10741 """The significand of the numeral as a bit-vector expression.
10742
10743 Remark: NaN are invalid arguments.
10744 """
10745
10746 def significand_as_bv(self):
10747 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10748
10749 """The exponent of the numeral.
10750
10751 >>> x = FPVal(2.5, FPSort(8, 24))
10752 >>> x.exponent()
10753 1
10754 """
10755
10756 def exponent(self, biased=True):
10757 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10758
10759 """The exponent of the numeral as a long.
10760
10761 >>> x = FPVal(2.5, FPSort(8, 24))
10762 >>> x.exponent_as_long()
10763 1
10764 """
10765
10766 def exponent_as_long(self, biased=True):
10767 ptr = (ctypes.c_longlong * 1)()
10768 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10769 raise Z3Exception("error retrieving the exponent of a numeral.")
10770 return ptr[0]
10771
10772 """The exponent of the numeral as a bit-vector expression.
10773
10774 Remark: NaNs are invalid arguments.
10775 """
10776
10777 def exponent_as_bv(self, biased=True):
10778 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10779
10780 """Indicates whether the numeral is a NaN."""
10781
10782 def isNaN(self):
10783 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10784
10785 """Indicates whether the numeral is +oo or -oo."""
10786
10787 def isInf(self):
10788 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10789
10790 """Indicates whether the numeral is +zero or -zero."""
10791
10792 def isZero(self):
10793 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10794
10795 """Indicates whether the numeral is normal."""
10796
10797 def isNormal(self):
10798 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10799
10800 """Indicates whether the numeral is subnormal."""
10801
10802 def isSubnormal(self):
10803 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10804
10805 """Indicates whether the numeral is positive."""
10806
10807 def isPositive(self):
10808 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10809
10810 """Indicates whether the numeral is negative."""
10811
10812 def isNegative(self):
10813 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10814
10815 """
10816 The string representation of the numeral.
10817
10818 >>> x = FPVal(20, FPSort(8, 24))
10819 >>> x.as_string()
10820 1.25*(2**4)
10821 """
10822
10823 def as_string(self):
10824 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10825 return ("FPVal(%s, %s)" % (s, self.sort()))
10826
10827 def py_value(self):
10828 bv = simplify(fpToIEEEBV(self))
10829 binary = bv.py_value()
10830 if not isinstance(binary, int):
10831 return None
10832 # Decode the IEEE 754 binary representation
10833 import struct
10834 bytes_rep = binary.to_bytes(8, byteorder='big')
10835 return struct.unpack('>d', bytes_rep)[0]
10836
10837
10838def is_fp(a):
10839 """Return `True` if `a` is a Z3 floating-point expression.
10840
10841 >>> b = FP('b', FPSort(8, 24))
10842 >>> is_fp(b)
10843 True
10844 >>> is_fp(b + 1.0)
10845 True
10846 >>> is_fp(Int('x'))
10847 False
10848 """
10849 return isinstance(a, FPRef)
10850
10851
10852def is_fp_value(a):
10853 """Return `True` if `a` is a Z3 floating-point numeral value.
10854
10855 >>> b = FP('b', FPSort(8, 24))
10856 >>> is_fp_value(b)
10857 False
10858 >>> b = FPVal(1.0, FPSort(8, 24))
10859 >>> b
10860 1
10861 >>> is_fp_value(b)
10862 True
10863 """
10864 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10865
10866
10867def FPSort(ebits, sbits, ctx=None):
10868 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10869
10870 >>> Single = FPSort(8, 24)
10871 >>> Double = FPSort(11, 53)
10872 >>> Single
10873 FPSort(8, 24)
10874 >>> x = Const('x', Single)
10875 >>> eq(x, FP('x', FPSort(8, 24)))
10876 True
10877 """
10878 ctx = _get_ctx(ctx)
10879 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10880
10881
10882def _to_float_str(val, exp=0):
10883 if isinstance(val, float):
10884 if math.isnan(val):
10885 res = "NaN"
10886 elif val == 0.0:
10887 sone = math.copysign(1.0, val)
10888 if sone < 0.0:
10889 return "-0.0"
10890 else:
10891 return "+0.0"
10892 elif val == float("+inf"):
10893 res = "+oo"
10894 elif val == float("-inf"):
10895 res = "-oo"
10896 else:
10897 v = val.as_integer_ratio()
10898 num = v[0]
10899 den = v[1]
10900 rvs = str(num) + "/" + str(den)
10901 res = rvs
10902 elif isinstance(val, bool):
10903 if val:
10904 res = "1.0"
10905 else:
10906 res = "0.0"
10907 elif _is_int(val):
10908 res = str(val)
10909 elif isinstance(val, str):
10910 inx = val.find("*(2**")
10911 if inx == -1:
10912 res = val
10913 if exp != 0:
10914 inx = val.lower().find("p")
10915 if inx != -1:
10916 res = val[:inx]
10917 exp = int(val[inx + 1:]) + int(exp)
10918 elif val[-1] == ")":
10919 res = val[0:inx]
10920 exp = str(int(val[inx + 5:-1]) + int(exp))
10921 else:
10922 _z3_assert(False, "String does not have floating-point numeral form.")
10923 elif z3_debug():
10924 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10925 if exp == 0:
10926 return res
10927 else:
10928 return res + "p" + str(exp)
10929
10930
10931def fpNaN(s):
10932 """Create a Z3 floating-point NaN term.
10933
10934 >>> s = FPSort(8, 24)
10935 >>> set_fpa_pretty(True)
10936 >>> fpNaN(s)
10937 NaN
10938 >>> pb = get_fpa_pretty()
10939 >>> set_fpa_pretty(False)
10940 >>> fpNaN(s)
10941 fpNaN(FPSort(8, 24))
10942 >>> set_fpa_pretty(pb)
10943 """
10944 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10945 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10946
10947
10948def fpPlusInfinity(s):
10949 """Create a Z3 floating-point +oo term.
10950
10951 >>> s = FPSort(8, 24)
10952 >>> pb = get_fpa_pretty()
10953 >>> set_fpa_pretty(True)
10954 >>> fpPlusInfinity(s)
10955 +oo
10956 >>> set_fpa_pretty(False)
10957 >>> fpPlusInfinity(s)
10958 fpPlusInfinity(FPSort(8, 24))
10959 >>> set_fpa_pretty(pb)
10960 """
10961 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10962 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10963
10964
10965def fpMinusInfinity(s):
10966 """Create a Z3 floating-point -oo term."""
10967 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10968 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10969
10970
10971def fpInfinity(s, negative):
10972 """Create a Z3 floating-point +oo or -oo term."""
10973 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10974 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10975 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10976
10977
10978def fpPlusZero(s):
10979 """Create a Z3 floating-point +0.0 term."""
10980 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10981 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10982
10983
10984def fpMinusZero(s):
10985 """Create a Z3 floating-point -0.0 term."""
10986 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10987 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10988
10989
10990def fpZero(s, negative):
10991 """Create a Z3 floating-point +0.0 or -0.0 term."""
10992 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10993 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10994 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10995
10996
10997def FPVal(sig, exp=None, fps=None, ctx=None):
10998 """Return a floating-point value of value `sig * 2**exp` and sort `fps`.
10999 If `exp=None`, then the exponent is zero.
11000 If `ctx=None`, then the global context is used.
11001
11002 >>> v = FPVal(20.0, FPSort(8, 24))
11003 >>> v
11004 1.25*(2**4)
11005 >>> print("0x%.8x" % v.exponent_as_long(False))
11006 0x00000004
11007 >>> v = FPVal(2.25, FPSort(8, 24))
11008 >>> v
11009 1.125*(2**1)
11010 >>> v = FPVal(-2.25, FPSort(8, 24))
11011 >>> v
11012 -1.125*(2**1)
11013 >>> FPVal(-0.0, FPSort(8, 24))
11014 -0.0
11015 >>> FPVal(0.0, FPSort(8, 24))
11016 +0.0
11017 >>> FPVal(+0.0, FPSort(8, 24))
11018 +0.0
11019 >>> FPVal(1.0, 3, Float32())
11020 1*(2**3)
11021 >>> FPVal(1, 3, Float32())
11022 1*(2**3)
11023 >>> FPVal("1.5", -2, Float32())
11024 1.5*(2**-2)
11025 >>> FPVal("1.25*(2**4)", 1, Float32())
11026 1.25*(2**5)
11027 >>> FPVal("1.25*(2**4)", -4, Float32())
11028 1.25
11029 >>> FPVal("1p2", 3, Float32())
11030 1*(2**5)
11031 >>> FPVal("1P2", 3, Float32())
11032 1*(2**5)
11033 >>> FPVal("1.5p-2", 2, Float32())
11034 1.5
11035 >>> FPVal(1.5, 0, Float32())
11036 1.5
11037 >>> FPVal(1.5, fps=Float32())
11038 1.5
11039 >>> [FPVal(v, 3, Float32()) for v in
11040 ... [float("nan"), float("inf"), float("-inf"), 0.0, -0.0]]
11041 [NaN, +oo, -oo, +0.0, -0.0]
11042 >>> [FPVal(v, -2, Float32()) for v in
11043 ... ["NaN", "+oo", "-oo", "+0.0", "-0.0"]]
11044 [NaN, +oo, -oo, +0.0, -0.0]
11045 """
11046 ctx = _get_ctx(ctx)
11047 if is_fp_sort(exp):
11048 fps = exp
11049 exp = None
11050 elif fps is None:
11051 fps = _dflt_fps(ctx)
11052 _z3_assert(is_fp_sort(fps), "sort mismatch")
11053 if exp is None:
11054 exp = 0
11055 val = _to_float_str(sig)
11056 if val == "NaN" or val == "nan":
11057 return fpNaN(fps)
11058 elif val == "-0.0":
11059 return fpMinusZero(fps)
11060 elif val == "0.0" or val == "+0.0":
11061 return fpPlusZero(fps)
11062 elif val == "+oo" or val == "+inf" or val == "+Inf":
11063 return fpPlusInfinity(fps)
11064 elif val == "-oo" or val == "-inf" or val == "-Inf":
11065 return fpMinusInfinity(fps)
11066 else:
11067 return FPNumRef(Z3_mk_numeral(ctx.ref(), _to_float_str(sig, exp), fps.ast), ctx)
11068
11069
11070def FP(name, fpsort, ctx=None):
11071 """Return a floating-point constant named `name`.
11072 `fpsort` is the floating-point sort.
11073 If `ctx=None`, then the global context is used.
11074
11075 >>> x = FP('x', FPSort(8, 24))
11076 >>> is_fp(x)
11077 True
11078 >>> x.ebits()
11079 8
11080 >>> x.sort()
11081 FPSort(8, 24)
11082 >>> word = FPSort(8, 24)
11083 >>> x2 = FP('x', word)
11084 >>> eq(x, x2)
11085 True
11086 """
11087 if isinstance(fpsort, FPSortRef) and ctx is None:
11088 ctx = fpsort.ctx
11089 else:
11090 ctx = _get_ctx(ctx)
11091 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
11092
11093
11094def FPs(names, fpsort, ctx=None):
11095 """Return an array of floating-point constants.
11096
11097 >>> x, y, z = FPs('x y z', FPSort(8, 24))
11098 >>> x.sort()
11099 FPSort(8, 24)
11100 >>> x.sbits()
11101 24
11102 >>> x.ebits()
11103 8
11104 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
11105 (x + y) * z
11106 """
11107 ctx = _get_ctx(ctx)
11108 if isinstance(names, str):
11109 names = names.split(" ")
11110 return [FP(name, fpsort, ctx) for name in names]
11111
11112
11113def fpAbs(a, ctx=None):
11114 """Create a Z3 floating-point absolute value expression.
11115
11116 >>> s = FPSort(8, 24)
11117 >>> rm = RNE()
11118 >>> x = FPVal(1.0, s)
11119 >>> fpAbs(x)
11120 fpAbs(1)
11121 >>> y = FPVal(-20.0, s)
11122 >>> y
11123 -1.25*(2**4)
11124 >>> fpAbs(y)
11125 fpAbs(-1.25*(2**4))
11126 >>> fpAbs(-1.25*(2**4))
11127 fpAbs(-1.25*(2**4))
11128 >>> fpAbs(x).sort()
11129 FPSort(8, 24)
11130 """
11131 ctx = _get_ctx(ctx)
11132 [a] = _coerce_fp_expr_list([a], ctx)
11133 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
11134
11135
11136def fpNeg(a, ctx=None):
11137 """Create a Z3 floating-point addition expression.
11138
11139 >>> s = FPSort(8, 24)
11140 >>> rm = RNE()
11141 >>> x = FP('x', s)
11142 >>> fpNeg(x)
11143 -x
11144 >>> fpNeg(x).sort()
11145 FPSort(8, 24)
11146 """
11147 ctx = _get_ctx(ctx)
11148 [a] = _coerce_fp_expr_list([a], ctx)
11149 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
11150
11151
11152def _mk_fp_unary(f, rm, a, ctx):
11153 ctx = _get_ctx(ctx)
11154 [a] = _coerce_fp_expr_list([a], ctx)
11155 if z3_debug():
11156 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11157 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
11158 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
11159
11160
11161def _mk_fp_unary_pred(f, a, ctx):
11162 ctx = _get_ctx(ctx)
11163 [a] = _coerce_fp_expr_list([a], ctx)
11164 if z3_debug():
11165 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
11166 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
11167
11168
11169def _mk_fp_bin(f, rm, a, b, ctx):
11170 ctx = _get_ctx(ctx)
11171 [a, b] = _coerce_fp_expr_list([a, b], ctx)
11172 if z3_debug():
11173 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11174 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
11175 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
11176
11177
11178def _mk_fp_bin_norm(f, a, b, ctx):
11179 ctx = _get_ctx(ctx)
11180 [a, b] = _coerce_fp_expr_list([a, b], ctx)
11181 if z3_debug():
11182 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
11183 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
11184
11185
11186def _mk_fp_bin_pred(f, a, b, ctx):
11187 ctx = _get_ctx(ctx)
11188 [a, b] = _coerce_fp_expr_list([a, b], ctx)
11189 if z3_debug():
11190 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
11191 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
11192
11193
11194def _mk_fp_tern(f, rm, a, b, c, ctx):
11195 ctx = _get_ctx(ctx)
11196 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
11197 if z3_debug():
11198 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11199 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
11200 c), "Second, third or fourth argument must be a Z3 floating-point expression")
11201 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
11202
11203
11204def fpAdd(rm, a, b, ctx=None):
11205 """Create a Z3 floating-point addition expression.
11206
11207 >>> s = FPSort(8, 24)
11208 >>> rm = RNE()
11209 >>> x = FP('x', s)
11210 >>> y = FP('y', s)
11211 >>> fpAdd(rm, x, y)
11212 x + y
11213 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
11214 fpAdd(RTZ(), x, y)
11215 >>> fpAdd(rm, x, y).sort()
11216 FPSort(8, 24)
11217 """
11218 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
11219
11220
11221def fpSub(rm, a, b, ctx=None):
11222 """Create a Z3 floating-point subtraction expression.
11223
11224 >>> s = FPSort(8, 24)
11225 >>> rm = RNE()
11226 >>> x = FP('x', s)
11227 >>> y = FP('y', s)
11228 >>> fpSub(rm, x, y)
11229 x - y
11230 >>> fpSub(rm, x, y).sort()
11231 FPSort(8, 24)
11232 """
11233 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
11234
11235
11236def fpMul(rm, a, b, ctx=None):
11237 """Create a Z3 floating-point multiplication expression.
11238
11239 >>> s = FPSort(8, 24)
11240 >>> rm = RNE()
11241 >>> x = FP('x', s)
11242 >>> y = FP('y', s)
11243 >>> fpMul(rm, x, y)
11244 x * y
11245 >>> fpMul(rm, x, y).sort()
11246 FPSort(8, 24)
11247 """
11248 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
11249
11250
11251def fpDiv(rm, a, b, ctx=None):
11252 """Create a Z3 floating-point division expression.
11253
11254 >>> s = FPSort(8, 24)
11255 >>> rm = RNE()
11256 >>> x = FP('x', s)
11257 >>> y = FP('y', s)
11258 >>> fpDiv(rm, x, y)
11259 x / y
11260 >>> fpDiv(rm, x, y).sort()
11261 FPSort(8, 24)
11262 """
11263 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
11264
11265
11266def fpRem(a, b, ctx=None):
11267 """Create a Z3 floating-point remainder expression.
11268
11269 >>> s = FPSort(8, 24)
11270 >>> x = FP('x', s)
11271 >>> y = FP('y', s)
11272 >>> fpRem(x, y)
11273 fpRem(x, y)
11274 >>> fpRem(x, y).sort()
11275 FPSort(8, 24)
11276 """
11277 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
11278
11279
11280def fpMin(a, b, ctx=None):
11281 """Create a Z3 floating-point minimum expression.
11282
11283 >>> s = FPSort(8, 24)
11284 >>> rm = RNE()
11285 >>> x = FP('x', s)
11286 >>> y = FP('y', s)
11287 >>> fpMin(x, y)
11288 fpMin(x, y)
11289 >>> fpMin(x, y).sort()
11290 FPSort(8, 24)
11291 """
11292 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
11293
11294
11295def fpMax(a, b, ctx=None):
11296 """Create a Z3 floating-point maximum expression.
11297
11298 >>> s = FPSort(8, 24)
11299 >>> rm = RNE()
11300 >>> x = FP('x', s)
11301 >>> y = FP('y', s)
11302 >>> fpMax(x, y)
11303 fpMax(x, y)
11304 >>> fpMax(x, y).sort()
11305 FPSort(8, 24)
11306 """
11307 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
11308
11309
11310def fpFMA(rm, a, b, c, ctx=None):
11311 """Create a Z3 floating-point fused multiply-add expression.
11312 """
11313 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
11314
11315
11316def fpSqrt(rm, a, ctx=None):
11317 """Create a Z3 floating-point square root expression.
11318 """
11319 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
11320
11321
11322def fpRoundToIntegral(rm, a, ctx=None):
11323 """Create a Z3 floating-point roundToIntegral expression.
11324 """
11325 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
11326
11327
11328def fpIsNaN(a, ctx=None):
11329 """Create a Z3 floating-point isNaN expression.
11330
11331 >>> s = FPSort(8, 24)
11332 >>> x = FP('x', s)
11333 >>> y = FP('y', s)
11334 >>> fpIsNaN(x)
11335 fpIsNaN(x)
11336 """
11337 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
11338
11339
11340def fpIsInf(a, ctx=None):
11341 """Create a Z3 floating-point isInfinite expression.
11342
11343 >>> s = FPSort(8, 24)
11344 >>> x = FP('x', s)
11345 >>> fpIsInf(x)
11346 fpIsInf(x)
11347 """
11348 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
11349
11350
11351def fpIsZero(a, ctx=None):
11352 """Create a Z3 floating-point isZero expression.
11353 """
11354 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
11355
11356
11357def fpIsNormal(a, ctx=None):
11358 """Create a Z3 floating-point isNormal expression.
11359 """
11360 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
11361
11362
11363def fpIsSubnormal(a, ctx=None):
11364 """Create a Z3 floating-point isSubnormal expression.
11365 """
11366 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
11367
11368
11369def fpIsNegative(a, ctx=None):
11370 """Create a Z3 floating-point isNegative expression.
11371 """
11372 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
11373
11374
11375def fpIsPositive(a, ctx=None):
11376 """Create a Z3 floating-point isPositive expression.
11377 """
11378 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
11379
11380
11381def _check_fp_args(a, b):
11382 if z3_debug():
11383 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
11384
11385
11386def fpLT(a, b, ctx=None):
11387 """Create the Z3 floating-point expression `other < self`.
11388
11389 >>> x, y = FPs('x y', FPSort(8, 24))
11390 >>> fpLT(x, y)
11391 x < y
11392 >>> (x < y).sexpr()
11393 '(fp.lt x y)'
11394 """
11395 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
11396
11397
11398def fpLEQ(a, b, ctx=None):
11399 """Create the Z3 floating-point expression `other <= self`.
11400
11401 >>> x, y = FPs('x y', FPSort(8, 24))
11402 >>> fpLEQ(x, y)
11403 x <= y
11404 >>> (x <= y).sexpr()
11405 '(fp.leq x y)'
11406 """
11407 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
11408
11409
11410def fpGT(a, b, ctx=None):
11411 """Create the Z3 floating-point expression `other > self`.
11412
11413 >>> x, y = FPs('x y', FPSort(8, 24))
11414 >>> fpGT(x, y)
11415 x > y
11416 >>> (x > y).sexpr()
11417 '(fp.gt x y)'
11418 """
11419 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
11420
11421
11422def fpGEQ(a, b, ctx=None):
11423 """Create the Z3 floating-point expression `other >= self`.
11424
11425 >>> x, y = FPs('x y', FPSort(8, 24))
11426 >>> fpGEQ(x, y)
11427 x >= y
11428 >>> (x >= y).sexpr()
11429 '(fp.geq x y)'
11430 """
11431 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
11432
11433
11434def fpEQ(a, b, ctx=None):
11435 """Create the Z3 floating-point expression `fpEQ(other, self)`.
11436
11437 >>> x, y = FPs('x y', FPSort(8, 24))
11438 >>> fpEQ(x, y)
11439 fpEQ(x, y)
11440 >>> fpEQ(x, y).sexpr()
11441 '(fp.eq x y)'
11442 """
11443 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
11444
11445
11446def fpNEQ(a, b, ctx=None):
11447 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
11448
11449 >>> x, y = FPs('x y', FPSort(8, 24))
11450 >>> fpNEQ(x, y)
11451 Not(fpEQ(x, y))
11452 >>> (x != y).sexpr()
11453 '(distinct x y)'
11454 """
11455 return Not(fpEQ(a, b, ctx))
11456
11457
11458def fpFP(sgn, exp, sig, ctx=None):
11459 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
11460
11461 >>> s = FPSort(8, 24)
11462 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
11463 >>> print(x)
11464 fpFP(1, 127, 4194304)
11465 >>> xv = FPVal(-1.5, s)
11466 >>> print(xv)
11467 -1.5
11468 >>> slvr = Solver()
11469 >>> slvr.add(fpEQ(x, xv))
11470 >>> slvr.check()
11471 sat
11472 >>> xv = FPVal(+1.5, s)
11473 >>> print(xv)
11474 1.5
11475 >>> slvr = Solver()
11476 >>> slvr.add(fpEQ(x, xv))
11477 >>> slvr.check()
11478 unsat
11479 """
11480 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
11481 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
11482 ctx = _get_ctx(ctx)
11483 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
11484 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
11485
11486
11487def fpToFP(a1, a2=None, a3=None, ctx=None):
11488 """Create a Z3 floating-point conversion expression from other term sorts
11489 to floating-point.
11490
11491 From a bit-vector term in IEEE 754-2008 format:
11492 >>> x = FPVal(1.0, Float32())
11493 >>> x_bv = fpToIEEEBV(x)
11494 >>> simplify(fpToFP(x_bv, Float32()))
11495 1
11496
11497 From a floating-point term with different precision:
11498 >>> x = FPVal(1.0, Float32())
11499 >>> x_db = fpToFP(RNE(), x, Float64())
11500 >>> x_db.sort()
11501 FPSort(11, 53)
11502
11503 From a real term:
11504 >>> x_r = RealVal(1.5)
11505 >>> simplify(fpToFP(RNE(), x_r, Float32()))
11506 1.5
11507
11508 From a signed bit-vector term:
11509 >>> x_signed = BitVecVal(-5, BitVecSort(32))
11510 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
11511 -1.25*(2**2)
11512 """
11513 ctx = _get_ctx(ctx)
11514 if is_bv(a1) and is_fp_sort(a2):
11515 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
11516 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
11517 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
11518 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
11519 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
11520 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
11521 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
11522 else:
11523 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
11524
11525
11526def fpBVToFP(v, sort, ctx=None):
11527 """Create a Z3 floating-point conversion expression that represents the
11528 conversion from a bit-vector term to a floating-point term.
11529
11530 >>> x_bv = BitVecVal(0x3F800000, 32)
11531 >>> x_fp = fpBVToFP(x_bv, Float32())
11532 >>> x_fp
11533 fpToFP(1065353216)
11534 >>> simplify(x_fp)
11535 1
11536 """
11537 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
11538 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
11539 ctx = _get_ctx(ctx)
11540 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
11541
11542
11543def fpFPToFP(rm, v, sort, ctx=None):
11544 """Create a Z3 floating-point conversion expression that represents the
11545 conversion from a floating-point term to a floating-point term of different precision.
11546
11547 >>> x_sgl = FPVal(1.0, Float32())
11548 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
11549 >>> x_dbl
11550 fpToFP(RNE(), 1)
11551 >>> simplify(x_dbl)
11552 1
11553 >>> x_dbl.sort()
11554 FPSort(11, 53)
11555 """
11556 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11557 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
11558 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11559 ctx = _get_ctx(ctx)
11560 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11561
11562
11563def fpRealToFP(rm, v, sort, ctx=None):
11564 """Create a Z3 floating-point conversion expression that represents the
11565 conversion from a real term to a floating-point term.
11566
11567 >>> x_r = RealVal(1.5)
11568 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
11569 >>> x_fp
11570 fpToFP(RNE(), 3/2)
11571 >>> simplify(x_fp)
11572 1.5
11573 """
11574 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11575 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
11576 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11577 ctx = _get_ctx(ctx)
11578 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11579
11580
11581def fpSignedToFP(rm, v, sort, ctx=None):
11582 """Create a Z3 floating-point conversion expression that represents the
11583 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
11584
11585 >>> x_signed = BitVecVal(-5, BitVecSort(32))
11586 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
11587 >>> x_fp
11588 fpToFP(RNE(), 4294967291)
11589 >>> simplify(x_fp)
11590 -1.25*(2**2)
11591 """
11592 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11593 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
11594 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11595 ctx = _get_ctx(ctx)
11596 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11597
11598
11599def fpUnsignedToFP(rm, v, sort, ctx=None):
11600 """Create a Z3 floating-point conversion expression that represents the
11601 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
11602
11603 >>> x_signed = BitVecVal(-5, BitVecSort(32))
11604 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
11605 >>> x_fp
11606 fpToFPUnsigned(RNE(), 4294967291)
11607 >>> simplify(x_fp)
11608 1*(2**32)
11609 """
11610 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11611 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
11612 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11613 ctx = _get_ctx(ctx)
11614 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11615
11616
11617def fpToFPUnsigned(rm, x, s, ctx=None):
11618 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
11619 if z3_debug():
11620 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11621 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
11622 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
11623 ctx = _get_ctx(ctx)
11624 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
11625
11626
11627def fpToSBV(rm, x, s, ctx=None):
11628 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
11629
11630 >>> x = FP('x', FPSort(8, 24))
11631 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
11632 >>> print(is_fp(x))
11633 True
11634 >>> print(is_bv(y))
11635 True
11636 >>> print(is_fp(y))
11637 False
11638 >>> print(is_bv(x))
11639 False
11640 """
11641 if z3_debug():
11642 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11643 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11644 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11645 ctx = _get_ctx(ctx)
11646 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11647
11648
11649def fpToUBV(rm, x, s, ctx=None):
11650 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
11651
11652 >>> x = FP('x', FPSort(8, 24))
11653 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
11654 >>> print(is_fp(x))
11655 True
11656 >>> print(is_bv(y))
11657 True
11658 >>> print(is_fp(y))
11659 False
11660 >>> print(is_bv(x))
11661 False
11662 """
11663 if z3_debug():
11664 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11665 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11666 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11667 ctx = _get_ctx(ctx)
11668 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11669
11670
11671def fpToReal(x, ctx=None):
11672 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
11673
11674 >>> x = FP('x', FPSort(8, 24))
11675 >>> y = fpToReal(x)
11676 >>> print(is_fp(x))
11677 True
11678 >>> print(is_real(y))
11679 True
11680 >>> print(is_fp(y))
11681 False
11682 >>> print(is_real(x))
11683 False
11684 """
11685 if z3_debug():
11686 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11687 ctx = _get_ctx(ctx)
11688 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
11689
11690
11691def fpToIEEEBV(x, ctx=None):
11692 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
11693
11694 The size of the resulting bit-vector is automatically determined.
11695
11696 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
11697 knows only one NaN and it will always produce the same bit-vector representation of
11698 that NaN.
11699
11700 >>> x = FP('x', FPSort(8, 24))
11701 >>> y = fpToIEEEBV(x)
11702 >>> print(is_fp(x))
11703 True
11704 >>> print(is_bv(y))
11705 True
11706 >>> print(is_fp(y))
11707 False
11708 >>> print(is_bv(x))
11709 False
11710 """
11711 if z3_debug():
11712 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11713 ctx = _get_ctx(ctx)
11714 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
11715
11716
11717#########################################
11718#
11719# Strings, Sequences and Regular expressions
11720#
11721#########################################
11722
11723class SeqSortRef(SortRef):
11724 """Sequence sort."""
11725
11726 def is_string(self):
11727 """Determine if sort is a string
11728 >>> s = StringSort()
11729 >>> s.is_string()
11730 True
11731 >>> s = SeqSort(IntSort())
11732 >>> s.is_string()
11733 False
11734 """
11735 return Z3_is_string_sort(self.ctx_ref(), self.ast)
11736
11737 def basis(self):
11738 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11739
11740class CharSortRef(SortRef):
11741 """Character sort."""
11742
11743
11744def StringSort(ctx=None):
11745 """Create a string sort
11746 >>> s = StringSort()
11747 >>> print(s)
11748 String
11749 """
11750 ctx = _get_ctx(ctx)
11751 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
11752
11753def CharSort(ctx=None):
11754 """Create a character sort
11755 >>> ch = CharSort()
11756 >>> print(ch)
11757 Char
11758 """
11759 ctx = _get_ctx(ctx)
11760 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11761
11762
11763def SeqSort(s):
11764 """Create a sequence sort over elements provided in the argument
11765 >>> s = SeqSort(IntSort())
11766 >>> s == Unit(IntVal(1)).sort()
11767 True
11768 """
11769 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11770
11771
11772class SeqRef(ExprRef):
11773 """Sequence expression."""
11774
11775 def sort(self):
11776 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11777
11778 def __add__(self, other):
11779 return Concat(self, other)
11780
11781 def __radd__(self, other):
11782 return Concat(other, self)
11783
11784 def __pow__(self, other):
11785 return SeqPower(self, other)
11786
11787 def __getitem__(self, i):
11788 if _is_int(i):
11789 i = IntVal(i, self.ctx)
11790 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11791
11792 def at(self, i):
11793 if _is_int(i):
11794 i = IntVal(i, self.ctx)
11795 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11796
11797 def is_string(self):
11798 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11799
11800 def is_string_value(self):
11801 return Z3_is_string(self.ctx_ref(), self.as_ast())
11802
11803 def as_string(self):
11804 """Return a string representation of sequence expression."""
11805 if self.is_string_value():
11806 string_length = ctypes.c_uint()
11807 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11808 return string_at(chars, size=string_length.value).decode("latin-1")
11809 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11810
11811 def py_value(self):
11812 return self.as_string()
11813
11814 def __le__(self, other):
11815 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11816
11817 def __lt__(self, other):
11818 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11819
11820 def __ge__(self, other):
11821 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11822
11823 def __gt__(self, other):
11824 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11825
11826
11827def _coerce_char(ch, ctx=None):
11828 if isinstance(ch, str):
11829 ctx = _get_ctx(ctx)
11830 ch = CharVal(ch, ctx)
11831 if not is_expr(ch):
11832 raise Z3Exception("Character expression expected")
11833 return ch
11834
11835class CharRef(ExprRef):
11836 """Character expression."""
11837
11838 def __le__(self, other):
11839 other = _coerce_char(other, self.ctx)
11840 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11841
11842 def to_int(self):
11843 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11844
11845 def to_bv(self):
11846 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11847
11848 def is_digit(self):
11849 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11850
11851
11852def CharVal(ch, ctx=None):
11853 ctx = _get_ctx(ctx)
11854 if isinstance(ch, str):
11855 ch = ord(ch)
11856 if not isinstance(ch, int):
11857 raise Z3Exception("character value should be an ordinal")
11858 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11859
11860def CharFromBv(bv):
11861 if not is_expr(bv):
11862 raise Z3Exception("Bit-vector expression needed")
11863 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11864
11865def CharToBv(ch, ctx=None):
11866 ch = _coerce_char(ch, ctx)
11867 return ch.to_bv()
11868
11869def CharToInt(ch, ctx=None):
11870 ch = _coerce_char(ch, ctx)
11871 return ch.to_int()
11872
11873def CharIsDigit(ch, ctx=None):
11874 ch = _coerce_char(ch, ctx)
11875 return ch.is_digit()
11876
11877def _coerce_seq(s, ctx=None):
11878 if isinstance(s, str):
11879 ctx = _get_ctx(ctx)
11880 s = StringVal(s, ctx)
11881 if not is_expr(s):
11882 raise Z3Exception("Non-expression passed as a sequence")
11883 if not is_seq(s):
11884 raise Z3Exception("Non-sequence passed as a sequence")
11885 return s
11886
11887
11888def _get_ctx2(a, b, ctx=None):
11889 if is_expr(a):
11890 return a.ctx
11891 if is_expr(b):
11892 return b.ctx
11893 if ctx is None:
11894 ctx = main_ctx()
11895 return ctx
11896
11897
11898def is_seq(a):
11899 """Return `True` if `a` is a Z3 sequence expression.
11900 >>> print (is_seq(Unit(IntVal(0))))
11901 True
11902 >>> print (is_seq(StringVal("abc")))
11903 True
11904 """
11905 return isinstance(a, SeqRef)
11906
11907
11908def is_string(a: Any) -> bool:
11909 """Return `True` if `a` is a Z3 string expression.
11910 >>> print (is_string(StringVal("ab")))
11911 True
11912 """
11913 return isinstance(a, SeqRef) and a.is_string()
11914
11915
11916def is_string_value(a: Any) -> bool:
11917 """return 'True' if 'a' is a Z3 string constant expression.
11918 >>> print (is_string_value(StringVal("a")))
11919 True
11920 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11921 False
11922 """
11923 return isinstance(a, SeqRef) and a.is_string_value()
11924
11925def StringVal(s, ctx=None):
11926 """create a string expression"""
11927 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11928 ctx = _get_ctx(ctx)
11929 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11930
11931
11932def String(name, ctx=None):
11933 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11934
11935 >>> x = String('x')
11936 """
11937 ctx = _get_ctx(ctx)
11938 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11939
11940
11941def Strings(names, ctx=None):
11942 """Return a tuple of String constants. """
11943 ctx = _get_ctx(ctx)
11944 if isinstance(names, str):
11945 names = names.split(" ")
11946 return [String(name, ctx) for name in names]
11947
11948
11949def SubString(s, offset, length):
11950 """Extract substring or subsequence starting at offset.
11951
11952 This is a convenience function that redirects to Extract(s, offset, length).
11953
11954 >>> s = StringVal("hello world")
11955 >>> SubString(s, 6, 5) # Extract "world"
11956 str.substr("hello world", 6, 5)
11957 >>> simplify(SubString(StringVal("hello"), 1, 3))
11958 "ell"
11959 """
11960 return Extract(s, offset, length)
11961
11962
11963def SubSeq(s, offset, length):
11964 """Extract substring or subsequence starting at offset.
11965
11966 This is a convenience function that redirects to Extract(s, offset, length).
11967
11968 >>> s = StringVal("hello world")
11969 >>> SubSeq(s, 0, 5) # Extract "hello"
11970 str.substr("hello world", 0, 5)
11971 >>> simplify(SubSeq(StringVal("testing"), 2, 4))
11972 "stin"
11973 """
11974 return Extract(s, offset, length)
11975
11976
11977def Empty(s):
11978 """Create the empty sequence of the given sort
11979 >>> e = Empty(StringSort())
11980 >>> e2 = StringVal("")
11981 >>> print(e.eq(e2))
11982 True
11983 >>> e3 = Empty(SeqSort(IntSort()))
11984 >>> print(e3)
11985 Empty(Seq(Int))
11986 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11987 >>> print(e4)
11988 Empty(ReSort(Seq(Int)))
11989 """
11990 if isinstance(s, SeqSortRef):
11991 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11992 if isinstance(s, ReSortRef):
11993 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11994 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11995
11996
11997def Full(s):
11998 """Create the regular expression that accepts the universal language
11999 >>> e = Full(ReSort(SeqSort(IntSort())))
12000 >>> print(e)
12001 Full(ReSort(Seq(Int)))
12002 >>> e1 = Full(ReSort(StringSort()))
12003 >>> print(e1)
12004 Full(ReSort(String))
12005 """
12006 if isinstance(s, ReSortRef):
12007 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
12008 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
12009
12010
12011
12012def Unit(a):
12013 """Create a singleton sequence"""
12014 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
12015
12016
12017def PrefixOf(a, b):
12018 """Check if 'a' is a prefix of 'b'
12019 >>> s1 = PrefixOf("ab", "abc")
12020 >>> simplify(s1)
12021 True
12022 >>> s2 = PrefixOf("bc", "abc")
12023 >>> simplify(s2)
12024 False
12025 """
12026 ctx = _get_ctx2(a, b)
12027 a = _coerce_seq(a, ctx)
12028 b = _coerce_seq(b, ctx)
12029 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
12030
12031
12032def SuffixOf(a, b):
12033 """Check if 'a' is a suffix of 'b'
12034 >>> s1 = SuffixOf("ab", "abc")
12035 >>> simplify(s1)
12036 False
12037 >>> s2 = SuffixOf("bc", "abc")
12038 >>> simplify(s2)
12039 True
12040 """
12041 ctx = _get_ctx2(a, b)
12042 a = _coerce_seq(a, ctx)
12043 b = _coerce_seq(b, ctx)
12044 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
12045
12046
12047def Contains(a, b):
12048 """Check if 'a' contains 'b'
12049 >>> s1 = Contains("abc", "ab")
12050 >>> simplify(s1)
12051 True
12052 >>> s2 = Contains("abc", "bc")
12053 >>> simplify(s2)
12054 True
12055 >>> x, y, z = Strings('x y z')
12056 >>> s3 = Contains(Concat(x,y,z), y)
12057 >>> simplify(s3)
12058 True
12059 """
12060 ctx = _get_ctx2(a, b)
12061 a = _coerce_seq(a, ctx)
12062 b = _coerce_seq(b, ctx)
12063 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
12064
12065
12066def Replace(s, src, dst):
12067 """Replace the first occurrence of 'src' by 'dst' in 's'
12068 >>> r = Replace("aaa", "a", "b")
12069 >>> simplify(r)
12070 "baa"
12071 """
12072 ctx = _get_ctx2(dst, s)
12073 if ctx is None and is_expr(src):
12074 ctx = src.ctx
12075 src = _coerce_seq(src, ctx)
12076 dst = _coerce_seq(dst, ctx)
12077 s = _coerce_seq(s, ctx)
12078 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
12079
12080
12081def IndexOf(s, substr, offset=None):
12082 """Retrieve the index of substring within a string starting at a specified offset.
12083 >>> simplify(IndexOf("abcabc", "bc", 0))
12084 1
12085 >>> simplify(IndexOf("abcabc", "bc", 2))
12086 4
12087 """
12088 if offset is None:
12089 offset = IntVal(0)
12090 ctx = None
12091 if is_expr(offset):
12092 ctx = offset.ctx
12093 ctx = _get_ctx2(s, substr, ctx)
12094 s = _coerce_seq(s, ctx)
12095 substr = _coerce_seq(substr, ctx)
12096 if _is_int(offset):
12097 offset = IntVal(offset, ctx)
12098 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
12099
12100
12101def LastIndexOf(s, substr):
12102 """Retrieve the last index of substring within a string"""
12103 ctx = None
12104 ctx = _get_ctx2(s, substr, ctx)
12105 s = _coerce_seq(s, ctx)
12106 substr = _coerce_seq(substr, ctx)
12107 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
12108
12109
12110def Length(s):
12111 """Obtain the length of a sequence 's'
12112 >>> l = Length(StringVal("abc"))
12113 >>> simplify(l)
12114 3
12115 """
12116 s = _coerce_seq(s)
12117 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
12118
12119def SeqPower(s, n):
12120 """Concatenate the sequence 's' with itself 'n' times. It is the empty sequence for n <= 0
12121 >>> p = SeqPower(StringVal("ab"), 2)
12122 >>> simplify(p)
12123 "abab"
12124 """
12125 s = _coerce_seq(s)
12126 n = _py2expr(n, s.ctx)
12127 return SeqRef(Z3_mk_seq_power(s.ctx_ref(), s.as_ast(), n.as_ast()), s.ctx)
12128
12129def SeqMap(f, s):
12130 """Map function 'f' over sequence 's'"""
12131 ctx = _get_ctx2(f, s)
12132 s = _coerce_seq(s, ctx)
12133 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
12134
12135def SeqMapI(f, i, s):
12136 """Map function 'f' over sequence 's' at index 'i'"""
12137 ctx = _get_ctx2(f, s)
12138 s = _coerce_seq(s, ctx)
12139 if not is_expr(i):
12140 i = _py2expr(i)
12141 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
12142
12143def SeqFoldLeft(f, a, s):
12144 ctx = _get_ctx2(f, s)
12145 s = _coerce_seq(s, ctx)
12146 a = _py2expr(a)
12147 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
12148
12149def SeqFoldLeftI(f, i, a, s):
12150 ctx = _get_ctx2(f, s)
12151 s = _coerce_seq(s, ctx)
12152 a = _py2expr(a)
12153 i = _py2expr(i)
12154 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
12155
12156def StrToInt(s):
12157 """Convert string expression to integer
12158 >>> a = StrToInt("1")
12159 >>> simplify(1 == a)
12160 True
12161 >>> b = StrToInt("2")
12162 >>> simplify(1 == b)
12163 False
12164 >>> c = StrToInt(IntToStr(2))
12165 >>> simplify(1 == c)
12166 False
12167 """
12168 s = _coerce_seq(s)
12169 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
12170
12171
12172def IntToStr(s):
12173 """Convert integer expression to string"""
12174 if not is_expr(s):
12175 s = _py2expr(s)
12176 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
12177
12178
12179def StrToCode(s):
12180 """Convert a unit length string to integer code"""
12181 if not is_expr(s):
12182 s = _py2expr(s)
12183 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
12184
12185def StrFromCode(c):
12186 """Convert code to a string"""
12187 if not is_expr(c):
12188 c = _py2expr(c)
12189 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
12190
12191def Re(s, ctx=None):
12192 """The regular expression that accepts sequence 's'
12193 >>> s1 = Re("ab")
12194 >>> s2 = Re(StringVal("ab"))
12195 >>> s3 = Re(Unit(BoolVal(True)))
12196 """
12197 s = _coerce_seq(s, ctx)
12198 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
12199
12200
12201# Regular expressions
12202
12203class ReSortRef(SortRef):
12204 """Regular expression sort."""
12205
12206 def basis(self):
12207 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
12208
12209
12210def ReSort(s):
12211 if is_ast(s):
12212 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
12213 if s is None or isinstance(s, Context):
12214 ctx = _get_ctx(s)
12215 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
12216 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
12217
12218
12219class ReRef(ExprRef):
12220 """Regular expressions."""
12221
12222 def __add__(self, other):
12223 return Union(self, other)
12224
12225
12226def is_re(s):
12227 return isinstance(s, ReRef)
12228
12229
12230def InRe(s, re):
12231 """Create regular expression membership test
12232 >>> re = Union(Re("a"),Re("b"))
12233 >>> print (simplify(InRe("a", re)))
12234 True
12235 >>> print (simplify(InRe("b", re)))
12236 True
12237 >>> print (simplify(InRe("c", re)))
12238 False
12239 """
12240 s = _coerce_seq(s, re.ctx)
12241 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
12242
12243
12244def Union(*args):
12245 """Create union of regular expressions.
12246 >>> re = Union(Re("a"), Re("b"), Re("c"))
12247 >>> print (simplify(InRe("d", re)))
12248 False
12249 """
12250 args = _get_args(args)
12251 sz = len(args)
12252 if z3_debug():
12253 _z3_assert(sz > 0, "At least one argument expected.")
12254 arg0 = args[0]
12255 if is_finite_set(arg0):
12256 for a in args[1:]:
12257 if not is_finite_set(a):
12258 raise Z3Exception("All arguments must be regular expressions or finite sets.")
12259 arg0 = arg0 | a
12260 return arg0
12261 if z3_debug():
12262 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
12263 if sz == 1:
12264 return args[0]
12265 ctx = args[0].ctx
12266 v = (Ast * sz)()
12267 for i in range(sz):
12268 v[i] = args[i].as_ast()
12269 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
12270
12271
12272def Intersect(*args):
12273 """Create intersection of regular expressions.
12274 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
12275 """
12276 args = _get_args(args)
12277 sz = len(args)
12278 if z3_debug():
12279 _z3_assert(sz > 0, "At least one argument expected.")
12280 arg0 = args[0]
12281 if is_finite_set(arg0):
12282 for a in args[1:]:
12283 if not is_finite_set(a):
12284 raise Z3Exception("All arguments must be regular expressions or finite sets.")
12285 arg0 = arg0 & a
12286 return arg0
12287 if z3_debug():
12288 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
12289 if sz == 1:
12290 return args[0]
12291 ctx = args[0].ctx
12292 v = (Ast * sz)()
12293 for i in range(sz):
12294 v[i] = args[i].as_ast()
12295 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
12296
12297
12298def Plus(re):
12299 """Create the regular expression accepting one or more repetitions of argument.
12300 >>> re = Plus(Re("a"))
12301 >>> print(simplify(InRe("aa", re)))
12302 True
12303 >>> print(simplify(InRe("ab", re)))
12304 False
12305 >>> print(simplify(InRe("", re)))
12306 False
12307 """
12308 if z3_debug():
12309 _z3_assert(is_expr(re), "expression expected")
12310 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
12311
12312
12313def Option(re):
12314 """Create the regular expression that optionally accepts the argument.
12315 >>> re = Option(Re("a"))
12316 >>> print(simplify(InRe("a", re)))
12317 True
12318 >>> print(simplify(InRe("", re)))
12319 True
12320 >>> print(simplify(InRe("aa", re)))
12321 False
12322 """
12323 if z3_debug():
12324 _z3_assert(is_expr(re), "expression expected")
12325 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
12326
12327
12328def Complement(re):
12329 """Create the complement regular expression."""
12330 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
12331
12332
12333def Star(re):
12334 """Create the regular expression accepting zero or more repetitions of argument.
12335 >>> re = Star(Re("a"))
12336 >>> print(simplify(InRe("aa", re)))
12337 True
12338 >>> print(simplify(InRe("ab", re)))
12339 False
12340 >>> print(simplify(InRe("", re)))
12341 True
12342 """
12343 if z3_debug():
12344 _z3_assert(is_expr(re), "expression expected")
12345 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
12346
12347
12348def Loop(re, lo, hi=0):
12349 """Create the regular expression accepting between a lower and upper bound repetitions
12350 >>> re = Loop(Re("a"), 1, 3)
12351 >>> print(simplify(InRe("aa", re)))
12352 True
12353 >>> print(simplify(InRe("aaaa", re)))
12354 False
12355 >>> print(simplify(InRe("", re)))
12356 False
12357 """
12358 if z3_debug():
12359 _z3_assert(is_expr(re), "expression expected")
12360 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
12361
12362
12363def Range(lo, hi, ctx=None):
12364 """Create the range regular expression over two sequences of length 1
12365 >>> range = Range("a","z")
12366 >>> print(simplify(InRe("b", range)))
12367 True
12368 >>> print(simplify(InRe("bb", range)))
12369 False
12370 """
12371 lo = _coerce_seq(lo, ctx)
12372 hi = _coerce_seq(hi, ctx)
12373 if z3_debug():
12374 _z3_assert(is_expr(lo), "expression expected")
12375 _z3_assert(is_expr(hi), "expression expected")
12376 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
12377
12378def Diff(a, b, ctx=None):
12379 """Create the difference regular expression
12380 """
12381 if z3_debug():
12382 _z3_assert(is_expr(a), "expression expected")
12383 _z3_assert(is_expr(b), "expression expected")
12384 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
12385
12386def AllChar(regex_sort, ctx=None):
12387 """Create a regular expression that accepts all single character strings
12388 """
12389 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
12390
12391# Special Relations
12392
12393
12394def PartialOrder(a, index):
12395 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
12396
12397
12398def LinearOrder(a, index):
12399 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
12400
12401
12402def TreeOrder(a, index):
12403 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
12404
12405
12406def PiecewiseLinearOrder(a, index):
12407 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
12408
12409
12410def TransitiveClosure(f):
12411 """Given a binary relation R, such that the two arguments have the same sort
12412 create the transitive closure relation R+.
12413 The transitive closure R+ is a new relation.
12414 """
12415 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
12416
12417def to_Ast(ptr,):
12418 ast = Ast(ptr)
12419 super(ctypes.c_void_p, ast).__init__(ptr)
12420 return ast
12421
12422def to_ContextObj(ptr,):
12423 ctx = ContextObj(ptr)
12424 super(ctypes.c_void_p, ctx).__init__(ptr)
12425 return ctx
12426
12427def to_AstVectorObj(ptr,):
12428 v = AstVectorObj(ptr)
12429 super(ctypes.c_void_p, v).__init__(ptr)
12430 return v
12431
12432# NB. my-hacky-class only works for a single instance of OnClause
12433# it should be replaced with a proper correlation between OnClause
12434# and object references that can be passed over the FFI.
12435# for UserPropagator we use a global dictionary, which isn't great code.
12436
12437_my_hacky_class = None
12438def on_clause_eh(ctx, p, n, dep, clause):
12439 onc = _my_hacky_class
12440 p = _to_expr_ref(to_Ast(p), onc.ctx)
12441 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
12442 deps = [dep[i] for i in range(n)]
12443 onc.on_clause(p, deps, clause)
12444
12445_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
12446
12447class OnClause:
12448 def __init__(self, s, on_clause):
12449 self.s = s
12450 self.ctx = s.ctx
12451 self.on_clause = on_clause
12452 self.idx = 22
12453 global _my_hacky_class
12454 _my_hacky_class = self
12455 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
12456
12457
12458class PropClosures:
12459 def __init__(self):
12460 self.bases = {}
12461 self.lock = None
12462
12463 def set_threaded(self):
12464 if self.lock is None:
12465 import threading
12466 self.lock = threading.Lock()
12467
12468 def get(self, ctx):
12469 if self.lock:
12470 with self.lock:
12471 r = self.bases[ctx]
12472 else:
12473 r = self.bases[ctx]
12474 return r
12475
12476 def set(self, ctx, r):
12477 if self.lock:
12478 with self.lock:
12479 self.bases[ctx] = r
12480 else:
12481 self.bases[ctx] = r
12482
12483 def insert(self, r):
12484 if self.lock:
12485 with self.lock:
12486 id = len(self.bases) + 3
12487 self.bases[id] = r
12488 else:
12489 id = len(self.bases) + 3
12490 self.bases[id] = r
12491 return id
12492
12493
12494_prop_closures = None
12495
12496
12497def ensure_prop_closures():
12498 global _prop_closures
12499 if _prop_closures is None:
12500 _prop_closures = PropClosures()
12501
12502
12503def user_prop_push(ctx, cb):
12504 prop = _prop_closures.get(ctx)
12505 prop.cb = cb
12506 prop.push()
12507
12508
12509def user_prop_pop(ctx, cb, num_scopes):
12510 prop = _prop_closures.get(ctx)
12511 prop.cb = cb
12512 prop.pop(num_scopes)
12513
12514
12515def user_prop_fresh(ctx, _new_ctx):
12516 _prop_closures.set_threaded()
12517 prop = _prop_closures.get(ctx)
12518 nctx = Context()
12519 Z3_del_context(nctx.ctx)
12520 new_ctx = to_ContextObj(_new_ctx)
12521 nctx.ctx = new_ctx
12522 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
12523 nctx.owner = False
12524 new_prop = prop.fresh(nctx)
12525 _prop_closures.set(new_prop.id, new_prop)
12526 return new_prop.id
12527
12528
12529def user_prop_fixed(ctx, cb, id, value):
12530 prop = _prop_closures.get(ctx)
12531 old_cb = prop.cb
12532 prop.cb = cb
12533 id = _to_expr_ref(to_Ast(id), prop.ctx())
12534 value = _to_expr_ref(to_Ast(value), prop.ctx())
12535 prop.fixed(id, value)
12536 prop.cb = old_cb
12537
12538def user_prop_created(ctx, cb, id):
12539 prop = _prop_closures.get(ctx)
12540 old_cb = prop.cb
12541 prop.cb = cb
12542 id = _to_expr_ref(to_Ast(id), prop.ctx())
12543 prop.created(id)
12544 prop.cb = old_cb
12545
12546
12547def user_prop_final(ctx, cb):
12548 prop = _prop_closures.get(ctx)
12549 old_cb = prop.cb
12550 prop.cb = cb
12551 prop.final()
12552 prop.cb = old_cb
12553
12554def user_prop_eq(ctx, cb, x, y):
12555 prop = _prop_closures.get(ctx)
12556 old_cb = prop.cb
12557 prop.cb = cb
12558 x = _to_expr_ref(to_Ast(x), prop.ctx())
12559 y = _to_expr_ref(to_Ast(y), prop.ctx())
12560 prop.eq(x, y)
12561 prop.cb = old_cb
12562
12563def user_prop_diseq(ctx, cb, x, y):
12564 prop = _prop_closures.get(ctx)
12565 old_cb = prop.cb
12566 prop.cb = cb
12567 x = _to_expr_ref(to_Ast(x), prop.ctx())
12568 y = _to_expr_ref(to_Ast(y), prop.ctx())
12569 prop.diseq(x, y)
12570 prop.cb = old_cb
12571
12572def user_prop_decide(ctx, cb, t_ref, idx, phase):
12573 prop = _prop_closures.get(ctx)
12574 old_cb = prop.cb
12575 prop.cb = cb
12576 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
12577 prop.decide(t, idx, phase)
12578 prop.cb = old_cb
12579
12580def user_prop_binding(ctx, cb, q_ref, inst_ref):
12581 prop = _prop_closures.get(ctx)
12582 old_cb = prop.cb
12583 prop.cb = cb
12584 q = _to_expr_ref(to_Ast(q_ref), prop.ctx())
12585 inst = _to_expr_ref(to_Ast(inst_ref), prop.ctx())
12586 r = prop.binding(q, inst)
12587 prop.cb = old_cb
12588 return r
12589
12590
12591_user_prop_push = Z3_push_eh(user_prop_push)
12592_user_prop_pop = Z3_pop_eh(user_prop_pop)
12593_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
12594_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
12595_user_prop_created = Z3_created_eh(user_prop_created)
12596_user_prop_final = Z3_final_eh(user_prop_final)
12597_user_prop_eq = Z3_eq_eh(user_prop_eq)
12598_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
12599_user_prop_decide = Z3_decide_eh(user_prop_decide)
12600_user_prop_binding = Z3_on_binding_eh(user_prop_binding)
12601
12602
12603def PropagateFunction(name, *sig):
12604 """Create a function that gets tracked by user propagator.
12605 Every term headed by this function symbol is tracked.
12606 If a term is fixed and the fixed callback is registered a
12607 callback is invoked that the term headed by this function is fixed.
12608 """
12609 sig = _get_args(sig)
12610 if z3_debug():
12611 _z3_assert(len(sig) > 0, "At least two arguments expected")
12612 arity = len(sig) - 1
12613 rng = sig[arity]
12614 if z3_debug():
12615 _z3_assert(is_sort(rng), "Z3 sort expected")
12616 dom = (Sort * arity)()
12617 for i in range(arity):
12618 if z3_debug():
12619 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
12620 dom[i] = sig[i].ast
12621 ctx = rng.ctx
12622 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
12623
12624
12625
12626class UserPropagateBase:
12627
12628 #
12629 # Either solver is set or ctx is set.
12630 # Propagators that are created through callbacks
12631 # to "fresh" inherit the context of that is supplied
12632 # as argument to the callback.
12633 # This context should not be deleted. It is owned by the solver.
12634 #
12635 def __init__(self, s, ctx=None):
12636 assert s is None or ctx is None
12637 ensure_prop_closures()
12638 self.solver = s
12639 self._ctx = None
12640 self.fresh_ctx = None
12641 self.cb = None
12642 self.id = _prop_closures.insert(self)
12643 self.fixed = None
12644 self.final = None
12645 self.eq = None
12646 self.diseq = None
12647 self.decide = None
12648 self.created = None
12649 self.binding = None
12650 if ctx:
12651 self.fresh_ctx = ctx
12652 if s:
12653 Z3_solver_propagate_init(self.ctx_ref(),
12654 s.solver,
12655 ctypes.c_void_p(self.id),
12656 _user_prop_push,
12657 _user_prop_pop,
12658 _user_prop_fresh)
12659
12660 def __del__(self):
12661 if self._ctx:
12662 self._ctx.ctx = None
12663
12664 def ctx(self):
12665 if self.fresh_ctx:
12666 return self.fresh_ctx
12667 else:
12668 return self.solver.ctx
12669
12670 def ctx_ref(self):
12671 return self.ctx().ref()
12672
12673 def add_fixed(self, fixed):
12674 if self.fixed:
12675 raise Z3Exception("fixed callback already registered")
12676 if self._ctx:
12677 raise Z3Exception("context already initialized")
12678 if self.solver:
12679 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
12680 self.fixed = fixed
12681
12682 def add_created(self, created):
12683 if self.created:
12684 raise Z3Exception("created callback already registered")
12685 if self._ctx:
12686 raise Z3Exception("context already initialized")
12687 if self.solver:
12688 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
12689 self.created = created
12690
12691 def add_final(self, final):
12692 if self.final:
12693 raise Z3Exception("final callback already registered")
12694 if self._ctx:
12695 raise Z3Exception("context already initialized")
12696 if self.solver:
12697 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
12698 self.final = final
12699
12700 def add_eq(self, eq):
12701 if self.eq:
12702 raise Z3Exception("eq callback already registered")
12703 if self._ctx:
12704 raise Z3Exception("context already initialized")
12705 if self.solver:
12706 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
12707 self.eq = eq
12708
12709 def add_diseq(self, diseq):
12710 if self.diseq:
12711 raise Z3Exception("diseq callback already registered")
12712 if self._ctx:
12713 raise Z3Exception("context already initialized")
12714 if self.solver:
12715 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
12716 self.diseq = diseq
12717
12718 def add_decide(self, decide):
12719 if self.decide:
12720 raise Z3Exception("decide callback already registered")
12721 if self._ctx:
12722 raise Z3Exception("context already initialized")
12723 if self.solver:
12724 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
12725 self.decide = decide
12726
12727 def add_on_binding(self, binding):
12728 if self.binding:
12729 raise Z3Exception("binding callback already registered")
12730 if self._ctx:
12731 raise Z3Exception("context already initialized")
12732 if self.solver:
12733 Z3_solver_propagate_on_binding(self.ctx_ref(), self.solver.solver, _user_prop_binding)
12734 self.binding = binding
12735
12736 def push(self):
12737 raise Z3Exception("push needs to be overwritten")
12738
12739 def pop(self, num_scopes):
12740 raise Z3Exception("pop needs to be overwritten")
12741
12742 def fresh(self, new_ctx):
12743 raise Z3Exception("fresh needs to be overwritten")
12744
12745 def add(self, e):
12746 if self._ctx:
12747 raise Z3Exception("context already initialized")
12748 if self.solver:
12749 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
12750 else:
12751 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
12752
12753 #
12754 # Tell the solver to perform the next split on a given term
12755 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
12756 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
12757 #
12758 def next_split(self, t, idx, phase):
12759 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
12760
12761 #
12762 # Propagation can only be invoked as during a fixed or final callback.
12763 #
12764 def propagate(self, e, ids, eqs=[]):
12765 _ids, num_fixed = _to_ast_array(ids)
12766 num_eqs = len(eqs)
12767 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
12768 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
12769 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
12770 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
12771
12772 def conflict(self, deps = [], eqs = []):
12773 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
12774
12775
12776class FiniteFieldSortRef(SortRef):
12777 """A prime field. Use SolverFor('QF_FF') for incremental field solving."""
12778 def size(self):
12779 return int(Z3_get_finite_field_sort_size(self.ctx_ref(), self.ast))
12780
12781 def cast(self, value):
12782 if is_expr(value):
12783 if not self.eq(value.sort()):
12784 raise Z3Exception("finite-field sort mismatch")
12785 return value
12786 return FiniteFieldVal(value, self)
12787
12788
12789class FiniteFieldRef(ExprRef):
12790 def sort(self):
12791 return FiniteFieldSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
12792
12793 def as_long(self):
12794 if not Z3_is_numeral_ast(self.ctx_ref(), self.as_ast()):
12795 raise Z3Exception("finite-field numeral expected")
12796 return int(Z3_get_numeral_string(self.ctx_ref(), self.as_ast()))
12797
12798 def _binary(self, other, operation):
12799 other = self.sort().cast(other)
12800 args = (Ast * 2)(self.as_ast(), other.as_ast())
12801 return FiniteFieldRef(operation(self.ctx_ref(), 2, args), self.ctx)
12802
12803 def __add__(self, other):
12804 return self._binary(other, Z3_mk_ff_add)
12805
12806 def __radd__(self, other):
12807 return self + other
12808
12809 def __mul__(self, other):
12810 return self._binary(other, Z3_mk_ff_mul)
12811
12812 def __rmul__(self, other):
12813 return self * other
12814
12815 def __neg__(self):
12816 return FiniteFieldRef(Z3_mk_ff_neg(self.ctx_ref(), self.as_ast()), self.ctx)
12817
12818 def __sub__(self, other):
12819 return self + -self.sort().cast(other)
12820
12821 def __rsub__(self, other):
12822 return self.sort().cast(other) + -self
12823
12824 def __pow__(self, n):
12825 if not isinstance(n, int) or n < 0:
12826 raise Z3Exception("finite-field exponent must be a nonnegative integer")
12827 result, base = FiniteFieldVal(1, self.sort()), self
12828 while n:
12829 if n & 1:
12830 result = result * base
12831 n >>= 1
12832 if n:
12833 base = base * base
12834 return result
12835
12836
12837def FiniteFieldSort(prime, ctx=None):
12838 ctx = _get_ctx(ctx)
12839 return FiniteFieldSortRef(Z3_mk_finite_field_sort(ctx.ref(), str(prime)), ctx)
12840
12841
12842def FiniteFieldVal(value, field, ctx=None):
12843 if not isinstance(field, FiniteFieldSortRef):
12844 field = FiniteFieldSort(field, ctx)
12845 if not isinstance(value, (int, str)):
12846 raise Z3Exception("finite-field value must be an integer")
12847 return FiniteFieldRef(Z3_mk_numeral(field.ctx_ref(), str(value), field.ast), field.ctx)
12848
12849
12850def FiniteFieldElem(name, field, ctx=None):
12851 if not isinstance(field, FiniteFieldSortRef):
12852 field = FiniteFieldSort(field, ctx)
12853 return Const(name, field)
12854
12855
12856def FiniteFieldElems(names, field, ctx=None):
12857 if not isinstance(field, FiniteFieldSortRef):
12858 field = FiniteFieldSort(field, ctx)
12859 return [Const(name, field) for name in (names.split() if isinstance(names, str) else names)]
12860
12861
12862def FiniteFieldBitsum(*args):
12863 args = _get_args(args)
12864 if len(args) < 2 or not isinstance(args[0], FiniteFieldRef):
12865 raise Z3Exception("bitsum needs at least two field arguments")
12866 field = args[0].sort()
12867 values = [field.cast(a) for a in args]
12868 raw = (Ast * len(values))(*[a.as_ast() for a in values])
12869 return FiniteFieldRef(Z3_mk_ff_bitsum(field.ctx_ref(), len(values), raw), field.ctx)
approx(self, precision=10)
Definition z3py.py:3280
as_decimal(self, prec)
Definition z3py.py:3292
__rmod__(self, other)
Definition z3py.py:2751
__mod__(self, other)
Definition z3py.py:2736
__pow__(self, other)
Definition z3py.py:2660
__gt__(self, other)
Definition z3py.py:2809
__lt__(self, other)
Definition z3py.py:2796
__rtruediv__(self, other)
Definition z3py.py:2732
__rmul__(self, other)
Definition z3py.py:2627
__abs__(self)
Definition z3py.py:2835
__rsub__(self, other)
Definition z3py.py:2650
__add__(self, other)
Definition z3py.py:2589
__sub__(self, other)
Definition z3py.py:2637
is_real(self)
Definition z3py.py:2578
is_int(self)
Definition z3py.py:2564
__radd__(self, other)
Definition z3py.py:2602
__truediv__(self, other)
Definition z3py.py:2711
__le__(self, other)
Definition z3py.py:2783
__rpow__(self, other)
Definition z3py.py:2674
__pos__(self)
Definition z3py.py:2774
sort(self)
Definition z3py.py:2554
__mul__(self, other)
Definition z3py.py:2612
__rdiv__(self, other)
Definition z3py.py:2715
__ge__(self, other)
Definition z3py.py:2822
__neg__(self)
Definition z3py.py:2763
__div__(self, other)
Definition z3py.py:2688
Arithmetic.
Definition z3py.py:2459
subsort(self, other)
Definition z3py.py:2493
cast(self, val)
Definition z3py.py:2497
domain(self)
Definition z3py.py:4910
domain_n(self, i)
Definition z3py.py:4919
__getitem__(self, arg)
Definition z3py.py:4932
range(self)
Definition z3py.py:4923
sort(self)
Definition z3py.py:4901
default(self)
Definition z3py.py:4944
domain_n(self, i)
Definition z3py.py:4883
erase(self, k)
Definition z3py.py:6847
__deepcopy__(self, memo={})
Definition z3py.py:6784
__init__(self, m=None, ctx=None)
Definition z3py.py:6773
__repr__(self)
Definition z3py.py:6844
__len__(self)
Definition z3py.py:6791
keys(self)
Definition z3py.py:6876
__setitem__(self, k, v)
Definition z3py.py:6828
__contains__(self, key)
Definition z3py.py:6804
__del__(self)
Definition z3py.py:6787
__getitem__(self, key)
Definition z3py.py:6817
reset(self)
Definition z3py.py:6861
__deepcopy__(self, memo={})
Definition z3py.py:382
__nonzero__(self)
Definition z3py.py:397
as_ast(self)
Definition z3py.py:419
translate(self, target)
Definition z3py.py:448
__hash__(self)
Definition z3py.py:394
__init__(self, ast, ctx=None)
Definition z3py.py:372
__str__(self)
Definition z3py.py:385
ctx_ref(self)
Definition z3py.py:427
py_value(self)
Definition z3py.py:477
__repr__(self)
Definition z3py.py:388
get_id(self)
Definition z3py.py:423
hash(self)
Definition z3py.py:467
__eq__(self, other)
Definition z3py.py:391
eq(self, other)
Definition z3py.py:431
sexpr(self)
Definition z3py.py:410
__del__(self)
Definition z3py.py:377
__bool__(self)
Definition z3py.py:400
__copy__(self)
Definition z3py.py:464
__deepcopy__(self, memo={})
Definition z3py.py:6753
translate(self, other_ctx)
Definition z3py.py:6734
__repr__(self)
Definition z3py.py:6756
__len__(self)
Definition z3py.py:6604
__init__(self, v=None, ctx=None)
Definition z3py.py:6589
push(self, v)
Definition z3py.py:6686
__getitem__(self, i)
Definition z3py.py:6617
sexpr(self)
Definition z3py.py:6759
__del__(self)
Definition z3py.py:6600
__setitem__(self, i, v)
Definition z3py.py:6668
__contains__(self, item)
Definition z3py.py:6711
__copy__(self)
Definition z3py.py:6750
resize(self, sz)
Definition z3py.py:6698
as_binary_string(self)
Definition z3py.py:4223
as_signed_long(self)
Definition z3py.py:4197
as_string(self)
Definition z3py.py:4220
__and__(self, other)
Definition z3py.py:3887
__rmod__(self, other)
Definition z3py.py:4028
__rrshift__(self, other)
Definition z3py.py:4154
__mod__(self, other)
Definition z3py.py:4007
__or__(self, other)
Definition z3py.py:3864
__rlshift__(self, other)
Definition z3py.py:4168
__gt__(self, other)
Definition z3py.py:4078
__lt__(self, other)
Definition z3py.py:4062
__invert__(self)
Definition z3py.py:3953
__rtruediv__(self, other)
Definition z3py.py:4003
__rmul__(self, other)
Definition z3py.py:3831
__rxor__(self, other)
Definition z3py.py:3923
__ror__(self, other)
Definition z3py.py:3877
__rsub__(self, other)
Definition z3py.py:3854
__add__(self, other)
Definition z3py.py:3795
__sub__(self, other)
Definition z3py.py:3841
__radd__(self, other)
Definition z3py.py:3808
size(self)
Definition z3py.py:3784
__rand__(self, other)
Definition z3py.py:3900
__truediv__(self, other)
Definition z3py.py:3983
__le__(self, other)
Definition z3py.py:4046
__xor__(self, other)
Definition z3py.py:3910
__lshift__(self, other)
Definition z3py.py:4140
__pos__(self)
Definition z3py.py:3933
sort(self)
Definition z3py.py:3773
__mul__(self, other)
Definition z3py.py:3818
__rdiv__(self, other)
Definition z3py.py:3987
__ge__(self, other)
Definition z3py.py:4094
__neg__(self)
Definition z3py.py:3942
__rshift__(self, other)
Definition z3py.py:4110
__div__(self, other)
Definition z3py.py:3964
Bit-Vectors.
Definition z3py.py:3726
subsort(self, other)
Definition z3py.py:3738
cast(self, val)
Definition z3py.py:3741
__and__(self, other)
Definition z3py.py:1709
__or__(self, other)
Definition z3py.py:1712
__invert__(self)
Definition z3py.py:1718
__rmul__(self, other)
Definition z3py.py:1695
__add__(self, other)
Definition z3py.py:1687
py_value(self)
Definition z3py.py:1721
__radd__(self, other)
Definition z3py.py:1692
__xor__(self, other)
Definition z3py.py:1715
sort(self)
Definition z3py.py:1684
__mul__(self, other)
Definition z3py.py:1698
Booleans.
Definition z3py.py:1645
subsort(self, other)
Definition z3py.py:1671
is_bool(self)
Definition z3py.py:1677
cast(self, val)
Definition z3py.py:1648
__deepcopy__(self, memo={})
Definition z3py.py:7643
__eq__(self, other)
Definition z3py.py:7646
__ne__(self, other)
Definition z3py.py:7649
__init__(self, r)
Definition z3py.py:7640
real_part(self)
Definition z3py.py:3334
imag_part(self)
Definition z3py.py:3337
subsort(self, other)
Definition z3py.py:3314
cast(self, val)
Definition z3py.py:3317
param_descrs(self)
Definition z3py.py:240
set_ast_print_mode(self, mode)
Definition z3py.py:244
__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:5677
create(self)
Definition z3py.py:5716
__init__(self, name, ctx=None)
Definition z3py.py:5672
__repr__(self)
Definition z3py.py:5713
list constructors
Definition z3py.py:5675
declare(self, name, *args)
Definition z3py.py:5692
create_polymorphic(self, type_params)
Definition z3py.py:5732
declare_core(self, name, rec_name, *args)
Definition z3py.py:5682
update_field(self, field_accessor, new_value)
Definition z3py.py:6041
constructor(self, idx)
Definition z3py.py:5953
accessor(self, i, j)
Definition z3py.py:6000
num_constructors(self)
Definition z3py.py:5940
recognizer(self, idx)
Definition z3py.py:5972
Expressions.
Definition z3py.py:1026
update(self, *args)
Definition z3py.py:1182
as_ast(self)
Definition z3py.py:1037
__hash__(self)
Definition z3py.py:1083
kind(self)
Definition z3py.py:1123
children(self)
Definition z3py.py:1167
serialize(self)
Definition z3py.py:1209
get_id(self)
Definition z3py.py:1040
num_args(self)
Definition z3py.py:1130
__eq__(self, other)
Definition z3py.py:1066
__ne__(self, other)
Definition z3py.py:1087
from_string(self, s)
Definition z3py.py:1206
sort_kind(self)
Definition z3py.py:1055
arg(self, idx)
Definition z3py.py:1146
sort(self)
Definition z3py.py:1043
params(self)
Definition z3py.py:1105
decl(self)
Definition z3py.py:1108
__and__(self, other)
Definition z3py.py:5492
__or__(self, other)
Definition z3py.py:5488
__sub__(self, other)
Definition z3py.py:5496
Finite Sets.
Definition z3py.py:5420
subsort(self, other)
Definition z3py.py:5442
cast(self, val)
Definition z3py.py:5427
Function Declarations.
Definition z3py.py:782
as_func_decl(self)
Definition z3py.py:797
domain(self, i)
Definition z3py.py:821
as_ast(self)
Definition z3py.py:790
__call__(self, *args)
Definition z3py.py:884
arity(self)
Definition z3py.py:811
get_id(self)
Definition z3py.py:794
range(self)
Definition z3py.py:833
params(self)
Definition z3py.py:856
Definition z3py.py:6895
__deepcopy__(self, memo={})
Definition z3py.py:6903
ctx
Definition z3py.py:6900
__repr__(self)
Definition z3py.py:7000
num_args(self)
Definition z3py.py:6910
entry
Definition z3py.py:6899
value(self)
Definition z3py.py:6959
__init__(self, entry, ctx)
Definition z3py.py:6898
__del__(self)
Definition z3py.py:6906
as_list(self)
Definition z3py.py:6981
arg_value(self, idx)
Definition z3py.py:6928
__deepcopy__(self, memo={})
Definition z3py.py:7098
translate(self, other_ctx)
Definition z3py.py:7090
arity(self)
Definition z3py.py:7056
__repr__(self)
Definition z3py.py:7118
num_entries(self)
Definition z3py.py:7040
__init__(self, f, ctx)
Definition z3py.py:7007
__del__(self)
Definition z3py.py:7013
as_list(self)
Definition z3py.py:7101
else_value(self)
Definition z3py.py:7017
entry(self, idx)
Definition z3py.py:7070
__copy__(self)
Definition z3py.py:7095
__deepcopy__(self, memo={})
Definition z3py.py:6534
get(self, i)
Definition z3py.py:6390
prec(self)
Definition z3py.py:6334
translate(self, target)
Definition z3py.py:6508
append(self, *args)
Definition z3py.py:6435
as_expr(self)
Definition z3py.py:6557
assert_exprs(self, *args)
Definition z3py.py:6420
__repr__(self)
Definition z3py.py:6497
__len__(self)
Definition z3py.py:6377
inconsistent(self)
Definition z3py.py:6316
dimacs(self, include_names=True)
Definition z3py.py:6504
__getitem__(self, arg)
Definition z3py.py:6403
size(self)
Definition z3py.py:6364
precision(self)
Definition z3py.py:6355
simplify(self, *arguments, **keywords)
Definition z3py.py:6537
sexpr(self)
Definition z3py.py:6500
add(self, *args)
Definition z3py.py:6457
__del__(self)
Definition z3py.py:6294
convert_model(self, model)
Definition z3py.py:6468
insert(self, *args)
Definition z3py.py:6446
depth(self)
Definition z3py.py:6298
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:6284
__copy__(self)
Definition z3py.py:6531
as_binary_string(self)
Definition z3py.py:3165
py_value(self)
Definition z3py.py:3173
as_long(self)
Definition z3py.py:3144
as_string(self)
Definition z3py.py:3157
__deepcopy__(self, memo={})
Definition z3py.py:7466
eval(self, t, model_completion=False)
Definition z3py.py:7142
translate(self, target)
Definition z3py.py:7431
__getitem__(self, idx)
Definition z3py.py:7343
num_sorts(self)
Definition z3py.py:7268
get_universe(self, s)
Definition z3py.py:7323
get_sort(self, idx)
Definition z3py.py:7283
project(self, vars, fml)
Definition z3py.py:7439
__repr__(self)
Definition z3py.py:7135
__len__(self)
Definition z3py.py:7199
get_interp(self, decl)
Definition z3py.py:7216
__init__(self, m, ctx)
Definition z3py.py:7125
sexpr(self)
Definition z3py.py:7138
sorts(self)
Definition z3py.py:7306
__del__(self)
Definition z3py.py:7131
decls(self)
Definition z3py.py:7390
project_with_witness(self, vars, fml)
Definition z3py.py:7451
update_value(self, x, value)
Definition z3py.py:7409
evaluate(self, t, model_completion=False)
Definition z3py.py:7173
__copy__(self)
Definition z3py.py:7463
__deepcopy__(self, memo={})
Definition z3py.py:6228
__init__(self, descr, ctx=None)
Definition z3py.py:6222
get_kind(self, n)
Definition z3py.py:6250
get_documentation(self, n)
Definition z3py.py:6255
__getitem__(self, arg)
Definition z3py.py:6260
get_name(self, i)
Definition z3py.py:6245
Parameter Sets.
Definition z3py.py:6149
__deepcopy__(self, memo={})
Definition z3py.py:6163
validate(self, ds)
Definition z3py.py:6190
__repr__(self)
Definition z3py.py:6187
__init__(self, ctx=None, params=None)
Definition z3py.py:6155
set(self, name, val)
Definition z3py.py:6170
__del__(self)
Definition z3py.py:6166
Patterns.
Definition z3py.py:2081
as_ast(self)
Definition z3py.py:2086
get_id(self)
Definition z3py.py:2090
Quantifiers.
Definition z3py.py:2149
num_no_patterns(self)
Definition z3py.py:2267
no_pattern(self, idx)
Definition z3py.py:2271
num_patterns(self)
Definition z3py.py:2237
var_name(self, idx)
Definition z3py.py:2300
__getitem__(self, arg)
Definition z3py.py:2206
var_sort(self, idx)
Definition z3py.py:2316
pattern(self, idx)
Definition z3py.py:2249
numerator_as_long(self)
Definition z3py.py:3206
is_int_value(self)
Definition z3py.py:3236
as_fraction(self)
Definition z3py.py:3264
py_value(self)
Definition z3py.py:3273
numerator(self)
Definition z3py.py:3180
is_real(self)
Definition z3py.py:3233
as_long(self)
Definition z3py.py:3239
is_int(self)
Definition z3py.py:3230
denominator_as_long(self)
Definition z3py.py:3219
as_string(self)
Definition z3py.py:3255
denominator(self)
Definition z3py.py:3195
as_decimal(self, prec)
Definition z3py.py:3243
__init__(self, c, ctx)
Definition z3py.py:5750
__init__(self, c, ctx)
Definition z3py.py:5762
Strings, Sequences and Regular expressions.
Definition z3py.py:11723
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7687
assert_and_track(self, a, p)
Definition z3py.py:7856
num_scopes(self)
Definition z3py.py:7768
append(self, *args)
Definition z3py.py:7834
__iadd__(self, fml)
Definition z3py.py:7830
pop(self, num=1)
Definition z3py.py:7746
import_model_converter(self, other)
Definition z3py.py:7934
assert_exprs(self, *args)
Definition z3py.py:7800
model(self)
Definition z3py.py:7915
set(self, *args, **keys)
Definition z3py.py:7711
__enter__(self)
Definition z3py.py:7704
add(self, *args)
Definition z3py.py:7819
__del__(self)
Definition z3py.py:7700
int backtrack_level
Definition z3py.py:7690
insert(self, *args)
Definition z3py.py:7845
check(self, *assumptions)
Definition z3py.py:7886
push(self)
Definition z3py.py:7724
__exit__(self, *exc_info)
Definition z3py.py:7708
reset(self)
Definition z3py.py:7786
subsort(self, other)
Definition z3py.py:617
as_ast(self)
Definition z3py.py:593
__hash__(self)
Definition z3py.py:678
kind(self)
Definition z3py.py:600
__gt__(self, other)
Definition z3py.py:674
get_id(self)
Definition z3py.py:597
__eq__(self, other)
Definition z3py.py:650
__ne__(self, other)
Definition z3py.py:663
cast(self, val)
Definition z3py.py:625
name(self)
Definition z3py.py:640
Statistics.
Definition z3py.py:7496
__deepcopy__(self, memo={})
Definition z3py.py:7504
__getattr__(self, name)
Definition z3py.py:7599
__getitem__(self, idx)
Definition z3py.py:7543
__init__(self, stats, ctx)
Definition z3py.py:7499
__repr__(self)
Definition z3py.py:7511
__len__(self)
Definition z3py.py:7529
__del__(self)
Definition z3py.py:7507
get_key_value(self, key)
Definition z3py.py:7579
subsort(self, other)
Definition z3py.py:758
cast(self, val)
Definition z3py.py:761
ASTs base class.
Definition z3py.py:355
_repr_html_(self)
Definition z3py.py:361
use_pp(self)
Definition z3py.py:358
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.
Z3_ast Z3_API Z3_mk_bvxnor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise xnor.
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_mk_bvnor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise nor.
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_ast Z3_API Z3_mk_finite_set_empty(Z3_context c, Z3_sort set_sort)
Create an empty finite set of the given sort.
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_is_finite_set_sort(Z3_context c, Z3_sort s)
Check if a sort is a finite set sort.
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.
Z3_ast Z3_API Z3_mk_finite_set_difference(Z3_context c, Z3_ast s1, Z3_ast s2)
Create the set difference of two finite sets.
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].
Z3_ast Z3_API Z3_mk_finite_set_subset(Z3_context c, Z3_ast s1, Z3_ast s2)
Check if one finite set is a subset of another.
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_sort Z3_API Z3_mk_polymorphic_datatype(Z3_context c, Z3_symbol name, unsigned num_parameters, Z3_sort parameters[], unsigned num_constructors, Z3_constructor constructors[])
Create a parametric datatype with explicit type parameters.
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 ...
Z3_ast Z3_API Z3_datatype_update_field(Z3_context c, Z3_func_decl field_access, Z3_ast t, Z3_ast value)
Update record field with a value.
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_sort Z3_API Z3_get_finite_set_sort_basis(Z3_context c, Z3_sort s)
Get the element sort of a finite set sort.
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_finite_set_filter(Z3_context c, Z3_ast f, Z3_ast set)
Filter a finite set using a predicate.
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,...
Z3_ast Z3_API Z3_mk_finite_set_member(Z3_context c, Z3_ast elem, Z3_ast set)
Check if an element is a member of a finite set.
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.
Z3_sort Z3_API Z3_mk_datatype_sort(Z3_context c, Z3_symbol name, unsigned num_params, Z3_sort const params[])
create a forward reference to a recursive datatype being declared. The forward reference can be used ...
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_ast Z3_API Z3_mk_finite_set_union(Z3_context c, Z3_ast s1, Z3_ast s2)
Create the union of two finite sets.
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_finite_set_intersect(Z3_context c, Z3_ast s1, Z3_ast s2)
Create the intersection of two finite sets.
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...
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_ast Z3_API Z3_update_term(Z3_context c, Z3_ast a, unsigned num_args, Z3_ast const args[])
Update the arguments of term a using the arguments args. The number of arguments num_args should coin...
Z3_string Z3_API Z3_get_symbol_string(Z3_context c, Z3_symbol s)
Return the symbol name.
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_mk_bvnand(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise nand.
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_sort Z3_API Z3_mk_complex_sort(Z3_context c)
Create the Complex sort. Complex numbers are pairs of Reals.
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_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_ast Z3_API Z3_mk_complex(Z3_context c, Z3_ast re, Z3_ast im)
Create a complex number with the given real and imaginary components. Integer components are coerced ...
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_finite_set_singleton(Z3_context c, Z3_ast elem)
Create a singleton finite set.
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_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_finite_set_map(Z3_context c, Z3_ast f, Z3_ast set)
Apply a function to all elements of a finite set.
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.
Z3_sort Z3_API Z3_mk_finite_set_sort(Z3_context c, Z3_sort elem_sort)
Create a finite set sort.
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_ast Z3_API Z3_mk_imag_part(Z3_context c, Z3_ast z)
Return the imaginary component of a Complex expression.
Z3_ast Z3_API Z3_mk_finite_set_size(Z3_context c, Z3_ast set)
Get the size (cardinality) of a finite set.
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_ast Z3_API Z3_mk_finite_set_range(Z3_context c, Z3_ast low, Z3_ast high)
Create a finite set of integers in the range [low, high].
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_ast Z3_API Z3_mk_as_array(Z3_context c, Z3_func_decl f)
Create array with the same interpretation as a function. The array satisfies the property (f x) = (se...
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_mk_real_part(Z3_context c, Z3_ast z)
Return the real component of a Complex expression.
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:3402
RotateRight(a, b)
Definition z3py.py:4658
_symbol2py(ctx, s)
Definition z3py.py:140
is_complex(a)
Definition z3py.py:3346
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4308
BVSNegNoOverflow(a)
Definition z3py.py:4844
SetAdd(s, e)
Definition z3py.py:5338
SetSort(s)
Sets.
Definition z3py.py:5281
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1318
UGT(a, b)
Definition z3py.py:4529
is_probe(p)
Definition z3py.py:9593
SetDel(s, e)
Definition z3py.py:5351
bool is_le(Any a)
Definition z3py.py:3051
BoolSort(ctx=None)
Definition z3py.py:1851
is_bv_sort(s)
Definition z3py.py:3759
ComplexSort(ctx=None)
Definition z3py.py:3351
_ctx_from_ast_args(*args)
Definition z3py.py:542
RatVal(a, b, ctx=None)
Definition z3py.py:3496
_to_func_decl_ref(a, ctx)
Definition z3py.py:970
SetUnion(*args)
Definition z3py.py:5306
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5636
BitVec(name, bv, ctx=None)
Definition z3py.py:4325
EmptySet(s)
Definition z3py.py:5286
BVMulNoUnderflow(a, b)
Definition z3py.py:4858
CreateDatatypes(*ds)
Definition z3py.py:5771
is_func_decl(a)
Definition z3py.py:915
FiniteSetUnion(s1, s2)
Definition z3py.py:5529
get_as_array_func(n)
Definition z3py.py:7483
Distinct(*args)
Definition z3py.py:1534
RecAddDefinition(f, args, body)
Definition z3py.py:992
ToInt(a)
Definition z3py.py:3659
Implies(a, b, ctx=None)
Definition z3py.py:1945
UGE(a, b)
Definition z3py.py:4511
Complex(name, ctx=None)
Definition z3py.py:3357
Ext(a, b)
Definition z3py.py:5220
_to_ast_array(args)
Definition z3py.py:554
bool is_sort(Any s)
Definition z3py.py:683
_check_bv_args(a, b)
Definition z3py.py:4470
RealSort(ctx=None)
Definition z3py.py:3436
IsSubset(a, b)
Definition z3py.py:5400
DeclareTypeVar(name, ctx=None)
Definition z3py.py:765
_get_args_ast_list(args)
Definition z3py.py:168
bool is_to_real(Any a)
Definition z3py.py:3111
_to_ref_array(ref, args)
Definition z3py.py:562
get_map_func(a)
Definition z3py.py:5026
is_finite_set(a)
Definition z3py.py:5461
_z3_check_cint_overflow(n, name)
Definition z3py.py:118
bool is_and(Any a)
Definition z3py.py:1781
TupleSort(name, sorts, ctx=None)
Definition z3py.py:6092
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1357
is_select(a)
Definition z3py.py:5250
SignExt(n, a)
Definition z3py.py:4674
Int(name, ctx=None)
Definition z3py.py:3529
Bools(names, ctx=None)
Definition z3py.py:1900
_probe_and(args, ctx)
Definition z3py.py:9660
Int2BV(a, num_bits)
Definition z3py.py:4284
Lambda(vs, body)
Definition z3py.py:2432
_to_param_value(val)
Definition z3py.py:178
FreshFunction(*sig)
Definition z3py.py:951
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3610
BVRedOr(a)
Definition z3py.py:4763
is_finite_set_sort(s)
Definition z3py.py:5472
SRem(a, b)
Definition z3py.py:4589
FiniteSetFilter(f, set)
Definition z3py.py:5608
SortRef _sort(Context ctx, Any a)
Definition z3py.py:733
set_option(*args, **kws)
Definition z3py.py:328
ExprRef RealVar(int idx, ctx=None)
Definition z3py.py:1617
bool is_sub(Any a)
Definition z3py.py:2998
is_bv(a)
Definition z3py.py:4232
SetDifference(a, b)
Definition z3py.py:5374
bool is_arith_sort(Any s)
Definition z3py.py:2535
BitVecs(names, bv, ctx=None)
Definition z3py.py:4349
_check_same_sort(a, b, ctx=None)
Definition z3py.py:1305
bool is_mod(Any a)
Definition z3py.py:3039
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1916
FiniteSetEmpty(set_sort)
Definition z3py.py:5510
_has_probe(args)
Definition z3py.py:2001
IsMember(e, s)
Definition z3py.py:5387
get_param(name)
Definition z3py.py:334
BVAddNoUnderflow(a, b)
Definition z3py.py:4816
deserialize(st)
Definition z3py.py:1215
bool is_not(Any a)
Definition z3py.py:1817
BvXnor(a, b)
Definition z3py.py:4796
ComplexVal(real, imag=0, ctx=None)
Definition z3py.py:3370
FiniteSetMap(f, set)
Definition z3py.py:5595
Extract(high, low, a)
Definition z3py.py:4416
Function(name, *sig)
Definition z3py.py:928
get_version()
Definition z3py.py:100
FreshConst(sort, prefix="c")
Definition z3py.py:1594
ULT(a, b)
Definition z3py.py:4493
EnumSort(name, values, ctx=None)
Definition z3py.py:6116
is_complex_sort(s)
Definition z3py.py:3341
bool is_is_int(Any a)
Definition z3py.py:3099
_to_int_str(val)
Definition z3py.py:3453
is_algebraic_value(a)
Definition z3py.py:2960
is_bv_value(a)
Definition z3py.py:4246
BVSDivNoOverflow(a, b)
Definition z3py.py:4837
bool is_eq(Any a)
Definition z3py.py:1829
Context main_ctx()
Definition z3py.py:266
CreatePolymorphicDatatype(d, type_params)
Definition z3py.py:5867
BvNand(a, b)
Definition z3py.py:4770
SetIntersect(*args)
Definition z3py.py:5322
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9727
BV2Int(a, is_signed=False)
Definition z3py.py:4261
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3568
_to_ast_ref(a, ctx)
Definition z3py.py:570
_to_func_decl_array(args)
Definition z3py.py:546
disable_trace(msg)
Definition z3py.py:87
bool is_to_int(Any a)
Definition z3py.py:3126
RealPart(value)
Definition z3py.py:3390
is_map(a)
Definition z3py.py:5001
Context _get_ctx(ctx)
Definition z3py.py:287
Or(*args)
Definition z3py.py:2042
is_re(s)
Definition z3py.py:12226
FiniteSetIntersect(s1, s2)
Definition z3py.py:5540
args2params(arguments, keywords, ctx=None)
Definition z3py.py:6195
bool is_idiv(Any a)
Definition z3py.py:3027
Consts(names, sort)
Definition z3py.py:1579
Cond(p, t1, t2, ctx=None)
Definition z3py.py:9710
_to_pattern(arg)
Definition z3py.py:2136
RealVarVector(int n, ctx=None)
Definition z3py.py:1627
is_arith(a)
Definition z3py.py:2847
bool is_true(Any a)
Definition z3py.py:1749
bool is_false(Any a)
Definition z3py.py:1767
bool is_int(a)
Definition z3py.py:2868
If(a, b, c, ctx=None)
Definition z3py.py:1511
bool eq(AstRef a, AstRef b)
Definition z3py.py:503
is_app_of(a, k)
Definition z3py.py:1498
is_app(a)
Definition z3py.py:1395
bool is_add(Any a)
Definition z3py.py:2974
z3_error_handler(c, e)
Definition z3py.py:184
None reset_params()
Definition z3py.py:322
Reals(names, ctx=None)
Definition z3py.py:3595
is_int_value(a)
Definition z3py.py:2914
set_param(*args, **kws)
Definition z3py.py:298
is_pattern(a)
Definition z3py.py:2094
_coerce_seq(s, ctx=None)
Definition z3py.py:11877
bool is_distinct(Any a)
Definition z3py.py:1839
bool is_lt(Any a)
Definition z3py.py:3063
FiniteSetRange(low, high)
Definition z3py.py:5621
ULE(a, b)
Definition z3py.py:4475
is_real(a)
Definition z3py.py:2887
Abs(arg)
Definition z3py.py:9888
FullSet(s)
Definition z3py.py:5297
to_symbol(s, ctx=None)
Definition z3py.py:132
FiniteSetMember(elem, set)
Definition z3py.py:5562
bool is_mul(Any a)
Definition z3py.py:2986
bool is_ast(Any a)
Definition z3py.py:482
_get_args(args)
Definition z3py.py:152
Singleton(elem)
Definition z3py.py:5520
And(*args)
Definition z3py.py:2009
RepeatBitVec(n, a)
Definition z3py.py:4732
FiniteSetDifference(s1, s2)
Definition z3py.py:5551
get_version_string()
Definition z3py.py:91
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3625
Array(name, *sorts)
Definition z3py.py:5085
Concat(*args)
Definition z3py.py:4370
_reduce(func, sequence, initial)
Definition z3py.py:1350
_is_algebraic(ctx, a)
Definition z3py.py:2910
Ints(names, ctx=None)
Definition z3py.py:3542
Select(a, *args)
Definition z3py.py:5159
Const(name, sort)
Definition z3py.py:1567
is_array_sort(a)
Definition z3py.py:4957
bool is_div(Any a)
Definition z3py.py:3010
ExprRef Var(int idx, SortRef s)
Definition z3py.py:1602
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4809
BvNor(a, b)
Definition z3py.py:4783
Real(name, ctx=None)
Definition z3py.py:3582
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1931
BitVecSort(sz, ctx=None)
Definition z3py.py:4293
open_log(fname)
Definition z3py.py:122
RecFunction(name, *sig)
Definition z3py.py:974
FiniteSetSize(set)
Definition z3py.py:5574
bool is_ge(Any a)
Definition z3py.py:3075
Model(ctx=None, eval={})
Definition z3py.py:7470
BVSubNoOverflow(a, b)
Definition z3py.py:4823
bool is_gt(Any a)
Definition z3py.py:3087
In(elem, set)
Definition z3py.py:5571
is_default(a)
Definition z3py.py:5017
is_K(a)
Definition z3py.py:4988
Bool(name, ctx=None)
Definition z3py.py:1888
_is_int(v)
Definition z3py.py:76
is_const_array(a)
Definition z3py.py:4975
Sqrt(a, ctx=None)
Definition z3py.py:3694
FiniteSetSort(elem_sort)
Definition z3py.py:5501
Default(a)
Definition z3py.py:5131
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:528
SetComplement(s)
Definition z3py.py:5364
is_as_array(n)
Definition z3py.py:7478
is_store(a)
Definition z3py.py:5263
FiniteSetSubset(s1, s2)
Definition z3py.py:5584
bool is_or(Any a)
Definition z3py.py:1793
is_quantifier(a)
Definition z3py.py:2344
_mk_bin(f, a, b)
Definition z3py.py:1558
K(dom, v)
Definition z3py.py:5198
Xor(a, b, ctx=None)
Definition z3py.py:1959
Store(a, *args)
Definition z3py.py:5142
bool is_array(Any a)
Definition z3py.py:4961
mk_not(a)
Definition z3py.py:1994
is_expr(a)
Definition z3py.py:1372
_array_select(ar, arg)
Definition z3py.py:4948
is_const(a)
Definition z3py.py:1421
BoolVal(val, ctx=None)
Definition z3py.py:1869
RealVal(val, ctx=None)
Definition z3py.py:3477
bool is_implies(Any a)
Definition z3py.py:1805
z3_debug()
Definition z3py.py:70
get_full_version()
Definition z3py.py:109
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3555
_coerce_expr_merge(s, a)
Definition z3py.py:1287
Context get_ctx(ctx)
Definition z3py.py:294
LShR(a, b)
Definition z3py.py:4610
ArraySort(*sig)
Definition z3py.py:5050
Map(f, *args)
Definition z3py.py:5175
is_rational_value(a)
Definition z3py.py:2938
_probe_or(args, ctx)
Definition z3py.py:9664
BVRedAnd(a)
Definition z3py.py:4756
Cbrt(a, ctx=None)
Definition z3py.py:3707
_to_expr_ref(a, ctx)
Definition z3py.py:1229
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:6104
IntSort(ctx=None)
Definition z3py.py:3419
is_seq(a)
Definition z3py.py:11898
Not(a, ctx=None)
Definition z3py.py:1975
_to_sort_ref(s, ctx)
Definition z3py.py:696
enable_trace(msg)
Definition z3py.py:83
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2411
ToReal(a)
Definition z3py.py:3639
URem(a, b)
Definition z3py.py:4568
bool is_bool(Any a)
Definition z3py.py:1731
StringVal(s, ctx=None)
Definition z3py.py:11925
IsInt(a)
Definition z3py.py:3677
_is_numeral(ctx, a)
Definition z3py.py:2906
MultiPattern(*args)
Definition z3py.py:2112
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2393
ZeroExt(n, a)
Definition z3py.py:4704
Complexes(names, ctx=None)
Definition z3py.py:3363
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:586
int _ast_kind(Context ctx, Any a)
Definition z3py.py:522
DatatypeSort(name, params=None, ctx=None)
Definition z3py.py:6067
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4830
UDiv(a, b)
Definition z3py.py:4547
ImagPart(value)
Definition z3py.py:3396
Q(a, b, ctx=None)
Definition z3py.py:3516
Update(a, *args)
Definition z3py.py:5099
get_var_index(a)
Definition z3py.py:1465
append_log(s)
Definition z3py.py:127
AsArray(f)
Definition z3py.py:5232
is_var(a)
Definition z3py.py:1440
SortRef DeclareSort(name, ctx=None)
Definition z3py.py:737
IntVal(val, ctx=None)
Definition z3py.py:3465
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4851
RotateLeft(a, b)
Definition z3py.py:4642
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2358
_z3_assert(cond, msg)
Definition z3py.py:113