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(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 return Z3_sort_to_ast(self.ctx_ref(), self.ast)
595
596 def get_id(self):
597 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
598
599 def kind(self):
600 """Return the Z3 internal kind of a sort.
601 This method can be used to test if `self` is one of the Z3 builtin sorts.
602
603 >>> b = BoolSort()
604 >>> b.kind() == Z3_BOOL_SORT
605 True
606 >>> b.kind() == Z3_INT_SORT
607 False
608 >>> A = ArraySort(IntSort(), IntSort())
609 >>> A.kind() == Z3_ARRAY_SORT
610 True
611 >>> A.kind() == Z3_INT_SORT
612 False
613 """
614 return _sort_kind(self.ctx, self.ast)
615
616 def subsort(self, other):
617 """Return `True` if `self` is a subsort of `other`.
618
619 >>> IntSort().subsort(RealSort())
620 True
621 """
622 return False
623
624 def cast(self, val):
625 """Try to cast `val` as an element of sort `self`.
626
627 This method is used in Z3Py to convert Python objects such as integers,
628 floats, longs and strings into Z3 expressions.
629
630 >>> x = Int('x')
631 >>> RealSort().cast(x)
632 ToReal(x)
633 """
634 if z3_debug():
635 _z3_assert(is_expr(val), "Z3 expression expected")
636 _z3_assert(self.eq(val.sort()), "Sort mismatch")
637 return val
638
639 def name(self):
640 """Return the name (string) of sort `self`.
641
642 >>> BoolSort().name()
643 'Bool'
644 >>> ArraySort(IntSort(), IntSort()).name()
645 'Array'
646 """
647 return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
648
649 def __eq__(self, other):
650 """Return `True` if `self` and `other` are the same Z3 sort.
651
652 >>> p = Bool('p')
653 >>> p.sort() == BoolSort()
654 True
655 >>> p.sort() == IntSort()
656 False
657 """
658 if other is None:
659 return False
660 return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
661
662 def __ne__(self, other):
663 """Return `True` if `self` and `other` are not the same Z3 sort.
664
665 >>> p = Bool('p')
666 >>> p.sort() != BoolSort()
667 False
668 >>> p.sort() != IntSort()
669 True
670 """
671 return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
672
673 def __gt__(self, other):
674 """Create the function space Array(self, other)"""
675 return ArraySort(self, other)
676
677 def __hash__(self):
678 """ Hash code. """
679 return AstRef.__hash__(self)
680
681
682def is_sort(s : Any) -> bool:
683 """Return `True` if `s` is a Z3 sort.
684
685 >>> is_sort(IntSort())
686 True
687 >>> is_sort(Int('x'))
688 False
689 >>> is_expr(Int('x'))
690 True
691 """
692 return isinstance(s, SortRef)
693
694
695def _to_sort_ref(s, ctx):
696 if z3_debug():
697 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
698 if Z3_is_finite_set_sort(ctx.ref(), s):
699 return FiniteSetSortRef(s, ctx)
700 k = _sort_kind(ctx, s)
701 if k == Z3_BOOL_SORT:
702 return BoolSortRef(s, ctx)
703 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
704 return ArithSortRef(s, ctx)
705 elif k == Z3_BV_SORT:
706 return BitVecSortRef(s, ctx)
707 elif k == Z3_ARRAY_SORT:
708 return ArraySortRef(s, ctx)
709 elif k == Z3_DATATYPE_SORT:
710 return DatatypeSortRef(s, ctx)
711 elif k == Z3_FINITE_FIELD_SORT:
712 return FiniteFieldSortRef(s, ctx)
713 elif k == Z3_FINITE_DOMAIN_SORT:
714 return FiniteDomainSortRef(s, ctx)
715 elif k == Z3_FLOATING_POINT_SORT:
716 return FPSortRef(s, ctx)
717 elif k == Z3_ROUNDING_MODE_SORT:
718 return FPRMSortRef(s, ctx)
719 elif k == Z3_RE_SORT:
720 return ReSortRef(s, ctx)
721 elif k == Z3_SEQ_SORT:
722 return SeqSortRef(s, ctx)
723 elif k == Z3_CHAR_SORT:
724 return CharSortRef(s, ctx)
725 elif k == Z3_TYPE_VAR:
726 return TypeVarRef(s, ctx)
727 return SortRef(s, ctx)
728
729
730def _sort(ctx : Context, a : Any) -> SortRef:
731 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
732
733
734def DeclareSort(name, ctx= None) -> SortRef:
735 """Create a new uninterpreted sort named `name`.
736
737 If `ctx=None`, then the new sort is declared in the global Z3Py context.
738
739 >>> A = DeclareSort('A')
740 >>> a = Const('a', A)
741 >>> b = Const('b', A)
742 >>> a.sort() == A
743 True
744 >>> b.sort() == A
745 True
746 >>> a == b
747 a == b
748 """
749 ctx = _get_ctx(ctx)
750 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
751
753 """Type variable reference"""
754
755 def subsort(self, other):
756 return True
757
758 def cast(self, val):
759 return val
760
761
762def DeclareTypeVar(name, ctx=None):
763 """Create a new type variable named `name`.
764
765 If `ctx=None`, then the new sort is declared in the global Z3Py context.
766
767 """
768 ctx = _get_ctx(ctx)
769 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
770
771
772
777
778
780 """Function declaration. Every constant and function have an associated declaration.
781
782 The declaration assigns a name, a sort (i.e., type), and for function
783 the sort (i.e., type) of each of its arguments. Note that, in Z3,
784 a constant is a function with 0 arguments.
785 """
786
787 def as_ast(self):
788 return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
789
790 def get_id(self):
791 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
792
793 def as_func_decl(self):
794 return self.ast
795
796 def name(self):
797 """Return the name of the function declaration `self`.
798
799 >>> f = Function('f', IntSort(), IntSort())
800 >>> f.name()
801 'f'
802 >>> isinstance(f.name(), str)
803 True
804 """
805 return _symbol2py(self.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
806
807 def arity(self):
808 """Return the number of arguments of a function declaration.
809 If `self` is a constant, then `self.arity()` is 0.
810
811 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
812 >>> f.arity()
813 2
814 """
815 return int(Z3_get_arity(self.ctx_ref(), self.ast))
816
817 def domain(self, i):
818 """Return the sort of the argument `i` of a function declaration.
819 This method assumes that `0 <= i < self.arity()`.
820
821 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
822 >>> f.domain(0)
823 Int
824 >>> f.domain(1)
825 Real
826 """
827 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
828
829 def range(self):
830 """Return the sort of the range of a function declaration.
831 For constants, this is the sort of the constant.
832
833 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
834 >>> f.range()
835 Bool
836 """
837 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.ast), self.ctx)
838
839 def kind(self):
840 """Return the internal kind of a function declaration.
841 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
842
843 >>> x = Int('x')
844 >>> d = (x + 1).decl()
845 >>> d.kind() == Z3_OP_ADD
846 True
847 >>> d.kind() == Z3_OP_MUL
848 False
849 """
850 return Z3_get_decl_kind(self.ctx_ref(), self.ast)
851
852 def params(self):
853 ctx = self.ctx
854 n = Z3_get_decl_num_parameters(self.ctx_ref(), self.ast)
855 result = [None for i in range(n)]
856 for i in range(n):
857 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.ast, i)
858 if k == Z3_PARAMETER_INT:
859 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.ast, i)
860 elif k == Z3_PARAMETER_DOUBLE:
861 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.ast, i)
862 elif k == Z3_PARAMETER_RATIONAL:
863 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.ast, i)
864 elif k == Z3_PARAMETER_SYMBOL:
865 result[i] = _symbol2py(ctx, Z3_get_decl_symbol_parameter(self.ctx_ref(), self.ast, i))
866 elif k == Z3_PARAMETER_SORT:
867 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.ast, i), ctx)
868 elif k == Z3_PARAMETER_AST:
869 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.ast, i), ctx)
870 elif k == Z3_PARAMETER_FUNC_DECL:
871 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.ast, i), ctx)
872 elif k == Z3_PARAMETER_INTERNAL:
873 result[i] = "internal parameter"
874 elif k == Z3_PARAMETER_ZSTRING:
875 result[i] = "internal string"
876 else:
877 raise Z3Exception("Unexpected parameter kind")
878 return result
879
880 def __call__(self, *args):
881 """Create a Z3 application expression using the function `self`, and the given arguments.
882
883 The arguments must be Z3 expressions. This method assumes that
884 the sorts of the elements in `args` match the sorts of the
885 domain. Limited coercion is supported. For example, if
886 args[0] is a Python integer, and the function expects a Z3
887 integer, then the argument is automatically converted into a
888 Z3 integer.
889
890 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
891 >>> x = Int('x')
892 >>> y = Real('y')
893 >>> f(x, y)
894 f(x, y)
895 >>> f(x, x)
896 f(x, ToReal(x))
897 """
898 args = _get_args(args)
899 num = len(args)
900 _args = (Ast * num)()
901 saved = []
902 for i in range(num):
903 # self.domain(i).cast(args[i]) may create a new Z3 expression,
904 # then we must save in 'saved' to prevent it from being garbage collected.
905 tmp = self.domain(i).cast(args[i])
906 saved.append(tmp)
907 _args[i] = tmp.as_ast()
908 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.ast, len(args), _args), self.ctx)
909
910
912 """Return `True` if `a` is a Z3 function declaration.
913
914 >>> f = Function('f', IntSort(), IntSort())
915 >>> is_func_decl(f)
916 True
917 >>> x = Real('x')
918 >>> is_func_decl(x)
919 False
920 """
921 return isinstance(a, FuncDeclRef)
922
923
924def Function(name, *sig):
925 """Create a new Z3 uninterpreted function with the given sorts.
926
927 >>> f = Function('f', IntSort(), IntSort())
928 >>> f(f(0))
929 f(f(0))
930 """
931 sig = _get_args(sig)
932 if z3_debug():
933 _z3_assert(len(sig) > 0, "At least two arguments expected")
934 arity = len(sig) - 1
935 rng = sig[arity]
936 if z3_debug():
937 _z3_assert(is_sort(rng), "Z3 sort expected")
938 dom = (Sort * arity)()
939 for i in range(arity):
940 if z3_debug():
941 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
942 dom[i] = sig[i].ast
943 ctx = rng.ctx
944 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
945
946
948 """Create a new fresh Z3 uninterpreted function with the given sorts.
949 """
950 sig = _get_args(sig)
951 if z3_debug():
952 _z3_assert(len(sig) > 0, "At least two arguments expected")
953 arity = len(sig) - 1
954 rng = sig[arity]
955 if z3_debug():
956 _z3_assert(is_sort(rng), "Z3 sort expected")
957 dom = (z3.Sort * arity)()
958 for i in range(arity):
959 if z3_debug():
960 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
961 dom[i] = sig[i].ast
962 ctx = rng.ctx
963 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
964
965
967 return FuncDeclRef(a, ctx)
968
969
970def RecFunction(name, *sig):
971 """Create a new Z3 recursive with the given sorts."""
972 sig = _get_args(sig)
973 if z3_debug():
974 _z3_assert(len(sig) > 0, "At least two arguments expected")
975 arity = len(sig) - 1
976 rng = sig[arity]
977 if z3_debug():
978 _z3_assert(is_sort(rng), "Z3 sort expected")
979 dom = (Sort * arity)()
980 for i in range(arity):
981 if z3_debug():
982 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
983 dom[i] = sig[i].ast
984 ctx = rng.ctx
985 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
986
987
988def RecAddDefinition(f, args, body):
989 """Set the body of a recursive function.
990 Recursive definitions can be simplified if they are applied to ground
991 arguments.
992 >>> ctx = Context()
993 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
994 >>> n = Int('n', ctx)
995 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
996 >>> simplify(fac(5))
997 120
998 >>> s = Solver(ctx=ctx)
999 >>> s.add(fac(n) < 3)
1000 >>> s.check()
1001 sat
1002 >>> s.model().eval(fac(5))
1003 120
1004 """
1005 if is_app(args):
1006 args = [args]
1007 ctx = body.ctx
1008 args = _get_args(args)
1009 n = len(args)
1010 _args = (Ast * n)()
1011 for i in range(n):
1012 _args[i] = args[i].ast
1013 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
1014
1015
1020
1021
1023 """Constraints, formulas and terms are expressions in Z3.
1024
1025 Expressions are ASTs. Every expression has a sort.
1026 There are three main kinds of expressions:
1027 function applications, quantifiers and bounded variables.
1028 A constant is a function application with 0 arguments.
1029 For quantifier free problems, all expressions are
1030 function applications.
1031 """
1032
1033 def as_ast(self):
1034 return self.ast
1035
1036 def get_id(self):
1037 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
1038
1039 def sort(self):
1040 """Return the sort of expression `self`.
1041
1042 >>> x = Int('x')
1043 >>> (x + 1).sort()
1044 Int
1045 >>> y = Real('y')
1046 >>> (x + y).sort()
1047 Real
1048 """
1049 return _sort(self.ctx, self.as_ast())
1050
1051 def sort_kind(self):
1052 """Shorthand for `self.sort().kind()`.
1053
1054 >>> a = Array('a', IntSort(), IntSort())
1055 >>> a.sort_kind() == Z3_ARRAY_SORT
1056 True
1057 >>> a.sort_kind() == Z3_INT_SORT
1058 False
1059 """
1060 return self.sort().kind()
1061
1062 def __eq__(self, other):
1063 """Return a Z3 expression that represents the constraint `self == other`.
1064
1065 If `other` is `None`, then this method simply returns `False`.
1066
1067 >>> a = Int('a')
1068 >>> b = Int('b')
1069 >>> a == b
1070 a == b
1071 >>> a is None
1072 False
1073 """
1074 if other is None:
1075 return False
1076 a, b = _coerce_exprs(self, other)
1077 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
1078
1079 def __hash__(self):
1080 """ Hash code. """
1081 return AstRef.__hash__(self)
1082
1083 def __ne__(self, other):
1084 """Return a Z3 expression that represents the constraint `self != other`.
1085
1086 If `other` is `None`, then this method simply returns `True`.
1087
1088 >>> a = Int('a')
1089 >>> b = Int('b')
1090 >>> a != b
1091 a != b
1092 >>> a is not None
1093 True
1094 """
1095 if other is None:
1096 return True
1097 a, b = _coerce_exprs(self, other)
1098 _args, sz = _to_ast_array((a, b))
1099 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
1100
1101 def params(self):
1102 return self.decl().params()
1103
1104 def decl(self):
1105 """Return the Z3 function declaration associated with a Z3 application.
1106
1107 >>> f = Function('f', IntSort(), IntSort())
1108 >>> a = Int('a')
1109 >>> t = f(a)
1110 >>> eq(t.decl(), f)
1111 True
1112 >>> (a + 1).decl()
1113 +
1114 """
1115 if z3_debug():
1116 _z3_assert(is_app(self), "Z3 application expected")
1117 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_ast()), self.ctx)
1118
1119 def kind(self):
1120 """Return the Z3 internal kind of a function application."""
1121 if z3_debug():
1122 _z3_assert(is_app(self), "Z3 application expected")
1124
1125
1126 def num_args(self):
1127 """Return the number of arguments of a Z3 application.
1128
1129 >>> a = Int('a')
1130 >>> b = Int('b')
1131 >>> (a + b).num_args()
1132 2
1133 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1134 >>> t = f(a, b, 0)
1135 >>> t.num_args()
1136 3
1137 """
1138 if z3_debug():
1139 _z3_assert(is_app(self), "Z3 application expected")
1140 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_ast()))
1141
1142 def arg(self, idx):
1143 """Return argument `idx` of the application `self`.
1144
1145 This method assumes that `self` is a function application with at least `idx+1` arguments.
1146
1147 >>> a = Int('a')
1148 >>> b = Int('b')
1149 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1150 >>> t = f(a, b, 0)
1151 >>> t.arg(0)
1152 a
1153 >>> t.arg(1)
1154 b
1155 >>> t.arg(2)
1156 0
1157 """
1158 if z3_debug():
1159 _z3_assert(is_app(self), "Z3 application expected")
1160 _z3_assert(idx < self.num_args(), "Invalid argument index")
1161 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_ast(), idx), self.ctx)
1162
1163 def children(self):
1164 """Return a list containing the children of the given expression
1165
1166 >>> a = Int('a')
1167 >>> b = Int('b')
1168 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1169 >>> t = f(a, b, 0)
1170 >>> t.children()
1171 [a, b, 0]
1172 """
1173 if is_app(self):
1174 return [self.arg(i) for i in range(self.num_args())]
1175 else:
1176 return []
1177
1178 def update(self, *args):
1179 """Update the arguments of the expression.
1180
1181 Return a new expression with the same function declaration and updated arguments.
1182 The number of new arguments must match the current number of arguments.
1183
1184 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1185 >>> a = Int('a')
1186 >>> b = Int('b')
1187 >>> c = Int('c')
1188 >>> t = f(a, b)
1189 >>> t.update(c, c)
1190 f(c, c)
1191 """
1192 if z3_debug():
1193 _z3_assert(is_app(self), "Z3 application expected")
1194 _z3_assert(len(args) == self.num_args(), "Number of arguments does not match")
1195 _z3_assert(all([is_expr(arg) for arg in args]), "Z3 expressions expected")
1196 num = len(args)
1197 _args = (Ast * num)()
1198 for i in range(num):
1199 _args[i] = args[i].as_ast()
1200 return _to_expr_ref(Z3_update_term(self.ctx_ref(), self.as_ast(), num, _args), self.ctx)
1201
1202 def from_string(self, s):
1203 pass
1204
1205 def serialize(self):
1206 s = Solver()
1207 f = Function('F', self.sort(), BoolSort(self.ctx))
1208 s.add(f(self))
1209 return s.sexpr()
1210
1212 """inverse function to the serialize method on ExprRef.
1213 It is made available to make it easier for users to serialize expressions back and forth between
1214 strings. Solvers can be serialized using the 'sexpr()' method.
1215 """
1216 s = Solver()
1217 s.from_string(st)
1218 if len(s.assertions()) != 1:
1219 raise Z3Exception("single assertion expected")
1220 fml = s.assertions()[0]
1221 if fml.num_args() != 1:
1222 raise Z3Exception("dummy function 'F' expected")
1223 return fml.arg(0)
1224
1225def _to_expr_ref(a, ctx):
1226 if isinstance(a, Pattern):
1227 return PatternRef(a, ctx)
1228 ctx_ref = ctx.ref()
1229 k = Z3_get_ast_kind(ctx_ref, a)
1230 if k == Z3_QUANTIFIER_AST:
1231 return QuantifierRef(a, ctx)
1232 # Check for finite set sort before checking sort kind
1233 s = Z3_get_sort(ctx_ref, a)
1234 if Z3_is_finite_set_sort(ctx_ref, s):
1235 return FiniteSetRef(a, ctx)
1236 sk = Z3_get_sort_kind(ctx_ref, s)
1237 if sk == Z3_BOOL_SORT:
1238 return BoolRef(a, ctx)
1239 if sk == Z3_INT_SORT:
1240 if k == Z3_NUMERAL_AST:
1241 return IntNumRef(a, ctx)
1242 return ArithRef(a, ctx)
1243 if sk == Z3_REAL_SORT:
1244 if k == Z3_NUMERAL_AST:
1245 return RatNumRef(a, ctx)
1246 if _is_algebraic(ctx, a):
1247 return AlgebraicNumRef(a, ctx)
1248 return ArithRef(a, ctx)
1249 if sk == Z3_BV_SORT:
1250 if k == Z3_NUMERAL_AST:
1251 return BitVecNumRef(a, ctx)
1252 else:
1253 return BitVecRef(a, ctx)
1254 if sk == Z3_ARRAY_SORT:
1255 return ArrayRef(a, ctx)
1256 if sk == Z3_DATATYPE_SORT:
1257 return DatatypeRef(a, ctx)
1258 if sk == Z3_FLOATING_POINT_SORT:
1259 if k == Z3_APP_AST and _is_numeral(ctx, a):
1260 return FPNumRef(a, ctx)
1261 else:
1262 return FPRef(a, ctx)
1263 if sk == Z3_FINITE_FIELD_SORT:
1264 return FiniteFieldRef(a, ctx)
1265 if sk == Z3_FINITE_DOMAIN_SORT:
1266 if k == Z3_NUMERAL_AST:
1267 return FiniteDomainNumRef(a, ctx)
1268 else:
1269 return FiniteDomainRef(a, ctx)
1270 if sk == Z3_ROUNDING_MODE_SORT:
1271 return FPRMRef(a, ctx)
1272 if sk == Z3_SEQ_SORT:
1273 return SeqRef(a, ctx)
1274 if sk == Z3_CHAR_SORT:
1275 return CharRef(a, ctx)
1276 if sk == Z3_RE_SORT:
1277 return ReRef(a, ctx)
1278 return ExprRef(a, ctx)
1279
1280
1282 if is_expr(a):
1283 s1 = a.sort()
1284 if s is None:
1285 return s1
1286 if s1.eq(s):
1287 return s
1288 elif s.subsort(s1):
1289 return s1
1290 elif s1.subsort(s):
1291 return s
1292 else:
1293 if z3_debug():
1294 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1295 _z3_assert(False, "sort mismatch")
1296 else:
1297 return s
1298
1299def _check_same_sort(a, b, ctx=None):
1300 if not isinstance(a, ExprRef):
1301 return False
1302 if not isinstance(b, ExprRef):
1303 return False
1304 if ctx is None:
1305 ctx = a.ctx
1306
1307 a_sort = Z3_get_sort(ctx.ctx, a.ast)
1308 b_sort = Z3_get_sort(ctx.ctx, b.ast)
1309 return Z3_is_eq_sort(ctx.ctx, a_sort, b_sort)
1310
1311
1312def _coerce_exprs(a, b, ctx=None):
1313 if not is_expr(a) and not is_expr(b):
1314 a = _py2expr(a, ctx)
1315 b = _py2expr(b, ctx)
1316 if isinstance(a, str) and isinstance(b, SeqRef):
1317 a = StringVal(a, b.ctx)
1318 if isinstance(b, str) and isinstance(a, SeqRef):
1319 b = StringVal(b, a.ctx)
1320 if isinstance(a, float) and isinstance(b, ArithRef):
1321 a = RealVal(a, b.ctx)
1322 if isinstance(b, float) and isinstance(a, ArithRef):
1323 b = RealVal(b, a.ctx)
1324
1325 if _check_same_sort(a, b, ctx):
1326 return (a, b)
1327
1328 s = None
1329 s = _coerce_expr_merge(s, a)
1330 s = _coerce_expr_merge(s, b)
1331 a = s.cast(a)
1332 b = s.cast(b)
1333 return (a, b)
1334
1335
1336def _reduce(func, sequence, initial):
1337 result = initial
1338 for element in sequence:
1339 result = func(result, element)
1340 return result
1341
1342
1343def _coerce_expr_list(alist, ctx=None):
1344 has_expr = False
1345 for a in alist:
1346 if is_expr(a):
1347 has_expr = True
1348 break
1349 if not has_expr:
1350 alist = [_py2expr(a, ctx) for a in alist]
1351 s = _reduce(_coerce_expr_merge, alist, None)
1352 return [s.cast(a) for a in alist]
1353
1354
1355def is_expr(a):
1356 """Return `True` if `a` is a Z3 expression.
1357
1358 >>> a = Int('a')
1359 >>> is_expr(a)
1360 True
1361 >>> is_expr(a + 1)
1362 True
1363 >>> is_expr(IntSort())
1364 False
1365 >>> is_expr(1)
1366 False
1367 >>> is_expr(IntVal(1))
1368 True
1369 >>> x = Int('x')
1370 >>> is_expr(ForAll(x, x >= 0))
1371 True
1372 >>> is_expr(FPVal(1.0))
1373 True
1374 """
1375 return isinstance(a, ExprRef)
1376
1377
1378def is_app(a):
1379 """Return `True` if `a` is a Z3 function application.
1380
1381 Note that, constants are function applications with 0 arguments.
1382
1383 >>> a = Int('a')
1384 >>> is_app(a)
1385 True
1386 >>> is_app(a + 1)
1387 True
1388 >>> is_app(IntSort())
1389 False
1390 >>> is_app(1)
1391 False
1392 >>> is_app(IntVal(1))
1393 True
1394 >>> x = Int('x')
1395 >>> is_app(ForAll(x, x >= 0))
1396 False
1397 """
1398 if not isinstance(a, ExprRef):
1399 return False
1400 k = _ast_kind(a.ctx, a)
1401 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1402
1403
1405 """Return `True` if `a` is Z3 constant/variable expression.
1406
1407 >>> a = Int('a')
1408 >>> is_const(a)
1409 True
1410 >>> is_const(a + 1)
1411 False
1412 >>> is_const(1)
1413 False
1414 >>> is_const(IntVal(1))
1415 True
1416 >>> x = Int('x')
1417 >>> is_const(ForAll(x, x >= 0))
1418 False
1419 """
1420 return is_app(a) and a.num_args() == 0
1421
1422
1423def is_var(a):
1424 """Return `True` if `a` is variable.
1425
1426 Z3 uses de-Bruijn indices for representing bound variables in
1427 quantifiers.
1428
1429 >>> x = Int('x')
1430 >>> is_var(x)
1431 False
1432 >>> is_const(x)
1433 True
1434 >>> f = Function('f', IntSort(), IntSort())
1435 >>> # Z3 replaces x with bound variables when ForAll is executed.
1436 >>> q = ForAll(x, f(x) == x)
1437 >>> b = q.body()
1438 >>> b
1439 f(Var(0)) == Var(0)
1440 >>> b.arg(1)
1441 Var(0)
1442 >>> is_var(b.arg(1))
1443 True
1444 """
1445 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1446
1447
1449 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1450
1451 >>> x = Int('x')
1452 >>> y = Int('y')
1453 >>> is_var(x)
1454 False
1455 >>> is_const(x)
1456 True
1457 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1458 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1459 >>> q = ForAll([x, y], f(x, y) == x + y)
1460 >>> q.body()
1461 f(Var(1), Var(0)) == Var(1) + Var(0)
1462 >>> b = q.body()
1463 >>> b.arg(0)
1464 f(Var(1), Var(0))
1465 >>> v1 = b.arg(0).arg(0)
1466 >>> v2 = b.arg(0).arg(1)
1467 >>> v1
1468 Var(1)
1469 >>> v2
1470 Var(0)
1471 >>> get_var_index(v1)
1472 1
1473 >>> get_var_index(v2)
1474 0
1475 """
1476 if z3_debug():
1477 _z3_assert(is_var(a), "Z3 bound variable expected")
1478 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1479
1480
1481def is_app_of(a, k):
1482 """Return `True` if `a` is an application of the given kind `k`.
1483
1484 >>> x = Int('x')
1485 >>> n = x + 1
1486 >>> is_app_of(n, Z3_OP_ADD)
1487 True
1488 >>> is_app_of(n, Z3_OP_MUL)
1489 False
1490 """
1491 return is_app(a) and a.kind() == k
1492
1493
1494def If(a, b, c, ctx=None):
1495 """Create a Z3 if-then-else expression.
1496
1497 >>> x = Int('x')
1498 >>> y = Int('y')
1499 >>> max = If(x > y, x, y)
1500 >>> max
1501 If(x > y, x, y)
1502 >>> simplify(max)
1503 If(x <= y, y, x)
1504 """
1505 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1506 return Cond(a, b, c, ctx)
1507 else:
1508 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1509 s = BoolSort(ctx)
1510 a = s.cast(a)
1511 b, c = _coerce_exprs(b, c, ctx)
1512 if z3_debug():
1513 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1514 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1515
1516
1517def Distinct(*args):
1518 """Create a Z3 distinct expression.
1519
1520 >>> x = Int('x')
1521 >>> y = Int('y')
1522 >>> Distinct(x, y)
1523 x != y
1524 >>> z = Int('z')
1525 >>> Distinct(x, y, z)
1526 Distinct(x, y, z)
1527 >>> simplify(Distinct(x, y, z))
1528 Distinct(x, y, z)
1529 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1530 And(Not(x == y), Not(x == z), Not(y == z))
1531 """
1532 args = _get_args(args)
1533 ctx = _ctx_from_ast_arg_list(args)
1534 if z3_debug():
1535 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1536 args = _coerce_expr_list(args, ctx)
1537 _args, sz = _to_ast_array(args)
1538 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1539
1540
1541def _mk_bin(f, a, b):
1542 args = (Ast * 2)()
1543 if z3_debug():
1544 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1545 args[0] = a.as_ast()
1546 args[1] = b.as_ast()
1547 return f(a.ctx.ref(), 2, args)
1548
1549
1550def Const(name, sort):
1551 """Create a constant of the given sort.
1552
1553 >>> Const('x', IntSort())
1554 x
1555 """
1556 if z3_debug():
1557 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1558 ctx = sort.ctx
1559 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1560
1561
1562def Consts(names, sort):
1563 """Create several constants of the given sort.
1564
1565 `names` is a string containing the names of all constants to be created.
1566 Blank spaces separate the names of different constants.
1567
1568 >>> x, y, z = Consts('x y z', IntSort())
1569 >>> x + y + z
1570 x + y + z
1571 """
1572 if isinstance(names, str):
1573 names = names.split(" ")
1574 return [Const(name, sort) for name in names]
1575
1576
1577def FreshConst(sort, prefix="c"):
1578 """Create a fresh constant of a specified sort"""
1579 if z3_debug():
1580 _z3_assert(is_sort(sort), f"Z3 sort expected, got {type(sort)}")
1581 ctx = _get_ctx(sort.ctx)
1582 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1583
1584
1585def Var(idx : int, s : SortRef) -> ExprRef:
1586 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1587 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1588 declarations.
1589
1590 >>> Var(0, IntSort())
1591 Var(0)
1592 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1593 False
1594 """
1595 if z3_debug():
1596 _z3_assert(is_sort(s), "Z3 sort expected")
1597 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1598
1599
1600def RealVar(idx: int, ctx=None) -> ExprRef:
1601 """
1602 Create a real free variable. Free variables are used to create quantified formulas.
1603 They are also used to create polynomials.
1604
1605 >>> RealVar(0)
1606 Var(0)
1607 """
1608 return Var(idx, RealSort(ctx))
1609
1610def RealVarVector(n: int, ctx= None):
1611 """
1612 Create a list of Real free variables.
1613 The variables have ids: 0, 1, ..., n-1
1614
1615 >>> x0, x1, x2, x3 = RealVarVector(4)
1616 >>> x2
1617 Var(2)
1618 """
1619 return [RealVar(i, ctx) for i in range(n)]
1620
1621
1626
1627
1629 """Boolean sort."""
1630
1631 def cast(self, val):
1632 """Try to cast `val` as a Boolean.
1633
1634 >>> x = BoolSort().cast(True)
1635 >>> x
1636 True
1637 >>> is_expr(x)
1638 True
1639 >>> is_expr(True)
1640 False
1641 >>> x.sort()
1642 Bool
1643 """
1644 if isinstance(val, bool):
1645 return BoolVal(val, self.ctx)
1646 if z3_debug():
1647 if not is_expr(val):
1648 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1649 _z3_assert(is_expr(val), msg % (val, type(val)))
1650 if not self.eq(val.sort()):
1651 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1652 return val
1653
1654 def subsort(self, other):
1655 return isinstance(other, ArithSortRef)
1656
1657 def is_int(self):
1658 return True
1659
1660 def is_bool(self):
1661 return True
1662
1663
1665 """All Boolean expressions are instances of this class."""
1666
1667 def sort(self):
1668 return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
1669
1670 def __add__(self, other):
1671 if isinstance(other, BoolRef):
1672 other = If(other, 1, 0)
1673 return If(self, 1, 0) + other
1674
1675 def __radd__(self, other):
1676 return self + other
1677
1678 def __rmul__(self, other):
1679 return self * other
1680
1681 def __mul__(self, other):
1682 """Create the Z3 expression `self * other`.
1683 """
1684 if isinstance(other, int) and other == 1:
1685 return If(self, 1, 0)
1686 if isinstance(other, int) and other == 0:
1687 return IntVal(0, self.ctx)
1688 if isinstance(other, BoolRef):
1689 other = If(other, 1, 0)
1690 return If(self, other, 0)
1691
1692 def __and__(self, other):
1693 return And(self, other)
1694
1695 def __or__(self, other):
1696 return Or(self, other)
1697
1698 def __xor__(self, other):
1699 return Xor(self, other)
1700
1701 def __invert__(self):
1702 return Not(self)
1703
1704 def py_value(self):
1705 if is_true(self):
1706 return True
1707 if is_false(self):
1708 return False
1709 return None
1710
1711
1712
1713
1714def is_bool(a : Any) -> bool:
1715 """Return `True` if `a` is a Z3 Boolean expression.
1716
1717 >>> p = Bool('p')
1718 >>> is_bool(p)
1719 True
1720 >>> q = Bool('q')
1721 >>> is_bool(And(p, q))
1722 True
1723 >>> x = Real('x')
1724 >>> is_bool(x)
1725 False
1726 >>> is_bool(x == 0)
1727 True
1728 """
1729 return isinstance(a, BoolRef)
1730
1731
1732def is_true(a : Any) -> bool:
1733 """Return `True` if `a` is the Z3 true expression.
1734
1735 >>> p = Bool('p')
1736 >>> is_true(p)
1737 False
1738 >>> is_true(simplify(p == p))
1739 True
1740 >>> x = Real('x')
1741 >>> is_true(x == 0)
1742 False
1743 >>> # True is a Python Boolean expression
1744 >>> is_true(True)
1745 False
1746 """
1747 return is_app_of(a, Z3_OP_TRUE)
1748
1749
1750def is_false(a : Any) -> bool:
1751 """Return `True` if `a` is the Z3 false expression.
1752
1753 >>> p = Bool('p')
1754 >>> is_false(p)
1755 False
1756 >>> is_false(False)
1757 False
1758 >>> is_false(BoolVal(False))
1759 True
1760 """
1761 return is_app_of(a, Z3_OP_FALSE)
1762
1763
1764def is_and(a : Any) -> bool:
1765 """Return `True` if `a` is a Z3 and expression.
1766
1767 >>> p, q = Bools('p q')
1768 >>> is_and(And(p, q))
1769 True
1770 >>> is_and(Or(p, q))
1771 False
1772 """
1773 return is_app_of(a, Z3_OP_AND)
1774
1775
1776def is_or(a : Any) -> bool:
1777 """Return `True` if `a` is a Z3 or expression.
1778
1779 >>> p, q = Bools('p q')
1780 >>> is_or(Or(p, q))
1781 True
1782 >>> is_or(And(p, q))
1783 False
1784 """
1785 return is_app_of(a, Z3_OP_OR)
1786
1787
1788def is_implies(a : Any) -> bool:
1789 """Return `True` if `a` is a Z3 implication expression.
1790
1791 >>> p, q = Bools('p q')
1792 >>> is_implies(Implies(p, q))
1793 True
1794 >>> is_implies(And(p, q))
1795 False
1796 """
1797 return is_app_of(a, Z3_OP_IMPLIES)
1798
1799
1800def is_not(a : Any) -> bool:
1801 """Return `True` if `a` is a Z3 not expression.
1802
1803 >>> p = Bool('p')
1804 >>> is_not(p)
1805 False
1806 >>> is_not(Not(p))
1807 True
1808 """
1809 return is_app_of(a, Z3_OP_NOT)
1810
1811
1812def is_eq(a : Any) -> bool:
1813 """Return `True` if `a` is a Z3 equality expression.
1814
1815 >>> x, y = Ints('x y')
1816 >>> is_eq(x == y)
1817 True
1818 """
1819 return is_app_of(a, Z3_OP_EQ)
1820
1821
1822def is_distinct(a : Any) -> bool:
1823 """Return `True` if `a` is a Z3 distinct expression.
1824
1825 >>> x, y, z = Ints('x y z')
1826 >>> is_distinct(x == y)
1827 False
1828 >>> is_distinct(Distinct(x, y, z))
1829 True
1830 """
1831 return is_app_of(a, Z3_OP_DISTINCT)
1832
1833
1834def BoolSort(ctx=None):
1835 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1836
1837 >>> BoolSort()
1838 Bool
1839 >>> p = Const('p', BoolSort())
1840 >>> is_bool(p)
1841 True
1842 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1843 >>> r(0, 1)
1844 r(0, 1)
1845 >>> is_bool(r(0, 1))
1846 True
1847 """
1848 ctx = _get_ctx(ctx)
1849 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1850
1851
1852def BoolVal(val, ctx=None):
1853 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1854
1855 >>> BoolVal(True)
1856 True
1857 >>> is_true(BoolVal(True))
1858 True
1859 >>> is_true(True)
1860 False
1861 >>> is_false(BoolVal(False))
1862 True
1863 """
1864 ctx = _get_ctx(ctx)
1865 if val:
1866 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1867 else:
1868 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1869
1870
1871def Bool(name, ctx=None):
1872 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1873
1874 >>> p = Bool('p')
1875 >>> q = Bool('q')
1876 >>> And(p, q)
1877 And(p, q)
1878 """
1879 ctx = _get_ctx(ctx)
1880 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1881
1882
1883def Bools(names, ctx=None):
1884 """Return a tuple of Boolean constants.
1885
1886 `names` is a single string containing all names separated by blank spaces.
1887 If `ctx=None`, then the global context is used.
1888
1889 >>> p, q, r = Bools('p q r')
1890 >>> And(p, Or(q, r))
1891 And(p, Or(q, r))
1892 """
1893 ctx = _get_ctx(ctx)
1894 if isinstance(names, str):
1895 names = names.split(" ")
1896 return [Bool(name, ctx) for name in names]
1897
1898
1899def BoolVector(prefix, sz, ctx=None):
1900 """Return a list of Boolean constants of size `sz`.
1901
1902 The constants are named using the given prefix.
1903 If `ctx=None`, then the global context is used.
1904
1905 >>> P = BoolVector('p', 3)
1906 >>> P
1907 [p__0, p__1, p__2]
1908 >>> And(P)
1909 And(p__0, p__1, p__2)
1910 """
1911 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1912
1913
1914def FreshBool(prefix="b", ctx=None):
1915 """Return a fresh Boolean constant in the given context using the given prefix.
1916
1917 If `ctx=None`, then the global context is used.
1918
1919 >>> b1 = FreshBool()
1920 >>> b2 = FreshBool()
1921 >>> eq(b1, b2)
1922 False
1923 """
1924 ctx = _get_ctx(ctx)
1925 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1926
1927
1928def Implies(a, b, ctx=None):
1929 """Create a Z3 implies expression.
1930
1931 >>> p, q = Bools('p q')
1932 >>> Implies(p, q)
1933 Implies(p, q)
1934 """
1935 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1936 s = BoolSort(ctx)
1937 a = s.cast(a)
1938 b = s.cast(b)
1939 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1940
1941
1942def Xor(a, b, ctx=None):
1943 """Create a Z3 Xor expression.
1944
1945 >>> p, q = Bools('p q')
1946 >>> Xor(p, q)
1947 Xor(p, q)
1948 >>> simplify(Xor(p, q))
1949 Not(p == q)
1950 """
1951 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1952 s = BoolSort(ctx)
1953 a = s.cast(a)
1954 b = s.cast(b)
1955 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1956
1957
1958def Not(a, ctx=None):
1959 """Create a Z3 not expression or probe.
1960
1961 >>> p = Bool('p')
1962 >>> Not(Not(p))
1963 Not(Not(p))
1964 >>> simplify(Not(Not(p)))
1965 p
1966 """
1967 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1968 if is_probe(a):
1969 # Not is also used to build probes
1970 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1971 else:
1972 s = BoolSort(ctx)
1973 a = s.cast(a)
1974 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1975
1976
1977def mk_not(a):
1978 if is_not(a):
1979 return a.arg(0)
1980 else:
1981 return Not(a)
1982
1983
1984def _has_probe(args):
1985 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1986 for arg in args:
1987 if is_probe(arg):
1988 return True
1989 return False
1990
1991
1992def And(*args):
1993 """Create a Z3 and-expression or and-probe.
1994
1995 >>> p, q, r = Bools('p q r')
1996 >>> And(p, q, r)
1997 And(p, q, r)
1998 >>> P = BoolVector('p', 5)
1999 >>> And(P)
2000 And(p__0, p__1, p__2, p__3, p__4)
2001 """
2002 last_arg = None
2003 if len(args) > 0:
2004 last_arg = args[len(args) - 1]
2005 if isinstance(last_arg, Context):
2006 ctx = args[len(args) - 1]
2007 args = args[:len(args) - 1]
2008 elif len(args) == 1 and isinstance(args[0], AstVector):
2009 ctx = args[0].ctx
2010 args = [a for a in args[0]]
2011 else:
2012 ctx = None
2013 args = _get_args(args)
2014 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2015 if z3_debug():
2016 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2017 if _has_probe(args):
2018 return _probe_and(args, ctx)
2019 else:
2020 args = _coerce_expr_list(args, ctx)
2021 _args, sz = _to_ast_array(args)
2022 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
2023
2024
2025def Or(*args):
2026 """Create a Z3 or-expression or or-probe.
2027
2028 >>> p, q, r = Bools('p q r')
2029 >>> Or(p, q, r)
2030 Or(p, q, r)
2031 >>> P = BoolVector('p', 5)
2032 >>> Or(P)
2033 Or(p__0, p__1, p__2, p__3, p__4)
2034 """
2035 last_arg = None
2036 if len(args) > 0:
2037 last_arg = args[len(args) - 1]
2038 if isinstance(last_arg, Context):
2039 ctx = args[len(args) - 1]
2040 args = args[:len(args) - 1]
2041 elif len(args) == 1 and isinstance(args[0], AstVector):
2042 ctx = args[0].ctx
2043 args = [a for a in args[0]]
2044 else:
2045 ctx = None
2046 args = _get_args(args)
2047 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2048 if z3_debug():
2049 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2050 if _has_probe(args):
2051 return _probe_or(args, ctx)
2052 else:
2053 args = _coerce_expr_list(args, ctx)
2054 _args, sz = _to_ast_array(args)
2055 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
2056
2057
2062
2063
2065 """Patterns are hints for quantifier instantiation.
2066
2067 """
2068
2069 def as_ast(self):
2070 return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
2071
2072 def get_id(self):
2073 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2074
2075
2077 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
2078
2079 >>> f = Function('f', IntSort(), IntSort())
2080 >>> x = Int('x')
2081 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
2082 >>> q
2083 ForAll(x, f(x) == 0)
2084 >>> q.num_patterns()
2085 1
2086 >>> is_pattern(q.pattern(0))
2087 True
2088 >>> q.pattern(0)
2089 f(Var(0))
2090 """
2091 return isinstance(a, PatternRef)
2092
2093
2094def MultiPattern(*args):
2095 """Create a Z3 multi-pattern using the given expressions `*args`
2096
2097 >>> f = Function('f', IntSort(), IntSort())
2098 >>> g = Function('g', IntSort(), IntSort())
2099 >>> x = Int('x')
2100 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2101 >>> q
2102 ForAll(x, f(x) != g(x))
2103 >>> q.num_patterns()
2104 1
2105 >>> is_pattern(q.pattern(0))
2106 True
2107 >>> q.pattern(0)
2108 MultiPattern(f(Var(0)), g(Var(0)))
2109 """
2110 if z3_debug():
2111 _z3_assert(len(args) > 0, "At least one argument expected")
2112 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2113 ctx = args[0].ctx
2114 args, sz = _to_ast_array(args)
2115 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2116
2117
2119 if is_pattern(arg):
2120 return arg
2121 else:
2122 return MultiPattern(arg)
2123
2124
2129
2130
2132 """Universally and Existentially quantified formulas."""
2133
2134 def as_ast(self):
2135 return self.ast
2136
2137 def get_id(self):
2138 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2139
2140 def sort(self):
2141 """Return the Boolean sort or sort of Lambda."""
2142 if self.is_lambda():
2143 return _sort(self.ctx, self.as_ast())
2144 return BoolSort(self.ctx)
2145
2146 def is_forall(self):
2147 """Return `True` if `self` is a universal quantifier.
2148
2149 >>> f = Function('f', IntSort(), IntSort())
2150 >>> x = Int('x')
2151 >>> q = ForAll(x, f(x) == 0)
2152 >>> q.is_forall()
2153 True
2154 >>> q = Exists(x, f(x) != 0)
2155 >>> q.is_forall()
2156 False
2157 """
2159
2160 def is_exists(self):
2161 """Return `True` if `self` is an existential quantifier.
2162
2163 >>> f = Function('f', IntSort(), IntSort())
2164 >>> x = Int('x')
2165 >>> q = ForAll(x, f(x) == 0)
2166 >>> q.is_exists()
2167 False
2168 >>> q = Exists(x, f(x) != 0)
2169 >>> q.is_exists()
2170 True
2171 """
2172 return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
2173
2174 def is_lambda(self):
2175 """Return `True` if `self` is a lambda expression.
2176
2177 >>> f = Function('f', IntSort(), IntSort())
2178 >>> x = Int('x')
2179 >>> q = Lambda(x, f(x))
2180 >>> q.is_lambda()
2181 True
2182 >>> q = Exists(x, f(x) != 0)
2183 >>> q.is_lambda()
2184 False
2185 """
2186 return Z3_is_lambda(self.ctx_ref(), self.ast)
2187
2188 def __getitem__(self, arg):
2189 """Return the Z3 expression `self[arg]`.
2190 """
2191 if z3_debug():
2192 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2193 return _array_select(self, arg)
2194
2195 def weight(self):
2196 """Return the weight annotation of `self`.
2197
2198 >>> f = Function('f', IntSort(), IntSort())
2199 >>> x = Int('x')
2200 >>> q = ForAll(x, f(x) == 0)
2201 >>> q.weight()
2202 1
2203 >>> q = ForAll(x, f(x) == 0, weight=10)
2204 >>> q.weight()
2205 10
2206 """
2207 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.ast))
2208
2209 def skolem_id(self):
2210 """Return the skolem id of `self`.
2211 """
2212 return _symbol2py(self.ctx, Z3_get_quantifier_skolem_id(self.ctx_ref(), self.ast))
2213
2214 def qid(self):
2215 """Return the quantifier id of `self`.
2216 """
2217 return _symbol2py(self.ctx, Z3_get_quantifier_id(self.ctx_ref(), self.ast))
2218
2219 def num_patterns(self):
2220 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2221
2222 >>> f = Function('f', IntSort(), IntSort())
2223 >>> g = Function('g', IntSort(), IntSort())
2224 >>> x = Int('x')
2225 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2226 >>> q.num_patterns()
2227 2
2228 """
2229 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.ast))
2230
2231 def pattern(self, idx):
2232 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2233
2234 >>> f = Function('f', IntSort(), IntSort())
2235 >>> g = Function('g', IntSort(), IntSort())
2236 >>> x = Int('x')
2237 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2238 >>> q.num_patterns()
2239 2
2240 >>> q.pattern(0)
2241 f(Var(0))
2242 >>> q.pattern(1)
2243 g(Var(0))
2244 """
2245 if z3_debug():
2246 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2247 return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2248
2250 """Return the number of no-patterns."""
2251 return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
2252
2253 def no_pattern(self, idx):
2254 """Return a no-pattern."""
2255 if z3_debug():
2256 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2257 return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2258
2259 def body(self):
2260 """Return the expression being quantified.
2261
2262 >>> f = Function('f', IntSort(), IntSort())
2263 >>> x = Int('x')
2264 >>> q = ForAll(x, f(x) == 0)
2265 >>> q.body()
2266 f(Var(0)) == 0
2267 """
2268 return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
2269
2270 def num_vars(self):
2271 """Return the number of variables bounded by this quantifier.
2272
2273 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2274 >>> x = Int('x')
2275 >>> y = Int('y')
2276 >>> q = ForAll([x, y], f(x, y) >= x)
2277 >>> q.num_vars()
2278 2
2279 """
2280 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.ast))
2281
2282 def var_name(self, idx):
2283 """Return a string representing a name used when displaying the quantifier.
2284
2285 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2286 >>> x = Int('x')
2287 >>> y = Int('y')
2288 >>> q = ForAll([x, y], f(x, y) >= x)
2289 >>> q.var_name(0)
2290 'x'
2291 >>> q.var_name(1)
2292 'y'
2293 """
2294 if z3_debug():
2295 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2296 return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, idx))
2297
2298 def var_sort(self, idx):
2299 """Return the sort of a bound variable.
2300
2301 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2302 >>> x = Int('x')
2303 >>> y = Real('y')
2304 >>> q = ForAll([x, y], f(x, y) >= x)
2305 >>> q.var_sort(0)
2306 Int
2307 >>> q.var_sort(1)
2308 Real
2309 """
2310 if z3_debug():
2311 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2312 return _to_sort_ref(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
2313
2314 def children(self):
2315 """Return a list containing a single element self.body()
2316
2317 >>> f = Function('f', IntSort(), IntSort())
2318 >>> x = Int('x')
2319 >>> q = ForAll(x, f(x) == 0)
2320 >>> q.children()
2321 [f(Var(0)) == 0]
2322 """
2323 return [self.body()]
2324
2325
2327 """Return `True` if `a` is a Z3 quantifier.
2328
2329 >>> f = Function('f', IntSort(), IntSort())
2330 >>> x = Int('x')
2331 >>> q = ForAll(x, f(x) == 0)
2332 >>> is_quantifier(q)
2333 True
2334 >>> is_quantifier(f(x))
2335 False
2336 """
2337 return isinstance(a, QuantifierRef)
2338
2339
2340def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2341 if z3_debug():
2342 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2343 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2344 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2345 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2346 if is_app(vs):
2347 ctx = vs.ctx
2348 vs = [vs]
2349 else:
2350 ctx = vs[0].ctx
2351 if not is_expr(body):
2352 body = BoolVal(body, ctx)
2353 num_vars = len(vs)
2354 if num_vars == 0:
2355 return body
2356 _vs = (Ast * num_vars)()
2357 for i in range(num_vars):
2358 # TODO: Check if is constant
2359 _vs[i] = vs[i].as_ast()
2360 patterns = [_to_pattern(p) for p in patterns]
2361 num_pats = len(patterns)
2362 _pats = (Pattern * num_pats)()
2363 for i in range(num_pats):
2364 _pats[i] = patterns[i].ast
2365 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2366 qid = to_symbol(qid, ctx)
2367 skid = to_symbol(skid, ctx)
2368 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2369 num_vars, _vs,
2370 num_pats, _pats,
2371 num_no_pats, _no_pats,
2372 body.as_ast()), ctx)
2373
2374
2375def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2376 """Create a Z3 forall formula.
2377
2378 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2379
2380 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2381 >>> x = Int('x')
2382 >>> y = Int('y')
2383 >>> ForAll([x, y], f(x, y) >= x)
2384 ForAll([x, y], f(x, y) >= x)
2385 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2386 ForAll([x, y], f(x, y) >= x)
2387 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2388 ForAll([x, y], f(x, y) >= x)
2389 """
2390 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2391
2392
2393def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2394 """Create a Z3 exists formula.
2395
2396 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2397
2398
2399 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2400 >>> x = Int('x')
2401 >>> y = Int('y')
2402 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2403 >>> q
2404 Exists([x, y], f(x, y) >= x)
2405 >>> is_quantifier(q)
2406 True
2407 >>> r = Tactic('nnf')(q).as_expr()
2408 >>> is_quantifier(r)
2409 False
2410 """
2411 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2412
2413
2414def Lambda(vs, body):
2415 """Create a Z3 lambda expression.
2416
2417 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2418 >>> mem0 = Array('mem0', IntSort(), IntSort())
2419 >>> lo, hi, e, i = Ints('lo hi e i')
2420 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2421 >>> mem1
2422 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2423 """
2424 ctx = body.ctx
2425 if is_app(vs):
2426 vs = [vs]
2427 num_vars = len(vs)
2428 _vs = (Ast * num_vars)()
2429 for i in range(num_vars):
2430 # TODO: Check if is constant
2431 _vs[i] = vs[i].as_ast()
2432 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2433
2434
2439
2440
2442 """Real and Integer sorts."""
2443
2444 def is_real(self):
2445 """Return `True` if `self` is of the sort Real.
2446
2447 >>> x = Real('x')
2448 >>> x.is_real()
2449 True
2450 >>> (x + 1).is_real()
2451 True
2452 >>> x = Int('x')
2453 >>> x.is_real()
2454 False
2455 """
2456 return self.kind() == Z3_REAL_SORT
2457
2458 def is_int(self):
2459 """Return `True` if `self` is of the sort Integer.
2460
2461 >>> x = Int('x')
2462 >>> x.is_int()
2463 True
2464 >>> (x + 1).is_int()
2465 True
2466 >>> x = Real('x')
2467 >>> x.is_int()
2468 False
2469 """
2470 return self.kind() == Z3_INT_SORT
2471
2472 def is_bool(self):
2473 return False
2474
2475 def subsort(self, other):
2476 """Return `True` if `self` is a subsort of `other`."""
2477 return self.is_int() and is_arith_sort(other) and other.is_real()
2478
2479 def cast(self, val):
2480 """Try to cast `val` as an Integer or Real.
2481
2482 >>> IntSort().cast(10)
2483 10
2484 >>> is_int(IntSort().cast(10))
2485 True
2486 >>> is_int(10)
2487 False
2488 >>> RealSort().cast(10)
2489 10
2490 >>> is_real(RealSort().cast(10))
2491 True
2492 """
2493 if is_expr(val):
2494 if z3_debug():
2495 _z3_assert(self.ctx == val.ctx, "Context mismatch")
2496 val_s = val.sort()
2497 if self.eq(val_s):
2498 return val
2499 if val_s.is_int() and self.is_real():
2500 return ToReal(val)
2501 if val_s.is_bool() and self.is_int():
2502 return If(val, 1, 0)
2503 if val_s.is_bool() and self.is_real():
2504 return ToReal(If(val, 1, 0))
2505 if z3_debug():
2506 _z3_assert(False, "Z3 Integer/Real expression expected")
2507 else:
2508 if self.is_int():
2509 return IntVal(val, self.ctx)
2510 if self.is_real():
2511 return RealVal(val, self.ctx)
2512 if z3_debug():
2513 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2514 _z3_assert(False, msg % self)
2515
2516
2517def is_arith_sort(s : Any) -> bool:
2518 """Return `True` if s is an arithmetical sort (type).
2519
2520 >>> is_arith_sort(IntSort())
2521 True
2522 >>> is_arith_sort(RealSort())
2523 True
2524 >>> is_arith_sort(BoolSort())
2525 False
2526 >>> n = Int('x') + 1
2527 >>> is_arith_sort(n.sort())
2528 True
2529 """
2530 return isinstance(s, ArithSortRef)
2531
2532
2534 """Integer and Real expressions."""
2535
2536 def sort(self):
2537 """Return the sort (type) of the arithmetical expression `self`.
2538
2539 >>> Int('x').sort()
2540 Int
2541 >>> (Real('x') + 1).sort()
2542 Real
2543 """
2544 return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
2545
2546 def is_int(self):
2547 """Return `True` if `self` is an integer expression.
2548
2549 >>> x = Int('x')
2550 >>> x.is_int()
2551 True
2552 >>> (x + 1).is_int()
2553 True
2554 >>> y = Real('y')
2555 >>> (x + y).is_int()
2556 False
2557 """
2558 return self.sort().is_int()
2559
2560 def is_real(self):
2561 """Return `True` if `self` is an real expression.
2562
2563 >>> x = Real('x')
2564 >>> x.is_real()
2565 True
2566 >>> (x + 1).is_real()
2567 True
2568 """
2569 return self.sort().is_real()
2570
2571 def __add__(self, other):
2572 """Create the Z3 expression `self + other`.
2573
2574 >>> x = Int('x')
2575 >>> y = Int('y')
2576 >>> x + y
2577 x + y
2578 >>> (x + y).sort()
2579 Int
2580 """
2581 a, b = _coerce_exprs(self, other)
2582 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctx)
2583
2584 def __radd__(self, other):
2585 """Create the Z3 expression `other + self`.
2586
2587 >>> x = Int('x')
2588 >>> 10 + x
2589 10 + x
2590 """
2591 a, b = _coerce_exprs(self, other)
2592 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctx)
2593
2594 def __mul__(self, other):
2595 """Create the Z3 expression `self * other`.
2596
2597 >>> x = Real('x')
2598 >>> y = Real('y')
2599 >>> x * y
2600 x*y
2601 >>> (x * y).sort()
2602 Real
2603 """
2604 if isinstance(other, BoolRef):
2605 return If(other, self, 0)
2606 a, b = _coerce_exprs(self, other)
2607 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
2608
2609 def __rmul__(self, other):
2610 """Create the Z3 expression `other * self`.
2611
2612 >>> x = Real('x')
2613 >>> 10 * x
2614 10*x
2615 """
2616 a, b = _coerce_exprs(self, other)
2617 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctx)
2618
2619 def __sub__(self, other):
2620 """Create the Z3 expression `self - other`.
2621
2622 >>> x = Int('x')
2623 >>> y = Int('y')
2624 >>> x - y
2625 x - y
2626 >>> (x - y).sort()
2627 Int
2628 """
2629 a, b = _coerce_exprs(self, other)
2630 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctx)
2631
2632 def __rsub__(self, other):
2633 """Create the Z3 expression `other - self`.
2634
2635 >>> x = Int('x')
2636 >>> 10 - x
2637 10 - x
2638 """
2639 a, b = _coerce_exprs(self, other)
2640 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctx)
2641
2642 def __pow__(self, other):
2643 """Create the Z3 expression `self**other` (** is the power operator).
2644
2645 >>> x = Real('x')
2646 >>> x**3
2647 x**3
2648 >>> (x**3).sort()
2649 Real
2650 >>> simplify(IntVal(2)**8)
2651 256
2652 """
2653 a, b = _coerce_exprs(self, other)
2654 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2655
2656 def __rpow__(self, other):
2657 """Create the Z3 expression `other**self` (** is the power operator).
2658
2659 >>> x = Real('x')
2660 >>> 2**x
2661 2**x
2662 >>> (2**x).sort()
2663 Real
2664 >>> simplify(2**IntVal(8))
2665 256
2666 """
2667 a, b = _coerce_exprs(self, other)
2668 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2669
2670 def __div__(self, other):
2671 """Create the Z3 expression `other/self`.
2672
2673 >>> x = Int('x')
2674 >>> y = Int('y')
2675 >>> x/y
2676 x/y
2677 >>> (x/y).sort()
2678 Int
2679 >>> (x/y).sexpr()
2680 '(div x y)'
2681 >>> x = Real('x')
2682 >>> y = Real('y')
2683 >>> x/y
2684 x/y
2685 >>> (x/y).sort()
2686 Real
2687 >>> (x/y).sexpr()
2688 '(/ x y)'
2689 """
2690 a, b = _coerce_exprs(self, other)
2691 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2692
2693 def __truediv__(self, other):
2694 """Create the Z3 expression `other/self`."""
2695 return self.__div__(other)
2696
2697 def __rdiv__(self, other):
2698 """Create the Z3 expression `other/self`.
2699
2700 >>> x = Int('x')
2701 >>> 10/x
2702 10/x
2703 >>> (10/x).sexpr()
2704 '(div 10 x)'
2705 >>> x = Real('x')
2706 >>> 10/x
2707 10/x
2708 >>> (10/x).sexpr()
2709 '(/ 10.0 x)'
2710 """
2711 a, b = _coerce_exprs(self, other)
2712 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2713
2714 def __rtruediv__(self, other):
2715 """Create the Z3 expression `other/self`."""
2716 return self.__rdiv__(other)
2717
2718 def __mod__(self, other):
2719 """Create the Z3 expression `other%self`.
2720
2721 >>> x = Int('x')
2722 >>> y = Int('y')
2723 >>> x % y
2724 x%y
2725 >>> simplify(IntVal(10) % IntVal(3))
2726 1
2727 """
2728 a, b = _coerce_exprs(self, other)
2729 if z3_debug():
2730 _z3_assert(a.is_int(), "Z3 integer expression expected")
2731 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2732
2733 def __rmod__(self, other):
2734 """Create the Z3 expression `other%self`.
2735
2736 >>> x = Int('x')
2737 >>> 10 % x
2738 10%x
2739 """
2740 a, b = _coerce_exprs(self, other)
2741 if z3_debug():
2742 _z3_assert(a.is_int(), "Z3 integer expression expected")
2743 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
2744
2745 def __neg__(self):
2746 """Return an expression representing `-self`.
2747
2748 >>> x = Int('x')
2749 >>> -x
2750 -x
2751 >>> simplify(-(-x))
2752 x
2753 """
2754 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_ast()), self.ctx)
2755
2756 def __pos__(self):
2757 """Return `self`.
2758
2759 >>> x = Int('x')
2760 >>> +x
2761 x
2762 """
2763 return self
2764
2765 def __le__(self, other):
2766 """Create the Z3 expression `other <= self`.
2767
2768 >>> x, y = Ints('x y')
2769 >>> x <= y
2770 x <= y
2771 >>> y = Real('y')
2772 >>> x <= y
2773 ToReal(x) <= y
2774 """
2775 a, b = _coerce_exprs(self, other)
2776 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2777
2778 def __lt__(self, other):
2779 """Create the Z3 expression `other < self`.
2780
2781 >>> x, y = Ints('x y')
2782 >>> x < y
2783 x < y
2784 >>> y = Real('y')
2785 >>> x < y
2786 ToReal(x) < y
2787 """
2788 a, b = _coerce_exprs(self, other)
2789 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2790
2791 def __gt__(self, other):
2792 """Create the Z3 expression `other > self`.
2793
2794 >>> x, y = Ints('x y')
2795 >>> x > y
2796 x > y
2797 >>> y = Real('y')
2798 >>> x > y
2799 ToReal(x) > y
2800 """
2801 a, b = _coerce_exprs(self, other)
2802 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2803
2804 def __ge__(self, other):
2805 """Create the Z3 expression `other >= self`.
2806
2807 >>> x, y = Ints('x y')
2808 >>> x >= y
2809 x >= y
2810 >>> y = Real('y')
2811 >>> x >= y
2812 ToReal(x) >= y
2813 """
2814 a, b = _coerce_exprs(self, other)
2815 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
2816
2817 def __abs__(self):
2818 """Return an expression representing `abs(self)`.
2819
2820 >>> x = Int('x')
2821 >>> abs(x)
2822 If(x > 0, x, -x)
2823 >>> eq(abs(x), Abs(x))
2824 True
2825 """
2826 return Abs(self)
2827
2828
2830 """Return `True` if `a` is an arithmetical expression.
2831
2832 >>> x = Int('x')
2833 >>> is_arith(x)
2834 True
2835 >>> is_arith(x + 1)
2836 True
2837 >>> is_arith(1)
2838 False
2839 >>> is_arith(IntVal(1))
2840 True
2841 >>> y = Real('y')
2842 >>> is_arith(y)
2843 True
2844 >>> is_arith(y + 1)
2845 True
2846 """
2847 return isinstance(a, ArithRef)
2848
2849
2850def is_int(a) -> bool:
2851 """Return `True` if `a` is an integer expression.
2852
2853 >>> x = Int('x')
2854 >>> is_int(x + 1)
2855 True
2856 >>> is_int(1)
2857 False
2858 >>> is_int(IntVal(1))
2859 True
2860 >>> y = Real('y')
2861 >>> is_int(y)
2862 False
2863 >>> is_int(y + 1)
2864 False
2865 """
2866 return is_arith(a) and a.is_int()
2867
2868
2869def is_real(a):
2870 """Return `True` if `a` is a real expression.
2871
2872 >>> x = Int('x')
2873 >>> is_real(x + 1)
2874 False
2875 >>> y = Real('y')
2876 >>> is_real(y)
2877 True
2878 >>> is_real(y + 1)
2879 True
2880 >>> is_real(1)
2881 False
2882 >>> is_real(RealVal(1))
2883 True
2884 """
2885 return is_arith(a) and a.is_real()
2886
2887
2888def _is_numeral(ctx, a):
2889 return Z3_is_numeral_ast(ctx.ref(), a)
2890
2891
2892def _is_algebraic(ctx, a):
2893 return Z3_is_algebraic_number(ctx.ref(), a)
2894
2895
2897 """Return `True` if `a` is an integer value of sort Int.
2898
2899 >>> is_int_value(IntVal(1))
2900 True
2901 >>> is_int_value(1)
2902 False
2903 >>> is_int_value(Int('x'))
2904 False
2905 >>> n = Int('x') + 1
2906 >>> n
2907 x + 1
2908 >>> n.arg(1)
2909 1
2910 >>> is_int_value(n.arg(1))
2911 True
2912 >>> is_int_value(RealVal("1/3"))
2913 False
2914 >>> is_int_value(RealVal(1))
2915 False
2916 """
2917 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2918
2919
2921 """Return `True` if `a` is rational value of sort Real.
2922
2923 >>> is_rational_value(RealVal(1))
2924 True
2925 >>> is_rational_value(RealVal("3/5"))
2926 True
2927 >>> is_rational_value(IntVal(1))
2928 False
2929 >>> is_rational_value(1)
2930 False
2931 >>> n = Real('x') + 1
2932 >>> n.arg(1)
2933 1
2934 >>> is_rational_value(n.arg(1))
2935 True
2936 >>> is_rational_value(Real('x'))
2937 False
2938 """
2939 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2940
2941
2943 """Return `True` if `a` is an algebraic value of sort Real.
2944
2945 >>> is_algebraic_value(RealVal("3/5"))
2946 False
2947 >>> n = simplify(Sqrt(2))
2948 >>> n
2949 1.4142135623?
2950 >>> is_algebraic_value(n)
2951 True
2952 """
2953 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2954
2955
2956def is_add(a : Any) -> bool:
2957 """Return `True` if `a` is an expression of the form b + c.
2958
2959 >>> x, y = Ints('x y')
2960 >>> is_add(x + y)
2961 True
2962 >>> is_add(x - y)
2963 False
2964 """
2965 return is_app_of(a, Z3_OP_ADD)
2966
2967
2968def is_mul(a : Any) -> bool:
2969 """Return `True` if `a` is an expression of the form b * c.
2970
2971 >>> x, y = Ints('x y')
2972 >>> is_mul(x * y)
2973 True
2974 >>> is_mul(x - y)
2975 False
2976 """
2977 return is_app_of(a, Z3_OP_MUL)
2978
2979
2980def is_sub(a : Any) -> bool:
2981 """Return `True` if `a` is an expression of the form b - c.
2982
2983 >>> x, y = Ints('x y')
2984 >>> is_sub(x - y)
2985 True
2986 >>> is_sub(x + y)
2987 False
2988 """
2989 return is_app_of(a, Z3_OP_SUB)
2990
2991
2992def is_div(a : Any) -> bool:
2993 """Return `True` if `a` is an expression of the form b / c.
2994
2995 >>> x, y = Reals('x y')
2996 >>> is_div(x / y)
2997 True
2998 >>> is_div(x + y)
2999 False
3000 >>> x, y = Ints('x y')
3001 >>> is_div(x / y)
3002 False
3003 >>> is_idiv(x / y)
3004 True
3005 """
3006 return is_app_of(a, Z3_OP_DIV)
3007
3008
3009def is_idiv(a : Any) -> bool:
3010 """Return `True` if `a` is an expression of the form b div c.
3011
3012 >>> x, y = Ints('x y')
3013 >>> is_idiv(x / y)
3014 True
3015 >>> is_idiv(x + y)
3016 False
3017 """
3018 return is_app_of(a, Z3_OP_IDIV)
3019
3020
3021def is_mod(a : Any) -> bool:
3022 """Return `True` if `a` is an expression of the form b % c.
3023
3024 >>> x, y = Ints('x y')
3025 >>> is_mod(x % y)
3026 True
3027 >>> is_mod(x + y)
3028 False
3029 """
3030 return is_app_of(a, Z3_OP_MOD)
3031
3032
3033def is_le(a : Any) -> bool:
3034 """Return `True` if `a` is an expression of the form b <= c.
3035
3036 >>> x, y = Ints('x y')
3037 >>> is_le(x <= y)
3038 True
3039 >>> is_le(x < y)
3040 False
3041 """
3042 return is_app_of(a, Z3_OP_LE)
3043
3044
3045def is_lt(a : Any) -> bool:
3046 """Return `True` if `a` is an expression of the form b < c.
3047
3048 >>> x, y = Ints('x y')
3049 >>> is_lt(x < y)
3050 True
3051 >>> is_lt(x == y)
3052 False
3053 """
3054 return is_app_of(a, Z3_OP_LT)
3055
3056
3057def is_ge(a : Any) -> bool:
3058 """Return `True` if `a` is an expression of the form b >= c.
3059
3060 >>> x, y = Ints('x y')
3061 >>> is_ge(x >= y)
3062 True
3063 >>> is_ge(x == y)
3064 False
3065 """
3066 return is_app_of(a, Z3_OP_GE)
3067
3068
3069def is_gt(a : Any) -> bool:
3070 """Return `True` if `a` is an expression of the form b > c.
3071
3072 >>> x, y = Ints('x y')
3073 >>> is_gt(x > y)
3074 True
3075 >>> is_gt(x == y)
3076 False
3077 """
3078 return is_app_of(a, Z3_OP_GT)
3079
3080
3081def is_is_int(a : Any) -> bool:
3082 """Return `True` if `a` is an expression of the form IsInt(b).
3083
3084 >>> x = Real('x')
3085 >>> is_is_int(IsInt(x))
3086 True
3087 >>> is_is_int(x)
3088 False
3089 """
3090 return is_app_of(a, Z3_OP_IS_INT)
3091
3092
3093def is_to_real(a : Any) -> bool:
3094 """Return `True` if `a` is an expression of the form ToReal(b).
3095
3096 >>> x = Int('x')
3097 >>> n = ToReal(x)
3098 >>> n
3099 ToReal(x)
3100 >>> is_to_real(n)
3101 True
3102 >>> is_to_real(x)
3103 False
3104 """
3105 return is_app_of(a, Z3_OP_TO_REAL)
3106
3107
3108def is_to_int(a : Any) -> bool:
3109 """Return `True` if `a` is an expression of the form ToInt(b).
3110
3111 >>> x = Real('x')
3112 >>> n = ToInt(x)
3113 >>> n
3114 ToInt(x)
3115 >>> is_to_int(n)
3116 True
3117 >>> is_to_int(x)
3118 False
3119 """
3120 return is_app_of(a, Z3_OP_TO_INT)
3121
3122
3124 """Integer values."""
3125
3126 def as_long(self):
3127 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3128
3129 >>> v = IntVal(1)
3130 >>> v + 1
3131 1 + 1
3132 >>> v.as_long() + 1
3133 2
3134 """
3135 if z3_debug():
3136 _z3_assert(self.is_int(), "Integer value expected")
3137 return int(self.as_string())
3138
3139 def as_string(self):
3140 """Return a Z3 integer numeral as a Python string.
3141 >>> v = IntVal(100)
3142 >>> v.as_string()
3143 '100'
3144 """
3145 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3146
3148 """Return a Z3 integer numeral as a Python binary string.
3149 >>> v = IntVal(10)
3150 >>> v.as_binary_string()
3151 '1010'
3152 """
3153 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3154
3155 def py_value(self):
3156 return self.as_long()
3157
3158
3160 """Rational values."""
3161
3162 def numerator(self):
3163 """ Return the numerator of a Z3 rational numeral.
3164
3165 >>> is_rational_value(RealVal("3/5"))
3166 True
3167 >>> n = RealVal("3/5")
3168 >>> n.numerator()
3169 3
3170 >>> is_rational_value(Q(3,5))
3171 True
3172 >>> Q(3,5).numerator()
3173 3
3174 """
3175 return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
3176
3177 def denominator(self):
3178 """ Return the denominator of a Z3 rational numeral.
3179
3180 >>> is_rational_value(Q(3,5))
3181 True
3182 >>> n = Q(3,5)
3183 >>> n.denominator()
3184 5
3185 """
3186 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
3187
3189 """ Return the numerator as a Python long.
3190
3191 >>> v = RealVal(10000000000)
3192 >>> v
3193 10000000000
3194 >>> v + 1
3195 10000000000 + 1
3196 >>> v.numerator_as_long() + 1 == 10000000001
3197 True
3198 """
3199 return self.numerator().as_long()
3200
3202 """ Return the denominator as a Python long.
3203
3204 >>> v = RealVal("1/3")
3205 >>> v
3206 1/3
3207 >>> v.denominator_as_long()
3208 3
3209 """
3210 return self.denominator().as_long()
3211
3212 def is_int(self):
3213 return False
3214
3215 def is_real(self):
3216 return True
3217
3218 def is_int_value(self):
3219 return self.denominator().is_int() and self.denominator_as_long() == 1
3220
3221 def as_long(self):
3222 _z3_assert(self.is_int_value(), "Expected integer fraction")
3223 return self.numerator_as_long()
3224
3225 def as_decimal(self, prec):
3226 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3227
3228 >>> v = RealVal("1/5")
3229 >>> v.as_decimal(3)
3230 '0.2'
3231 >>> v = RealVal("1/3")
3232 >>> v.as_decimal(3)
3233 '0.333?'
3234 """
3235 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3236
3237 def as_string(self):
3238 """Return a Z3 rational numeral as a Python string.
3239
3240 >>> v = Q(3,6)
3241 >>> v.as_string()
3242 '1/2'
3243 """
3244 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3245
3246 def as_fraction(self):
3247 """Return a Z3 rational as a Python Fraction object.
3248
3249 >>> v = RealVal("1/5")
3250 >>> v.as_fraction()
3251 Fraction(1, 5)
3252 """
3253 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3254
3255 def py_value(self):
3256 return Z3_get_numeral_double(self.ctx_ref(), self.as_ast())
3257
3258
3260 """Algebraic irrational values."""
3261
3262 def approx(self, precision=10):
3263 """Return a Z3 rational number that approximates the algebraic number `self`.
3264 The result `r` is such that |r - self| <= 1/10^precision
3265
3266 >>> x = simplify(Sqrt(2))
3267 >>> x.approx(20)
3268 6838717160008073720548335/4835703278458516698824704
3269 >>> x.approx(5)
3270 2965821/2097152
3271 """
3272 return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
3273
3274 def as_decimal(self, prec):
3275 """Return a string representation of the algebraic number `self` in decimal notation
3276 using `prec` decimal places.
3277
3278 >>> x = simplify(Sqrt(2))
3279 >>> x.as_decimal(10)
3280 '1.4142135623?'
3281 >>> x.as_decimal(20)
3282 '1.41421356237309504880?'
3283 """
3284 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3285
3286 def poly(self):
3287 return AstVector(Z3_algebraic_get_poly(self.ctx_ref(), self.as_ast()), self.ctx)
3288
3289 def index(self):
3290 return Z3_algebraic_get_i(self.ctx_ref(), self.as_ast())
3291
3292
3293def _py2expr(a, ctx=None):
3294 if isinstance(a, bool):
3295 return BoolVal(a, ctx)
3296 if _is_int(a):
3297 return IntVal(a, ctx)
3298 if isinstance(a, float):
3299 return RealVal(a, ctx)
3300 if isinstance(a, str):
3301 return StringVal(a, ctx)
3302 if is_expr(a):
3303 return a
3304 if z3_debug():
3305 _z3_assert(False, "Python bool, int, long or float expected")
3306
3307
3308def IntSort(ctx=None):
3309 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3310
3311 >>> IntSort()
3312 Int
3313 >>> x = Const('x', IntSort())
3314 >>> is_int(x)
3315 True
3316 >>> x.sort() == IntSort()
3317 True
3318 >>> x.sort() == BoolSort()
3319 False
3320 """
3321 ctx = _get_ctx(ctx)
3322 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3323
3324
3325def RealSort(ctx=None):
3326 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3327
3328 >>> RealSort()
3329 Real
3330 >>> x = Const('x', RealSort())
3331 >>> is_real(x)
3332 True
3333 >>> is_int(x)
3334 False
3335 >>> x.sort() == RealSort()
3336 True
3337 """
3338 ctx = _get_ctx(ctx)
3339 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3340
3341
3343 if isinstance(val, float):
3344 return str(int(val))
3345 elif isinstance(val, bool):
3346 if val:
3347 return "1"
3348 else:
3349 return "0"
3350 else:
3351 return str(val)
3352
3353
3354def IntVal(val, ctx=None):
3355 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3356
3357 >>> IntVal(1)
3358 1
3359 >>> IntVal("100")
3360 100
3361 """
3362 ctx = _get_ctx(ctx)
3363 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3364
3365
3366def RealVal(val, ctx=None):
3367 """Return a Z3 real value.
3368
3369 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3370 If `ctx=None`, then the global context is used.
3371
3372 >>> RealVal(1)
3373 1
3374 >>> RealVal(1).sort()
3375 Real
3376 >>> RealVal("3/5")
3377 3/5
3378 >>> RealVal("1.5")
3379 3/2
3380 """
3381 ctx = _get_ctx(ctx)
3382 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3383
3384
3385def RatVal(a, b, ctx=None):
3386 """Return a Z3 rational a/b.
3387
3388 If `ctx=None`, then the global context is used.
3389
3390 Note: Division by zero (b == 0) is allowed in Z3 symbolic expressions.
3391 Z3 can reason about such expressions symbolically.
3392
3393 >>> RatVal(3,5)
3394 3/5
3395 >>> RatVal(3,5).sort()
3396 Real
3397 """
3398 if z3_debug():
3399 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3400 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3401 # Division by 0 is intentionally allowed - Z3 handles it symbolically
3402 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3403
3404
3405def Q(a, b, ctx=None):
3406 """Return a Z3 rational a/b.
3407
3408 If `ctx=None`, then the global context is used.
3409
3410 >>> Q(3,5)
3411 3/5
3412 >>> Q(3,5).sort()
3413 Real
3414 """
3415 return simplify(RatVal(a, b, ctx=ctx))
3416
3417
3418def Int(name, ctx=None):
3419 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3420
3421 >>> x = Int('x')
3422 >>> is_int(x)
3423 True
3424 >>> is_int(x + 1)
3425 True
3426 """
3427 ctx = _get_ctx(ctx)
3428 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3429
3430
3431def Ints(names, ctx=None):
3432 """Return a tuple of Integer constants.
3433
3434 >>> x, y, z = Ints('x y z')
3435 >>> Sum(x, y, z)
3436 x + y + z
3437 """
3438 ctx = _get_ctx(ctx)
3439 if isinstance(names, str):
3440 names = names.split(" ")
3441 return [Int(name, ctx) for name in names]
3442
3443
3444def IntVector(prefix, sz, ctx=None):
3445 """Return a list of integer constants of size `sz`.
3446
3447 >>> X = IntVector('x', 3)
3448 >>> X
3449 [x__0, x__1, x__2]
3450 >>> Sum(X)
3451 x__0 + x__1 + x__2
3452 """
3453 ctx = _get_ctx(ctx)
3454 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3455
3456
3457def FreshInt(prefix="x", ctx=None):
3458 """Return a fresh integer constant in the given context using the given prefix.
3459
3460 >>> x = FreshInt()
3461 >>> y = FreshInt()
3462 >>> eq(x, y)
3463 False
3464 >>> x.sort()
3465 Int
3466 """
3467 ctx = _get_ctx(ctx)
3468 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3469
3470
3471def Real(name, ctx=None):
3472 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3473
3474 >>> x = Real('x')
3475 >>> is_real(x)
3476 True
3477 >>> is_real(x + 1)
3478 True
3479 """
3480 ctx = _get_ctx(ctx)
3481 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3482
3483
3484def Reals(names, ctx=None):
3485 """Return a tuple of real constants.
3486
3487 >>> x, y, z = Reals('x y z')
3488 >>> Sum(x, y, z)
3489 x + y + z
3490 >>> Sum(x, y, z).sort()
3491 Real
3492 """
3493 ctx = _get_ctx(ctx)
3494 if isinstance(names, str):
3495 names = names.split(" ")
3496 return [Real(name, ctx) for name in names]
3497
3498
3499def RealVector(prefix, sz, ctx=None):
3500 """Return a list of real constants of size `sz`.
3501
3502 >>> X = RealVector('x', 3)
3503 >>> X
3504 [x__0, x__1, x__2]
3505 >>> Sum(X)
3506 x__0 + x__1 + x__2
3507 >>> Sum(X).sort()
3508 Real
3509 """
3510 ctx = _get_ctx(ctx)
3511 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3512
3513
3514def FreshReal(prefix="b", ctx=None):
3515 """Return a fresh real constant in the given context using the given prefix.
3516
3517 >>> x = FreshReal()
3518 >>> y = FreshReal()
3519 >>> eq(x, y)
3520 False
3521 >>> x.sort()
3522 Real
3523 """
3524 ctx = _get_ctx(ctx)
3525 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3526
3527
3528def ToReal(a):
3529 """ Return the Z3 expression ToReal(a).
3530
3531 >>> x = Int('x')
3532 >>> x.sort()
3533 Int
3534 >>> n = ToReal(x)
3535 >>> n
3536 ToReal(x)
3537 >>> n.sort()
3538 Real
3539 """
3540 ctx = a.ctx
3541 if isinstance(a, BoolRef):
3542 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3543 if z3_debug():
3544 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3545 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3546
3547
3548def ToInt(a):
3549 """ Return the Z3 expression ToInt(a).
3550
3551 >>> x = Real('x')
3552 >>> x.sort()
3553 Real
3554 >>> n = ToInt(x)
3555 >>> n
3556 ToInt(x)
3557 >>> n.sort()
3558 Int
3559 """
3560 if z3_debug():
3561 _z3_assert(a.is_real(), "Z3 real expression expected.")
3562 ctx = a.ctx
3563 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3564
3565
3566def IsInt(a):
3567 """ Return the Z3 predicate IsInt(a).
3568
3569 >>> x = Real('x')
3570 >>> IsInt(x + "1/2")
3571 IsInt(x + 1/2)
3572 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3573 [x = 1/2]
3574 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3575 no solution
3576 """
3577 if z3_debug():
3578 _z3_assert(a.is_real(), "Z3 real expression expected.")
3579 ctx = a.ctx
3580 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3581
3582
3583def Sqrt(a, ctx=None):
3584 """ Return a Z3 expression which represents the square root of a.
3585
3586 >>> x = Real('x')
3587 >>> Sqrt(x)
3588 x**(1/2)
3589 """
3590 if not is_expr(a):
3591 ctx = _get_ctx(ctx)
3592 a = RealVal(a, ctx)
3593 return a ** "1/2"
3594
3595
3596def Cbrt(a, ctx=None):
3597 """ Return a Z3 expression which represents the cubic root of a.
3598
3599 >>> x = Real('x')
3600 >>> Cbrt(x)
3601 x**(1/3)
3602 """
3603 if not is_expr(a):
3604 ctx = _get_ctx(ctx)
3605 a = RealVal(a, ctx)
3606 return a ** "1/3"
3607
3608
3613
3614
3616 """Bit-vector sort."""
3617
3618 def size(self):
3619 """Return the size (number of bits) of the bit-vector sort `self`.
3620
3621 >>> b = BitVecSort(32)
3622 >>> b.size()
3623 32
3624 """
3625 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
3626
3627 def subsort(self, other):
3628 return is_bv_sort(other) and self.size() < other.size()
3629
3630 def cast(self, val):
3631 """Try to cast `val` as a Bit-Vector.
3632
3633 >>> b = BitVecSort(32)
3634 >>> b.cast(10)
3635 10
3636 >>> b.cast(10).sexpr()
3637 '#x0000000a'
3638 """
3639 if is_expr(val):
3640 if z3_debug():
3641 _z3_assert(self.ctx == val.ctx, "Context mismatch")
3642 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3643 return val
3644 else:
3645 return BitVecVal(val, self)
3646
3647
3649 """Return True if `s` is a Z3 bit-vector sort.
3650
3651 >>> is_bv_sort(BitVecSort(32))
3652 True
3653 >>> is_bv_sort(IntSort())
3654 False
3655 """
3656 return isinstance(s, BitVecSortRef)
3657
3658
3660 """Bit-vector expressions."""
3661
3662 def sort(self):
3663 """Return the sort of the bit-vector expression `self`.
3664
3665 >>> x = BitVec('x', 32)
3666 >>> x.sort()
3667 BitVec(32)
3668 >>> x.sort() == BitVecSort(32)
3669 True
3670 """
3671 return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3672
3673 def size(self):
3674 """Return the number of bits of the bit-vector expression `self`.
3675
3676 >>> x = BitVec('x', 32)
3677 >>> (x + 1).size()
3678 32
3679 >>> Concat(x, x).size()
3680 64
3681 """
3682 return self.sort().size()
3683
3684 def __add__(self, other):
3685 """Create the Z3 expression `self + other`.
3686
3687 >>> x = BitVec('x', 32)
3688 >>> y = BitVec('y', 32)
3689 >>> x + y
3690 x + y
3691 >>> (x + y).sort()
3692 BitVec(32)
3693 """
3694 a, b = _coerce_exprs(self, other)
3695 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3696
3697 def __radd__(self, other):
3698 """Create the Z3 expression `other + self`.
3699
3700 >>> x = BitVec('x', 32)
3701 >>> 10 + x
3702 10 + x
3703 """
3704 a, b = _coerce_exprs(self, other)
3705 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3706
3707 def __mul__(self, other):
3708 """Create the Z3 expression `self * other`.
3709
3710 >>> x = BitVec('x', 32)
3711 >>> y = BitVec('y', 32)
3712 >>> x * y
3713 x*y
3714 >>> (x * y).sort()
3715 BitVec(32)
3716 """
3717 a, b = _coerce_exprs(self, other)
3718 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3719
3720 def __rmul__(self, other):
3721 """Create the Z3 expression `other * self`.
3722
3723 >>> x = BitVec('x', 32)
3724 >>> 10 * x
3725 10*x
3726 """
3727 a, b = _coerce_exprs(self, other)
3728 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3729
3730 def __sub__(self, other):
3731 """Create the Z3 expression `self - other`.
3732
3733 >>> x = BitVec('x', 32)
3734 >>> y = BitVec('y', 32)
3735 >>> x - y
3736 x - y
3737 >>> (x - y).sort()
3738 BitVec(32)
3739 """
3740 a, b = _coerce_exprs(self, other)
3741 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3742
3743 def __rsub__(self, other):
3744 """Create the Z3 expression `other - self`.
3745
3746 >>> x = BitVec('x', 32)
3747 >>> 10 - x
3748 10 - x
3749 """
3750 a, b = _coerce_exprs(self, other)
3751 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3752
3753 def __or__(self, other):
3754 """Create the Z3 expression bitwise-or `self | other`.
3755
3756 >>> x = BitVec('x', 32)
3757 >>> y = BitVec('y', 32)
3758 >>> x | y
3759 x | y
3760 >>> (x | y).sort()
3761 BitVec(32)
3762 """
3763 a, b = _coerce_exprs(self, other)
3764 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3765
3766 def __ror__(self, other):
3767 """Create the Z3 expression bitwise-or `other | self`.
3768
3769 >>> x = BitVec('x', 32)
3770 >>> 10 | x
3771 10 | x
3772 """
3773 a, b = _coerce_exprs(self, other)
3774 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3775
3776 def __and__(self, other):
3777 """Create the Z3 expression bitwise-and `self & other`.
3778
3779 >>> x = BitVec('x', 32)
3780 >>> y = BitVec('y', 32)
3781 >>> x & y
3782 x & y
3783 >>> (x & y).sort()
3784 BitVec(32)
3785 """
3786 a, b = _coerce_exprs(self, other)
3787 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3788
3789 def __rand__(self, other):
3790 """Create the Z3 expression bitwise-or `other & self`.
3791
3792 >>> x = BitVec('x', 32)
3793 >>> 10 & x
3794 10 & x
3795 """
3796 a, b = _coerce_exprs(self, other)
3797 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3798
3799 def __xor__(self, other):
3800 """Create the Z3 expression bitwise-xor `self ^ other`.
3801
3802 >>> x = BitVec('x', 32)
3803 >>> y = BitVec('y', 32)
3804 >>> x ^ y
3805 x ^ y
3806 >>> (x ^ y).sort()
3807 BitVec(32)
3808 """
3809 a, b = _coerce_exprs(self, other)
3810 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3811
3812 def __rxor__(self, other):
3813 """Create the Z3 expression bitwise-xor `other ^ self`.
3814
3815 >>> x = BitVec('x', 32)
3816 >>> 10 ^ x
3817 10 ^ x
3818 """
3819 a, b = _coerce_exprs(self, other)
3820 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3821
3822 def __pos__(self):
3823 """Return `self`.
3824
3825 >>> x = BitVec('x', 32)
3826 >>> +x
3827 x
3828 """
3829 return self
3830
3831 def __neg__(self):
3832 """Return an expression representing `-self`.
3833
3834 >>> x = BitVec('x', 32)
3835 >>> -x
3836 -x
3837 >>> simplify(-(-x))
3838 x
3839 """
3840 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3841
3842 def __invert__(self):
3843 """Create the Z3 expression bitwise-not `~self`.
3844
3845 >>> x = BitVec('x', 32)
3846 >>> ~x
3847 ~x
3848 >>> simplify(~(~x))
3849 x
3850 """
3851 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3852
3853 def __div__(self, other):
3854 """Create the Z3 expression (signed) division `self / other`.
3855
3856 Use the function UDiv() for unsigned division.
3857
3858 >>> x = BitVec('x', 32)
3859 >>> y = BitVec('y', 32)
3860 >>> x / y
3861 x/y
3862 >>> (x / y).sort()
3863 BitVec(32)
3864 >>> (x / y).sexpr()
3865 '(bvsdiv x y)'
3866 >>> UDiv(x, y).sexpr()
3867 '(bvudiv x y)'
3868 """
3869 a, b = _coerce_exprs(self, other)
3870 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3871
3872 def __truediv__(self, other):
3873 """Create the Z3 expression (signed) division `self / other`."""
3874 return self.__div__(other)
3875
3876 def __rdiv__(self, other):
3877 """Create the Z3 expression (signed) division `other / self`.
3878
3879 Use the function UDiv() for unsigned division.
3880
3881 >>> x = BitVec('x', 32)
3882 >>> 10 / x
3883 10/x
3884 >>> (10 / x).sexpr()
3885 '(bvsdiv #x0000000a x)'
3886 >>> UDiv(10, x).sexpr()
3887 '(bvudiv #x0000000a x)'
3888 """
3889 a, b = _coerce_exprs(self, other)
3890 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3891
3892 def __rtruediv__(self, other):
3893 """Create the Z3 expression (signed) division `other / self`."""
3894 return self.__rdiv__(other)
3895
3896 def __mod__(self, other):
3897 """Create the Z3 expression (signed) mod `self % other`.
3898
3899 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3900
3901 >>> x = BitVec('x', 32)
3902 >>> y = BitVec('y', 32)
3903 >>> x % y
3904 x%y
3905 >>> (x % y).sort()
3906 BitVec(32)
3907 >>> (x % y).sexpr()
3908 '(bvsmod x y)'
3909 >>> URem(x, y).sexpr()
3910 '(bvurem x y)'
3911 >>> SRem(x, y).sexpr()
3912 '(bvsrem x y)'
3913 """
3914 a, b = _coerce_exprs(self, other)
3915 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3916
3917 def __rmod__(self, other):
3918 """Create the Z3 expression (signed) mod `other % self`.
3919
3920 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3921
3922 >>> x = BitVec('x', 32)
3923 >>> 10 % x
3924 10%x
3925 >>> (10 % x).sexpr()
3926 '(bvsmod #x0000000a x)'
3927 >>> URem(10, x).sexpr()
3928 '(bvurem #x0000000a x)'
3929 >>> SRem(10, x).sexpr()
3930 '(bvsrem #x0000000a x)'
3931 """
3932 a, b = _coerce_exprs(self, other)
3933 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3934
3935 def __le__(self, other):
3936 """Create the Z3 expression (signed) `other <= self`.
3937
3938 Use the function ULE() for unsigned less than or equal to.
3939
3940 >>> x, y = BitVecs('x y', 32)
3941 >>> x <= y
3942 x <= y
3943 >>> (x <= y).sexpr()
3944 '(bvsle x y)'
3945 >>> ULE(x, y).sexpr()
3946 '(bvule x y)'
3947 """
3948 a, b = _coerce_exprs(self, other)
3949 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3950
3951 def __lt__(self, other):
3952 """Create the Z3 expression (signed) `other < self`.
3953
3954 Use the function ULT() for unsigned less than.
3955
3956 >>> x, y = BitVecs('x y', 32)
3957 >>> x < y
3958 x < y
3959 >>> (x < y).sexpr()
3960 '(bvslt x y)'
3961 >>> ULT(x, y).sexpr()
3962 '(bvult x y)'
3963 """
3964 a, b = _coerce_exprs(self, other)
3965 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3966
3967 def __gt__(self, other):
3968 """Create the Z3 expression (signed) `other > self`.
3969
3970 Use the function UGT() for unsigned greater than.
3971
3972 >>> x, y = BitVecs('x y', 32)
3973 >>> x > y
3974 x > y
3975 >>> (x > y).sexpr()
3976 '(bvsgt x y)'
3977 >>> UGT(x, y).sexpr()
3978 '(bvugt x y)'
3979 """
3980 a, b = _coerce_exprs(self, other)
3981 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3982
3983 def __ge__(self, other):
3984 """Create the Z3 expression (signed) `other >= self`.
3985
3986 Use the function UGE() for unsigned greater than or equal to.
3987
3988 >>> x, y = BitVecs('x y', 32)
3989 >>> x >= y
3990 x >= y
3991 >>> (x >= y).sexpr()
3992 '(bvsge x y)'
3993 >>> UGE(x, y).sexpr()
3994 '(bvuge x y)'
3995 """
3996 a, b = _coerce_exprs(self, other)
3997 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3998
3999 def __rshift__(self, other):
4000 """Create the Z3 expression (arithmetical) right shift `self >> other`
4001
4002 Use the function LShR() for the right logical shift
4003
4004 >>> x, y = BitVecs('x y', 32)
4005 >>> x >> y
4006 x >> y
4007 >>> (x >> y).sexpr()
4008 '(bvashr x y)'
4009 >>> LShR(x, y).sexpr()
4010 '(bvlshr x y)'
4011 >>> BitVecVal(4, 3)
4012 4
4013 >>> BitVecVal(4, 3).as_signed_long()
4014 -4
4015 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4016 -2
4017 >>> simplify(BitVecVal(4, 3) >> 1)
4018 6
4019 >>> simplify(LShR(BitVecVal(4, 3), 1))
4020 2
4021 >>> simplify(BitVecVal(2, 3) >> 1)
4022 1
4023 >>> simplify(LShR(BitVecVal(2, 3), 1))
4024 1
4025 """
4026 a, b = _coerce_exprs(self, other)
4027 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4028
4029 def __lshift__(self, other):
4030 """Create the Z3 expression left shift `self << other`
4031
4032 >>> x, y = BitVecs('x y', 32)
4033 >>> x << y
4034 x << y
4035 >>> (x << y).sexpr()
4036 '(bvshl x y)'
4037 >>> simplify(BitVecVal(2, 3) << 1)
4038 4
4039 """
4040 a, b = _coerce_exprs(self, other)
4041 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4042
4043 def __rrshift__(self, other):
4044 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
4045
4046 Use the function LShR() for the right logical shift
4047
4048 >>> x = BitVec('x', 32)
4049 >>> 10 >> x
4050 10 >> x
4051 >>> (10 >> x).sexpr()
4052 '(bvashr #x0000000a x)'
4053 """
4054 a, b = _coerce_exprs(self, other)
4055 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
4056
4057 def __rlshift__(self, other):
4058 """Create the Z3 expression left shift `other << self`.
4059
4060 Use the function LShR() for the right logical shift
4061
4062 >>> x = BitVec('x', 32)
4063 >>> 10 << x
4064 10 << x
4065 >>> (10 << x).sexpr()
4066 '(bvshl #x0000000a x)'
4067 """
4068 a, b = _coerce_exprs(self, other)
4069 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
4070
4071
4073 """Bit-vector values."""
4074
4075 def as_long(self):
4076 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4077
4078 >>> v = BitVecVal(0xbadc0de, 32)
4079 >>> v
4080 195936478
4081 >>> print("0x%.8x" % v.as_long())
4082 0x0badc0de
4083 """
4084 return int(self.as_string())
4085
4087 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4088 The most significant bit is assumed to be the sign.
4089
4090 >>> BitVecVal(4, 3).as_signed_long()
4091 -4
4092 >>> BitVecVal(7, 3).as_signed_long()
4093 -1
4094 >>> BitVecVal(3, 3).as_signed_long()
4095 3
4096 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4097 -1
4098 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4099 -1
4100 """
4101 sz = self.size()
4102 val = self.as_long()
4103 if val >= 2**(sz - 1):
4104 val = val - 2**sz
4105 if val < -2**(sz - 1):
4106 val = val + 2**sz
4107 return int(val)
4108
4109 def as_string(self):
4110 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
4111
4113 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
4114
4115 def py_value(self):
4116 """Return the Python value of a Z3 bit-vector numeral."""
4117 return self.as_long()
4118
4119
4120
4121def is_bv(a):
4122 """Return `True` if `a` is a Z3 bit-vector expression.
4123
4124 >>> b = BitVec('b', 32)
4125 >>> is_bv(b)
4126 True
4127 >>> is_bv(b + 10)
4128 True
4129 >>> is_bv(Int('x'))
4130 False
4131 """
4132 return isinstance(a, BitVecRef)
4133
4134
4136 """Return `True` if `a` is a Z3 bit-vector numeral value.
4137
4138 >>> b = BitVec('b', 32)
4139 >>> is_bv_value(b)
4140 False
4141 >>> b = BitVecVal(10, 32)
4142 >>> b
4143 10
4144 >>> is_bv_value(b)
4145 True
4146 """
4147 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4148
4149
4150def BV2Int(a, is_signed=False):
4151 """Return the Z3 expression BV2Int(a).
4152
4153 >>> b = BitVec('b', 3)
4154 >>> BV2Int(b).sort()
4155 Int
4156 >>> x = Int('x')
4157 >>> x > BV2Int(b)
4158 x > BV2Int(b)
4159 >>> x > BV2Int(b, is_signed=False)
4160 x > BV2Int(b)
4161 >>> x > BV2Int(b, is_signed=True)
4162 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4163 >>> solve(x > BV2Int(b), b == 1, x < 3)
4164 [x = 2, b = 1]
4165 """
4166 if z3_debug():
4167 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4168 ctx = a.ctx
4169 # investigate problem with bv2int
4170 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4171
4172
4173def Int2BV(a, num_bits):
4174 """Return the z3 expression Int2BV(a, num_bits).
4175 It is a bit-vector of width num_bits and represents the
4176 modulo of a by 2^num_bits
4177 """
4178 ctx = a.ctx
4179 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4180
4181
4182def BitVecSort(sz, ctx=None):
4183 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4184
4185 >>> Byte = BitVecSort(8)
4186 >>> Word = BitVecSort(16)
4187 >>> Byte
4188 BitVec(8)
4189 >>> x = Const('x', Byte)
4190 >>> eq(x, BitVec('x', 8))
4191 True
4192 """
4193 ctx = _get_ctx(ctx)
4194 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4195
4196
4197def BitVecVal(val, bv, ctx=None):
4198 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4199
4200 >>> v = BitVecVal(10, 32)
4201 >>> v
4202 10
4203 >>> print("0x%.8x" % v.as_long())
4204 0x0000000a
4205 """
4206 if is_bv_sort(bv):
4207 ctx = bv.ctx
4208 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4209 else:
4210 ctx = _get_ctx(ctx)
4211 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4212
4213
4214def BitVec(name, bv, ctx=None):
4215 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4216 If `ctx=None`, then the global context is used.
4217
4218 >>> x = BitVec('x', 16)
4219 >>> is_bv(x)
4220 True
4221 >>> x.size()
4222 16
4223 >>> x.sort()
4224 BitVec(16)
4225 >>> word = BitVecSort(16)
4226 >>> x2 = BitVec('x', word)
4227 >>> eq(x, x2)
4228 True
4229 """
4230 if isinstance(bv, BitVecSortRef):
4231 ctx = bv.ctx
4232 else:
4233 ctx = _get_ctx(ctx)
4234 bv = BitVecSort(bv, ctx)
4235 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4236
4237
4238def BitVecs(names, bv, ctx=None):
4239 """Return a tuple of bit-vector constants of size bv.
4240
4241 >>> x, y, z = BitVecs('x y z', 16)
4242 >>> x.size()
4243 16
4244 >>> x.sort()
4245 BitVec(16)
4246 >>> Sum(x, y, z)
4247 0 + x + y + z
4248 >>> Product(x, y, z)
4249 1*x*y*z
4250 >>> simplify(Product(x, y, z))
4251 x*y*z
4252 """
4253 ctx = _get_ctx(ctx)
4254 if isinstance(names, str):
4255 names = names.split(" ")
4256 return [BitVec(name, bv, ctx) for name in names]
4257
4258
4259def Concat(*args):
4260 """Create a Z3 bit-vector concatenation expression.
4261
4262 >>> v = BitVecVal(1, 4)
4263 >>> Concat(v, v+1, v)
4264 Concat(Concat(1, 1 + 1), 1)
4265 >>> simplify(Concat(v, v+1, v))
4266 289
4267 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4268 121
4269 """
4270 args = _get_args(args)
4271 sz = len(args)
4272 if z3_debug():
4273 _z3_assert(sz >= 2, "At least two arguments expected.")
4274
4275 ctx = None
4276 for a in args:
4277 if is_expr(a):
4278 ctx = a.ctx
4279 break
4280 if is_seq(args[0]) or isinstance(args[0], str):
4281 args = [_coerce_seq(s, ctx) for s in args]
4282 if z3_debug():
4283 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4284 v = (Ast * sz)()
4285 for i in range(sz):
4286 v[i] = args[i].as_ast()
4287 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4288
4289 if is_re(args[0]):
4290 if z3_debug():
4291 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4292 v = (Ast * sz)()
4293 for i in range(sz):
4294 v[i] = args[i].as_ast()
4295 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4296
4297 if z3_debug():
4298 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4299 r = args[0]
4300 for i in range(sz - 1):
4301 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4302 return r
4303
4304
4305def Extract(high, low, a):
4306 """Create a Z3 bit-vector extraction expression or sequence extraction expression.
4307
4308 Extract is overloaded to work with both bit-vectors and sequences:
4309
4310 **Bit-vector extraction**: Extract(high, low, bitvector)
4311 Extracts bits from position `high` down to position `low` (both inclusive).
4312 - high: int - the highest bit position to extract (0-indexed from right)
4313 - low: int - the lowest bit position to extract (0-indexed from right)
4314 - bitvector: BitVecRef - the bit-vector to extract from
4315 Returns a new bit-vector containing bits [high:low]
4316
4317 **Sequence extraction**: Extract(sequence, offset, length)
4318 Extracts a subsequence starting at the given offset with the specified length.
4319 The functions SubString and SubSeq are redirected to this form of Extract.
4320 - sequence: SeqRef or str - the sequence to extract from
4321 - offset: int - the starting position (0-indexed)
4322 - length: int - the number of elements to extract
4323 Returns a new sequence containing the extracted subsequence
4324
4325 >>> # Bit-vector extraction examples
4326 >>> x = BitVec('x', 8)
4327 >>> Extract(6, 2, x) # Extract bits 6 down to 2 (5 bits total)
4328 Extract(6, 2, x)
4329 >>> Extract(6, 2, x).sort() # Result is a 5-bit vector
4330 BitVec(5)
4331 >>> Extract(7, 0, x) # Extract all 8 bits
4332 Extract(7, 0, x)
4333 >>> Extract(3, 3, x) # Extract single bit at position 3
4334 Extract(3, 3, x)
4335
4336 >>> # Sequence extraction examples
4337 >>> s = StringVal("hello")
4338 >>> Extract(s, 1, 3) # Extract 3 characters starting at position 1
4339 str.substr("hello", 1, 3)
4340 >>> simplify(Extract(StringVal("abcd"), 2, 1)) # Extract 1 character at position 2
4341 "c"
4342 >>> simplify(Extract(StringVal("abcd"), 0, 2)) # Extract first 2 characters
4343 "ab"
4344 """
4345 if isinstance(high, str):
4346 high = StringVal(high)
4347 if is_seq(high):
4348 s = high
4349 offset, length = _coerce_exprs(low, a, s.ctx)
4350 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4351 if z3_debug():
4352 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4353 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4354 "First and second arguments must be non negative integers")
4355 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4356 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4357
4358
4360 if z3_debug():
4361 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4362
4363
4364def ULE(a, b):
4365 """Create the Z3 expression (unsigned) `other <= self`.
4366
4367 Use the operator <= for signed less than or equal to.
4368
4369 >>> x, y = BitVecs('x y', 32)
4370 >>> ULE(x, y)
4371 ULE(x, y)
4372 >>> (x <= y).sexpr()
4373 '(bvsle x y)'
4374 >>> ULE(x, y).sexpr()
4375 '(bvule x y)'
4376 """
4377 _check_bv_args(a, b)
4378 a, b = _coerce_exprs(a, b)
4379 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4380
4381
4382def ULT(a, b):
4383 """Create the Z3 expression (unsigned) `other < self`.
4384
4385 Use the operator < for signed less than.
4386
4387 >>> x, y = BitVecs('x y', 32)
4388 >>> ULT(x, y)
4389 ULT(x, y)
4390 >>> (x < y).sexpr()
4391 '(bvslt x y)'
4392 >>> ULT(x, y).sexpr()
4393 '(bvult x y)'
4394 """
4395 _check_bv_args(a, b)
4396 a, b = _coerce_exprs(a, b)
4397 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4398
4399
4400def UGE(a, b):
4401 """Create the Z3 expression (unsigned) `other >= self`.
4402
4403 Use the operator >= for signed greater than or equal to.
4404
4405 >>> x, y = BitVecs('x y', 32)
4406 >>> UGE(x, y)
4407 UGE(x, y)
4408 >>> (x >= y).sexpr()
4409 '(bvsge x y)'
4410 >>> UGE(x, y).sexpr()
4411 '(bvuge x y)'
4412 """
4413 _check_bv_args(a, b)
4414 a, b = _coerce_exprs(a, b)
4415 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4416
4417
4418def UGT(a, b):
4419 """Create the Z3 expression (unsigned) `other > self`.
4420
4421 Use the operator > for signed greater than.
4422
4423 >>> x, y = BitVecs('x y', 32)
4424 >>> UGT(x, y)
4425 UGT(x, y)
4426 >>> (x > y).sexpr()
4427 '(bvsgt x y)'
4428 >>> UGT(x, y).sexpr()
4429 '(bvugt x y)'
4430 """
4431 _check_bv_args(a, b)
4432 a, b = _coerce_exprs(a, b)
4433 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4434
4435
4436def UDiv(a, b):
4437 """Create the Z3 expression (unsigned) division `self / other`.
4438
4439 Use the operator / for signed division.
4440
4441 >>> x = BitVec('x', 32)
4442 >>> y = BitVec('y', 32)
4443 >>> UDiv(x, y)
4444 UDiv(x, y)
4445 >>> UDiv(x, y).sort()
4446 BitVec(32)
4447 >>> (x / y).sexpr()
4448 '(bvsdiv x y)'
4449 >>> UDiv(x, y).sexpr()
4450 '(bvudiv x y)'
4451 """
4452 _check_bv_args(a, b)
4453 a, b = _coerce_exprs(a, b)
4454 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4455
4456
4457def URem(a, b):
4458 """Create the Z3 expression (unsigned) remainder `self % other`.
4459
4460 Use the operator % for signed modulus, and SRem() for signed remainder.
4461
4462 >>> x = BitVec('x', 32)
4463 >>> y = BitVec('y', 32)
4464 >>> URem(x, y)
4465 URem(x, y)
4466 >>> URem(x, y).sort()
4467 BitVec(32)
4468 >>> (x % y).sexpr()
4469 '(bvsmod x y)'
4470 >>> URem(x, y).sexpr()
4471 '(bvurem x y)'
4472 """
4473 _check_bv_args(a, b)
4474 a, b = _coerce_exprs(a, b)
4475 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4476
4477
4478def SRem(a, b):
4479 """Create the Z3 expression signed remainder.
4480
4481 Use the operator % for signed modulus, and URem() for unsigned remainder.
4482
4483 >>> x = BitVec('x', 32)
4484 >>> y = BitVec('y', 32)
4485 >>> SRem(x, y)
4486 SRem(x, y)
4487 >>> SRem(x, y).sort()
4488 BitVec(32)
4489 >>> (x % y).sexpr()
4490 '(bvsmod x y)'
4491 >>> SRem(x, y).sexpr()
4492 '(bvsrem x y)'
4493 """
4494 _check_bv_args(a, b)
4495 a, b = _coerce_exprs(a, b)
4496 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4497
4498
4499def LShR(a, b):
4500 """Create the Z3 expression logical right shift.
4501
4502 Use the operator >> for the arithmetical right shift.
4503
4504 >>> x, y = BitVecs('x y', 32)
4505 >>> LShR(x, y)
4506 LShR(x, y)
4507 >>> (x >> y).sexpr()
4508 '(bvashr x y)'
4509 >>> LShR(x, y).sexpr()
4510 '(bvlshr x y)'
4511 >>> BitVecVal(4, 3)
4512 4
4513 >>> BitVecVal(4, 3).as_signed_long()
4514 -4
4515 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4516 -2
4517 >>> simplify(BitVecVal(4, 3) >> 1)
4518 6
4519 >>> simplify(LShR(BitVecVal(4, 3), 1))
4520 2
4521 >>> simplify(BitVecVal(2, 3) >> 1)
4522 1
4523 >>> simplify(LShR(BitVecVal(2, 3), 1))
4524 1
4525 """
4526 _check_bv_args(a, b)
4527 a, b = _coerce_exprs(a, b)
4528 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4529
4530
4531def RotateLeft(a, b):
4532 """Return an expression representing `a` rotated to the left `b` times.
4533
4534 >>> a, b = BitVecs('a b', 16)
4535 >>> RotateLeft(a, b)
4536 RotateLeft(a, b)
4537 >>> simplify(RotateLeft(a, 0))
4538 a
4539 >>> simplify(RotateLeft(a, 16))
4540 a
4541 """
4542 _check_bv_args(a, b)
4543 a, b = _coerce_exprs(a, b)
4544 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4545
4546
4547def RotateRight(a, b):
4548 """Return an expression representing `a` rotated to the right `b` times.
4549
4550 >>> a, b = BitVecs('a b', 16)
4551 >>> RotateRight(a, b)
4552 RotateRight(a, b)
4553 >>> simplify(RotateRight(a, 0))
4554 a
4555 >>> simplify(RotateRight(a, 16))
4556 a
4557 """
4558 _check_bv_args(a, b)
4559 a, b = _coerce_exprs(a, b)
4560 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4561
4562
4563def SignExt(n, a):
4564 """Return a bit-vector expression with `n` extra sign-bits.
4565
4566 >>> x = BitVec('x', 16)
4567 >>> n = SignExt(8, x)
4568 >>> n.size()
4569 24
4570 >>> n
4571 SignExt(8, x)
4572 >>> n.sort()
4573 BitVec(24)
4574 >>> v0 = BitVecVal(2, 2)
4575 >>> v0
4576 2
4577 >>> v0.size()
4578 2
4579 >>> v = simplify(SignExt(6, v0))
4580 >>> v
4581 254
4582 >>> v.size()
4583 8
4584 >>> print("%.x" % v.as_long())
4585 fe
4586 """
4587 if z3_debug():
4588 _z3_assert(_is_int(n), "First argument must be an integer")
4589 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4590 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4591
4592
4593def ZeroExt(n, a):
4594 """Return a bit-vector expression with `n` extra zero-bits.
4595
4596 >>> x = BitVec('x', 16)
4597 >>> n = ZeroExt(8, x)
4598 >>> n.size()
4599 24
4600 >>> n
4601 ZeroExt(8, x)
4602 >>> n.sort()
4603 BitVec(24)
4604 >>> v0 = BitVecVal(2, 2)
4605 >>> v0
4606 2
4607 >>> v0.size()
4608 2
4609 >>> v = simplify(ZeroExt(6, v0))
4610 >>> v
4611 2
4612 >>> v.size()
4613 8
4614 """
4615 if z3_debug():
4616 _z3_assert(_is_int(n), "First argument must be an integer")
4617 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4618 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4619
4620
4622 """Return an expression representing `n` copies of `a`.
4623
4624 >>> x = BitVec('x', 8)
4625 >>> n = RepeatBitVec(4, x)
4626 >>> n
4627 RepeatBitVec(4, x)
4628 >>> n.size()
4629 32
4630 >>> v0 = BitVecVal(10, 4)
4631 >>> print("%.x" % v0.as_long())
4632 a
4633 >>> v = simplify(RepeatBitVec(4, v0))
4634 >>> v.size()
4635 16
4636 >>> print("%.x" % v.as_long())
4637 aaaa
4638 """
4639 if z3_debug():
4640 _z3_assert(_is_int(n), "First argument must be an integer")
4641 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4642 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4643
4644
4646 """Return the reduction-and expression of `a`."""
4647 if z3_debug():
4648 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4649 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4650
4651
4652def BVRedOr(a):
4653 """Return the reduction-or expression of `a`."""
4654 if z3_debug():
4655 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4656 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4657
4658
4659def BvNand(a, b):
4660 """Return the bitwise NAND of `a` and `b`.
4661
4662 >>> x = BitVec('x', 8)
4663 >>> y = BitVec('y', 8)
4664 >>> BvNand(x, y)
4665 bvnand(x, y)
4666 """
4667 _check_bv_args(a, b)
4668 a, b = _coerce_exprs(a, b)
4669 return BitVecRef(Z3_mk_bvnand(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4670
4671
4672def BvNor(a, b):
4673 """Return the bitwise NOR of `a` and `b`.
4674
4675 >>> x = BitVec('x', 8)
4676 >>> y = BitVec('y', 8)
4677 >>> BvNor(x, y)
4678 bvnor(x, y)
4679 """
4680 _check_bv_args(a, b)
4681 a, b = _coerce_exprs(a, b)
4682 return BitVecRef(Z3_mk_bvnor(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4683
4684
4685def BvXnor(a, b):
4686 """Return the bitwise XNOR of `a` and `b`.
4687
4688 >>> x = BitVec('x', 8)
4689 >>> y = BitVec('y', 8)
4690 >>> BvXnor(x, y)
4691 bvxnor(x, y)
4692 """
4693 _check_bv_args(a, b)
4694 a, b = _coerce_exprs(a, b)
4695 return BitVecRef(Z3_mk_bvxnor(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4696
4697
4698def BVAddNoOverflow(a, b, signed):
4699 """A predicate the determines that bit-vector addition does not overflow"""
4700 _check_bv_args(a, b)
4701 a, b = _coerce_exprs(a, b)
4702 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4703
4704
4706 """A predicate the determines that signed bit-vector addition does not underflow"""
4707 _check_bv_args(a, b)
4708 a, b = _coerce_exprs(a, b)
4709 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4710
4711
4713 """A predicate the determines that bit-vector subtraction does not overflow"""
4714 _check_bv_args(a, b)
4715 a, b = _coerce_exprs(a, b)
4716 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4717
4718
4719def BVSubNoUnderflow(a, b, signed):
4720 """A predicate the determines that bit-vector subtraction does not underflow"""
4721 _check_bv_args(a, b)
4722 a, b = _coerce_exprs(a, b)
4723 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4724
4725
4727 """A predicate the determines that bit-vector signed division does not overflow"""
4728 _check_bv_args(a, b)
4729 a, b = _coerce_exprs(a, b)
4730 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4731
4732
4734 """A predicate the determines that bit-vector unary negation does not overflow"""
4735 if z3_debug():
4736 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4737 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4738
4739
4740def BVMulNoOverflow(a, b, signed):
4741 """A predicate the determines that bit-vector multiplication does not overflow"""
4742 _check_bv_args(a, b)
4743 a, b = _coerce_exprs(a, b)
4744 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4745
4746
4748 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4749 _check_bv_args(a, b)
4750 a, b = _coerce_exprs(a, b)
4751 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4752
4753
4754
4759
4761 """Array sorts."""
4762
4763 def domain(self):
4764 """Return the domain of the array sort `self`.
4765
4766 >>> A = ArraySort(IntSort(), BoolSort())
4767 >>> A.domain()
4768 Int
4769 """
4771
4772 def domain_n(self, i):
4773 """Return the domain of the array sort `self`.
4774 """
4775 return _to_sort_ref(Z3_get_array_sort_domain_n(self.ctx_ref(), self.ast, i), self.ctx)
4776
4777 def range(self):
4778 """Return the range of the array sort `self`.
4779
4780 >>> A = ArraySort(IntSort(), BoolSort())
4781 >>> A.range()
4782 Bool
4783 """
4784 return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
4785
4786
4788 """Array expressions. """
4789
4790 def sort(self):
4791 """Return the array sort of the array expression `self`.
4792
4793 >>> a = Array('a', IntSort(), BoolSort())
4794 >>> a.sort()
4795 Array(Int, Bool)
4796 """
4797 return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4798
4799 def domain(self):
4800 """Shorthand for `self.sort().domain()`.
4801
4802 >>> a = Array('a', IntSort(), BoolSort())
4803 >>> a.domain()
4804 Int
4805 """
4806 return self.sort().domain()
4807
4808 def domain_n(self, i):
4809 """Shorthand for self.sort().domain_n(i)`."""
4810 return self.sort().domain_n(i)
4811
4812 def range(self):
4813 """Shorthand for `self.sort().range()`.
4814
4815 >>> a = Array('a', IntSort(), BoolSort())
4816 >>> a.range()
4817 Bool
4818 """
4819 return self.sort().range()
4820
4821 def __getitem__(self, arg):
4822 """Return the Z3 expression `self[arg]`.
4823
4824 >>> a = Array('a', IntSort(), BoolSort())
4825 >>> i = Int('i')
4826 >>> a[i]
4827 a[i]
4828 >>> a[i].sexpr()
4829 '(select a i)'
4830 """
4831 return _array_select(self, arg)
4832
4833 def default(self):
4834 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)
4835
4836
4837def _array_select(ar, arg):
4838 if isinstance(arg, tuple):
4839 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4840 _args, sz = _to_ast_array(args)
4841 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4842 arg = ar.sort().domain().cast(arg)
4843 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4844
4845
4847 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4848
4849
4850def is_array(a : Any) -> bool:
4851 """Return `True` if `a` is a Z3 array expression.
4852
4853 >>> a = Array('a', IntSort(), IntSort())
4854 >>> is_array(a)
4855 True
4856 >>> is_array(Store(a, 0, 1))
4857 True
4858 >>> is_array(a[0])
4859 False
4860 """
4861 return isinstance(a, ArrayRef)
4862
4863
4865 """Return `True` if `a` is a Z3 constant array.
4866
4867 >>> a = K(IntSort(), 10)
4868 >>> is_const_array(a)
4869 True
4870 >>> a = Array('a', IntSort(), IntSort())
4871 >>> is_const_array(a)
4872 False
4873 """
4874 return is_app_of(a, Z3_OP_CONST_ARRAY)
4875
4876
4877def is_K(a):
4878 """Return `True` if `a` is a Z3 constant array.
4879
4880 >>> a = K(IntSort(), 10)
4881 >>> is_K(a)
4882 True
4883 >>> a = Array('a', IntSort(), IntSort())
4884 >>> is_K(a)
4885 False
4886 """
4887 return is_app_of(a, Z3_OP_CONST_ARRAY)
4888
4889
4890def is_map(a):
4891 """Return `True` if `a` is a Z3 map array expression.
4892
4893 >>> f = Function('f', IntSort(), IntSort())
4894 >>> b = Array('b', IntSort(), IntSort())
4895 >>> a = Map(f, b)
4896 >>> a
4897 Map(f, b)
4898 >>> is_map(a)
4899 True
4900 >>> is_map(b)
4901 False
4902 """
4903 return is_app_of(a, Z3_OP_ARRAY_MAP)
4904
4905
4907 """Return `True` if `a` is a Z3 default array expression.
4908 >>> d = Default(K(IntSort(), 10))
4909 >>> is_default(d)
4910 True
4911 """
4912 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4913
4914
4916 """Return the function declaration associated with a Z3 map array expression.
4917
4918 >>> f = Function('f', IntSort(), IntSort())
4919 >>> b = Array('b', IntSort(), IntSort())
4920 >>> a = Map(f, b)
4921 >>> eq(f, get_map_func(a))
4922 True
4923 >>> get_map_func(a)
4924 f
4925 >>> get_map_func(a)(0)
4926 f(0)
4927 """
4928 if z3_debug():
4929 _z3_assert(is_map(a), "Z3 array map expression expected.")
4930 return FuncDeclRef(
4932 a.ctx_ref(),
4933 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4934 ),
4935 ctx=a.ctx,
4936 )
4937
4938
4939def ArraySort(*sig):
4940 """Return the Z3 array sort with the given domain and range sorts.
4941
4942 >>> A = ArraySort(IntSort(), BoolSort())
4943 >>> A
4944 Array(Int, Bool)
4945 >>> A.domain()
4946 Int
4947 >>> A.range()
4948 Bool
4949 >>> AA = ArraySort(IntSort(), A)
4950 >>> AA
4951 Array(Int, Array(Int, Bool))
4952 >>> ArraySort(IntSort(), BoolSort(), RealSort())
4953 Array(Int, Bool, Real)
4954 """
4955 sig = _get_args(sig)
4956 if z3_debug():
4957 _z3_assert(len(sig) > 1, "At least two arguments expected")
4958 arity = len(sig) - 1
4959 r = sig[arity]
4960 d = sig[0]
4961 if z3_debug():
4962 for s in sig:
4963 _z3_assert(is_sort(s), "Z3 sort expected")
4964 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4965 ctx = d.ctx
4966 if len(sig) == 2:
4967 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4968 dom = (Sort * arity)()
4969 for i in range(arity):
4970 dom[i] = sig[i].ast
4971 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4972
4973
4974def Array(name, *sorts):
4975 """Return an array constant named `name` with the given domain and range sorts.
4976
4977 >>> a = Array('a', IntSort(), IntSort())
4978 >>> a.sort()
4979 Array(Int, Int)
4980 >>> a[0]
4981 a[0]
4982 """
4983 s = ArraySort(sorts)
4984 ctx = s.ctx
4985 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4986
4987
4988def Update(a, *args):
4989 """Return a Z3 store array expression.
4990
4991 >>> a = Array('a', IntSort(), IntSort())
4992 >>> i, v = Ints('i v')
4993 >>> s = Update(a, i, v)
4994 >>> s.sort()
4995 Array(Int, Int)
4996 >>> prove(s[i] == v)
4997 proved
4998 >>> j = Int('j')
4999 >>> prove(Implies(i != j, s[j] == a[j]))
5000 proved
5001 """
5002 if z3_debug():
5003 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
5004 args = _get_args(args)
5005 ctx = a.ctx
5006 if len(args) <= 1:
5007 raise Z3Exception("array update requires index and value arguments")
5008 if len(args) == 2:
5009 i = args[0]
5010 v = args[1]
5011 i = a.sort().domain().cast(i)
5012 v = a.sort().range().cast(v)
5013 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
5014 v = a.sort().range().cast(args[-1])
5015 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
5016 _args, sz = _to_ast_array(idxs)
5017 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
5018
5019
5020def Default(a):
5021 """ Return a default value for array expression.
5022 >>> b = K(IntSort(), 1)
5023 >>> prove(Default(b) == 1)
5024 proved
5025 """
5026 if z3_debug():
5027 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
5028 return a.default()
5029
5030
5031def Store(a, *args):
5032 """Return a Z3 store array expression.
5033
5034 >>> a = Array('a', IntSort(), IntSort())
5035 >>> i, v = Ints('i v')
5036 >>> s = Store(a, i, v)
5037 >>> s.sort()
5038 Array(Int, Int)
5039 >>> prove(s[i] == v)
5040 proved
5041 >>> j = Int('j')
5042 >>> prove(Implies(i != j, s[j] == a[j]))
5043 proved
5044 """
5045 return Update(a, args)
5046
5047
5048def Select(a, *args):
5049 """Return a Z3 select array expression.
5050
5051 >>> a = Array('a', IntSort(), IntSort())
5052 >>> i = Int('i')
5053 >>> Select(a, i)
5054 a[i]
5055 >>> eq(Select(a, i), a[i])
5056 True
5057 """
5058 args = _get_args(args)
5059 if z3_debug():
5060 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
5061 return a[args]
5062
5063
5064def Map(f, *args):
5065 """Return a Z3 map array expression.
5066
5067 >>> f = Function('f', IntSort(), IntSort(), IntSort())
5068 >>> a1 = Array('a1', IntSort(), IntSort())
5069 >>> a2 = Array('a2', IntSort(), IntSort())
5070 >>> b = Map(f, a1, a2)
5071 >>> b
5072 Map(f, a1, a2)
5073 >>> prove(b[0] == f(a1[0], a2[0]))
5074 proved
5075 """
5076 args = _get_args(args)
5077 if z3_debug():
5078 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
5079 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
5080 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
5081 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
5082 _args, sz = _to_ast_array(args)
5083 ctx = f.ctx
5084 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
5085
5086
5087def K(dom, v):
5088 """Return a Z3 constant array expression.
5089
5090 >>> a = K(IntSort(), 10)
5091 >>> a
5092 K(Int, 10)
5093 >>> a.sort()
5094 Array(Int, Int)
5095 >>> i = Int('i')
5096 >>> a[i]
5097 K(Int, 10)[i]
5098 >>> simplify(a[i])
5099 10
5100 """
5101 if z3_debug():
5102 _z3_assert(is_sort(dom), "Z3 sort expected")
5103 ctx = dom.ctx
5104 if not is_expr(v):
5105 v = _py2expr(v, ctx)
5106 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
5107
5108
5109def Ext(a, b):
5110 """Return extensionality index for one-dimensional arrays.
5111 >> a, b = Consts('a b', SetSort(IntSort()))
5112 >> Ext(a, b)
5113 Ext(a, b)
5114 """
5115 ctx = a.ctx
5116 if z3_debug():
5117 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
5118 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5119
5120
5121def AsArray(f):
5122 """Return a Z3 as-array expression for the given function declaration.
5123
5124 >>> f = Function('f', IntSort(), IntSort())
5125 >>> a = AsArray(f)
5126 >>> a.sort()
5127 Array(Int, Int)
5128 >>> is_as_array(a)
5129 True
5130 >>> get_as_array_func(a) == f
5131 True
5132 """
5133 if z3_debug():
5134 _z3_assert(isinstance(f, FuncDeclRef), "function declaration expected")
5135 ctx = f.ctx
5136 return ArrayRef(Z3_mk_as_array(ctx.ref(), f.ast), ctx)
5137
5138
5140 """Return `True` if `a` is a Z3 array select application.
5141
5142 >>> a = Array('a', IntSort(), IntSort())
5143 >>> is_select(a)
5144 False
5145 >>> i = Int('i')
5146 >>> is_select(a[i])
5147 True
5148 """
5149 return is_app_of(a, Z3_OP_SELECT)
5150
5151
5153 """Return `True` if `a` is a Z3 array store application.
5154
5155 >>> a = Array('a', IntSort(), IntSort())
5156 >>> is_store(a)
5157 False
5158 >>> is_store(Store(a, 0, 1))
5159 True
5160 """
5161 return is_app_of(a, Z3_OP_STORE)
5162
5163
5168
5169
5170def SetSort(s):
5171 """ Create a set sort over element sort s"""
5172 return ArraySort(s, BoolSort())
5173
5174
5176 """Create the empty set
5177 >>> EmptySet(IntSort())
5178 K(Int, False)
5179 """
5180 ctx = s.ctx
5181 if is_finite_set_sort(s):
5182 return FiniteSetEmpty(s)
5183 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5184
5185
5186def FullSet(s):
5187 """Create the full set
5188 >>> FullSet(IntSort())
5189 K(Int, True)
5190 """
5191 ctx = s.ctx
5192 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5193
5194
5195def SetUnion(*args):
5196 """ Take the union of sets
5197 >>> a = Const('a', SetSort(IntSort()))
5198 >>> b = Const('b', SetSort(IntSort()))
5199 >>> SetUnion(a, b)
5200 union(a, b)
5201 """
5202 args = _get_args(args)
5203 if len(args) > 0 and is_finite_set(args[0]):
5204 from functools import reduce
5205 return reduce(FiniteSetUnion, args)
5206 ctx = _ctx_from_ast_arg_list(args)
5207 _args, sz = _to_ast_array(args)
5208 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5209
5210
5211def SetIntersect(*args):
5212 """ Take the union of sets
5213 >>> a = Const('a', SetSort(IntSort()))
5214 >>> b = Const('b', SetSort(IntSort()))
5215 >>> SetIntersect(a, b)
5216 intersection(a, b)
5217 """
5218 args = _get_args(args)
5219 ctx = _ctx_from_ast_arg_list(args)
5220 if len(args) > 0 and is_finite_set(args[0]):
5221 from functools import reduce
5222 return reduce(FiniteSetIntersect, args)
5223 _args, sz = _to_ast_array(args)
5224 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5225
5226
5227def SetAdd(s, e):
5228 """ Add element e to set s
5229 >>> a = Const('a', SetSort(IntSort()))
5230 >>> SetAdd(a, 1)
5231 Store(a, 1, True)
5232 """
5233 ctx = _ctx_from_ast_arg_list([s, e])
5234 e = _py2expr(e, ctx)
5235 if is_finite_set(s):
5236 return FiniteSetSingleton(e) | s
5237 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5238
5239
5240def SetDel(s, e):
5241 """ Remove element e to set s
5242 >>> a = Const('a', SetSort(IntSort()))
5243 >>> SetDel(a, 1)
5244 Store(a, 1, False)
5245 """
5246 ctx = _ctx_from_ast_arg_list([s, e])
5247 e = _py2expr(e, ctx)
5248 if is_finite_set(s):
5249 return s - FiniteSetSingleton(e)
5250 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5251
5252
5254 """ The complement of set s
5255 >>> a = Const('a', SetSort(IntSort()))
5256 >>> SetComplement(a)
5257 complement(a)
5258 """
5259 ctx = s.ctx
5260 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5261
5262
5264 """ The set difference of a and b
5265 >>> a = Const('a', SetSort(IntSort()))
5266 >>> b = Const('b', SetSort(IntSort()))
5267 >>> SetDifference(a, b)
5268 setminus(a, b)
5269 """
5270 ctx = _ctx_from_ast_arg_list([a, b])
5271 if is_finite_set(a):
5272 return FiniteSetDifference(a, b)
5273 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5274
5275
5276def IsMember(e, s):
5277 """ Check if e is a member of set s
5278 >>> a = Const('a', SetSort(IntSort()))
5279 >>> IsMember(1, a)
5280 a[1]
5281 """
5282 ctx = _ctx_from_ast_arg_list([s, e])
5283 e = _py2expr(e, ctx)
5284 if is_finite_set(s):
5285 return FiniteSetIsMember(e, s)
5286 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5287
5288
5289def IsSubset(a, b):
5290 """ Check if a is a subset of b
5291 >>> a = Const('a', SetSort(IntSort()))
5292 >>> b = Const('b', SetSort(IntSort()))
5293 >>> IsSubset(a, b)
5294 subset(a, b)
5295 """
5296 ctx = _ctx_from_ast_arg_list([a, b])
5297 if is_finite_set(a):
5298 return FiniteSetIsSubset(a, b)
5299 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5300
5301
5302
5307
5308
5310 """Finite set sort."""
5311
5312 def element_sort(self):
5313 """Return the element sort of this finite set sort."""
5315
5316 def cast(self, val):
5317 """Try to cast val as a finite set expression."""
5318 if is_expr(val):
5319 if self.eq(val.sort()):
5320 return val
5321 else:
5322 _z3_assert(False, "Cannot cast to finite set sort")
5323 if isinstance(val, set):
5324 elem_sort = self.element_sort()
5325 result = FiniteSetEmpty(self)
5326 for e in val:
5327 result = FiniteSetUnion(result, Singleton(_py2expr(e, self.ctx, elem_sort)))
5328 return result
5329 _z3_assert(False, "Cannot cast to finite set sort")
5330
5331 def subsort(self, other):
5332 return False
5333
5334 def is_int(self):
5335 return False
5336
5337 def is_bool(self):
5338 return False
5339
5340 def is_datatype(self):
5341 return False
5342
5343 def is_array(self):
5344 return False
5345
5346 def is_bv(self):
5347 return False
5348
5349
5351 """Return True if a is a Z3 finite set expression.
5352 >>> s = FiniteSetSort(IntSort())
5353 >>> is_finite_set(FiniteSetEmpty(s))
5354 True
5355 >>> is_finite_set(IntVal(1))
5356 False
5357 """
5358 return isinstance(a, FiniteSetRef)
5359
5360
5362 """Return True if s is a Z3 finite set sort.
5363 >>> is_finite_set_sort(FiniteSetSort(IntSort()))
5364 True
5365 >>> is_finite_set_sort(IntSort())
5366 False
5367 """
5368 return isinstance(s, FiniteSetSortRef)
5369
5370
5372 """Finite set expression."""
5373
5374 def sort(self):
5375 return FiniteSetSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5376
5377 def __or__(self, other):
5378 """Return the union of self and other."""
5379 return FiniteSetUnion(self, other)
5380
5381 def __and__(self, other):
5382 """Return the intersection of self and other."""
5383 return FiniteSetIntersect(self, other)
5384
5385 def __sub__(self, other):
5386 """Return the set difference of self and other."""
5387 return FiniteSetDifference(self, other)
5388
5389
5390def FiniteSetSort(elem_sort):
5391 """Create a finite set sort over element sort elem_sort.
5392 >>> s = FiniteSetSort(IntSort())
5393 >>> s
5394 FiniteSet(Int)
5395 """
5396 return FiniteSetSortRef(Z3_mk_finite_set_sort(elem_sort.ctx_ref(), elem_sort.ast), elem_sort.ctx)
5397
5398
5399def FiniteSetEmpty(set_sort):
5400 """Create an empty finite set of the given sort.
5401 >>> s = FiniteSetSort(IntSort())
5402 >>> FiniteSetEmpty(s)
5403 set.empty
5404 """
5405 ctx = set_sort.ctx
5406 return FiniteSetRef(Z3_mk_finite_set_empty(ctx.ref(), set_sort.ast), ctx)
5407
5408
5409def Singleton(elem):
5410 """Create a singleton finite set containing elem.
5411 >>> Singleton(IntVal(1))
5412 set.singleton(1)
5413 """
5414 ctx = elem.ctx
5415 return FiniteSetRef(Z3_mk_finite_set_singleton(ctx.ref(), elem.as_ast()), ctx)
5416
5417
5418def FiniteSetUnion(s1, s2):
5419 """Create the union of two finite sets.
5420 >>> a = Const('a', FiniteSetSort(IntSort()))
5421 >>> b = Const('b', FiniteSetSort(IntSort()))
5422 >>> FiniteSetUnion(a, b)
5423 set.union(a, b)
5424 """
5425 ctx = _ctx_from_ast_arg_list([s1, s2])
5426 return FiniteSetRef(Z3_mk_finite_set_union(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx)
5427
5428
5430 """Create the intersection of two finite sets.
5431 >>> a = Const('a', FiniteSetSort(IntSort()))
5432 >>> b = Const('b', FiniteSetSort(IntSort()))
5433 >>> FiniteSetIntersect(a, b)
5434 set.intersect(a, b)
5435 """
5436 ctx = _ctx_from_ast_arg_list([s1, s2])
5437 return FiniteSetRef(Z3_mk_finite_set_intersect(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx)
5438
5439
5441 """Create the set difference of two finite sets.
5442 >>> a = Const('a', FiniteSetSort(IntSort()))
5443 >>> b = Const('b', FiniteSetSort(IntSort()))
5444 >>> FiniteSetDifference(a, b)
5445 set.difference(a, b)
5446 """
5447 ctx = _ctx_from_ast_arg_list([s1, s2])
5448 return FiniteSetRef(Z3_mk_finite_set_difference(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx)
5449
5450
5451def FiniteSetMember(elem, set):
5452 """Check if elem is a member of the finite set.
5453 >>> a = Const('a', FiniteSetSort(IntSort()))
5454 >>> FiniteSetMember(IntVal(1), a)
5455 set.in(1, a)
5456 """
5457 ctx = _ctx_from_ast_arg_list([elem, set])
5458 return BoolRef(Z3_mk_finite_set_member(ctx.ref(), elem.as_ast(), set.as_ast()), ctx)
5459
5460def In(elem, set):
5461 return FiniteSetMember(elem, set)
5462
5464 """Get the size (cardinality) of a finite set.
5465 >>> a = Const('a', FiniteSetSort(IntSort()))
5466 >>> FiniteSetSize(a)
5467 set.size(a)
5468 """
5469 ctx = set.ctx
5470 return ArithRef(Z3_mk_finite_set_size(ctx.ref(), set.as_ast()), ctx)
5471
5472
5474 """Check if s1 is a subset of s2.
5475 >>> a = Const('a', FiniteSetSort(IntSort()))
5476 >>> b = Const('b', FiniteSetSort(IntSort()))
5477 >>> FiniteSetSubset(a, b)
5478 set.subset(a, b)
5479 """
5480 ctx = _ctx_from_ast_arg_list([s1, s2])
5481 return BoolRef(Z3_mk_finite_set_subset(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx)
5482
5483
5484def FiniteSetMap(f, set):
5485 """Apply function f to all elements of the finite set.
5486 >>> f = Array('f', IntSort(), IntSort())
5487 >>> a = Const('a', FiniteSetSort(IntSort()))
5488 >>> FiniteSetMap(f, a)
5489 set.map(f, a)
5490 """
5491 if isinstance(f, FuncDeclRef):
5492 f = AsArray(f)
5493 ctx = _ctx_from_ast_arg_list([f, set])
5494 return FiniteSetRef(Z3_mk_finite_set_map(ctx.ref(), f.as_ast(), set.as_ast()), ctx)
5495
5496
5498 """Filter a finite set using predicate f.
5499 >>> f = Array('f', IntSort(), BoolSort())
5500 >>> a = Const('a', FiniteSetSort(IntSort()))
5501 >>> FiniteSetFilter(f, a)
5502 set.filter(f, a)
5503 """
5504 if isinstance(f, FuncDeclRef):
5505 f = AsArray(f)
5506 ctx = _ctx_from_ast_arg_list([f, set])
5507 return FiniteSetRef(Z3_mk_finite_set_filter(ctx.ref(), f.as_ast(), set.as_ast()), ctx)
5508
5509
5510def FiniteSetRange(low, high):
5511 """Create a finite set of integers in the range [low, high).
5512 >>> FiniteSetRange(IntVal(0), IntVal(5))
5513 set.range(0, 5)
5514 """
5515 ctx = _ctx_from_ast_arg_list([low, high])
5516 return FiniteSetRef(Z3_mk_finite_set_range(ctx.ref(), low.as_ast(), high.as_ast()), ctx)
5517
5518
5519
5524
5526 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5527 if not isinstance(acc, tuple):
5528 return False
5529 if len(acc) != 2:
5530 return False
5531 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5532
5533
5535 """Helper class for declaring Z3 datatypes.
5536
5537 >>> List = Datatype('List')
5538 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5539 >>> List.declare('nil')
5540 >>> List = List.create()
5541 >>> # List is now a Z3 declaration
5542 >>> List.nil
5543 nil
5544 >>> List.cons(10, List.nil)
5545 cons(10, nil)
5546 >>> List.cons(10, List.nil).sort()
5547 List
5548 >>> cons = List.cons
5549 >>> nil = List.nil
5550 >>> car = List.car
5551 >>> cdr = List.cdr
5552 >>> n = cons(1, cons(0, nil))
5553 >>> n
5554 cons(1, cons(0, nil))
5555 >>> simplify(cdr(n))
5556 cons(0, nil)
5557 >>> simplify(car(n))
5558 1
5559 """
5560
5561 def __init__(self, name, ctx=None):
5562 self.ctx = _get_ctx(ctx)
5563 self.name = name
5565
5566 def __deepcopy__(self, memo={}):
5567 r = Datatype(self.name, self.ctx)
5568 r.constructors = copy.deepcopy(self.constructors)
5569 return r
5570
5571 def declare_core(self, name, rec_name, *args):
5572 if z3_debug():
5573 _z3_assert(isinstance(name, str), "String expected")
5574 _z3_assert(isinstance(rec_name, str), "String expected")
5575 _z3_assert(
5576 all([_valid_accessor(a) for a in args]),
5577 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5578 )
5579 self.constructors.append((name, rec_name, args))
5580
5581 def declare(self, name, *args):
5582 """Declare constructor named `name` with the given accessors `args`.
5583 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5584 or a reference to the datatypes being declared.
5585
5586 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5587 declares the constructor named `cons` that builds a new List using an integer and a List.
5588 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5589 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5590 we use the method create() to create the actual datatype in Z3.
5591
5592 >>> List = Datatype('List')
5593 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5594 >>> List.declare('nil')
5595 >>> List = List.create()
5596 """
5597 if z3_debug():
5598 _z3_assert(isinstance(name, str), "String expected")
5599 _z3_assert(name != "", "Constructor name cannot be empty")
5600 return self.declare_core(name, "is-" + name, *args)
5601
5602 def __repr__(self):
5603 return "Datatype(%s, %s)" % (self.name, self.constructors)
5604
5605 def create(self):
5606 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5607
5608 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5609
5610 >>> List = Datatype('List')
5611 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5612 >>> List.declare('nil')
5613 >>> List = List.create()
5614 >>> List.nil
5615 nil
5616 >>> List.cons(10, List.nil)
5617 cons(10, nil)
5618 """
5619 return CreateDatatypes([self])[0]
5620
5621 def create_polymorphic(self, type_params):
5622 """Create a polymorphic Z3 datatype with explicit type variables.
5623
5624 `type_params` is a list of type variables created with `DeclareTypeVar`.
5625 Constructor field sorts may reference these type variables.
5626 Self-recursive fields may reference this datatype directly.
5627
5628 >>> A = DeclareTypeVar('A')
5629 >>> Pair = Datatype('Pair')
5630 >>> Pair.declare('pair', ('fst', A), ('snd', A))
5631 >>> Pair = Pair.create_polymorphic([A])
5632 """
5633 return CreatePolymorphicDatatype(self, type_params)
5634
5635
5637 """Auxiliary object used to create Z3 datatypes."""
5638
5639 def __init__(self, c, ctx):
5640 self.c = c
5641 self.ctx = ctx
5642
5643 def __del__(self):
5644 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5645 Z3_del_constructor(self.ctx.ref(), self.c)
5646
5647
5649 """Auxiliary object used to create Z3 datatypes."""
5650
5651 def __init__(self, c, ctx):
5652 self.c = c
5653 self.ctx = ctx
5654
5655 def __del__(self):
5656 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5657 Z3_del_constructor_list(self.ctx.ref(), self.c)
5658
5659
5661 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5662
5663 In the following example we define a Tree-List using two mutually recursive datatypes.
5664
5665 >>> TreeList = Datatype('TreeList')
5666 >>> Tree = Datatype('Tree')
5667 >>> # Tree has two constructors: leaf and node
5668 >>> Tree.declare('leaf', ('val', IntSort()))
5669 >>> # a node contains a list of trees
5670 >>> Tree.declare('node', ('children', TreeList))
5671 >>> TreeList.declare('nil')
5672 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5673 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5674 >>> Tree.val(Tree.leaf(10))
5675 val(leaf(10))
5676 >>> simplify(Tree.val(Tree.leaf(10)))
5677 10
5678 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5679 >>> n1
5680 node(cons(leaf(10), cons(leaf(20), nil)))
5681 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5682 >>> simplify(n2 == n1)
5683 False
5684 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5685 True
5686 """
5687 ds = _get_args(ds)
5688 if z3_debug():
5689 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5690 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5691 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5692 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5693 ctx = ds[0].ctx
5694 num = len(ds)
5695 names = (Symbol * num)()
5696 out = (Sort * num)()
5697 clists = (ConstructorList * num)()
5698 to_delete = []
5699 for i in range(num):
5700 d = ds[i]
5701 names[i] = to_symbol(d.name, ctx)
5702 num_cs = len(d.constructors)
5703 cs = (Constructor * num_cs)()
5704 for j in range(num_cs):
5705 c = d.constructors[j]
5706 cname = to_symbol(c[0], ctx)
5707 rname = to_symbol(c[1], ctx)
5708 fs = c[2]
5709 num_fs = len(fs)
5710 fnames = (Symbol * num_fs)()
5711 sorts = (Sort * num_fs)()
5712 refs = (ctypes.c_uint * num_fs)()
5713 for k in range(num_fs):
5714 fname = fs[k][0]
5715 ftype = fs[k][1]
5716 fnames[k] = to_symbol(fname, ctx)
5717 if isinstance(ftype, Datatype):
5718 if z3_debug():
5719 _z3_assert(
5720 ds.count(ftype) == 1,
5721 "One and only one occurrence of each datatype is expected",
5722 )
5723 sorts[k] = None
5724 refs[k] = ds.index(ftype)
5725 else:
5726 if z3_debug():
5727 _z3_assert(is_sort(ftype), "Z3 sort expected")
5728 sorts[k] = ftype.ast
5729 refs[k] = 0
5730 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5731 to_delete.append(ScopedConstructor(cs[j], ctx))
5732 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5733 to_delete.append(ScopedConstructorList(clists[i], ctx))
5734 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5735 result = []
5736 # Create a field for every constructor, recognizer and accessor
5737 for i in range(num):
5738 dref = DatatypeSortRef(out[i], ctx)
5739 num_cs = dref.num_constructors()
5740 for j in range(num_cs):
5741 cref = dref.constructor(j)
5742 cref_name = cref.name()
5743 cref_arity = cref.arity()
5744 if cref.arity() == 0:
5745 cref = cref()
5746 setattr(dref, cref_name, cref)
5747 rref = dref.recognizer(j)
5748 setattr(dref, "is_" + cref_name, rref)
5749 for k in range(cref_arity):
5750 aref = dref.accessor(j, k)
5751 setattr(dref, aref.name(), aref)
5752 result.append(dref)
5753 return tuple(result)
5754
5755
5756def CreatePolymorphicDatatype(d, type_params):
5757 """Create a single polymorphic Z3 datatype with explicit type parameters.
5758
5759 `d` is a `Datatype` helper object whose constructors have been declared.
5760 `type_params` is a list of type variables created with `DeclareTypeVar`.
5761 Constructor field sorts may reference these type variables, and self-recursive
5762 fields may reference `d` directly.
5763
5764 >>> A = DeclareTypeVar('A')
5765 >>> Pair = Datatype('Pair')
5766 >>> Pair.declare('pair', ('fst', A), ('snd', A))
5767 >>> Pair = CreatePolymorphicDatatype(Pair, [A])
5768 """
5769 if z3_debug():
5770 _z3_assert(isinstance(d, Datatype), "Datatype expected")
5771 _z3_assert(d.constructors != [], "Non-empty Datatype expected")
5772 ctx = d.ctx
5773 name = to_symbol(d.name, ctx)
5774 num_params = len(type_params)
5775 params_arr = (Sort * num_params)()
5776 for i, p in enumerate(type_params):
5777 if z3_debug():
5778 _z3_assert(is_sort(p), "Z3 sort expected for type parameter")
5779 params_arr[i] = p.ast
5780 num_cs = len(d.constructors)
5781 cs = (Constructor * num_cs)()
5782 to_delete = []
5783 for j in range(num_cs):
5784 c = d.constructors[j]
5785 cname = to_symbol(c[0], ctx)
5786 rname = to_symbol(c[1], ctx)
5787 fs = c[2]
5788 num_fs = len(fs)
5789 fnames = (Symbol * num_fs)()
5790 sorts = (Sort * num_fs)()
5791 refs = (ctypes.c_uint * num_fs)()
5792 for k in range(num_fs):
5793 fname = fs[k][0]
5794 ftype = fs[k][1]
5795 fnames[k] = to_symbol(fname, ctx)
5796 if isinstance(ftype, Datatype):
5797 if z3_debug():
5798 _z3_assert(ftype is d, "Only self-recursive references are supported in polymorphic datatypes. Use CreateDatatypes for mutually recursive datatypes.")
5799 sorts[k] = None
5800 refs[k] = 0
5801 else:
5802 if z3_debug():
5803 _z3_assert(is_sort(ftype), "Z3 sort expected")
5804 sorts[k] = ftype.ast
5805 refs[k] = 0
5806 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5807 to_delete.append(ScopedConstructor(cs[j], ctx))
5808 out = Z3_mk_polymorphic_datatype(ctx.ref(), name, num_params, params_arr, num_cs, cs)
5809 dref = DatatypeSortRef(out, ctx)
5810 num_cs_actual = dref.num_constructors()
5811 for j in range(num_cs_actual):
5812 cref = dref.constructor(j)
5813 cref_name = cref.name()
5814 cref_arity = cref.arity()
5815 if cref_arity == 0:
5816 cref = cref()
5817 setattr(dref, cref_name, cref)
5818 rref = dref.recognizer(j)
5819 setattr(dref, "is_" + cref_name, rref)
5820 for k in range(cref_arity):
5821 aref = dref.accessor(j, k)
5822 setattr(dref, aref.name(), aref)
5823 return dref
5824
5825
5827 """Datatype sorts."""
5828
5830 """Return the number of constructors in the given Z3 datatype.
5831
5832 >>> List = Datatype('List')
5833 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5834 >>> List.declare('nil')
5835 >>> List = List.create()
5836 >>> # List is now a Z3 declaration
5837 >>> List.num_constructors()
5838 2
5839 """
5841
5842 def constructor(self, idx):
5843 """Return a constructor of the datatype `self`.
5844
5845 >>> List = Datatype('List')
5846 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5847 >>> List.declare('nil')
5848 >>> List = List.create()
5849 >>> # List is now a Z3 declaration
5850 >>> List.num_constructors()
5851 2
5852 >>> List.constructor(0)
5853 cons
5854 >>> List.constructor(1)
5855 nil
5856 """
5857 if z3_debug():
5858 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5860
5861 def recognizer(self, idx):
5862 """In Z3, each constructor has an associated recognizer predicate.
5863
5864 If the constructor is named `name`, then the recognizer `is_name`.
5865
5866 >>> List = Datatype('List')
5867 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5868 >>> List.declare('nil')
5869 >>> List = List.create()
5870 >>> # List is now a Z3 declaration
5871 >>> List.num_constructors()
5872 2
5873 >>> List.recognizer(0)
5874 is(cons)
5875 >>> List.recognizer(1)
5876 is(nil)
5877 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5878 False
5879 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5880 True
5881 >>> l = Const('l', List)
5882 >>> simplify(List.is_cons(l))
5883 is(cons, l)
5884 """
5885 if z3_debug():
5886 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5887 return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
5888
5889 def accessor(self, i, j):
5890 """In Z3, each constructor has 0 or more accessor.
5891 The number of accessors is equal to the arity of the constructor.
5892
5893 >>> List = Datatype('List')
5894 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5895 >>> List.declare('nil')
5896 >>> List = List.create()
5897 >>> List.num_constructors()
5898 2
5899 >>> List.constructor(0)
5900 cons
5901 >>> num_accs = List.constructor(0).arity()
5902 >>> num_accs
5903 2
5904 >>> List.accessor(0, 0)
5905 car
5906 >>> List.accessor(0, 1)
5907 cdr
5908 >>> List.constructor(1)
5909 nil
5910 >>> num_accs = List.constructor(1).arity()
5911 >>> num_accs
5912 0
5913 """
5914 if z3_debug():
5915 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5916 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5917 return FuncDeclRef(
5919 ctx=self.ctx,
5920 )
5921
5922
5924 """Datatype expressions."""
5925
5926 def sort(self):
5927 """Return the datatype sort of the datatype expression `self`."""
5928 return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5929
5930 def update_field(self, field_accessor, new_value):
5931 """Return a new datatype expression with the specified field updated.
5932
5933 Args:
5934 field_accessor: The accessor function declaration for the field to update
5935 new_value: The new value for the field
5936
5937 Returns:
5938 A new datatype expression with the field updated, other fields unchanged
5939
5940 Example:
5941 >>> Person = Datatype('Person')
5942 >>> Person.declare('person', ('name', StringSort()), ('age', IntSort()))
5943 >>> Person = Person.create()
5944 >>> person_age = Person.accessor(0, 1) # age accessor
5945 >>> p = Const('p', Person)
5946 >>> p2 = p.update_field(person_age, IntVal(30))
5947 """
5948 if z3_debug():
5949 _z3_assert(is_func_decl(field_accessor), "Z3 function declaration expected")
5950 _z3_assert(is_expr(new_value), "Z3 expression expected")
5951 return _to_expr_ref(
5952 Z3_datatype_update_field(self.ctx_ref(), field_accessor.ast, self.as_ast(), new_value.as_ast()),
5953 self.ctx
5954 )
5955
5956def DatatypeSort(name, params=None, ctx=None):
5957 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype.
5958
5959 Args:
5960 name: name of the datatype sort
5961 params: optional list/tuple of sort parameters for parametric datatypes
5962 ctx: Z3 context (optional)
5963
5964 Example:
5965 >>> # Non-parametric datatype
5966 >>> TreeRef = DatatypeSort('Tree')
5967 >>> # Parametric datatype with one parameter
5968 >>> ListIntRef = DatatypeSort('List', [IntSort()])
5969 >>> # Parametric datatype with multiple parameters
5970 >>> PairRef = DatatypeSort('Pair', [IntSort(), BoolSort()])
5971 """
5972 ctx = _get_ctx(ctx)
5973 if params is None or len(params) == 0:
5974 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), 0, (Sort * 0)()), ctx)
5975 else:
5976 _params = (Sort * len(params))()
5977 for i in range(len(params)):
5978 _params[i] = params[i].ast
5979 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), len(params), _params), ctx)
5980
5981def TupleSort(name, sorts, ctx=None):
5982 """Create a named tuple sort base on a set of underlying sorts
5983 Example:
5984 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5985 """
5986 tuple = Datatype(name, ctx)
5987 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5988 tuple.declare(name, *projects)
5989 tuple = tuple.create()
5990 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5991
5992
5993def DisjointSum(name, sorts, ctx=None):
5994 """Create a named tagged union sort base on a set of underlying sorts
5995 Example:
5996 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5997 """
5998 sum = Datatype(name, ctx)
5999 for i in range(len(sorts)):
6000 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
6001 sum = sum.create()
6002 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
6003
6004
6005def EnumSort(name, values, ctx=None):
6006 """Return a new enumeration sort named `name` containing the given values.
6007
6008 The result is a pair (sort, list of constants).
6009 Example:
6010 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
6011 """
6012 if z3_debug():
6013 _z3_assert(isinstance(name, str), "Name must be a string")
6014 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
6015 _z3_assert(len(values) > 0, "At least one value expected")
6016 ctx = _get_ctx(ctx)
6017 num = len(values)
6018 _val_names = (Symbol * num)()
6019 for i in range(num):
6020 _val_names[i] = to_symbol(values[i], ctx)
6021 _values = (FuncDecl * num)()
6022 _testers = (FuncDecl * num)()
6023 name = to_symbol(name, ctx)
6024 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
6025 V = []
6026 for i in range(num):
6027 V.append(FuncDeclRef(_values[i], ctx))
6028 V = [a() for a in V]
6029 return S, V
6030
6031
6036
6037
6039 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
6040
6041 Consider using the function `args2params` to create instances of this object.
6042 """
6043
6044 def __init__(self, ctx=None, params=None):
6045 self.ctx = _get_ctx(ctx)
6046 if params is None:
6047 self.params = Z3_mk_params(self.ctx.ref())
6048 else:
6049 self.params = params
6050 Z3_params_inc_ref(self.ctx.ref(), self.params)
6051
6052 def __deepcopy__(self, memo={}):
6053 return ParamsRef(self.ctx, self.params)
6054
6055 def __del__(self):
6056 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
6057 Z3_params_dec_ref(self.ctx.ref(), self.params)
6058
6059 def set(self, name, val):
6060 """Set parameter name with value val."""
6061 if z3_debug():
6062 _z3_assert(isinstance(name, str), "parameter name must be a string")
6063 name_sym = to_symbol(name, self.ctx)
6064 if isinstance(val, bool):
6065 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
6066 elif _is_int(val):
6067 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
6068 elif isinstance(val, float):
6069 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
6070 elif isinstance(val, str):
6071 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
6072 else:
6073 if z3_debug():
6074 _z3_assert(False, "invalid parameter value")
6075
6076 def __repr__(self):
6077 return Z3_params_to_string(self.ctx.ref(), self.params)
6078
6079 def validate(self, ds):
6080 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
6081 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
6082
6083
6084def args2params(arguments, keywords, ctx=None):
6085 """Convert python arguments into a Z3_params object.
6086 A ':' is added to the keywords, and '_' is replaced with '-'
6087
6088 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
6089 (params model true relevancy 2 elim_and true)
6090 """
6091 if z3_debug():
6092 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
6093 prev = None
6094 r = ParamsRef(ctx)
6095 for a in arguments:
6096 if prev is None:
6097 prev = a
6098 else:
6099 r.set(prev, a)
6100 prev = None
6101 for k in keywords:
6102 v = keywords[k]
6103 r.set(k, v)
6104 return r
6105
6106
6108 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
6109 """
6110
6111 def __init__(self, descr, ctx=None):
6112 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
6113 self.ctx = _get_ctx(ctx)
6114 self.descr = descr
6115 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
6116
6117 def __deepcopy__(self, memo={}):
6118 return ParamsDescrsRef(self.descr, self.ctx)
6119
6120 def __del__(self):
6121 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
6122 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
6123
6124 def size(self):
6125 """Return the size of in the parameter description `self`.
6126 """
6127 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
6128
6129 def __len__(self):
6130 """Return the size of in the parameter description `self`.
6131 """
6132 return self.size()
6133
6134 def get_name(self, i):
6135 """Return the i-th parameter name in the parameter description `self`.
6136 """
6137 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
6138
6139 def get_kind(self, n):
6140 """Return the kind of the parameter named `n`.
6141 """
6142 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
6143
6144 def get_documentation(self, n):
6145 """Return the documentation string of the parameter named `n`.
6146 """
6147 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
6148
6149 def __getitem__(self, arg):
6150 if _is_int(arg):
6151 return self.get_name(arg)
6152 else:
6153 return self.get_kind(arg)
6154
6155 def __repr__(self):
6156 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
6157
6158
6163
6164
6166 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
6167
6168 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
6169 A goal has a solution if one of its subgoals has a solution.
6170 A goal is unsatisfiable if all subgoals are unsatisfiable.
6171 """
6172
6173 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
6174 if z3_debug():
6175 _z3_assert(goal is None or ctx is not None,
6176 "If goal is different from None, then ctx must be also different from None")
6177 self.ctx = _get_ctx(ctx)
6178 self.goal = goal
6179 if self.goal is None:
6180 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
6181 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
6182
6183 def __del__(self):
6184 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
6185 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
6186
6187 def depth(self):
6188 """Return the depth of the goal `self`.
6189 The depth corresponds to the number of tactics applied to `self`.
6190
6191 >>> x, y = Ints('x y')
6192 >>> g = Goal()
6193 >>> g.add(x == 0, y >= x + 1)
6194 >>> g.depth()
6195 0
6196 >>> r = Then('simplify', 'solve-eqs')(g)
6197 >>> # r has 1 subgoal
6198 >>> len(r)
6199 1
6200 >>> r[0].depth()
6201 2
6202 """
6203 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
6204
6205 def inconsistent(self):
6206 """Return `True` if `self` contains the `False` constraints.
6207
6208 >>> x, y = Ints('x y')
6209 >>> g = Goal()
6210 >>> g.inconsistent()
6211 False
6212 >>> g.add(x == 0, x == 1)
6213 >>> g
6214 [x == 0, x == 1]
6215 >>> g.inconsistent()
6216 False
6217 >>> g2 = Tactic('propagate-values')(g)[0]
6218 >>> g2.inconsistent()
6219 True
6220 """
6221 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
6222
6223 def prec(self):
6224 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
6225
6226 >>> g = Goal()
6227 >>> g.prec() == Z3_GOAL_PRECISE
6228 True
6229 >>> x, y = Ints('x y')
6230 >>> g.add(x == y + 1)
6231 >>> g.prec() == Z3_GOAL_PRECISE
6232 True
6233 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
6234 >>> g2 = t(g)[0]
6235 >>> g2
6236 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
6237 >>> g2.prec() == Z3_GOAL_PRECISE
6238 False
6239 >>> g2.prec() == Z3_GOAL_UNDER
6240 True
6241 """
6242 return Z3_goal_precision(self.ctx.ref(), self.goal)
6243
6244 def precision(self):
6245 """Alias for `prec()`.
6246
6247 >>> g = Goal()
6248 >>> g.precision() == Z3_GOAL_PRECISE
6249 True
6250 """
6251 return self.prec()
6252
6253 def size(self):
6254 """Return the number of constraints in the goal `self`.
6255
6256 >>> g = Goal()
6257 >>> g.size()
6258 0
6259 >>> x, y = Ints('x y')
6260 >>> g.add(x == 0, y > x)
6261 >>> g.size()
6262 2
6263 """
6264 return int(Z3_goal_size(self.ctx.ref(), self.goal))
6265
6266 def __len__(self):
6267 """Return the number of constraints in the goal `self`.
6268
6269 >>> g = Goal()
6270 >>> len(g)
6271 0
6272 >>> x, y = Ints('x y')
6273 >>> g.add(x == 0, y > x)
6274 >>> len(g)
6275 2
6276 """
6277 return self.size()
6278
6279 def get(self, i):
6280 """Return a constraint in the goal `self`.
6281
6282 >>> g = Goal()
6283 >>> x, y = Ints('x y')
6284 >>> g.add(x == 0, y > x)
6285 >>> g.get(0)
6286 x == 0
6287 >>> g.get(1)
6288 y > x
6289 """
6290 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
6291
6292 def __getitem__(self, arg):
6293 """Return a constraint in the goal `self`.
6294
6295 >>> g = Goal()
6296 >>> x, y = Ints('x y')
6297 >>> g.add(x == 0, y > x)
6298 >>> g[0]
6299 x == 0
6300 >>> g[1]
6301 y > x
6302 """
6303 if arg < 0:
6304 arg += len(self)
6305 if arg < 0 or arg >= len(self):
6306 raise IndexError
6307 return self.get(arg)
6308
6309 def assert_exprs(self, *args):
6310 """Assert constraints into the goal.
6311
6312 >>> x = Int('x')
6313 >>> g = Goal()
6314 >>> g.assert_exprs(x > 0, x < 2)
6315 >>> g
6316 [x > 0, x < 2]
6317 """
6318 args = _get_args(args)
6319 s = BoolSort(self.ctx)
6320 for arg in args:
6321 arg = s.cast(arg)
6322 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
6323
6324 def append(self, *args):
6325 """Add constraints.
6326
6327 >>> x = Int('x')
6328 >>> g = Goal()
6329 >>> g.append(x > 0, x < 2)
6330 >>> g
6331 [x > 0, x < 2]
6332 """
6333 self.assert_exprs(*args)
6334
6335 def insert(self, *args):
6336 """Add constraints.
6337
6338 >>> x = Int('x')
6339 >>> g = Goal()
6340 >>> g.insert(x > 0, x < 2)
6341 >>> g
6342 [x > 0, x < 2]
6343 """
6344 self.assert_exprs(*args)
6345
6346 def add(self, *args):
6347 """Add constraints.
6348
6349 >>> x = Int('x')
6350 >>> g = Goal()
6351 >>> g.add(x > 0, x < 2)
6352 >>> g
6353 [x > 0, x < 2]
6354 """
6355 self.assert_exprs(*args)
6356
6357 def convert_model(self, model):
6358 """Retrieve model from a satisfiable goal
6359 >>> a, b = Ints('a b')
6360 >>> g = Goal()
6361 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
6362 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
6363 >>> r = t(g)
6364 >>> r[0]
6365 [Or(b == 0, b == 1), Not(0 <= b)]
6366 >>> r[1]
6367 [Or(b == 0, b == 1), Not(1 <= b)]
6368 >>> # Remark: the subgoal r[0] is unsatisfiable
6369 >>> # Creating a solver for solving the second subgoal
6370 >>> s = Solver()
6371 >>> s.add(r[1])
6372 >>> s.check()
6373 sat
6374 >>> s.model()
6375 [b = 0]
6376 >>> # Model s.model() does not assign a value to `a`
6377 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
6378 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
6379 >>> r[1].convert_model(s.model())
6380 [b = 0, a = 1]
6381 """
6382 if z3_debug():
6383 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
6384 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
6385
6386 def __repr__(self):
6387 return obj_to_string(self)
6388
6389 def sexpr(self):
6390 """Return a textual representation of the s-expression representing the goal."""
6391 return Z3_goal_to_string(self.ctx.ref(), self.goal)
6392
6393 def dimacs(self, include_names=True):
6394 """Return a textual representation of the goal in DIMACS format."""
6395 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
6396
6397 def translate(self, target):
6398 """Copy goal `self` to context `target`.
6399
6400 >>> x = Int('x')
6401 >>> g = Goal()
6402 >>> g.add(x > 10)
6403 >>> g
6404 [x > 10]
6405 >>> c2 = Context()
6406 >>> g2 = g.translate(c2)
6407 >>> g2
6408 [x > 10]
6409 >>> g.ctx == main_ctx()
6410 True
6411 >>> g2.ctx == c2
6412 True
6413 >>> g2.ctx == main_ctx()
6414 False
6415 """
6416 if z3_debug():
6417 _z3_assert(isinstance(target, Context), "target must be a context")
6418 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
6419
6420 def __copy__(self):
6421 return self.translate(self.ctx)
6422
6423 def __deepcopy__(self, memo={}):
6424 return self.translate(self.ctx)
6425
6426 def simplify(self, *arguments, **keywords):
6427 """Return a new simplified goal.
6428
6429 This method is essentially invoking the simplify tactic.
6430
6431 >>> g = Goal()
6432 >>> x = Int('x')
6433 >>> g.add(x + 1 >= 2)
6434 >>> g
6435 [x + 1 >= 2]
6436 >>> g2 = g.simplify()
6437 >>> g2
6438 [x >= 1]
6439 >>> # g was not modified
6440 >>> g
6441 [x + 1 >= 2]
6442 """
6443 t = Tactic("simplify")
6444 return t.apply(self, *arguments, **keywords)[0]
6445
6446 def as_expr(self):
6447 """Return goal `self` as a single Z3 expression.
6448
6449 >>> x = Int('x')
6450 >>> g = Goal()
6451 >>> g.as_expr()
6452 True
6453 >>> g.add(x > 1)
6454 >>> g.as_expr()
6455 x > 1
6456 >>> g.add(x < 10)
6457 >>> g.as_expr()
6458 And(x > 1, x < 10)
6459 """
6460 sz = len(self)
6461 if sz == 0:
6462 return BoolVal(True, self.ctx)
6463 elif sz == 1:
6464 return self.get(0)
6465 else:
6466 return And([self.get(i) for i in range(len(self))], self.ctx)
6467
6468
6473
6474
6476 """A collection (vector) of ASTs."""
6477
6478 def __init__(self, v=None, ctx=None):
6479 self.vector = None
6480 if v is None:
6481 self.ctx = _get_ctx(ctx)
6482 self.vector = Z3_mk_ast_vector(self.ctx.ref())
6483 else:
6484 self.vector = v
6485 assert ctx is not None
6486 self.ctx = ctx
6487 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
6488
6489 def __del__(self):
6490 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
6491 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
6492
6493 def __len__(self):
6494 """Return the size of the vector `self`.
6495
6496 >>> A = AstVector()
6497 >>> len(A)
6498 0
6499 >>> A.push(Int('x'))
6500 >>> A.push(Int('x'))
6501 >>> len(A)
6502 2
6503 """
6504 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
6505
6506 def __getitem__(self, i):
6507 """Return the AST at position `i`.
6508
6509 >>> A = AstVector()
6510 >>> A.push(Int('x') + 1)
6511 >>> A.push(Int('y'))
6512 >>> A[0]
6513 x + 1
6514 >>> A[1]
6515 y
6516 """
6517
6518 if isinstance(i, int):
6519 if i < 0:
6520 i += self.__len__()
6521
6522 if i >= self.__len__():
6523 raise IndexError
6524 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
6525
6526 elif isinstance(i, slice):
6527 result = []
6528 for ii in range(*i.indices(self.__len__())):
6529 result.append(_to_ast_ref(
6530 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6531 self.ctx,
6532 ))
6533 return result
6534
6535 def __setitem__(self, i, v):
6536 """Update AST at position `i`.
6537
6538 >>> A = AstVector()
6539 >>> A.push(Int('x') + 1)
6540 >>> A.push(Int('y'))
6541 >>> A[0]
6542 x + 1
6543 >>> A[0] = Int('x')
6544 >>> A[0]
6545 x
6546 """
6547 if i < 0:
6548 i += self.__len__()
6549 if i < 0 or i >= self.__len__():
6550 raise IndexError
6551 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6552
6553 def push(self, v):
6554 """Add `v` in the end of the vector.
6555
6556 >>> A = AstVector()
6557 >>> len(A)
6558 0
6559 >>> A.push(Int('x'))
6560 >>> len(A)
6561 1
6562 """
6563 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6564
6565 def resize(self, sz):
6566 """Resize the vector to `sz` elements.
6567
6568 >>> A = AstVector()
6569 >>> A.resize(10)
6570 >>> len(A)
6571 10
6572 >>> for i in range(10): A[i] = Int('x')
6573 >>> A[5]
6574 x
6575 """
6576 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6577
6578 def __contains__(self, item):
6579 """Return `True` if the vector contains `item`.
6580
6581 >>> x = Int('x')
6582 >>> A = AstVector()
6583 >>> x in A
6584 False
6585 >>> A.push(x)
6586 >>> x in A
6587 True
6588 >>> (x+1) in A
6589 False
6590 >>> A.push(x+1)
6591 >>> (x+1) in A
6592 True
6593 >>> A
6594 [x, x + 1]
6595 """
6596 for elem in self:
6597 if elem.eq(item):
6598 return True
6599 return False
6600
6601 def translate(self, other_ctx):
6602 """Copy vector `self` to context `other_ctx`.
6603
6604 >>> x = Int('x')
6605 >>> A = AstVector()
6606 >>> A.push(x)
6607 >>> c2 = Context()
6608 >>> B = A.translate(c2)
6609 >>> B
6610 [x]
6611 """
6612 return AstVector(
6613 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6614 ctx=other_ctx,
6615 )
6616
6617 def __copy__(self):
6618 return self.translate(self.ctx)
6619
6620 def __deepcopy__(self, memo={}):
6621 return self.translate(self.ctx)
6622
6623 def __repr__(self):
6624 return obj_to_string(self)
6625
6626 def sexpr(self):
6627 """Return a textual representation of the s-expression representing the vector."""
6628 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6629
6630
6635
6636
6638 """A mapping from ASTs to ASTs."""
6639
6640 def __init__(self, m=None, ctx=None):
6641 self.map = None
6642 if m is None:
6643 self.ctx = _get_ctx(ctx)
6644 self.map = Z3_mk_ast_map(self.ctx.ref())
6645 else:
6646 self.map = m
6647 assert ctx is not None
6648 self.ctx = ctx
6649 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6650
6651 def __deepcopy__(self, memo={}):
6652 return AstMap(self.map, self.ctx)
6653
6654 def __del__(self):
6655 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6656 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6657
6658 def __len__(self):
6659 """Return the size of the map.
6660
6661 >>> M = AstMap()
6662 >>> len(M)
6663 0
6664 >>> x = Int('x')
6665 >>> M[x] = IntVal(1)
6666 >>> len(M)
6667 1
6668 """
6669 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6670
6671 def __contains__(self, key):
6672 """Return `True` if the map contains key `key`.
6673
6674 >>> M = AstMap()
6675 >>> x = Int('x')
6676 >>> M[x] = x + 1
6677 >>> x in M
6678 True
6679 >>> x+1 in M
6680 False
6681 """
6682 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6683
6684 def __getitem__(self, key):
6685 """Retrieve the value associated with key `key`.
6686
6687 >>> M = AstMap()
6688 >>> x = Int('x')
6689 >>> M[x] = x + 1
6690 >>> M[x]
6691 x + 1
6692 """
6693 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6694
6695 def __setitem__(self, k, v):
6696 """Add/Update key `k` with value `v`.
6697
6698 >>> M = AstMap()
6699 >>> x = Int('x')
6700 >>> M[x] = x + 1
6701 >>> len(M)
6702 1
6703 >>> M[x]
6704 x + 1
6705 >>> M[x] = IntVal(1)
6706 >>> M[x]
6707 1
6708 """
6709 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6710
6711 def __repr__(self):
6712 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6713
6714 def erase(self, k):
6715 """Remove the entry associated with key `k`.
6716
6717 >>> M = AstMap()
6718 >>> x = Int('x')
6719 >>> M[x] = x + 1
6720 >>> len(M)
6721 1
6722 >>> M.erase(x)
6723 >>> len(M)
6724 0
6725 """
6726 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6727
6728 def reset(self):
6729 """Remove all entries from the map.
6730
6731 >>> M = AstMap()
6732 >>> x = Int('x')
6733 >>> M[x] = x + 1
6734 >>> M[x+x] = IntVal(1)
6735 >>> len(M)
6736 2
6737 >>> M.reset()
6738 >>> len(M)
6739 0
6740 """
6741 Z3_ast_map_reset(self.ctx.ref(), self.map)
6742
6743 def keys(self):
6744 """Return an AstVector containing all keys in the map.
6745
6746 >>> M = AstMap()
6747 >>> x = Int('x')
6748 >>> M[x] = x + 1
6749 >>> M[x+x] = IntVal(1)
6750 >>> M.keys()
6751 [x + x, x]
6752 """
6753 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6754
6755
6760
6761
6763 """Store the value of the interpretation of a function in a particular point."""
6764
6765 def __init__(self, entry, ctx):
6766 self.entry = entry
6767 self.ctx = ctx
6768 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6769
6770 def __deepcopy__(self, memo={}):
6771 return FuncEntry(self.entry, self.ctx)
6772
6773 def __del__(self):
6774 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6775 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6776
6777 def num_args(self):
6778 """Return the number of arguments in the given entry.
6779
6780 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6781 >>> s = Solver()
6782 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6783 >>> s.check()
6784 sat
6785 >>> m = s.model()
6786 >>> f_i = m[f]
6787 >>> f_i.num_entries()
6788 1
6789 >>> e = f_i.entry(0)
6790 >>> e.num_args()
6791 2
6792 """
6793 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6794
6795 def arg_value(self, idx):
6796 """Return the value of argument `idx`.
6797
6798 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6799 >>> s = Solver()
6800 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6801 >>> s.check()
6802 sat
6803 >>> m = s.model()
6804 >>> f_i = m[f]
6805 >>> f_i.num_entries()
6806 1
6807 >>> e = f_i.entry(0)
6808 >>> e
6809 [1, 2, 20]
6810 >>> e.num_args()
6811 2
6812 >>> e.arg_value(0)
6813 1
6814 >>> e.arg_value(1)
6815 2
6816 >>> try:
6817 ... e.arg_value(2)
6818 ... except IndexError:
6819 ... print("index error")
6820 index error
6821 """
6822 if idx >= self.num_args():
6823 raise IndexError
6824 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6825
6826 def value(self):
6827 """Return the value of the function at point `self`.
6828
6829 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6830 >>> s = Solver()
6831 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6832 >>> s.check()
6833 sat
6834 >>> m = s.model()
6835 >>> f_i = m[f]
6836 >>> f_i.num_entries()
6837 1
6838 >>> e = f_i.entry(0)
6839 >>> e
6840 [1, 2, 20]
6841 >>> e.num_args()
6842 2
6843 >>> e.value()
6844 20
6845 """
6846 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6847
6848 def as_list(self):
6849 """Return entry `self` as a Python list.
6850 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6851 >>> s = Solver()
6852 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6853 >>> s.check()
6854 sat
6855 >>> m = s.model()
6856 >>> f_i = m[f]
6857 >>> f_i.num_entries()
6858 1
6859 >>> e = f_i.entry(0)
6860 >>> e.as_list()
6861 [1, 2, 20]
6862 """
6863 args = [self.arg_value(i) for i in range(self.num_args())]
6864 args.append(self.value())
6865 return args
6866
6867 def __repr__(self):
6868 return repr(self.as_list())
6869
6870
6872 """Stores the interpretation of a function in a Z3 model."""
6873
6874 def __init__(self, f, ctx):
6875 self.f = f
6876 self.ctx = ctx
6877 if self.f is not None:
6878 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6879
6880 def __del__(self):
6881 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6882 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6883
6884 def else_value(self):
6885 """
6886 Return the `else` value for a function interpretation.
6887 Return None if Z3 did not specify the `else` value for
6888 this object.
6889
6890 >>> f = Function('f', IntSort(), IntSort())
6891 >>> s = Solver()
6892 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6893 >>> s.check()
6894 sat
6895 >>> m = s.model()
6896 >>> m[f]
6897 [2 -> 0, else -> 1]
6898 >>> m[f].else_value()
6899 1
6900 """
6901 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6902 if r:
6903 return _to_expr_ref(r, self.ctx)
6904 else:
6905 return None
6906
6907 def num_entries(self):
6908 """Return the number of entries/points in the function interpretation `self`.
6909
6910 >>> f = Function('f', IntSort(), IntSort())
6911 >>> s = Solver()
6912 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6913 >>> s.check()
6914 sat
6915 >>> m = s.model()
6916 >>> m[f]
6917 [2 -> 0, else -> 1]
6918 >>> m[f].num_entries()
6919 1
6920 """
6921 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6922
6923 def arity(self):
6924 """Return the number of arguments for each entry in the function interpretation `self`.
6925
6926 >>> f = Function('f', IntSort(), IntSort())
6927 >>> s = Solver()
6928 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6929 >>> s.check()
6930 sat
6931 >>> m = s.model()
6932 >>> m[f].arity()
6933 1
6934 """
6935 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6936
6937 def entry(self, idx):
6938 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6939
6940 >>> f = Function('f', IntSort(), IntSort())
6941 >>> s = Solver()
6942 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6943 >>> s.check()
6944 sat
6945 >>> m = s.model()
6946 >>> m[f]
6947 [2 -> 0, else -> 1]
6948 >>> m[f].num_entries()
6949 1
6950 >>> m[f].entry(0)
6951 [2, 0]
6952 """
6953 if idx >= self.num_entries():
6954 raise IndexError
6955 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6956
6957 def translate(self, other_ctx):
6958 """Copy model 'self' to context 'other_ctx'.
6959 """
6960 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6961
6962 def __copy__(self):
6963 return self.translate(self.ctx)
6964
6965 def __deepcopy__(self, memo={}):
6966 return self.translate(self.ctx)
6967
6968 def as_list(self):
6969 """Return the function interpretation as a Python list.
6970 >>> f = Function('f', IntSort(), IntSort())
6971 >>> s = Solver()
6972 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6973 >>> s.check()
6974 sat
6975 >>> m = s.model()
6976 >>> m[f]
6977 [2 -> 0, else -> 1]
6978 >>> m[f].as_list()
6979 [[2, 0], 1]
6980 """
6981 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6982 r.append(self.else_value())
6983 return r
6984
6985 def __repr__(self):
6986 return obj_to_string(self)
6987
6988
6990 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6991
6992 def __init__(self, m, ctx):
6993 assert ctx is not None
6994 self.model = m
6995 self.ctx = ctx
6996 Z3_model_inc_ref(self.ctx.ref(), self.model)
6997
6998 def __del__(self):
6999 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
7000 Z3_model_dec_ref(self.ctx.ref(), self.model)
7001
7002 def __repr__(self):
7003 return obj_to_string(self)
7004
7005 def sexpr(self):
7006 """Return a textual representation of the s-expression representing the model."""
7007 return Z3_model_to_string(self.ctx.ref(), self.model)
7008
7009 def eval(self, t, model_completion=False):
7010 """Evaluate the expression `t` in the model `self`.
7011 If `model_completion` is enabled, then a default interpretation is automatically added
7012 for symbols that do not have an interpretation in the model `self`.
7013
7014 >>> x = Int('x')
7015 >>> s = Solver()
7016 >>> s.add(x > 0, x < 2)
7017 >>> s.check()
7018 sat
7019 >>> m = s.model()
7020 >>> m.eval(x + 1)
7021 2
7022 >>> m.eval(x == 1)
7023 True
7024 >>> y = Int('y')
7025 >>> m.eval(y + x)
7026 1 + y
7027 >>> m.eval(y)
7028 y
7029 >>> m.eval(y, model_completion=True)
7030 0
7031 >>> # Now, m contains an interpretation for y
7032 >>> m.eval(y + x)
7033 1
7034 """
7035 r = (Ast * 1)()
7036 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
7037 return _to_expr_ref(r[0], self.ctx)
7038 raise Z3Exception("failed to evaluate expression in the model")
7039
7040 def evaluate(self, t, model_completion=False):
7041 """Alias for `eval`.
7042
7043 >>> x = Int('x')
7044 >>> s = Solver()
7045 >>> s.add(x > 0, x < 2)
7046 >>> s.check()
7047 sat
7048 >>> m = s.model()
7049 >>> m.evaluate(x + 1)
7050 2
7051 >>> m.evaluate(x == 1)
7052 True
7053 >>> y = Int('y')
7054 >>> m.evaluate(y + x)
7055 1 + y
7056 >>> m.evaluate(y)
7057 y
7058 >>> m.evaluate(y, model_completion=True)
7059 0
7060 >>> # Now, m contains an interpretation for y
7061 >>> m.evaluate(y + x)
7062 1
7063 """
7064 return self.eval(t, model_completion)
7065
7066 def __len__(self):
7067 """Return the number of constant and function declarations in the model `self`.
7068
7069 >>> f = Function('f', IntSort(), IntSort())
7070 >>> x = Int('x')
7071 >>> s = Solver()
7072 >>> s.add(x > 0, f(x) != x)
7073 >>> s.check()
7074 sat
7075 >>> m = s.model()
7076 >>> len(m)
7077 2
7078 """
7079 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
7080 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
7081 return num_consts + num_funcs
7082
7083 def get_interp(self, decl):
7084 """Return the interpretation for a given declaration or constant.
7085
7086 >>> f = Function('f', IntSort(), IntSort())
7087 >>> x = Int('x')
7088 >>> s = Solver()
7089 >>> s.add(x > 0, x < 2, f(x) == 0)
7090 >>> s.check()
7091 sat
7092 >>> m = s.model()
7093 >>> m[x]
7094 1
7095 >>> m[f]
7096 [else -> 0]
7097 """
7098 if z3_debug():
7099 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
7100 if is_const(decl):
7101 decl = decl.decl()
7102 try:
7103 if decl.arity() == 0:
7104 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
7105 if _r.value is None:
7106 return None
7107 r = _to_expr_ref(_r, self.ctx)
7108 if is_as_array(r):
7109 fi = self.get_interp(get_as_array_func(r))
7110 if fi is None:
7111 return fi
7112 e = fi.else_value()
7113 if e is None:
7114 return fi
7115 if fi.arity() != 1:
7116 return fi
7117 srt = decl.range()
7118 dom = srt.domain()
7119 e = K(dom, e)
7120 i = 0
7121 sz = fi.num_entries()
7122 n = fi.arity()
7123 while i < sz:
7124 fe = fi.entry(i)
7125 e = Store(e, fe.arg_value(0), fe.value())
7126 i += 1
7127 return e
7128 else:
7129 return r
7130 else:
7131 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
7132 except Z3Exception:
7133 return None
7134
7135 def num_sorts(self):
7136 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
7137
7138 >>> A = DeclareSort('A')
7139 >>> a, b = Consts('a b', A)
7140 >>> s = Solver()
7141 >>> s.add(a != b)
7142 >>> s.check()
7143 sat
7144 >>> m = s.model()
7145 >>> m.num_sorts()
7146 1
7147 """
7148 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
7149
7150 def get_sort(self, idx):
7151 """Return the uninterpreted sort at position `idx` < self.num_sorts().
7152
7153 >>> A = DeclareSort('A')
7154 >>> B = DeclareSort('B')
7155 >>> a1, a2 = Consts('a1 a2', A)
7156 >>> b1, b2 = Consts('b1 b2', B)
7157 >>> s = Solver()
7158 >>> s.add(a1 != a2, b1 != b2)
7159 >>> s.check()
7160 sat
7161 >>> m = s.model()
7162 >>> m.num_sorts()
7163 2
7164 >>> m.get_sort(0)
7165 A
7166 >>> m.get_sort(1)
7167 B
7168 """
7169 if idx >= self.num_sorts():
7170 raise IndexError
7171 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
7172
7173 def sorts(self):
7174 """Return all uninterpreted sorts that have an interpretation in the model `self`.
7175
7176 >>> A = DeclareSort('A')
7177 >>> B = DeclareSort('B')
7178 >>> a1, a2 = Consts('a1 a2', A)
7179 >>> b1, b2 = Consts('b1 b2', B)
7180 >>> s = Solver()
7181 >>> s.add(a1 != a2, b1 != b2)
7182 >>> s.check()
7183 sat
7184 >>> m = s.model()
7185 >>> m.sorts()
7186 [A, B]
7187 """
7188 return [self.get_sort(i) for i in range(self.num_sorts())]
7189
7190 def get_universe(self, s):
7191 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
7192
7193 >>> A = DeclareSort('A')
7194 >>> a, b = Consts('a b', A)
7195 >>> s = Solver()
7196 >>> s.add(a != b)
7197 >>> s.check()
7198 sat
7199 >>> m = s.model()
7200 >>> m.get_universe(A)
7201 [A!val!0, A!val!1]
7202 """
7203 if z3_debug():
7204 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
7205 try:
7206 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
7207 except Z3Exception:
7208 return None
7209
7210 def __getitem__(self, idx):
7211 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
7212 If `idx` is a declaration, then the actual interpretation is returned.
7213
7214 The elements can be retrieved using position or the actual declaration.
7215
7216 >>> f = Function('f', IntSort(), IntSort())
7217 >>> x = Int('x')
7218 >>> s = Solver()
7219 >>> s.add(x > 0, x < 2, f(x) == 0)
7220 >>> s.check()
7221 sat
7222 >>> m = s.model()
7223 >>> len(m)
7224 2
7225 >>> m[0]
7226 x
7227 >>> m[1]
7228 f
7229 >>> m[x]
7230 1
7231 >>> m[f]
7232 [else -> 0]
7233 >>> for d in m: print("%s -> %s" % (d, m[d]))
7234 x -> 1
7235 f -> [else -> 0]
7236 """
7237 if _is_int(idx):
7238 if idx < 0:
7239 idx += len(self)
7240 if idx < 0 or idx >= len(self):
7241 raise IndexError
7242 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
7243 if (idx < num_consts):
7244 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
7245 else:
7246 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
7247 if isinstance(idx, FuncDeclRef):
7248 return self.get_interp(idx)
7249 if is_const(idx):
7250 return self.get_interp(idx.decl())
7251 if isinstance(idx, SortRef):
7252 return self.get_universe(idx)
7253 if z3_debug():
7254 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected. Use model.eval instead for complicated expressions")
7255 return None
7256
7257 def decls(self):
7258 """Return a list with all symbols that have an interpretation in the model `self`.
7259 >>> f = Function('f', IntSort(), IntSort())
7260 >>> x = Int('x')
7261 >>> s = Solver()
7262 >>> s.add(x > 0, x < 2, f(x) == 0)
7263 >>> s.check()
7264 sat
7265 >>> m = s.model()
7266 >>> m.decls()
7267 [x, f]
7268 """
7269 r = []
7270 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
7271 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
7272 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
7273 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
7274 return r
7275
7276 def update_value(self, x, value):
7277 """Update the interpretation of a constant"""
7278 if is_expr(x):
7279 x = x.decl()
7280 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
7281 fi1 = value.f
7282 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
7283 fi2 = FuncInterp(fi2, x.ctx)
7284 for i in range(value.num_entries()):
7285 e = value.entry(i)
7286 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
7287 v = AstVector()
7288 for j in range(n):
7289 v.push(e.arg_value(j))
7290 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
7291 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
7292 return
7293 if not is_func_decl(x) or x.arity() != 0:
7294 raise Z3Exception("Expecting 0-ary function or constant expression")
7295 value = _py2expr(value)
7296 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
7297
7298 def translate(self, target):
7299 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7300 """
7301 if z3_debug():
7302 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7303 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
7304 return ModelRef(model, target)
7305
7306 def project(self, vars, fml):
7307 """Perform model-based projection on fml with respect to vars.
7308 Assume that the model satisfies fml. Then compute a projection fml_p, such
7309 that vars do not occur free in fml_p, fml_p is true in the model and
7310 fml_p => exists vars . fml
7311 """
7312 ctx = self.ctx.ref()
7313 _vars = (Ast * len(vars))()
7314 for i in range(len(vars)):
7315 _vars[i] = vars[i].as_ast()
7316 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
7317
7318 def project_with_witness(self, vars, fml):
7319 """Perform model-based projection, but also include realizer terms for the projected variables"""
7320 ctx = self.ctx.ref()
7321 _vars = (Ast * len(vars))()
7322 for i in range(len(vars)):
7323 _vars[i] = vars[i].as_ast()
7324 defs = AstMap()
7325 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
7326 result = _to_expr_ref(result, self.ctx)
7327 return result, defs
7328
7329
7330 def __copy__(self):
7331 return self.translate(self.ctx)
7332
7333 def __deepcopy__(self, memo={}):
7334 return self.translate(self.ctx)
7335
7336
7337def Model(ctx=None, eval = {}):
7338 ctx = _get_ctx(ctx)
7339 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
7340 for k, v in eval.items():
7341 mdl.update_value(k, v)
7342 return mdl
7343
7344
7346 """Return true if n is a Z3 expression of the form (_ as-array f)."""
7347 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
7348
7349
7351 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
7352 if z3_debug():
7353 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
7354 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
7355
7356
7361
7362
7364 """Statistics for `Solver.check()`."""
7365
7366 def __init__(self, stats, ctx):
7367 self.stats = stats
7368 self.ctx = ctx
7369 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
7370
7371 def __deepcopy__(self, memo={}):
7372 return Statistics(self.stats, self.ctx)
7373
7374 def __del__(self):
7375 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
7376 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
7377
7378 def __repr__(self):
7379 if in_html_mode():
7380 out = io.StringIO()
7381 even = True
7382 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
7383 for k, v in self:
7384 if even:
7385 out.write(u('<tr style="background-color:#CFCFCF">'))
7386 even = False
7387 else:
7388 out.write(u("<tr>"))
7389 even = True
7390 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
7391 out.write(u("</table>"))
7392 return out.getvalue()
7393 else:
7394 return Z3_stats_to_string(self.ctx.ref(), self.stats)
7395
7396 def __len__(self):
7397 """Return the number of statistical counters.
7398
7399 >>> x = Int('x')
7400 >>> s = Then('simplify', 'nlsat').solver()
7401 >>> s.add(x > 0)
7402 >>> s.check()
7403 sat
7404 >>> st = s.statistics()
7405 >>> len(st) > 0
7406 True
7407 """
7408 return int(Z3_stats_size(self.ctx.ref(), self.stats))
7409
7410 def __getitem__(self, idx):
7411 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
7412
7413 >>> x = Int('x')
7414 >>> s = Then('simplify', 'nlsat').solver()
7415 >>> s.add(x > 0)
7416 >>> s.check()
7417 sat
7418 >>> st = s.statistics()
7419 >>> len(st) > 0
7420 True
7421 >>> st[0]
7422 ('nlsat propagations', 2)
7423 >>> st[1]
7424 ('nlsat restarts', 1)
7425 """
7426 if idx >= len(self):
7427 raise IndexError
7428 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7429 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7430 else:
7431 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7432 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
7433
7434 def keys(self):
7435 """Return the list of statistical counters.
7436
7437 >>> x = Int('x')
7438 >>> s = Then('simplify', 'nlsat').solver()
7439 >>> s.add(x > 0)
7440 >>> s.check()
7441 sat
7442 >>> st = s.statistics()
7443 """
7444 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
7445
7446 def get_key_value(self, key):
7447 """Return the value of a particular statistical counter.
7448
7449 >>> x = Int('x')
7450 >>> s = Then('simplify', 'nlsat').solver()
7451 >>> s.add(x > 0)
7452 >>> s.check()
7453 sat
7454 >>> st = s.statistics()
7455 >>> st.get_key_value('nlsat propagations')
7456 2
7457 """
7458 for idx in range(len(self)):
7459 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
7460 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7461 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7462 else:
7463 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7464 raise Z3Exception("unknown key")
7465
7466 def __getattr__(self, name):
7467 """Access the value of statistical using attributes.
7468
7469 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
7470 we should use '_' (e.g., 'nlsat_propagations').
7471
7472 >>> x = Int('x')
7473 >>> s = Then('simplify', 'nlsat').solver()
7474 >>> s.add(x > 0)
7475 >>> s.check()
7476 sat
7477 >>> st = s.statistics()
7478 >>> st.nlsat_propagations
7479 2
7480 >>> st.nlsat_stages
7481 2
7482 """
7483 key = name.replace("_", " ")
7484 try:
7485 return self.get_key_value(key)
7486 except Z3Exception:
7487 raise AttributeError
7488
7489
7494
7495
7497 """Represents the result of a satisfiability check: sat, unsat, unknown.
7498
7499 >>> s = Solver()
7500 >>> s.check()
7501 sat
7502 >>> r = s.check()
7503 >>> isinstance(r, CheckSatResult)
7504 True
7505 """
7506
7507 def __init__(self, r):
7508 self.r = r
7509
7510 def __deepcopy__(self, memo={}):
7511 return CheckSatResult(self.r)
7512
7513 def __eq__(self, other):
7514 return isinstance(other, CheckSatResult) and self.r == other.r
7515
7516 def __ne__(self, other):
7517 return not self.__eq__(other)
7518
7519 def __repr__(self):
7520 if in_html_mode():
7521 if self.r == Z3_L_TRUE:
7522 return "<b>sat</b>"
7523 elif self.r == Z3_L_FALSE:
7524 return "<b>unsat</b>"
7525 else:
7526 return "<b>unknown</b>"
7527 else:
7528 if self.r == Z3_L_TRUE:
7529 return "sat"
7530 elif self.r == Z3_L_FALSE:
7531 return "unsat"
7532 else:
7533 return "unknown"
7534
7535 def _repr_html_(self):
7536 in_html = in_html_mode()
7537 set_html_mode(True)
7538 res = repr(self)
7539 set_html_mode(in_html)
7540 return res
7541
7542
7543sat = CheckSatResult(Z3_L_TRUE)
7544unsat = CheckSatResult(Z3_L_FALSE)
7545unknown = CheckSatResult(Z3_L_UNDEF)
7546
7547
7549 """
7550 Solver API provides methods for implementing the main SMT 2.0 commands:
7551 push, pop, check, get-model, etc.
7552 """
7553
7554 def __init__(self, solver=None, ctx=None, logFile=None):
7555 assert solver is None or ctx is not None
7556 self.ctx = _get_ctx(ctx)
7557 self.backtrack_level = 4000000000
7558 self.solver = None
7559 if solver is None:
7560 self.solver = Z3_mk_solver(self.ctx.ref())
7561 else:
7562 self.solver = solver
7563 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7564 if logFile is not None:
7565 self.set("smtlib2_log", logFile)
7566
7567 def __del__(self):
7568 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7569 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7570
7571 def __enter__(self):
7572 self.push()
7573 return self
7574
7575 def __exit__(self, *exc_info):
7576 self.pop()
7577
7578 def set(self, *args, **keys):
7579 """Set a configuration option.
7580 The method `help()` return a string containing all available options.
7581
7582 >>> s = Solver()
7583 >>> # The option MBQI can be set using three different approaches.
7584 >>> s.set(mbqi=True)
7585 >>> s.set('MBQI', True)
7586 >>> s.set(':mbqi', True)
7587 """
7588 p = args2params(args, keys, self.ctx)
7589 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7590
7591 def push(self):
7592 """Create a backtracking point.
7593
7594 >>> x = Int('x')
7595 >>> s = Solver()
7596 >>> s.add(x > 0)
7597 >>> s
7598 [x > 0]
7599 >>> s.push()
7600 >>> s.add(x < 1)
7601 >>> s
7602 [x > 0, x < 1]
7603 >>> s.check()
7604 unsat
7605 >>> s.pop()
7606 >>> s.check()
7607 sat
7608 >>> s
7609 [x > 0]
7610 """
7611 Z3_solver_push(self.ctx.ref(), self.solver)
7612
7613 def pop(self, num=1):
7614 """Backtrack \\c num backtracking points.
7615
7616 >>> x = Int('x')
7617 >>> s = Solver()
7618 >>> s.add(x > 0)
7619 >>> s
7620 [x > 0]
7621 >>> s.push()
7622 >>> s.add(x < 1)
7623 >>> s
7624 [x > 0, x < 1]
7625 >>> s.check()
7626 unsat
7627 >>> s.pop()
7628 >>> s.check()
7629 sat
7630 >>> s
7631 [x > 0]
7632 """
7633 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7634
7635 def num_scopes(self):
7636 """Return the current number of backtracking points.
7637
7638 >>> s = Solver()
7639 >>> s.num_scopes()
7640 0
7641 >>> s.push()
7642 >>> s.num_scopes()
7643 1
7644 >>> s.push()
7645 >>> s.num_scopes()
7646 2
7647 >>> s.pop()
7648 >>> s.num_scopes()
7649 1
7650 """
7651 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7652
7653 def reset(self):
7654 """Remove all asserted constraints and backtracking points created using `push()`.
7655
7656 >>> x = Int('x')
7657 >>> s = Solver()
7658 >>> s.add(x > 0)
7659 >>> s
7660 [x > 0]
7661 >>> s.reset()
7662 >>> s
7663 []
7664 """
7665 Z3_solver_reset(self.ctx.ref(), self.solver)
7666
7667 def assert_exprs(self, *args):
7668 """Assert constraints into the solver.
7669
7670 >>> x = Int('x')
7671 >>> s = Solver()
7672 >>> s.assert_exprs(x > 0, x < 2)
7673 >>> s
7674 [x > 0, x < 2]
7675 """
7676 args = _get_args(args)
7677 s = BoolSort(self.ctx)
7678 for arg in args:
7679 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7680 for f in arg:
7681 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7682 else:
7683 arg = s.cast(arg)
7684 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7685
7686 def add(self, *args):
7687 """Assert constraints into the solver.
7688
7689 >>> x = Int('x')
7690 >>> s = Solver()
7691 >>> s.add(x > 0, x < 2)
7692 >>> s
7693 [x > 0, x < 2]
7694 """
7695 self.assert_exprs(*args)
7696
7697 def __iadd__(self, fml):
7698 self.add(fml)
7699 return self
7700
7701 def append(self, *args):
7702 """Assert constraints into the solver.
7703
7704 >>> x = Int('x')
7705 >>> s = Solver()
7706 >>> s.append(x > 0, x < 2)
7707 >>> s
7708 [x > 0, x < 2]
7709 """
7710 self.assert_exprs(*args)
7711
7712 def insert(self, *args):
7713 """Assert constraints into the solver.
7714
7715 >>> x = Int('x')
7716 >>> s = Solver()
7717 >>> s.insert(x > 0, x < 2)
7718 >>> s
7719 [x > 0, x < 2]
7720 """
7721 self.assert_exprs(*args)
7722
7723 def assert_and_track(self, a, p):
7724 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7725
7726 If `p` is a string, it will be automatically converted into a Boolean constant.
7727
7728 >>> x = Int('x')
7729 >>> p3 = Bool('p3')
7730 >>> s = Solver()
7731 >>> s.set(unsat_core=True)
7732 >>> s.assert_and_track(x > 0, 'p1')
7733 >>> s.assert_and_track(x != 1, 'p2')
7734 >>> s.assert_and_track(x < 0, p3)
7735 >>> print(s.check())
7736 unsat
7737 >>> c = s.unsat_core()
7738 >>> len(c)
7739 2
7740 >>> Bool('p1') in c
7741 True
7742 >>> Bool('p2') in c
7743 False
7744 >>> p3 in c
7745 True
7746 """
7747 if isinstance(p, str):
7748 p = Bool(p, self.ctx)
7749 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7750 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7751 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7752
7753 def check(self, *assumptions):
7754 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7755
7756 >>> x = Int('x')
7757 >>> s = Solver()
7758 >>> s.check()
7759 sat
7760 >>> s.add(x > 0, x < 2)
7761 >>> s.check()
7762 sat
7763 >>> s.model().eval(x)
7764 1
7765 >>> s.add(x < 1)
7766 >>> s.check()
7767 unsat
7768 >>> s.reset()
7769 >>> s.add(2**x == 4)
7770 >>> s.check()
7771 sat
7772 """
7773 s = BoolSort(self.ctx)
7774 assumptions = _get_args(assumptions)
7775 num = len(assumptions)
7776 _assumptions = (Ast * num)()
7777 for i in range(num):
7778 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7779 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7780 return CheckSatResult(r)
7781
7782 def model(self):
7783 """Return a model for the last `check()`.
7784
7785 This function raises an exception if
7786 a model is not available (e.g., last `check()` returned unsat).
7787
7788 >>> s = Solver()
7789 >>> a = Int('a')
7790 >>> s.add(a + 2 == 0)
7791 >>> s.check()
7792 sat
7793 >>> s.model()
7794 [a = -2]
7795 """
7796 try:
7797 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7798 except Z3Exception:
7799 raise Z3Exception("model is not available")
7800
7801 def import_model_converter(self, other):
7802 """Import model converter from other into the current solver"""
7803 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7804
7805 def interrupt(self):
7806 """Interrupt the execution of the solver object.
7807 Remarks: This ensures that the interrupt applies only
7808 to the given solver object and it applies only if it is running.
7809 """
7810 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7811
7812 def unsat_core(self):
7813 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7814
7815 These are the assumptions Z3 used in the unsatisfiability proof.
7816 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7817 They may be also used to "retract" assumptions. Note that, assumptions are not really
7818 "soft constraints", but they can be used to implement them.
7819
7820 >>> p1, p2, p3 = Bools('p1 p2 p3')
7821 >>> x, y = Ints('x y')
7822 >>> s = Solver()
7823 >>> s.add(Implies(p1, x > 0))
7824 >>> s.add(Implies(p2, y > x))
7825 >>> s.add(Implies(p2, y < 1))
7826 >>> s.add(Implies(p3, y > -3))
7827 >>> s.check(p1, p2, p3)
7828 unsat
7829 >>> core = s.unsat_core()
7830 >>> len(core)
7831 2
7832 >>> p1 in core
7833 True
7834 >>> p2 in core
7835 True
7836 >>> p3 in core
7837 False
7838 >>> # "Retracting" p2
7839 >>> s.check(p1, p3)
7840 sat
7841 """
7842 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7843
7844 def consequences(self, assumptions, variables):
7845 """Determine fixed values for the variables based on the solver state and assumptions.
7846 >>> s = Solver()
7847 >>> a, b, c, d = Bools('a b c d')
7848 >>> s.add(Implies(a,b), Implies(b, c))
7849 >>> s.consequences([a],[b,c,d])
7850 (sat, [Implies(a, b), Implies(a, c)])
7851 >>> s.consequences([Not(c),d],[a,b,c,d])
7852 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7853 """
7854 if isinstance(assumptions, list):
7855 _asms = AstVector(None, self.ctx)
7856 for a in assumptions:
7857 _asms.push(a)
7858 assumptions = _asms
7859 if isinstance(variables, list):
7860 _vars = AstVector(None, self.ctx)
7861 for a in variables:
7862 _vars.push(a)
7863 variables = _vars
7864 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7865 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7866 consequences = AstVector(None, self.ctx)
7867 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7868 variables.vector, consequences.vector)
7869 sz = len(consequences)
7870 consequences = [consequences[i] for i in range(sz)]
7871 return CheckSatResult(r), consequences
7872
7873 def from_file(self, filename):
7874 """Parse assertions from a file"""
7875 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7876
7877 def from_string(self, s):
7878 """Parse assertions from a string"""
7879 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7880
7881 def cube(self, vars=None):
7882 """Get set of cubes
7883 The method takes an optional set of variables that restrict which
7884 variables may be used as a starting point for cubing.
7885 If vars is not None, then the first case split is based on a variable in
7886 this set.
7887 """
7888 self.cube_vs = AstVector(None, self.ctx)
7889 if vars is not None:
7890 for v in vars:
7891 self.cube_vs.push(v)
7892 while True:
7893 lvl = self.backtrack_level
7894 self.backtrack_level = 4000000000
7895 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7896 if (len(r) == 1 and is_false(r[0])):
7897 return
7898 yield r
7899 if (len(r) == 0):
7900 return
7901
7902 def cube_vars(self):
7903 """Access the set of variables that were touched by the most recently generated cube.
7904 This set of variables can be used as a starting point for additional cubes.
7905 The idea is that variables that appear in clauses that are reduced by the most recent
7906 cube are likely more useful to cube on."""
7907 return self.cube_vs
7908
7909 def congruence_root(self, t):
7910 """Retrieve congruence closure root of the term t relative to the current search state
7911 The function primarily works for SimpleSolver. Terms and variables that are
7912 eliminated during pre-processing are not visible to the congruence closure.
7913 """
7914 t = _py2expr(t, self.ctx)
7915 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7916
7917 def congruence_next(self, t):
7918 """Retrieve congruence closure sibling of the term t relative to the current search state
7919 The function primarily works for SimpleSolver. Terms and variables that are
7920 eliminated during pre-processing are not visible to the congruence closure.
7921 """
7922 t = _py2expr(t, self.ctx)
7923 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7924
7925 def congruence_explain(self, a, b):
7926 """Explain congruence of a and b relative to the current search state"""
7927 a = _py2expr(a, self.ctx)
7928 b = _py2expr(b, self.ctx)
7929 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7930
7931
7932 def solve_for(self, ts):
7933 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7934 vars = AstVector(ctx=self.ctx);
7935 terms = AstVector(ctx=self.ctx);
7936 guards = AstVector(ctx=self.ctx);
7937 for t in ts:
7938 t = _py2expr(t, self.ctx)
7939 vars.push(t)
7940 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7941 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7942
7943
7944 def proof(self):
7945 """Return a proof for the last `check()`. Proof construction must be enabled."""
7946 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7947
7948 def assertions(self):
7949 """Return an AST vector containing all added constraints.
7950
7951 >>> s = Solver()
7952 >>> s.assertions()
7953 []
7954 >>> a = Int('a')
7955 >>> s.add(a > 0)
7956 >>> s.add(a < 10)
7957 >>> s.assertions()
7958 [a > 0, a < 10]
7959 """
7960 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7961
7962 def units(self):
7963 """Return an AST vector containing all currently inferred units.
7964 """
7965 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7966
7967 def non_units(self):
7968 """Return an AST vector containing all atomic formulas in solver state that are not units.
7969 """
7970 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7971
7972 def trail_levels(self):
7973 """Return trail and decision levels of the solver state after a check() call.
7974 """
7975 trail = self.trail()
7976 levels = (ctypes.c_uint * len(trail))()
7977 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7978 return trail, levels
7979
7980 def set_initial_value(self, var, value):
7981 """initialize the solver's state by setting the initial value of var to value
7982 """
7983 s = var.sort()
7984 value = s.cast(value)
7985 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7986
7987 def trail(self):
7988 """Return trail of the solver state after a check() call.
7989 """
7990 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7991
7992 def statistics(self):
7993 """Return statistics for the last `check()`.
7994
7995 >>> s = SimpleSolver()
7996 >>> x = Int('x')
7997 >>> s.add(x > 0)
7998 >>> s.check()
7999 sat
8000 >>> st = s.statistics()
8001 >>> st.get_key_value('final checks')
8002 1
8003 >>> len(st) > 0
8004 True
8005 >>> st[0] != 0
8006 True
8007 """
8008 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
8009
8010 def reason_unknown(self):
8011 """Return a string describing why the last `check()` returned `unknown`.
8012
8013 >>> x = Int('x')
8014 >>> s = SimpleSolver()
8015 >>> s.add(x == 2**x)
8016 >>> s.check()
8017 unknown
8018 >>> s.reason_unknown()
8019 '(incomplete (theory arithmetic))'
8020 """
8021 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
8022
8023 def help(self):
8024 """Display a string describing all available options."""
8025 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
8026
8027 def param_descrs(self):
8028 """Return the parameter description set."""
8029 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
8030
8031 def __repr__(self):
8032 """Return a formatted string with all added constraints."""
8033 return obj_to_string(self)
8034
8035 def translate(self, target):
8036 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
8037
8038 >>> c1 = Context()
8039 >>> c2 = Context()
8040 >>> s1 = Solver(ctx=c1)
8041 >>> s2 = s1.translate(c2)
8042 """
8043 if z3_debug():
8044 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
8045 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
8046 return Solver(solver, target)
8047
8048 def __copy__(self):
8049 return self.translate(self.ctx)
8050
8051 def __deepcopy__(self, memo={}):
8052 return self.translate(self.ctx)
8053
8054 def sexpr(self):
8055 """Return a formatted string (in Lisp-like format) with all added constraints.
8056 """
8057 return Z3_solver_to_string(self.ctx.ref(), self.solver)
8058
8059 def dimacs(self, include_names=True):
8060 """Return a textual representation of the solver in DIMACS format."""
8061 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
8062
8063 def to_smt2(self):
8064 """return SMTLIB2 formatted benchmark for solver's assertions"""
8065 es = self.assertions()
8066 sz = len(es)
8067 sz1 = sz
8068 if sz1 > 0:
8069 sz1 -= 1
8070 v = (Ast * sz1)()
8071 for i in range(sz1):
8072 v[i] = es[i].as_ast()
8073 if sz > 0:
8074 e = es[sz1].as_ast()
8075 else:
8076 e = BoolVal(True, self.ctx).as_ast()
8077 return Z3_benchmark_to_smtlib_string(
8078 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
8079 )
8080
8081 def solutions(self, t):
8082 """Returns an iterator over solutions that satisfy the constraints.
8083
8084 The parameter `t` is an expression whose values should be returned.
8085
8086 >>> s = Solver()
8087 >>> x, y, z = Ints("x y z")
8088 >>> s.add(x * x == 4)
8089 >>> print(list(s.solutions(x)))
8090 [-2, 2]
8091 >>> s.reset()
8092 >>> s.add(x >= 0, x < 10)
8093 >>> print(list(s.solutions(x)))
8094 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8095 >>> s.reset()
8096 >>> s.add(x >= 0, y < 10, y == 2*x)
8097 >>> print(list(s.solutions([x, y])))
8098 [[0, 0], [1, 2], [2, 4], [3, 6], [4, 8]]
8099 """
8100 s = Solver()
8101 s.add(self.assertions())
8102 t = _get_args(t)
8103 if isinstance(t, (list, tuple)):
8104 while s.check() == sat:
8105 result = [s.model().eval(t_, model_completion=True) for t_ in t]
8106 yield result
8107 s.add(Or(t_ != result_ for t_, result_ in zip(t, result)))
8108 else:
8109 while s.check() == sat:
8110 result = s.model().eval(t, model_completion=True)
8111 yield result
8112 s.add(t != result)
8113
8114
8115def SolverFor(logic, ctx=None, logFile=None):
8116 """Create a solver customized for the given logic.
8117
8118 The parameter `logic` is a string. It should be contains
8119 the name of a SMT-LIB logic.
8120 See http://www.smtlib.org/ for the name of all available logics.
8121
8122 >>> s = SolverFor("QF_LIA")
8123 >>> x = Int('x')
8124 >>> s.add(x > 0)
8125 >>> s.add(x < 2)
8126 >>> s.check()
8127 sat
8128 >>> s.model()
8129 [x = 1]
8130 """
8131 ctx = _get_ctx(ctx)
8132 logic = to_symbol(logic)
8133 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
8134
8135
8136def SimpleSolver(ctx=None, logFile=None):
8137 """Return a simple general purpose solver with limited amount of preprocessing.
8138
8139 >>> s = SimpleSolver()
8140 >>> x = Int('x')
8141 >>> s.add(x > 0)
8142 >>> s.check()
8143 sat
8144 """
8145 ctx = _get_ctx(ctx)
8146 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
8147
8148#########################################
8149#
8150# Fixedpoint
8151#
8152#########################################
8153
8154
8155class Fixedpoint(Z3PPObject):
8156 """Fixedpoint API provides methods for solving with recursive predicates"""
8157
8158 def __init__(self, fixedpoint=None, ctx=None):
8159 assert fixedpoint is None or ctx is not None
8160 self.ctx = _get_ctx(ctx)
8161 self.fixedpoint = None
8162 if fixedpoint is None:
8163 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
8164 else:
8165 self.fixedpoint = fixedpoint
8166 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
8167 self.vars = []
8168
8169 def __deepcopy__(self, memo={}):
8170 return FixedPoint(self.fixedpoint, self.ctx)
8171
8172 def __del__(self):
8173 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
8174 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
8175
8176 def set(self, *args, **keys):
8177 """Set a configuration option. The method `help()` return a string containing all available options.
8178 """
8179 p = args2params(args, keys, self.ctx)
8180 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
8181
8182 def help(self):
8183 """Display a string describing all available options."""
8184 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
8185
8186 def param_descrs(self):
8187 """Return the parameter description set."""
8188 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
8189
8190 def assert_exprs(self, *args):
8191 """Assert constraints as background axioms for the fixedpoint solver."""
8192 args = _get_args(args)
8193 s = BoolSort(self.ctx)
8194 for arg in args:
8195 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8196 for f in arg:
8197 f = self.abstract(f)
8198 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
8199 else:
8200 arg = s.cast(arg)
8201 arg = self.abstract(arg)
8202 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
8203
8204 def add(self, *args):
8205 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
8206 self.assert_exprs(*args)
8207
8208 def __iadd__(self, fml):
8209 self.add(fml)
8210 return self
8211
8212 def append(self, *args):
8213 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
8214 self.assert_exprs(*args)
8215
8216 def insert(self, *args):
8217 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
8218 self.assert_exprs(*args)
8219
8220 def add_rule(self, head, body=None, name=None):
8221 """Assert rules defining recursive predicates to the fixedpoint solver.
8222 >>> a = Bool('a')
8223 >>> b = Bool('b')
8224 >>> s = Fixedpoint()
8225 >>> s.register_relation(a.decl())
8226 >>> s.register_relation(b.decl())
8227 >>> s.fact(a)
8228 >>> s.rule(b, a)
8229 >>> s.query(b)
8230 sat
8231 """
8232 if name is None:
8233 name = ""
8234 name = to_symbol(name, self.ctx)
8235 if body is None:
8236 head = self.abstract(head)
8237 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
8238 else:
8239 body = _get_args(body)
8240 f = self.abstract(Implies(And(body, self.ctx), head))
8241 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
8242
8243 def rule(self, head, body=None, name=None):
8244 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
8245 self.add_rule(head, body, name)
8246
8247 def fact(self, head, name=None):
8248 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
8249 self.add_rule(head, None, name)
8250
8251 def query(self, *query):
8252 """Query the fixedpoint engine whether formula is derivable.
8253 You can also pass an tuple or list of recursive predicates.
8254 """
8255 query = _get_args(query)
8256 sz = len(query)
8257 if sz >= 1 and isinstance(query[0], FuncDeclRef):
8258 _decls = (FuncDecl * sz)()
8259 i = 0
8260 for q in query:
8261 _decls[i] = q.ast
8262 i = i + 1
8263 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
8264 else:
8265 if sz == 1:
8266 query = query[0]
8267 else:
8268 query = And(query, self.ctx)
8269 query = self.abstract(query, False)
8270 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
8271 return CheckSatResult(r)
8272
8273 def query_from_lvl(self, lvl, *query):
8274 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
8275 """
8276 query = _get_args(query)
8277 sz = len(query)
8278 if sz >= 1 and isinstance(query[0], FuncDecl):
8279 _z3_assert(False, "unsupported")
8280 else:
8281 if sz == 1:
8282 query = query[0]
8283 else:
8284 query = And(query)
8285 query = self.abstract(query, False)
8286 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
8287 return CheckSatResult(r)
8288
8289 def update_rule(self, head, body, name):
8290 """update rule"""
8291 if name is None:
8292 name = ""
8293 name = to_symbol(name, self.ctx)
8294 body = _get_args(body)
8295 f = self.abstract(Implies(And(body, self.ctx), head))
8296 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
8297
8298 def get_answer(self):
8299 """Retrieve answer from last query call."""
8300 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
8301 return _to_expr_ref(r, self.ctx)
8302
8303 def get_ground_sat_answer(self):
8304 """Retrieve a ground cex from last query call."""
8305 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
8306 return _to_expr_ref(r, self.ctx)
8307
8308 def get_rules_along_trace(self):
8309 """retrieve rules along the counterexample trace"""
8310 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
8311
8312 def get_rule_names_along_trace(self):
8313 """retrieve rule names along the counterexample trace"""
8314 # this is a hack as I don't know how to return a list of symbols from C++;
8315 # obtain names as a single string separated by semicolons
8316 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
8317 # split into individual names
8318 return names.split(";")
8319
8320 def get_num_levels(self, predicate):
8321 """Retrieve number of levels used for predicate in PDR engine"""
8322 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
8323
8324 def get_cover_delta(self, level, predicate):
8325 """Retrieve properties known about predicate for the level'th unfolding.
8326 -1 is treated as the limit (infinity)
8327 """
8328 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
8329 return _to_expr_ref(r, self.ctx)
8330
8331 def add_cover(self, level, predicate, property):
8332 """Add property to predicate for the level'th unfolding.
8333 -1 is treated as infinity (infinity)
8334 """
8335 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
8336
8337 def register_relation(self, *relations):
8338 """Register relation as recursive"""
8339 relations = _get_args(relations)
8340 for f in relations:
8341 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
8342
8343 def set_predicate_representation(self, f, *representations):
8344 """Control how relation is represented"""
8345 representations = _get_args(representations)
8346 representations = [to_symbol(s) for s in representations]
8347 sz = len(representations)
8348 args = (Symbol * sz)()
8349 for i in range(sz):
8350 args[i] = representations[i]
8351 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
8352
8353 def parse_string(self, s):
8354 """Parse rules and queries from a string"""
8355 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
8356
8357 def parse_file(self, f):
8358 """Parse rules and queries from a file"""
8359 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
8360
8361 def get_rules(self):
8362 """retrieve rules that have been added to fixedpoint context"""
8363 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
8364
8365 def get_assertions(self):
8366 """retrieve assertions that have been added to fixedpoint context"""
8367 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
8368
8369 def __repr__(self):
8370 """Return a formatted string with all added rules and constraints."""
8371 return self.sexpr()
8372
8373 def sexpr(self):
8374 """Return a formatted string (in Lisp-like format) with all added constraints.
8375 We say the string is in s-expression format.
8376 """
8377 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
8378
8379 def to_string(self, queries):
8380 """Return a formatted string (in Lisp-like format) with all added constraints.
8381 We say the string is in s-expression format.
8382 Include also queries.
8383 """
8384 args, len = _to_ast_array(queries)
8385 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
8386
8387 def statistics(self):
8388 """Return statistics for the last `query()`.
8389 """
8390 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
8391
8392 def reason_unknown(self):
8393 """Return a string describing why the last `query()` returned `unknown`.
8394 """
8395 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
8396
8397 def declare_var(self, *vars):
8398 """Add variable or several variables.
8399 The added variable or variables will be bound in the rules
8400 and queries
8401 """
8402 vars = _get_args(vars)
8403 for v in vars:
8404 self.vars += [v]
8405
8406 def abstract(self, fml, is_forall=True):
8407 if self.vars == []:
8408 return fml
8409 if is_forall:
8410 return ForAll(self.vars, fml)
8411 else:
8412 return Exists(self.vars, fml)
8413
8414
8415#########################################
8416#
8417# Finite domains
8418#
8419#########################################
8420
8421class FiniteDomainSortRef(SortRef):
8422 """Finite domain sort."""
8423
8424 def size(self):
8425 """Return the size of the finite domain sort"""
8426 r = (ctypes.c_ulonglong * 1)()
8427 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
8428 return r[0]
8429 else:
8430 raise Z3Exception("Failed to retrieve finite domain sort size")
8431
8432
8433def FiniteDomainSort(name, sz, ctx=None):
8434 """Create a named finite domain sort of a given size sz"""
8435 if not isinstance(name, Symbol):
8436 name = to_symbol(name)
8437 ctx = _get_ctx(ctx)
8438 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
8439
8440
8441def is_finite_domain_sort(s):
8442 """Return True if `s` is a Z3 finite-domain sort.
8443
8444 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
8445 True
8446 >>> is_finite_domain_sort(IntSort())
8447 False
8448 """
8449 return isinstance(s, FiniteDomainSortRef)
8450
8451
8452class FiniteDomainRef(ExprRef):
8453 """Finite-domain expressions."""
8454
8455 def sort(self):
8456 """Return the sort of the finite-domain expression `self`."""
8457 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
8458
8459 def as_string(self):
8460 """Return a Z3 floating point expression as a Python string."""
8461 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
8462
8463
8464def is_finite_domain(a):
8465 """Return `True` if `a` is a Z3 finite-domain expression.
8466
8467 >>> s = FiniteDomainSort('S', 100)
8468 >>> b = Const('b', s)
8469 >>> is_finite_domain(b)
8470 True
8471 >>> is_finite_domain(Int('x'))
8472 False
8473 """
8474 return isinstance(a, FiniteDomainRef)
8475
8476
8477class FiniteDomainNumRef(FiniteDomainRef):
8478 """Integer values."""
8479
8480 def as_long(self):
8481 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
8482
8483 >>> s = FiniteDomainSort('S', 100)
8484 >>> v = FiniteDomainVal(3, s)
8485 >>> v
8486 3
8487 >>> v.as_long() + 1
8488 4
8489 """
8490 return int(self.as_string())
8491
8492 def as_string(self):
8493 """Return a Z3 finite-domain numeral as a Python string.
8494
8495 >>> s = FiniteDomainSort('S', 100)
8496 >>> v = FiniteDomainVal(42, s)
8497 >>> v.as_string()
8498 '42'
8499 """
8500 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
8501
8502
8503def FiniteDomainVal(val, sort, ctx=None):
8504 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
8505
8506 >>> s = FiniteDomainSort('S', 256)
8507 >>> FiniteDomainVal(255, s)
8508 255
8509 >>> FiniteDomainVal('100', s)
8510 100
8511 """
8512 if z3_debug():
8513 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
8514 ctx = sort.ctx
8515 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
8516
8517
8518def is_finite_domain_value(a):
8519 """Return `True` if `a` is a Z3 finite-domain value.
8520
8521 >>> s = FiniteDomainSort('S', 100)
8522 >>> b = Const('b', s)
8523 >>> is_finite_domain_value(b)
8524 False
8525 >>> b = FiniteDomainVal(10, s)
8526 >>> b
8527 10
8528 >>> is_finite_domain_value(b)
8529 True
8530 """
8531 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
8532
8533
8534#########################################
8535#
8536# Optimize
8537#
8538#########################################
8539
8540class OptimizeObjective:
8541 def __init__(self, opt, value, is_max):
8542 self._opt = opt
8543 self._value = value
8544 self._is_max = is_max
8545
8546 def lower(self):
8547 opt = self._opt
8548 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8549
8550 def upper(self):
8551 opt = self._opt
8552 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8553
8554 def lower_values(self):
8555 opt = self._opt
8556 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8557
8558 def upper_values(self):
8559 opt = self._opt
8560 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8561
8562 def value(self):
8563 if self._is_max:
8564 return self.upper()
8565 else:
8566 return self.lower()
8567
8568 def __str__(self):
8569 return "%s:%s" % (self._value, self._is_max)
8570
8571
8572_on_models = {}
8573
8574
8575def _global_on_model(ctx):
8576 (fn, mdl) = _on_models[ctx]
8577 fn(mdl)
8578
8579
8580_on_model_eh = on_model_eh_type(_global_on_model)
8581
8582
8583class Optimize(Z3PPObject):
8584 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8585
8586 def __init__(self, optimize=None, ctx=None):
8587 self.ctx = _get_ctx(ctx)
8588 if optimize is None:
8589 self.optimize = Z3_mk_optimize(self.ctx.ref())
8590 else:
8591 self.optimize = optimize
8592 self._on_models_id = None
8593 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8594
8595 def __copy__(self):
8596 return self.translate(self.ctx)
8597
8598 def __deepcopy__(self, memo={}):
8599 return self.translate(self.ctx)
8600
8601 def __del__(self):
8602 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8603 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8604 if self._on_models_id is not None:
8605 del _on_models[self._on_models_id]
8606
8607 def __enter__(self):
8608 self.push()
8609 return self
8610
8611 def __exit__(self, *exc_info):
8612 self.pop()
8613
8614 def set(self, *args, **keys):
8615 """Set a configuration option.
8616 The method `help()` return a string containing all available options.
8617 """
8618 p = args2params(args, keys, self.ctx)
8619 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8620
8621 def help(self):
8622 """Display a string describing all available options."""
8623 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8624
8625 def param_descrs(self):
8626 """Return the parameter description set."""
8627 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8628
8629 def assert_exprs(self, *args):
8630 """Assert constraints as background axioms for the optimize solver."""
8631 args = _get_args(args)
8632 s = BoolSort(self.ctx)
8633 for arg in args:
8634 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8635 for f in arg:
8636 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8637 else:
8638 arg = s.cast(arg)
8639 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8640
8641 def add(self, *args):
8642 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8643 self.assert_exprs(*args)
8644
8645 def __iadd__(self, fml):
8646 self.add(fml)
8647 return self
8648
8649 def assert_and_track(self, a, p):
8650 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8651
8652 If `p` is a string, it will be automatically converted into a Boolean constant.
8653
8654 >>> x = Int('x')
8655 >>> p3 = Bool('p3')
8656 >>> s = Optimize()
8657 >>> s.assert_and_track(x > 0, 'p1')
8658 >>> s.assert_and_track(x != 1, 'p2')
8659 >>> s.assert_and_track(x < 0, p3)
8660 >>> print(s.check())
8661 unsat
8662 >>> c = s.unsat_core()
8663 >>> len(c)
8664 2
8665 >>> Bool('p1') in c
8666 True
8667 >>> Bool('p2') in c
8668 False
8669 >>> p3 in c
8670 True
8671 """
8672 if isinstance(p, str):
8673 p = Bool(p, self.ctx)
8674 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8675 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8676 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8677
8678 def add_soft(self, arg, weight="1", id=None):
8679 """Add soft constraint with optional weight and optional identifier.
8680 If no weight is supplied, then the penalty for violating the soft constraint
8681 is 1.
8682 Soft constraints are grouped by identifiers. Soft constraints that are
8683 added without identifiers are grouped by default.
8684 """
8685 if _is_int(weight):
8686 weight = "%d" % weight
8687 elif isinstance(weight, float):
8688 weight = "%f" % weight
8689 if not isinstance(weight, str):
8690 raise Z3Exception("weight should be a string or an integer")
8691 if id is None:
8692 id = ""
8693 id = to_symbol(id, self.ctx)
8694
8695 def asoft(a):
8696 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8697 return OptimizeObjective(self, v, False)
8698 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8699 return [asoft(a) for a in arg]
8700 return asoft(arg)
8701
8702 def set_initial_value(self, var, value):
8703 """initialize the solver's state by setting the initial value of var to value
8704 """
8705 s = var.sort()
8706 value = s.cast(value)
8707 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8708
8709 def maximize(self, arg):
8710 """Add objective function to maximize."""
8711 return OptimizeObjective(
8712 self,
8713 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8714 is_max=True,
8715 )
8716
8717 def minimize(self, arg):
8718 """Add objective function to minimize."""
8719 return OptimizeObjective(
8720 self,
8721 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8722 is_max=False,
8723 )
8724
8725 def push(self):
8726 """create a backtracking point for added rules, facts and assertions"""
8727 Z3_optimize_push(self.ctx.ref(), self.optimize)
8728
8729 def pop(self):
8730 """restore to previously created backtracking point"""
8731 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8732
8733 def check(self, *assumptions):
8734 """Check consistency and produce optimal values."""
8735 assumptions = _get_args(assumptions)
8736 num = len(assumptions)
8737 _assumptions = (Ast * num)()
8738 for i in range(num):
8739 _assumptions[i] = assumptions[i].as_ast()
8740 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8741
8742 def reason_unknown(self):
8743 """Return a string that describes why the last `check()` returned `unknown`."""
8744 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8745
8746 def model(self):
8747 """Return a model for the last check()."""
8748 try:
8749 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8750 except Z3Exception:
8751 raise Z3Exception("model is not available")
8752
8753 def unsat_core(self):
8754 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8755
8756 def lower(self, obj):
8757 if not isinstance(obj, OptimizeObjective):
8758 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8759 return obj.lower()
8760
8761 def upper(self, obj):
8762 if not isinstance(obj, OptimizeObjective):
8763 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8764 return obj.upper()
8765
8766 def lower_values(self, obj):
8767 if not isinstance(obj, OptimizeObjective):
8768 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8769 return obj.lower_values()
8770
8771 def upper_values(self, obj):
8772 if not isinstance(obj, OptimizeObjective):
8773 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8774 return obj.upper_values()
8775
8776 def from_file(self, filename):
8777 """Parse assertions and objectives from a file"""
8778 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8779
8780 def from_string(self, s):
8781 """Parse assertions and objectives from a string"""
8782 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8783
8784 def assertions(self):
8785 """Return an AST vector containing all added constraints."""
8786 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8787
8788 def objectives(self):
8789 """returns set of objective functions"""
8790 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8791
8792 def __repr__(self):
8793 """Return a formatted string with all added rules and constraints."""
8794 return self.sexpr()
8795
8796 def sexpr(self):
8797 """Return a formatted string (in Lisp-like format) with all added constraints.
8798 We say the string is in s-expression format.
8799 """
8800 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8801
8802 def statistics(self):
8803 """Return statistics for the last check`.
8804 """
8805 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8806
8807 def translate(self, target):
8808 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
8809
8810 >>> c1 = Context()
8811 >>> c2 = Context()
8812 >>> o1 = Optimize(ctx=c1)
8813 >>> o2 = o1.translate(c2)
8814 """
8815 if z3_debug():
8816 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
8817 opt = Z3_optimize_translate(self.ctx.ref(), self.optimize, target.ref())
8818 return Optimize(opt, target)
8819
8820 def set_on_model(self, on_model):
8821 """Register a callback that is invoked with every incremental improvement to
8822 objective values. The callback takes a model as argument.
8823 The life-time of the model is limited to the callback so the
8824 model has to be (deep) copied if it is to be used after the callback
8825 """
8826 id = len(_on_models) + 41
8827 mdl = Model(self.ctx)
8828 _on_models[id] = (on_model, mdl)
8829 self._on_models_id = id
8830 Z3_optimize_register_model_eh(
8831 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8832 )
8833
8834
8835#########################################
8836#
8837# ApplyResult
8838#
8839#########################################
8840class ApplyResult(Z3PPObject):
8841 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8842 It also contains model and proof converters.
8843 """
8844
8845 def __init__(self, result, ctx):
8846 self.result = result
8847 self.ctx = ctx
8848 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8849
8850 def __deepcopy__(self, memo={}):
8851 return ApplyResult(self.result, self.ctx)
8852
8853 def __del__(self):
8854 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8855 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8856
8857 def __len__(self):
8858 """Return the number of subgoals in `self`.
8859
8860 >>> a, b = Ints('a b')
8861 >>> g = Goal()
8862 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8863 >>> t = Tactic('split-clause')
8864 >>> r = t(g)
8865 >>> len(r)
8866 2
8867 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8868 >>> len(t(g))
8869 4
8870 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8871 >>> len(t(g))
8872 1
8873 """
8874 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8875
8876 def __getitem__(self, idx):
8877 """Return one of the subgoals stored in ApplyResult object `self`.
8878
8879 >>> a, b = Ints('a b')
8880 >>> g = Goal()
8881 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8882 >>> t = Tactic('split-clause')
8883 >>> r = t(g)
8884 >>> r[0]
8885 [a == 0, Or(b == 0, b == 1), a > b]
8886 >>> r[1]
8887 [a == 1, Or(b == 0, b == 1), a > b]
8888 """
8889 if idx < 0:
8890 idx += len(self)
8891 if idx < 0 or idx >= len(self):
8892 raise IndexError
8893 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8894
8895 def __repr__(self):
8896 return obj_to_string(self)
8897
8898 def sexpr(self):
8899 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8900 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8901
8902 def as_expr(self):
8903 """Return a Z3 expression consisting of all subgoals.
8904
8905 >>> x = Int('x')
8906 >>> g = Goal()
8907 >>> g.add(x > 1)
8908 >>> g.add(Or(x == 2, x == 3))
8909 >>> r = Tactic('simplify')(g)
8910 >>> r
8911 [[Not(x <= 1), Or(x == 2, x == 3)]]
8912 >>> r.as_expr()
8913 And(Not(x <= 1), Or(x == 2, x == 3))
8914 >>> r = Tactic('split-clause')(g)
8915 >>> r
8916 [[x > 1, x == 2], [x > 1, x == 3]]
8917 >>> r.as_expr()
8918 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8919 """
8920 sz = len(self)
8921 if sz == 0:
8922 return BoolVal(False, self.ctx)
8923 elif sz == 1:
8924 return self[0].as_expr()
8925 else:
8926 return Or([self[i].as_expr() for i in range(len(self))])
8927
8928#########################################
8929#
8930# Simplifiers
8931#
8932#########################################
8933
8934def num_simplifiers(ctx=None):
8935 """Return the number of simplifiers supported by the given context."""
8936 return Z3_get_num_simplifiers(_get_ctx(ctx).ref())
8937
8938
8939def simplifier_name(i, ctx=None):
8940 """Return the name of the i-th simplifier supported by the given context."""
8941 return Z3_get_simplifier_name(_get_ctx(ctx).ref(), i)
8942
8943
8944def simplifier_description(name, ctx=None):
8945 """Return the description of the simplifier identified by name."""
8946 return Z3_simplifier_get_descr(_get_ctx(ctx).ref(), name)
8947
8948
8949class Simplifier:
8950 """Simplifiers act as pre-processing utilities for solvers.
8951 Build a custom simplifier and add it to a solver"""
8952
8953 def __init__(self, simplifier, ctx=None):
8954 self.ctx = _get_ctx(ctx)
8955 self.simplifier = None
8956 if isinstance(simplifier, SimplifierObj):
8957 self.simplifier = simplifier
8958 elif isinstance(simplifier, list):
8959 simps = [Simplifier(s, ctx) for s in simplifier]
8960 self.simplifier = simps[0].simplifier
8961 for i in range(1, len(simps)):
8962 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8963 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8964 return
8965 else:
8966 if z3_debug():
8967 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8968 try:
8969 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8970 except Z3Exception:
8971 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8972 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8973
8974 def __deepcopy__(self, memo={}):
8975 return Simplifier(self.simplifier, self.ctx)
8976
8977 def __del__(self):
8978 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8979 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8980
8981 def using_params(self, *args, **keys):
8982 """Return a simplifier that uses the given configuration options"""
8983 p = args2params(args, keys, self.ctx)
8984 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8985
8986 def add(self, solver):
8987 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8988 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8989
8990 def help(self):
8991 """Display a string containing a description of the available options for the `self` simplifier."""
8992 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8993
8994 def param_descrs(self):
8995 """Return the parameter description set."""
8996 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8997
8998
8999#########################################
9000#
9001# Tactics
9002#
9003#########################################
9004
9005
9006class Tactic:
9007 """Tactics transform, solver and/or simplify sets of constraints (Goal).
9008 A Tactic can be converted into a Solver using the method solver().
9009
9010 Several combinators are available for creating new tactics using the built-in ones:
9011 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
9012 """
9013
9014 def __init__(self, tactic, ctx=None):
9015 self.ctx = _get_ctx(ctx)
9016 self.tactic = None
9017 if isinstance(tactic, TacticObj):
9018 self.tactic = tactic
9019 else:
9020 if z3_debug():
9021 _z3_assert(isinstance(tactic, str), "tactic name expected")
9022 try:
9023 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
9024 except Z3Exception:
9025 raise Z3Exception("unknown tactic '%s'" % tactic)
9026 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
9027
9028 def __deepcopy__(self, memo={}):
9029 return Tactic(self.tactic, self.ctx)
9030
9031 def __del__(self):
9032 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
9033 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
9034
9035 def solver(self, logFile=None):
9036 """Create a solver using the tactic `self`.
9037
9038 The solver supports the methods `push()` and `pop()`, but it
9039 will always solve each `check()` from scratch.
9040
9041 >>> t = Then('simplify', 'nlsat')
9042 >>> s = t.solver()
9043 >>> x = Real('x')
9044 >>> s.add(x**2 == 2, x > 0)
9045 >>> s.check()
9046 sat
9047 >>> s.model()
9048 [x = 1.4142135623?]
9049 """
9050 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
9051
9052 def apply(self, goal, *arguments, **keywords):
9053 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
9054
9055 >>> x, y = Ints('x y')
9056 >>> t = Tactic('solve-eqs')
9057 >>> t.apply(And(x == 0, y >= x + 1))
9058 [[y >= 1]]
9059 """
9060 if z3_debug():
9061 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
9062 goal = _to_goal(goal)
9063 if len(arguments) > 0 or len(keywords) > 0:
9064 p = args2params(arguments, keywords, self.ctx)
9065 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
9066 else:
9067 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
9068
9069 def __call__(self, goal, *arguments, **keywords):
9070 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
9071
9072 >>> x, y = Ints('x y')
9073 >>> t = Tactic('solve-eqs')
9074 >>> t(And(x == 0, y >= x + 1))
9075 [[y >= 1]]
9076 """
9077 return self.apply(goal, *arguments, **keywords)
9078
9079 def help(self):
9080 """Display a string containing a description of the available options for the `self` tactic."""
9081 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
9082
9083 def param_descrs(self):
9084 """Return the parameter description set."""
9085 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
9086
9087
9088def _to_goal(a):
9089 if isinstance(a, BoolRef):
9090 goal = Goal(ctx=a.ctx)
9091 goal.add(a)
9092 return goal
9093 else:
9094 return a
9095
9096
9097def _to_tactic(t, ctx=None):
9098 if isinstance(t, Tactic):
9099 return t
9100 else:
9101 return Tactic(t, ctx)
9102
9103
9104def _and_then(t1, t2, ctx=None):
9105 t1 = _to_tactic(t1, ctx)
9106 t2 = _to_tactic(t2, ctx)
9107 if z3_debug():
9108 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
9109 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
9110
9111
9112def _or_else(t1, t2, ctx=None):
9113 t1 = _to_tactic(t1, ctx)
9114 t2 = _to_tactic(t2, ctx)
9115 if z3_debug():
9116 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
9117 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
9118
9119
9120def AndThen(*ts, **ks):
9121 """Return a tactic that applies the tactics in `*ts` in sequence.
9122
9123 >>> x, y = Ints('x y')
9124 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
9125 >>> t(And(x == 0, y > x + 1))
9126 [[Not(y <= 1)]]
9127 >>> t(And(x == 0, y > x + 1)).as_expr()
9128 Not(y <= 1)
9129 """
9130 if z3_debug():
9131 _z3_assert(len(ts) >= 2, "At least two arguments expected")
9132 ctx = ks.get("ctx", None)
9133 num = len(ts)
9134 r = ts[0]
9135 for i in range(num - 1):
9136 r = _and_then(r, ts[i + 1], ctx)
9137 return r
9138
9139
9140def Then(*ts, **ks):
9141 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
9142
9143 >>> x, y = Ints('x y')
9144 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
9145 >>> t(And(x == 0, y > x + 1))
9146 [[Not(y <= 1)]]
9147 >>> t(And(x == 0, y > x + 1)).as_expr()
9148 Not(y <= 1)
9149 """
9150 return AndThen(*ts, **ks)
9151
9152
9153def OrElse(*ts, **ks):
9154 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
9155
9156 >>> x = Int('x')
9157 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
9158 >>> # Tactic split-clause fails if there is no clause in the given goal.
9159 >>> t(x == 0)
9160 [[x == 0]]
9161 >>> t(Or(x == 0, x == 1))
9162 [[x == 0], [x == 1]]
9163 """
9164 if z3_debug():
9165 _z3_assert(len(ts) >= 2, "At least two arguments expected")
9166 ctx = ks.get("ctx", None)
9167 num = len(ts)
9168 r = ts[0]
9169 for i in range(num - 1):
9170 r = _or_else(r, ts[i + 1], ctx)
9171 return r
9172
9173
9174def ParOr(*ts, **ks):
9175 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
9176
9177 >>> x = Int('x')
9178 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
9179 >>> t(x + 1 == 2)
9180 [[x == 1]]
9181 """
9182 if z3_debug():
9183 _z3_assert(len(ts) >= 2, "At least two arguments expected")
9184 ctx = _get_ctx(ks.get("ctx", None))
9185 ts = [_to_tactic(t, ctx) for t in ts]
9186 sz = len(ts)
9187 _args = (TacticObj * sz)()
9188 for i in range(sz):
9189 _args[i] = ts[i].tactic
9190 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
9191
9192
9193def ParThen(t1, t2, ctx=None):
9194 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
9195 The subgoals are processed in parallel.
9196
9197 >>> x, y = Ints('x y')
9198 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
9199 >>> t(And(Or(x == 1, x == 2), y == x + 1))
9200 [[x == 1, y == 2], [x == 2, y == 3]]
9201 """
9202 t1 = _to_tactic(t1, ctx)
9203 t2 = _to_tactic(t2, ctx)
9204 if z3_debug():
9205 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
9206 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
9207
9208
9209def ParAndThen(t1, t2, ctx=None):
9210 """Alias for ParThen(t1, t2, ctx)."""
9211 return ParThen(t1, t2, ctx)
9212
9213
9214def With(t, *args, **keys):
9215 """Return a tactic that applies tactic `t` using the given configuration options.
9216
9217 >>> x, y = Ints('x y')
9218 >>> t = With(Tactic('simplify'), som=True)
9219 >>> t((x + 1)*(y + 2) == 0)
9220 [[2*x + y + x*y == -2]]
9221 """
9222 ctx = keys.pop("ctx", None)
9223 t = _to_tactic(t, ctx)
9224 p = args2params(args, keys, t.ctx)
9225 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
9226
9227
9228def WithParams(t, p):
9229 """Return a tactic that applies tactic `t` using the given configuration options.
9230
9231 >>> x, y = Ints('x y')
9232 >>> p = ParamsRef()
9233 >>> p.set("som", True)
9234 >>> t = WithParams(Tactic('simplify'), p)
9235 >>> t((x + 1)*(y + 2) == 0)
9236 [[2*x + y + x*y == -2]]
9237 """
9238 t = _to_tactic(t, None)
9239 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
9240
9241
9242def Repeat(t, max=4294967295, ctx=None):
9243 """Return a tactic that keeps applying `t` until the goal is not modified anymore
9244 or the maximum number of iterations `max` is reached.
9245
9246 >>> x, y = Ints('x y')
9247 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
9248 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
9249 >>> r = t(c)
9250 >>> for subgoal in r: print(subgoal)
9251 [x == 0, y == 0, x > y]
9252 [x == 0, y == 1, x > y]
9253 [x == 1, y == 0, x > y]
9254 [x == 1, y == 1, x > y]
9255 >>> t = Then(t, Tactic('propagate-values'))
9256 >>> t(c)
9257 [[x == 1, y == 0]]
9258 """
9259 t = _to_tactic(t, ctx)
9260 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
9261
9262
9263def TryFor(t, ms, ctx=None):
9264 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
9265
9266 If `t` does not terminate in `ms` milliseconds, then it fails.
9267 """
9268 t = _to_tactic(t, ctx)
9269 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
9270
9271
9272def tactics(ctx=None):
9273 """Return a list of all available tactics in Z3.
9274
9275 >>> l = tactics()
9276 >>> l.count('simplify') == 1
9277 True
9278 """
9279 ctx = _get_ctx(ctx)
9280 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
9281
9282
9283def tactic_description(name, ctx=None):
9284 """Return a short description for the tactic named `name`.
9285
9286 >>> d = tactic_description('simplify')
9287 """
9288 ctx = _get_ctx(ctx)
9289 return Z3_tactic_get_descr(ctx.ref(), name)
9290
9291
9292def describe_tactics():
9293 """Display a (tabular) description of all available tactics in Z3."""
9294 if in_html_mode():
9295 even = True
9296 print('<table border="1" cellpadding="2" cellspacing="0">')
9297 for t in tactics():
9298 if even:
9299 print('<tr style="background-color:#CFCFCF">')
9300 even = False
9301 else:
9302 print("<tr>")
9303 even = True
9304 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
9305 print("</table>")
9306 else:
9307 for t in tactics():
9308 print("%s : %s" % (t, tactic_description(t)))
9309
9310
9311class Probe:
9312 """Probes are used to inspect a goal (aka problem) and collect information that may be used
9313 to decide which solver and/or preprocessing step will be used.
9314 """
9315
9316 def __init__(self, probe, ctx=None):
9317 self.ctx = _get_ctx(ctx)
9318 self.probe = None
9319 if isinstance(probe, ProbeObj):
9320 self.probe = probe
9321 elif isinstance(probe, float):
9322 self.probe = Z3_probe_const(self.ctx.ref(), probe)
9323 elif _is_int(probe):
9324 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
9325 elif isinstance(probe, bool):
9326 if probe:
9327 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
9328 else:
9329 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
9330 else:
9331 if z3_debug():
9332 _z3_assert(isinstance(probe, str), "probe name expected")
9333 try:
9334 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
9335 except Z3Exception:
9336 raise Z3Exception("unknown probe '%s'" % probe)
9337 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
9338
9339 def __deepcopy__(self, memo={}):
9340 return Probe(self.probe, self.ctx)
9341
9342 def __del__(self):
9343 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
9344 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
9345
9346 def __lt__(self, other):
9347 """Return a probe that evaluates to "true" when the value returned by `self`
9348 is less than the value returned by `other`.
9349
9350 >>> p = Probe('size') < 10
9351 >>> x = Int('x')
9352 >>> g = Goal()
9353 >>> g.add(x > 0)
9354 >>> g.add(x < 10)
9355 >>> p(g)
9356 1.0
9357 """
9358 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9359
9360 def __gt__(self, other):
9361 """Return a probe that evaluates to "true" when the value returned by `self`
9362 is greater than the value returned by `other`.
9363
9364 >>> p = Probe('size') > 10
9365 >>> x = Int('x')
9366 >>> g = Goal()
9367 >>> g.add(x > 0)
9368 >>> g.add(x < 10)
9369 >>> p(g)
9370 0.0
9371 """
9372 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9373
9374 def __le__(self, other):
9375 """Return a probe that evaluates to "true" when the value returned by `self`
9376 is less than or equal to the value returned by `other`.
9377
9378 >>> p = Probe('size') <= 2
9379 >>> x = Int('x')
9380 >>> g = Goal()
9381 >>> g.add(x > 0)
9382 >>> g.add(x < 10)
9383 >>> p(g)
9384 1.0
9385 """
9386 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9387
9388 def __ge__(self, other):
9389 """Return a probe that evaluates to "true" when the value returned by `self`
9390 is greater than or equal to the value returned by `other`.
9391
9392 >>> p = Probe('size') >= 2
9393 >>> x = Int('x')
9394 >>> g = Goal()
9395 >>> g.add(x > 0)
9396 >>> g.add(x < 10)
9397 >>> p(g)
9398 1.0
9399 """
9400 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9401
9402 def __eq__(self, other):
9403 """Return a probe that evaluates to "true" when the value returned by `self`
9404 is equal to the value returned by `other`.
9405
9406 >>> p = Probe('size') == 2
9407 >>> x = Int('x')
9408 >>> g = Goal()
9409 >>> g.add(x > 0)
9410 >>> g.add(x < 10)
9411 >>> p(g)
9412 1.0
9413 """
9414 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
9415
9416 def __ne__(self, other):
9417 """Return a probe that evaluates to "true" when the value returned by `self`
9418 is not equal to the value returned by `other`.
9419
9420 >>> p = Probe('size') != 2
9421 >>> x = Int('x')
9422 >>> g = Goal()
9423 >>> g.add(x > 0)
9424 >>> g.add(x < 10)
9425 >>> p(g)
9426 0.0
9427 """
9428 p = self.__eq__(other)
9429 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
9430
9431 def __call__(self, goal):
9432 """Evaluate the probe `self` in the given goal.
9433
9434 >>> p = Probe('size')
9435 >>> x = Int('x')
9436 >>> g = Goal()
9437 >>> g.add(x > 0)
9438 >>> g.add(x < 10)
9439 >>> p(g)
9440 2.0
9441 >>> g.add(x < 20)
9442 >>> p(g)
9443 3.0
9444 >>> p = Probe('num-consts')
9445 >>> p(g)
9446 1.0
9447 >>> p = Probe('is-propositional')
9448 >>> p(g)
9449 0.0
9450 >>> p = Probe('is-qflia')
9451 >>> p(g)
9452 1.0
9453 """
9454 if z3_debug():
9455 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
9456 goal = _to_goal(goal)
9457 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
9458
9459
9460def is_probe(p):
9461 """Return `True` if `p` is a Z3 probe.
9462
9463 >>> is_probe(Int('x'))
9464 False
9465 >>> is_probe(Probe('memory'))
9466 True
9467 """
9468 return isinstance(p, Probe)
9469
9470
9471def _to_probe(p, ctx=None):
9472 if is_probe(p):
9473 return p
9474 else:
9475 return Probe(p, ctx)
9476
9477
9478def probes(ctx=None):
9479 """Return a list of all available probes in Z3.
9480
9481 >>> l = probes()
9482 >>> l.count('memory') == 1
9483 True
9484 """
9485 ctx = _get_ctx(ctx)
9486 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
9487
9488
9489def probe_description(name, ctx=None):
9490 """Return a short description for the probe named `name`.
9491
9492 >>> d = probe_description('memory')
9493 """
9494 ctx = _get_ctx(ctx)
9495 return Z3_probe_get_descr(ctx.ref(), name)
9496
9497
9498def describe_probes():
9499 """Display a (tabular) description of all available probes in Z3."""
9500 if in_html_mode():
9501 even = True
9502 print('<table border="1" cellpadding="2" cellspacing="0">')
9503 for p in probes():
9504 if even:
9505 print('<tr style="background-color:#CFCFCF">')
9506 even = False
9507 else:
9508 print("<tr>")
9509 even = True
9510 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
9511 print("</table>")
9512 else:
9513 for p in probes():
9514 print("%s : %s" % (p, probe_description(p)))
9515
9516
9517def _probe_nary(f, args, ctx):
9518 if z3_debug():
9519 _z3_assert(len(args) > 0, "At least one argument expected")
9520 num = len(args)
9521 r = _to_probe(args[0], ctx)
9522 for i in range(num - 1):
9523 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
9524 return r
9525
9526
9527def _probe_and(args, ctx):
9528 return _probe_nary(Z3_probe_and, args, ctx)
9529
9530
9531def _probe_or(args, ctx):
9532 return _probe_nary(Z3_probe_or, args, ctx)
9533
9534
9535def FailIf(p, ctx=None):
9536 """Return a tactic that fails if the probe `p` evaluates to true.
9537 Otherwise, it returns the input goal unmodified.
9538
9539 In the following example, the tactic applies 'simplify' if and only if there are
9540 more than 2 constraints in the goal.
9541
9542 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
9543 >>> x, y = Ints('x y')
9544 >>> g = Goal()
9545 >>> g.add(x > 0)
9546 >>> g.add(y > 0)
9547 >>> t(g)
9548 [[x > 0, y > 0]]
9549 >>> g.add(x == y + 1)
9550 >>> t(g)
9551 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9552 """
9553 p = _to_probe(p, ctx)
9554 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
9555
9556
9557def When(p, t, ctx=None):
9558 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
9559 Otherwise, it returns the input goal unmodified.
9560
9561 >>> t = When(Probe('size') > 2, Tactic('simplify'))
9562 >>> x, y = Ints('x y')
9563 >>> g = Goal()
9564 >>> g.add(x > 0)
9565 >>> g.add(y > 0)
9566 >>> t(g)
9567 [[x > 0, y > 0]]
9568 >>> g.add(x == y + 1)
9569 >>> t(g)
9570 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9571 """
9572 p = _to_probe(p, ctx)
9573 t = _to_tactic(t, ctx)
9574 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
9575
9576
9577def Cond(p, t1, t2, ctx=None):
9578 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
9579
9580 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
9581 """
9582 p = _to_probe(p, ctx)
9583 t1 = _to_tactic(t1, ctx)
9584 t2 = _to_tactic(t2, ctx)
9585 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
9586
9587#########################################
9588#
9589# Utils
9590#
9591#########################################
9592
9593
9594def simplify(a, *arguments, **keywords):
9595 """Simplify the expression `a` using the given options.
9596
9597 This function has many options. Use `help_simplify` to obtain the complete list.
9598
9599 >>> x = Int('x')
9600 >>> y = Int('y')
9601 >>> simplify(x + 1 + y + x + 1)
9602 2 + 2*x + y
9603 >>> simplify((x + 1)*(y + 1), som=True)
9604 1 + x + y + x*y
9605 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9606 And(Not(x == y), Not(x == 1), Not(y == 1))
9607 >>> simplify(And(x == 0, y == 1), elim_and=True)
9608 Not(Or(Not(x == 0), Not(y == 1)))
9609 """
9610 if z3_debug():
9611 _z3_assert(is_expr(a), "Z3 expression expected")
9612 if len(arguments) > 0 or len(keywords) > 0:
9613 p = args2params(arguments, keywords, a.ctx)
9614 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9615 else:
9616 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9617
9618
9619def help_simplify():
9620 """Return a string describing all options available for Z3 `simplify` procedure."""
9621 print(Z3_simplify_get_help(main_ctx().ref()))
9622
9623
9624def simplify_param_descrs():
9625 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9626 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9627
9628
9629def substitute(t, *m):
9630 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9631 Every occurrence in t of from is replaced with to.
9632
9633 >>> x = Int('x')
9634 >>> y = Int('y')
9635 >>> substitute(x + 1, (x, y + 1))
9636 y + 1 + 1
9637 >>> f = Function('f', IntSort(), IntSort())
9638 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9639 1 + 1
9640 """
9641 if isinstance(m, tuple):
9642 m1 = _get_args(m)
9643 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9644 m = m1
9645 if z3_debug():
9646 _z3_assert(is_expr(t), "Z3 expression expected")
9647 _z3_assert(
9648 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9649 "Z3 invalid substitution, expression pairs expected.")
9650 _z3_assert(
9651 all([p[0].sort().eq(p[1].sort()) for p in m]),
9652 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9653 num = len(m)
9654 _from = (Ast * num)()
9655 _to = (Ast * num)()
9656 for i in range(num):
9657 _from[i] = m[i][0].as_ast()
9658 _to[i] = m[i][1].as_ast()
9659 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9660
9661
9662def substitute_vars(t, *m):
9663 """Substitute the free variables in t with the expression in m.
9664
9665 >>> v0 = Var(0, IntSort())
9666 >>> v1 = Var(1, IntSort())
9667 >>> x = Int('x')
9668 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9669 >>> # replace v0 with x+1 and v1 with x
9670 >>> substitute_vars(f(v0, v1), x + 1, x)
9671 f(x + 1, x)
9672 """
9673 if z3_debug():
9674 _z3_assert(is_expr(t), "Z3 expression expected")
9675 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9676 num = len(m)
9677 _to = (Ast * num)()
9678 for i in range(num):
9679 _to[i] = m[i].as_ast()
9680 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9681
9682def substitute_funs(t, *m):
9683 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9684 Every occurrence in to of the function from is replaced with the expression to.
9685 The expression to can have free variables, that refer to the arguments of from.
9686 For examples, see
9687 """
9688 if isinstance(m, tuple):
9689 m1 = _get_args(m)
9690 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9691 m = m1
9692 if z3_debug():
9693 _z3_assert(is_expr(t), "Z3 expression expected")
9694 _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.")
9695 num = len(m)
9696 _from = (FuncDecl * num)()
9697 _to = (Ast * num)()
9698 for i in range(num):
9699 _from[i] = m[i][0].as_func_decl()
9700 _to[i] = m[i][1].as_ast()
9701 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9702
9703
9704def Sum(*args):
9705 """Create the sum of the Z3 expressions.
9706
9707 >>> a, b, c = Ints('a b c')
9708 >>> Sum(a, b, c)
9709 a + b + c
9710 >>> Sum([a, b, c])
9711 a + b + c
9712 >>> A = IntVector('a', 5)
9713 >>> Sum(A)
9714 a__0 + a__1 + a__2 + a__3 + a__4
9715 """
9716 args = _get_args(args)
9717 if len(args) == 0:
9718 return 0
9719 ctx = _ctx_from_ast_arg_list(args)
9720 if ctx is None:
9721 return _reduce(lambda a, b: a + b, args, 0)
9722 args = _coerce_expr_list(args, ctx)
9723 if is_bv(args[0]) or isinstance(args[0], FiniteFieldRef):
9724 return _reduce(lambda a, b: a + b, args, 0)
9725 else:
9726 _args, sz = _to_ast_array(args)
9727 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9728
9729
9730def Product(*args):
9731 """Create the product of the Z3 expressions.
9732
9733 >>> a, b, c = Ints('a b c')
9734 >>> Product(a, b, c)
9735 a*b*c
9736 >>> Product([a, b, c])
9737 a*b*c
9738 >>> A = IntVector('a', 5)
9739 >>> Product(A)
9740 a__0*a__1*a__2*a__3*a__4
9741 """
9742 args = _get_args(args)
9743 if len(args) == 0:
9744 return 1
9745 ctx = _ctx_from_ast_arg_list(args)
9746 if ctx is None:
9747 return _reduce(lambda a, b: a * b, args, 1)
9748 args = _coerce_expr_list(args, ctx)
9749 if is_bv(args[0]) or isinstance(args[0], FiniteFieldRef):
9750 return _reduce(lambda a, b: a * b, args, 1)
9751 else:
9752 _args, sz = _to_ast_array(args)
9753 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9754
9755def Abs(arg):
9756 """Create the absolute value of an arithmetic expression"""
9757 return If(arg > 0, arg, -arg)
9758
9759
9760def AtMost(*args):
9761 """Create an at-most Pseudo-Boolean k constraint.
9762
9763 >>> a, b, c = Bools('a b c')
9764 >>> f = AtMost(a, b, c, 2)
9765 """
9766 args = _get_args(args)
9767 if z3_debug():
9768 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9769 ctx = _ctx_from_ast_arg_list(args)
9770 if z3_debug():
9771 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9772 args1 = _coerce_expr_list(args[:-1], ctx)
9773 k = args[-1]
9774 _args, sz = _to_ast_array(args1)
9775 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9776
9777
9778def AtLeast(*args):
9779 """Create an at-least Pseudo-Boolean k constraint.
9780
9781 >>> a, b, c = Bools('a b c')
9782 >>> f = AtLeast(a, b, c, 2)
9783 """
9784 args = _get_args(args)
9785 if z3_debug():
9786 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9787 ctx = _ctx_from_ast_arg_list(args)
9788 if z3_debug():
9789 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9790 args1 = _coerce_expr_list(args[:-1], ctx)
9791 k = args[-1]
9792 _args, sz = _to_ast_array(args1)
9793 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9794
9795
9796def _reorder_pb_arg(arg):
9797 a, b = arg
9798 if not _is_int(b) and _is_int(a):
9799 return b, a
9800 return arg
9801
9802
9803def _pb_args_coeffs(args, default_ctx=None):
9804 args = _get_args_ast_list(args)
9805 if len(args) == 0:
9806 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9807 args = [_reorder_pb_arg(arg) for arg in args]
9808 args, coeffs = zip(*args)
9809 if z3_debug():
9810 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9811 ctx = _ctx_from_ast_arg_list(args)
9812 if z3_debug():
9813 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9814 args = _coerce_expr_list(args, ctx)
9815 _args, sz = _to_ast_array(args)
9816 _coeffs = (ctypes.c_int * len(coeffs))()
9817 for i in range(len(coeffs)):
9818 _z3_check_cint_overflow(coeffs[i], "coefficient")
9819 _coeffs[i] = coeffs[i]
9820 return ctx, sz, _args, _coeffs, args
9821
9822
9823def PbLe(args, k):
9824 """Create a Pseudo-Boolean inequality k constraint.
9825
9826 >>> a, b, c = Bools('a b c')
9827 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9828 """
9829 _z3_check_cint_overflow(k, "k")
9830 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9831 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9832
9833
9834def PbGe(args, k):
9835 """Create a Pseudo-Boolean inequality k constraint.
9836
9837 >>> a, b, c = Bools('a b c')
9838 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9839 """
9840 _z3_check_cint_overflow(k, "k")
9841 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9842 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9843
9844
9845def PbEq(args, k, ctx=None):
9846 """Create a Pseudo-Boolean equality k constraint.
9847
9848 >>> a, b, c = Bools('a b c')
9849 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9850 """
9851 _z3_check_cint_overflow(k, "k")
9852 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9853 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9854
9855
9856def solve(*args, **keywords):
9857 """Solve the constraints `*args`.
9858
9859 This is a simple function for creating demonstrations. It creates a solver,
9860 configure it using the options in `keywords`, adds the constraints
9861 in `args`, and invokes check.
9862
9863 >>> a = Int('a')
9864 >>> solve(a > 0, a < 2)
9865 [a = 1]
9866 """
9867 show = keywords.pop("show", False)
9868 s = Solver()
9869 s.set(**keywords)
9870 s.add(*args)
9871 if show:
9872 print(s)
9873 r = s.check()
9874 if r == unsat:
9875 print("no solution")
9876 elif r == unknown:
9877 print("failed to solve")
9878 try:
9879 print(s.model())
9880 except Z3Exception:
9881 return
9882 else:
9883 print(s.model())
9884
9885
9886def solve_using(s, *args, **keywords):
9887 """Solve the constraints `*args` using solver `s`.
9888
9889 This is a simple function for creating demonstrations. It is similar to `solve`,
9890 but it uses the given solver `s`.
9891 It configures solver `s` using the options in `keywords`, adds the constraints
9892 in `args`, and invokes check.
9893 """
9894 show = keywords.pop("show", False)
9895 if z3_debug():
9896 _z3_assert(isinstance(s, Solver), "Solver object expected")
9897 s.set(**keywords)
9898 s.add(*args)
9899 if show:
9900 print("Problem:")
9901 print(s)
9902 r = s.check()
9903 if r == unsat:
9904 print("no solution")
9905 elif r == unknown:
9906 print("failed to solve")
9907 try:
9908 print(s.model())
9909 except Z3Exception:
9910 return
9911 else:
9912 if show:
9913 print("Solution:")
9914 print(s.model())
9915
9916
9917def prove(claim, show=False, **keywords):
9918 """Try to prove the given claim.
9919
9920 This is a simple function for creating demonstrations. It tries to prove
9921 `claim` by showing the negation is unsatisfiable.
9922
9923 >>> p, q = Bools('p q')
9924 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9925 proved
9926 """
9927 if z3_debug():
9928 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9929 s = Solver()
9930 s.set(**keywords)
9931 s.add(Not(claim))
9932 if show:
9933 print(s)
9934 r = s.check()
9935 if r == unsat:
9936 print("proved")
9937 elif r == unknown:
9938 print("failed to prove")
9939 print(s.model())
9940 else:
9941 print("counterexample")
9942 print(s.model())
9943
9944
9945def _solve_html(*args, **keywords):
9946 """Version of function `solve` that renders HTML output."""
9947 show = keywords.pop("show", False)
9948 s = Solver()
9949 s.set(**keywords)
9950 s.add(*args)
9951 if show:
9952 print("<b>Problem:</b>")
9953 print(s)
9954 r = s.check()
9955 if r == unsat:
9956 print("<b>no solution</b>")
9957 elif r == unknown:
9958 print("<b>failed to solve</b>")
9959 try:
9960 print(s.model())
9961 except Z3Exception:
9962 return
9963 else:
9964 if show:
9965 print("<b>Solution:</b>")
9966 print(s.model())
9967
9968
9969def _solve_using_html(s, *args, **keywords):
9970 """Version of function `solve_using` that renders HTML."""
9971 show = keywords.pop("show", False)
9972 if z3_debug():
9973 _z3_assert(isinstance(s, Solver), "Solver object expected")
9974 s.set(**keywords)
9975 s.add(*args)
9976 if show:
9977 print("<b>Problem:</b>")
9978 print(s)
9979 r = s.check()
9980 if r == unsat:
9981 print("<b>no solution</b>")
9982 elif r == unknown:
9983 print("<b>failed to solve</b>")
9984 try:
9985 print(s.model())
9986 except Z3Exception:
9987 return
9988 else:
9989 if show:
9990 print("<b>Solution:</b>")
9991 print(s.model())
9992
9993
9994def _prove_html(claim, show=False, **keywords):
9995 """Version of function `prove` that renders HTML."""
9996 if z3_debug():
9997 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9998 s = Solver()
9999 s.set(**keywords)
10000 s.add(Not(claim))
10001 if show:
10002 print(s)
10003 r = s.check()
10004 if r == unsat:
10005 print("<b>proved</b>")
10006 elif r == unknown:
10007 print("<b>failed to prove</b>")
10008 print(s.model())
10009 else:
10010 print("<b>counterexample</b>")
10011 print(s.model())
10012
10013
10014def _dict2sarray(sorts, ctx):
10015 sz = len(sorts)
10016 _names = (Symbol * sz)()
10017 _sorts = (Sort * sz)()
10018 i = 0
10019 for k in sorts:
10020 v = sorts[k]
10021 if z3_debug():
10022 _z3_assert(isinstance(k, str), "String expected")
10023 _z3_assert(is_sort(v), "Z3 sort expected")
10024 _names[i] = to_symbol(k, ctx)
10025 _sorts[i] = v.ast
10026 i = i + 1
10027 return sz, _names, _sorts
10028
10029
10030def _dict2darray(decls, ctx):
10031 sz = len(decls)
10032 _names = (Symbol * sz)()
10033 _decls = (FuncDecl * sz)()
10034 i = 0
10035 for k in decls:
10036 v = decls[k]
10037 if z3_debug():
10038 _z3_assert(isinstance(k, str), "String expected")
10039 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
10040 _names[i] = to_symbol(k, ctx)
10041 if is_const(v):
10042 _decls[i] = v.decl().ast
10043 else:
10044 _decls[i] = v.ast
10045 i = i + 1
10046 return sz, _names, _decls
10047
10048class ParserContext:
10049 def __init__(self, ctx= None):
10050 self.ctx = _get_ctx(ctx)
10051 self.pctx = Z3_mk_parser_context(self.ctx.ref())
10052 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
10053
10054 def __del__(self):
10055 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
10056 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
10057 self.pctx = None
10058
10059 def add_sort(self, sort):
10060 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
10061
10062 def add_decl(self, decl):
10063 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
10064
10065 def from_string(self, s):
10066 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
10067
10068def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
10069 """Parse a string in SMT 2.0 format using the given sorts and decls.
10070
10071 The arguments sorts and decls are Python dictionaries used to initialize
10072 the symbol table used for the SMT 2.0 parser.
10073
10074 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
10075 [x > 0, x < 10]
10076 >>> x, y = Ints('x y')
10077 >>> f = Function('f', IntSort(), IntSort())
10078 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
10079 [x + f(y) > 0]
10080 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
10081 [a > 0]
10082 """
10083 ctx = _get_ctx(ctx)
10084 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
10085 dsz, dnames, ddecls = _dict2darray(decls, ctx)
10086 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
10087
10088
10089def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
10090 """Parse a file in SMT 2.0 format using the given sorts and decls.
10091
10092 This function is similar to parse_smt2_string().
10093 """
10094 ctx = _get_ctx(ctx)
10095 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
10096 dsz, dnames, ddecls = _dict2darray(decls, ctx)
10097 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
10098
10099
10100#########################################
10101#
10102# Floating-Point Arithmetic
10103#
10104#########################################
10105
10106
10107# Global default rounding mode
10108_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
10109_dflt_fpsort_ebits = 11
10110_dflt_fpsort_sbits = 53
10111
10112
10113def get_default_rounding_mode(ctx=None):
10114 """Retrieves the global default rounding mode."""
10115 global _dflt_rounding_mode
10116 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
10117 return RTZ(ctx)
10118 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
10119 return RTN(ctx)
10120 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
10121 return RTP(ctx)
10122 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
10123 return RNE(ctx)
10124 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
10125 return RNA(ctx)
10126
10127
10128_ROUNDING_MODES = frozenset({
10129 Z3_OP_FPA_RM_TOWARD_ZERO,
10130 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
10131 Z3_OP_FPA_RM_TOWARD_POSITIVE,
10132 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
10133 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
10134})
10135
10136
10137def set_default_rounding_mode(rm, ctx=None):
10138 global _dflt_rounding_mode
10139 if is_fprm_value(rm):
10140 _dflt_rounding_mode = rm.kind()
10141 else:
10142 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
10143 _dflt_rounding_mode = rm
10144
10145
10146def get_default_fp_sort(ctx=None):
10147 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
10148
10149
10150def set_default_fp_sort(ebits, sbits, ctx=None):
10151 global _dflt_fpsort_ebits
10152 global _dflt_fpsort_sbits
10153 _dflt_fpsort_ebits = ebits
10154 _dflt_fpsort_sbits = sbits
10155
10156
10157def _dflt_rm(ctx=None):
10158 return get_default_rounding_mode(ctx)
10159
10160
10161def _dflt_fps(ctx=None):
10162 return get_default_fp_sort(ctx)
10163
10164
10165def _coerce_fp_expr_list(alist, ctx):
10166 first_fp_sort = None
10167 for a in alist:
10168 if is_fp(a):
10169 if first_fp_sort is None:
10170 first_fp_sort = a.sort()
10171 elif first_fp_sort == a.sort():
10172 pass # OK, same as before
10173 else:
10174 # we saw at least 2 different float sorts; something will
10175 # throw a sort mismatch later, for now assume None.
10176 first_fp_sort = None
10177 break
10178
10179 r = []
10180 for i in range(len(alist)):
10181 a = alist[i]
10182 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
10183 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
10184 r.append(FPVal(a, None, first_fp_sort, ctx))
10185 else:
10186 r.append(a)
10187 return _coerce_expr_list(r, ctx)
10188
10189
10190# FP Sorts
10191
10192class FPSortRef(SortRef):
10193 """Floating-point sort."""
10194
10195 def ebits(self):
10196 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
10197 >>> b = FPSort(8, 24)
10198 >>> b.ebits()
10199 8
10200 """
10201 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
10202
10203 def sbits(self):
10204 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
10205 >>> b = FPSort(8, 24)
10206 >>> b.sbits()
10207 24
10208 """
10209 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
10210
10211 def cast(self, val):
10212 """Try to cast `val` as a floating-point expression.
10213 >>> b = FPSort(8, 24)
10214 >>> b.cast(1.0)
10215 1
10216 >>> b.cast(1.0).sexpr()
10217 '(fp #b0 #x7f #b00000000000000000000000)'
10218 """
10219 if is_expr(val):
10220 if z3_debug():
10221 _z3_assert(self.ctx == val.ctx, "Context mismatch")
10222 return val
10223 else:
10224 return FPVal(val, None, self, self.ctx)
10225
10226
10227def Float16(ctx=None):
10228 """Floating-point 16-bit (half) sort."""
10229 ctx = _get_ctx(ctx)
10230 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
10231
10232
10233def FloatHalf(ctx=None):
10234 """Floating-point 16-bit (half) sort."""
10235 ctx = _get_ctx(ctx)
10236 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
10237
10238
10239def Float32(ctx=None):
10240 """Floating-point 32-bit (single) sort."""
10241 ctx = _get_ctx(ctx)
10242 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
10243
10244
10245def FloatSingle(ctx=None):
10246 """Floating-point 32-bit (single) sort."""
10247 ctx = _get_ctx(ctx)
10248 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
10249
10250
10251def Float64(ctx=None):
10252 """Floating-point 64-bit (double) sort."""
10253 ctx = _get_ctx(ctx)
10254 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
10255
10256
10257def FloatDouble(ctx=None):
10258 """Floating-point 64-bit (double) sort."""
10259 ctx = _get_ctx(ctx)
10260 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
10261
10262
10263def Float128(ctx=None):
10264 """Floating-point 128-bit (quadruple) sort."""
10265 ctx = _get_ctx(ctx)
10266 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
10267
10268
10269def FloatQuadruple(ctx=None):
10270 """Floating-point 128-bit (quadruple) sort."""
10271 ctx = _get_ctx(ctx)
10272 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
10273
10274
10275class FPRMSortRef(SortRef):
10276 """"Floating-point rounding mode sort."""
10277
10278
10279def is_fp_sort(s):
10280 """Return True if `s` is a Z3 floating-point sort.
10281
10282 >>> is_fp_sort(FPSort(8, 24))
10283 True
10284 >>> is_fp_sort(IntSort())
10285 False
10286 """
10287 return isinstance(s, FPSortRef)
10288
10289
10290def is_fprm_sort(s):
10291 """Return True if `s` is a Z3 floating-point rounding mode sort.
10292
10293 >>> is_fprm_sort(FPSort(8, 24))
10294 False
10295 >>> is_fprm_sort(RNE().sort())
10296 True
10297 """
10298 return isinstance(s, FPRMSortRef)
10299
10300# FP Expressions
10301
10302
10303class FPRef(ExprRef):
10304 """Floating-point expressions."""
10305
10306 def sort(self):
10307 """Return the sort of the floating-point expression `self`.
10308
10309 >>> x = FP('1.0', FPSort(8, 24))
10310 >>> x.sort()
10311 FPSort(8, 24)
10312 >>> x.sort() == FPSort(8, 24)
10313 True
10314 """
10315 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
10316
10317 def ebits(self):
10318 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
10319 >>> b = FPSort(8, 24)
10320 >>> b.ebits()
10321 8
10322 """
10323 return self.sort().ebits()
10324
10325 def sbits(self):
10326 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
10327 >>> b = FPSort(8, 24)
10328 >>> b.sbits()
10329 24
10330 """
10331 return self.sort().sbits()
10332
10333 def as_string(self):
10334 """Return a Z3 floating point expression as a Python string."""
10335 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10336
10337 def __le__(self, other):
10338 return fpLEQ(self, other, self.ctx)
10339
10340 def __lt__(self, other):
10341 return fpLT(self, other, self.ctx)
10342
10343 def __ge__(self, other):
10344 return fpGEQ(self, other, self.ctx)
10345
10346 def __gt__(self, other):
10347 return fpGT(self, other, self.ctx)
10348
10349 def __add__(self, other):
10350 """Create the Z3 expression `self + other`.
10351
10352 >>> x = FP('x', FPSort(8, 24))
10353 >>> y = FP('y', FPSort(8, 24))
10354 >>> x + y
10355 x + y
10356 >>> (x + y).sort()
10357 FPSort(8, 24)
10358 """
10359 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10360 return fpAdd(_dflt_rm(), a, b, self.ctx)
10361
10362 def __radd__(self, other):
10363 """Create the Z3 expression `other + self`.
10364
10365 >>> x = FP('x', FPSort(8, 24))
10366 >>> 10 + x
10367 1.25*(2**3) + x
10368 """
10369 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10370 return fpAdd(_dflt_rm(), a, b, self.ctx)
10371
10372 def __sub__(self, other):
10373 """Create the Z3 expression `self - other`.
10374
10375 >>> x = FP('x', FPSort(8, 24))
10376 >>> y = FP('y', FPSort(8, 24))
10377 >>> x - y
10378 x - y
10379 >>> (x - y).sort()
10380 FPSort(8, 24)
10381 """
10382 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10383 return fpSub(_dflt_rm(), a, b, self.ctx)
10384
10385 def __rsub__(self, other):
10386 """Create the Z3 expression `other - self`.
10387
10388 >>> x = FP('x', FPSort(8, 24))
10389 >>> 10 - x
10390 1.25*(2**3) - x
10391 """
10392 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10393 return fpSub(_dflt_rm(), a, b, self.ctx)
10394
10395 def __mul__(self, other):
10396 """Create the Z3 expression `self * other`.
10397
10398 >>> x = FP('x', FPSort(8, 24))
10399 >>> y = FP('y', FPSort(8, 24))
10400 >>> x * y
10401 x * y
10402 >>> (x * y).sort()
10403 FPSort(8, 24)
10404 >>> 10 * y
10405 1.25*(2**3) * y
10406 """
10407 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10408 return fpMul(_dflt_rm(), a, b, self.ctx)
10409
10410 def __rmul__(self, other):
10411 """Create the Z3 expression `other * self`.
10412
10413 >>> x = FP('x', FPSort(8, 24))
10414 >>> y = FP('y', FPSort(8, 24))
10415 >>> x * y
10416 x * y
10417 >>> x * 10
10418 x * 1.25*(2**3)
10419 """
10420 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10421 return fpMul(_dflt_rm(), a, b, self.ctx)
10422
10423 def __pos__(self):
10424 """Create the Z3 expression `+self`."""
10425 return self
10426
10427 def __neg__(self):
10428 """Create the Z3 expression `-self`.
10429
10430 >>> x = FP('x', Float32())
10431 >>> -x
10432 -x
10433 """
10434 return fpNeg(self)
10435
10436 def __div__(self, other):
10437 """Create the Z3 expression `self / other`.
10438
10439 >>> x = FP('x', FPSort(8, 24))
10440 >>> y = FP('y', FPSort(8, 24))
10441 >>> x / y
10442 x / y
10443 >>> (x / y).sort()
10444 FPSort(8, 24)
10445 >>> 10 / y
10446 1.25*(2**3) / y
10447 """
10448 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10449 return fpDiv(_dflt_rm(), a, b, self.ctx)
10450
10451 def __rdiv__(self, other):
10452 """Create the Z3 expression `other / self`.
10453
10454 >>> x = FP('x', FPSort(8, 24))
10455 >>> y = FP('y', FPSort(8, 24))
10456 >>> x / y
10457 x / y
10458 >>> x / 10
10459 x / 1.25*(2**3)
10460 """
10461 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10462 return fpDiv(_dflt_rm(), a, b, self.ctx)
10463
10464 def __truediv__(self, other):
10465 """Create the Z3 expression division `self / other`."""
10466 return self.__div__(other)
10467
10468 def __rtruediv__(self, other):
10469 """Create the Z3 expression division `other / self`."""
10470 return self.__rdiv__(other)
10471
10472 def __mod__(self, other):
10473 """Create the Z3 expression mod `self % other`."""
10474 return fpRem(self, other)
10475
10476 def __rmod__(self, other):
10477 """Create the Z3 expression mod `other % self`."""
10478 return fpRem(other, self)
10479
10480
10481class FPRMRef(ExprRef):
10482 """Floating-point rounding mode expressions"""
10483
10484 def as_string(self):
10485 """Return a Z3 floating point expression as a Python string."""
10486 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10487
10488
10489def RoundNearestTiesToEven(ctx=None):
10490 ctx = _get_ctx(ctx)
10491 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10492
10493
10494def RNE(ctx=None):
10495 ctx = _get_ctx(ctx)
10496 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10497
10498
10499def RoundNearestTiesToAway(ctx=None):
10500 ctx = _get_ctx(ctx)
10501 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10502
10503
10504def RNA(ctx=None):
10505 ctx = _get_ctx(ctx)
10506 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10507
10508
10509def RoundTowardPositive(ctx=None):
10510 ctx = _get_ctx(ctx)
10511 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10512
10513
10514def RTP(ctx=None):
10515 ctx = _get_ctx(ctx)
10516 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10517
10518
10519def RoundTowardNegative(ctx=None):
10520 ctx = _get_ctx(ctx)
10521 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10522
10523
10524def RTN(ctx=None):
10525 ctx = _get_ctx(ctx)
10526 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10527
10528
10529def RoundTowardZero(ctx=None):
10530 ctx = _get_ctx(ctx)
10531 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10532
10533
10534def RTZ(ctx=None):
10535 ctx = _get_ctx(ctx)
10536 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10537
10538
10539def is_fprm(a):
10540 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
10541
10542 >>> rm = RNE()
10543 >>> is_fprm(rm)
10544 True
10545 >>> rm = 1.0
10546 >>> is_fprm(rm)
10547 False
10548 """
10549 return isinstance(a, FPRMRef)
10550
10551
10552def is_fprm_value(a):
10553 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
10554 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
10555
10556# FP Numerals
10557
10558
10559class FPNumRef(FPRef):
10560 """The sign of the numeral.
10561
10562 >>> x = FPVal(+1.0, FPSort(8, 24))
10563 >>> x.sign()
10564 False
10565 >>> x = FPVal(-1.0, FPSort(8, 24))
10566 >>> x.sign()
10567 True
10568 """
10569
10570 def sign(self):
10571 num = ctypes.c_bool()
10572 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
10573 if nsign is False:
10574 raise Z3Exception("error retrieving the sign of a numeral.")
10575 return num.value != 0
10576
10577 """The sign of a floating-point numeral as a bit-vector expression.
10578
10579 Remark: NaN's are invalid arguments.
10580 """
10581
10582 def sign_as_bv(self):
10583 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10584
10585 """The significand of the numeral.
10586
10587 >>> x = FPVal(2.5, FPSort(8, 24))
10588 >>> x.significand()
10589 1.25
10590 """
10591
10592 def significand(self):
10593 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10594
10595 """The significand of the numeral as a long.
10596
10597 >>> x = FPVal(2.5, FPSort(8, 24))
10598 >>> x.significand_as_long()
10599 1.25
10600 """
10601
10602 def significand_as_long(self):
10603 ptr = (ctypes.c_ulonglong * 1)()
10604 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10605 raise Z3Exception("error retrieving the significand of a numeral.")
10606 return ptr[0]
10607
10608 """The significand of the numeral as a bit-vector expression.
10609
10610 Remark: NaN are invalid arguments.
10611 """
10612
10613 def significand_as_bv(self):
10614 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10615
10616 """The exponent of the numeral.
10617
10618 >>> x = FPVal(2.5, FPSort(8, 24))
10619 >>> x.exponent()
10620 1
10621 """
10622
10623 def exponent(self, biased=True):
10624 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10625
10626 """The exponent of the numeral as a long.
10627
10628 >>> x = FPVal(2.5, FPSort(8, 24))
10629 >>> x.exponent_as_long()
10630 1
10631 """
10632
10633 def exponent_as_long(self, biased=True):
10634 ptr = (ctypes.c_longlong * 1)()
10635 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10636 raise Z3Exception("error retrieving the exponent of a numeral.")
10637 return ptr[0]
10638
10639 """The exponent of the numeral as a bit-vector expression.
10640
10641 Remark: NaNs are invalid arguments.
10642 """
10643
10644 def exponent_as_bv(self, biased=True):
10645 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10646
10647 """Indicates whether the numeral is a NaN."""
10648
10649 def isNaN(self):
10650 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10651
10652 """Indicates whether the numeral is +oo or -oo."""
10653
10654 def isInf(self):
10655 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10656
10657 """Indicates whether the numeral is +zero or -zero."""
10658
10659 def isZero(self):
10660 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10661
10662 """Indicates whether the numeral is normal."""
10663
10664 def isNormal(self):
10665 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10666
10667 """Indicates whether the numeral is subnormal."""
10668
10669 def isSubnormal(self):
10670 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10671
10672 """Indicates whether the numeral is positive."""
10673
10674 def isPositive(self):
10675 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10676
10677 """Indicates whether the numeral is negative."""
10678
10679 def isNegative(self):
10680 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10681
10682 """
10683 The string representation of the numeral.
10684
10685 >>> x = FPVal(20, FPSort(8, 24))
10686 >>> x.as_string()
10687 1.25*(2**4)
10688 """
10689
10690 def as_string(self):
10691 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10692 return ("FPVal(%s, %s)" % (s, self.sort()))
10693
10694 def py_value(self):
10695 bv = simplify(fpToIEEEBV(self))
10696 binary = bv.py_value()
10697 if not isinstance(binary, int):
10698 return None
10699 # Decode the IEEE 754 binary representation
10700 import struct
10701 bytes_rep = binary.to_bytes(8, byteorder='big')
10702 return struct.unpack('>d', bytes_rep)[0]
10703
10704
10705def is_fp(a):
10706 """Return `True` if `a` is a Z3 floating-point expression.
10707
10708 >>> b = FP('b', FPSort(8, 24))
10709 >>> is_fp(b)
10710 True
10711 >>> is_fp(b + 1.0)
10712 True
10713 >>> is_fp(Int('x'))
10714 False
10715 """
10716 return isinstance(a, FPRef)
10717
10718
10719def is_fp_value(a):
10720 """Return `True` if `a` is a Z3 floating-point numeral value.
10721
10722 >>> b = FP('b', FPSort(8, 24))
10723 >>> is_fp_value(b)
10724 False
10725 >>> b = FPVal(1.0, FPSort(8, 24))
10726 >>> b
10727 1
10728 >>> is_fp_value(b)
10729 True
10730 """
10731 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10732
10733
10734def FPSort(ebits, sbits, ctx=None):
10735 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10736
10737 >>> Single = FPSort(8, 24)
10738 >>> Double = FPSort(11, 53)
10739 >>> Single
10740 FPSort(8, 24)
10741 >>> x = Const('x', Single)
10742 >>> eq(x, FP('x', FPSort(8, 24)))
10743 True
10744 """
10745 ctx = _get_ctx(ctx)
10746 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10747
10748
10749def _to_float_str(val, exp=0):
10750 if isinstance(val, float):
10751 if math.isnan(val):
10752 res = "NaN"
10753 elif val == 0.0:
10754 sone = math.copysign(1.0, val)
10755 if sone < 0.0:
10756 return "-0.0"
10757 else:
10758 return "+0.0"
10759 elif val == float("+inf"):
10760 res = "+oo"
10761 elif val == float("-inf"):
10762 res = "-oo"
10763 else:
10764 v = val.as_integer_ratio()
10765 num = v[0]
10766 den = v[1]
10767 rvs = str(num) + "/" + str(den)
10768 res = rvs
10769 elif isinstance(val, bool):
10770 if val:
10771 res = "1.0"
10772 else:
10773 res = "0.0"
10774 elif _is_int(val):
10775 res = str(val)
10776 elif isinstance(val, str):
10777 inx = val.find("*(2**")
10778 if inx == -1:
10779 res = val
10780 if exp != 0:
10781 inx = val.lower().find("p")
10782 if inx != -1:
10783 res = val[:inx]
10784 exp = int(val[inx + 1:]) + int(exp)
10785 elif val[-1] == ")":
10786 res = val[0:inx]
10787 exp = str(int(val[inx + 5:-1]) + int(exp))
10788 else:
10789 _z3_assert(False, "String does not have floating-point numeral form.")
10790 elif z3_debug():
10791 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10792 if exp == 0:
10793 return res
10794 else:
10795 return res + "p" + str(exp)
10796
10797
10798def fpNaN(s):
10799 """Create a Z3 floating-point NaN term.
10800
10801 >>> s = FPSort(8, 24)
10802 >>> set_fpa_pretty(True)
10803 >>> fpNaN(s)
10804 NaN
10805 >>> pb = get_fpa_pretty()
10806 >>> set_fpa_pretty(False)
10807 >>> fpNaN(s)
10808 fpNaN(FPSort(8, 24))
10809 >>> set_fpa_pretty(pb)
10810 """
10811 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10812 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10813
10814
10815def fpPlusInfinity(s):
10816 """Create a Z3 floating-point +oo term.
10817
10818 >>> s = FPSort(8, 24)
10819 >>> pb = get_fpa_pretty()
10820 >>> set_fpa_pretty(True)
10821 >>> fpPlusInfinity(s)
10822 +oo
10823 >>> set_fpa_pretty(False)
10824 >>> fpPlusInfinity(s)
10825 fpPlusInfinity(FPSort(8, 24))
10826 >>> set_fpa_pretty(pb)
10827 """
10828 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10829 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10830
10831
10832def fpMinusInfinity(s):
10833 """Create a Z3 floating-point -oo term."""
10834 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10835 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10836
10837
10838def fpInfinity(s, negative):
10839 """Create a Z3 floating-point +oo or -oo term."""
10840 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10841 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10842 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10843
10844
10845def fpPlusZero(s):
10846 """Create a Z3 floating-point +0.0 term."""
10847 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10848 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10849
10850
10851def fpMinusZero(s):
10852 """Create a Z3 floating-point -0.0 term."""
10853 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10854 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10855
10856
10857def fpZero(s, negative):
10858 """Create a Z3 floating-point +0.0 or -0.0 term."""
10859 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10860 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10861 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10862
10863
10864def FPVal(sig, exp=None, fps=None, ctx=None):
10865 """Return a floating-point value of value `sig * 2**exp` and sort `fps`.
10866 If `exp=None`, then the exponent is zero.
10867 If `ctx=None`, then the global context is used.
10868
10869 >>> v = FPVal(20.0, FPSort(8, 24))
10870 >>> v
10871 1.25*(2**4)
10872 >>> print("0x%.8x" % v.exponent_as_long(False))
10873 0x00000004
10874 >>> v = FPVal(2.25, FPSort(8, 24))
10875 >>> v
10876 1.125*(2**1)
10877 >>> v = FPVal(-2.25, FPSort(8, 24))
10878 >>> v
10879 -1.125*(2**1)
10880 >>> FPVal(-0.0, FPSort(8, 24))
10881 -0.0
10882 >>> FPVal(0.0, FPSort(8, 24))
10883 +0.0
10884 >>> FPVal(+0.0, FPSort(8, 24))
10885 +0.0
10886 >>> FPVal(1.0, 3, Float32())
10887 1*(2**3)
10888 >>> FPVal(1, 3, Float32())
10889 1*(2**3)
10890 >>> FPVal("1.5", -2, Float32())
10891 1.5*(2**-2)
10892 >>> FPVal("1.25*(2**4)", 1, Float32())
10893 1.25*(2**5)
10894 >>> FPVal("1.25*(2**4)", -4, Float32())
10895 1.25
10896 >>> FPVal("1p2", 3, Float32())
10897 1*(2**5)
10898 >>> FPVal("1P2", 3, Float32())
10899 1*(2**5)
10900 >>> FPVal("1.5p-2", 2, Float32())
10901 1.5
10902 >>> FPVal(1.5, 0, Float32())
10903 1.5
10904 >>> FPVal(1.5, fps=Float32())
10905 1.5
10906 >>> [FPVal(v, 3, Float32()) for v in
10907 ... [float("nan"), float("inf"), float("-inf"), 0.0, -0.0]]
10908 [NaN, +oo, -oo, +0.0, -0.0]
10909 >>> [FPVal(v, -2, Float32()) for v in
10910 ... ["NaN", "+oo", "-oo", "+0.0", "-0.0"]]
10911 [NaN, +oo, -oo, +0.0, -0.0]
10912 """
10913 ctx = _get_ctx(ctx)
10914 if is_fp_sort(exp):
10915 fps = exp
10916 exp = None
10917 elif fps is None:
10918 fps = _dflt_fps(ctx)
10919 _z3_assert(is_fp_sort(fps), "sort mismatch")
10920 if exp is None:
10921 exp = 0
10922 val = _to_float_str(sig)
10923 if val == "NaN" or val == "nan":
10924 return fpNaN(fps)
10925 elif val == "-0.0":
10926 return fpMinusZero(fps)
10927 elif val == "0.0" or val == "+0.0":
10928 return fpPlusZero(fps)
10929 elif val == "+oo" or val == "+inf" or val == "+Inf":
10930 return fpPlusInfinity(fps)
10931 elif val == "-oo" or val == "-inf" or val == "-Inf":
10932 return fpMinusInfinity(fps)
10933 else:
10934 return FPNumRef(Z3_mk_numeral(ctx.ref(), _to_float_str(sig, exp), fps.ast), ctx)
10935
10936
10937def FP(name, fpsort, ctx=None):
10938 """Return a floating-point constant named `name`.
10939 `fpsort` is the floating-point sort.
10940 If `ctx=None`, then the global context is used.
10941
10942 >>> x = FP('x', FPSort(8, 24))
10943 >>> is_fp(x)
10944 True
10945 >>> x.ebits()
10946 8
10947 >>> x.sort()
10948 FPSort(8, 24)
10949 >>> word = FPSort(8, 24)
10950 >>> x2 = FP('x', word)
10951 >>> eq(x, x2)
10952 True
10953 """
10954 if isinstance(fpsort, FPSortRef) and ctx is None:
10955 ctx = fpsort.ctx
10956 else:
10957 ctx = _get_ctx(ctx)
10958 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10959
10960
10961def FPs(names, fpsort, ctx=None):
10962 """Return an array of floating-point constants.
10963
10964 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10965 >>> x.sort()
10966 FPSort(8, 24)
10967 >>> x.sbits()
10968 24
10969 >>> x.ebits()
10970 8
10971 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10972 (x + y) * z
10973 """
10974 ctx = _get_ctx(ctx)
10975 if isinstance(names, str):
10976 names = names.split(" ")
10977 return [FP(name, fpsort, ctx) for name in names]
10978
10979
10980def fpAbs(a, ctx=None):
10981 """Create a Z3 floating-point absolute value expression.
10982
10983 >>> s = FPSort(8, 24)
10984 >>> rm = RNE()
10985 >>> x = FPVal(1.0, s)
10986 >>> fpAbs(x)
10987 fpAbs(1)
10988 >>> y = FPVal(-20.0, s)
10989 >>> y
10990 -1.25*(2**4)
10991 >>> fpAbs(y)
10992 fpAbs(-1.25*(2**4))
10993 >>> fpAbs(-1.25*(2**4))
10994 fpAbs(-1.25*(2**4))
10995 >>> fpAbs(x).sort()
10996 FPSort(8, 24)
10997 """
10998 ctx = _get_ctx(ctx)
10999 [a] = _coerce_fp_expr_list([a], ctx)
11000 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
11001
11002
11003def fpNeg(a, ctx=None):
11004 """Create a Z3 floating-point addition expression.
11005
11006 >>> s = FPSort(8, 24)
11007 >>> rm = RNE()
11008 >>> x = FP('x', s)
11009 >>> fpNeg(x)
11010 -x
11011 >>> fpNeg(x).sort()
11012 FPSort(8, 24)
11013 """
11014 ctx = _get_ctx(ctx)
11015 [a] = _coerce_fp_expr_list([a], ctx)
11016 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
11017
11018
11019def _mk_fp_unary(f, rm, a, ctx):
11020 ctx = _get_ctx(ctx)
11021 [a] = _coerce_fp_expr_list([a], ctx)
11022 if z3_debug():
11023 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11024 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
11025 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
11026
11027
11028def _mk_fp_unary_pred(f, a, ctx):
11029 ctx = _get_ctx(ctx)
11030 [a] = _coerce_fp_expr_list([a], ctx)
11031 if z3_debug():
11032 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
11033 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
11034
11035
11036def _mk_fp_bin(f, rm, a, b, ctx):
11037 ctx = _get_ctx(ctx)
11038 [a, b] = _coerce_fp_expr_list([a, b], ctx)
11039 if z3_debug():
11040 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11041 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
11042 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
11043
11044
11045def _mk_fp_bin_norm(f, a, b, ctx):
11046 ctx = _get_ctx(ctx)
11047 [a, b] = _coerce_fp_expr_list([a, b], ctx)
11048 if z3_debug():
11049 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
11050 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
11051
11052
11053def _mk_fp_bin_pred(f, a, b, ctx):
11054 ctx = _get_ctx(ctx)
11055 [a, b] = _coerce_fp_expr_list([a, b], ctx)
11056 if z3_debug():
11057 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
11058 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
11059
11060
11061def _mk_fp_tern(f, rm, a, b, c, ctx):
11062 ctx = _get_ctx(ctx)
11063 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
11064 if z3_debug():
11065 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11066 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
11067 c), "Second, third or fourth argument must be a Z3 floating-point expression")
11068 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
11069
11070
11071def fpAdd(rm, a, b, ctx=None):
11072 """Create a Z3 floating-point addition expression.
11073
11074 >>> s = FPSort(8, 24)
11075 >>> rm = RNE()
11076 >>> x = FP('x', s)
11077 >>> y = FP('y', s)
11078 >>> fpAdd(rm, x, y)
11079 x + y
11080 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
11081 fpAdd(RTZ(), x, y)
11082 >>> fpAdd(rm, x, y).sort()
11083 FPSort(8, 24)
11084 """
11085 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
11086
11087
11088def fpSub(rm, a, b, ctx=None):
11089 """Create a Z3 floating-point subtraction expression.
11090
11091 >>> s = FPSort(8, 24)
11092 >>> rm = RNE()
11093 >>> x = FP('x', s)
11094 >>> y = FP('y', s)
11095 >>> fpSub(rm, x, y)
11096 x - y
11097 >>> fpSub(rm, x, y).sort()
11098 FPSort(8, 24)
11099 """
11100 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
11101
11102
11103def fpMul(rm, a, b, ctx=None):
11104 """Create a Z3 floating-point multiplication expression.
11105
11106 >>> s = FPSort(8, 24)
11107 >>> rm = RNE()
11108 >>> x = FP('x', s)
11109 >>> y = FP('y', s)
11110 >>> fpMul(rm, x, y)
11111 x * y
11112 >>> fpMul(rm, x, y).sort()
11113 FPSort(8, 24)
11114 """
11115 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
11116
11117
11118def fpDiv(rm, a, b, ctx=None):
11119 """Create a Z3 floating-point division expression.
11120
11121 >>> s = FPSort(8, 24)
11122 >>> rm = RNE()
11123 >>> x = FP('x', s)
11124 >>> y = FP('y', s)
11125 >>> fpDiv(rm, x, y)
11126 x / y
11127 >>> fpDiv(rm, x, y).sort()
11128 FPSort(8, 24)
11129 """
11130 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
11131
11132
11133def fpRem(a, b, ctx=None):
11134 """Create a Z3 floating-point remainder expression.
11135
11136 >>> s = FPSort(8, 24)
11137 >>> x = FP('x', s)
11138 >>> y = FP('y', s)
11139 >>> fpRem(x, y)
11140 fpRem(x, y)
11141 >>> fpRem(x, y).sort()
11142 FPSort(8, 24)
11143 """
11144 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
11145
11146
11147def fpMin(a, b, ctx=None):
11148 """Create a Z3 floating-point minimum expression.
11149
11150 >>> s = FPSort(8, 24)
11151 >>> rm = RNE()
11152 >>> x = FP('x', s)
11153 >>> y = FP('y', s)
11154 >>> fpMin(x, y)
11155 fpMin(x, y)
11156 >>> fpMin(x, y).sort()
11157 FPSort(8, 24)
11158 """
11159 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
11160
11161
11162def fpMax(a, b, ctx=None):
11163 """Create a Z3 floating-point maximum expression.
11164
11165 >>> s = FPSort(8, 24)
11166 >>> rm = RNE()
11167 >>> x = FP('x', s)
11168 >>> y = FP('y', s)
11169 >>> fpMax(x, y)
11170 fpMax(x, y)
11171 >>> fpMax(x, y).sort()
11172 FPSort(8, 24)
11173 """
11174 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
11175
11176
11177def fpFMA(rm, a, b, c, ctx=None):
11178 """Create a Z3 floating-point fused multiply-add expression.
11179 """
11180 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
11181
11182
11183def fpSqrt(rm, a, ctx=None):
11184 """Create a Z3 floating-point square root expression.
11185 """
11186 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
11187
11188
11189def fpRoundToIntegral(rm, a, ctx=None):
11190 """Create a Z3 floating-point roundToIntegral expression.
11191 """
11192 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
11193
11194
11195def fpIsNaN(a, ctx=None):
11196 """Create a Z3 floating-point isNaN expression.
11197
11198 >>> s = FPSort(8, 24)
11199 >>> x = FP('x', s)
11200 >>> y = FP('y', s)
11201 >>> fpIsNaN(x)
11202 fpIsNaN(x)
11203 """
11204 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
11205
11206
11207def fpIsInf(a, ctx=None):
11208 """Create a Z3 floating-point isInfinite expression.
11209
11210 >>> s = FPSort(8, 24)
11211 >>> x = FP('x', s)
11212 >>> fpIsInf(x)
11213 fpIsInf(x)
11214 """
11215 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
11216
11217
11218def fpIsZero(a, ctx=None):
11219 """Create a Z3 floating-point isZero expression.
11220 """
11221 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
11222
11223
11224def fpIsNormal(a, ctx=None):
11225 """Create a Z3 floating-point isNormal expression.
11226 """
11227 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
11228
11229
11230def fpIsSubnormal(a, ctx=None):
11231 """Create a Z3 floating-point isSubnormal expression.
11232 """
11233 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
11234
11235
11236def fpIsNegative(a, ctx=None):
11237 """Create a Z3 floating-point isNegative expression.
11238 """
11239 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
11240
11241
11242def fpIsPositive(a, ctx=None):
11243 """Create a Z3 floating-point isPositive expression.
11244 """
11245 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
11246
11247
11248def _check_fp_args(a, b):
11249 if z3_debug():
11250 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
11251
11252
11253def fpLT(a, b, ctx=None):
11254 """Create the Z3 floating-point expression `other < self`.
11255
11256 >>> x, y = FPs('x y', FPSort(8, 24))
11257 >>> fpLT(x, y)
11258 x < y
11259 >>> (x < y).sexpr()
11260 '(fp.lt x y)'
11261 """
11262 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
11263
11264
11265def fpLEQ(a, b, ctx=None):
11266 """Create the Z3 floating-point expression `other <= self`.
11267
11268 >>> x, y = FPs('x y', FPSort(8, 24))
11269 >>> fpLEQ(x, y)
11270 x <= y
11271 >>> (x <= y).sexpr()
11272 '(fp.leq x y)'
11273 """
11274 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
11275
11276
11277def fpGT(a, b, ctx=None):
11278 """Create the Z3 floating-point expression `other > self`.
11279
11280 >>> x, y = FPs('x y', FPSort(8, 24))
11281 >>> fpGT(x, y)
11282 x > y
11283 >>> (x > y).sexpr()
11284 '(fp.gt x y)'
11285 """
11286 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
11287
11288
11289def fpGEQ(a, b, ctx=None):
11290 """Create the Z3 floating-point expression `other >= self`.
11291
11292 >>> x, y = FPs('x y', FPSort(8, 24))
11293 >>> fpGEQ(x, y)
11294 x >= y
11295 >>> (x >= y).sexpr()
11296 '(fp.geq x y)'
11297 """
11298 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
11299
11300
11301def fpEQ(a, b, ctx=None):
11302 """Create the Z3 floating-point expression `fpEQ(other, self)`.
11303
11304 >>> x, y = FPs('x y', FPSort(8, 24))
11305 >>> fpEQ(x, y)
11306 fpEQ(x, y)
11307 >>> fpEQ(x, y).sexpr()
11308 '(fp.eq x y)'
11309 """
11310 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
11311
11312
11313def fpNEQ(a, b, ctx=None):
11314 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
11315
11316 >>> x, y = FPs('x y', FPSort(8, 24))
11317 >>> fpNEQ(x, y)
11318 Not(fpEQ(x, y))
11319 >>> (x != y).sexpr()
11320 '(distinct x y)'
11321 """
11322 return Not(fpEQ(a, b, ctx))
11323
11324
11325def fpFP(sgn, exp, sig, ctx=None):
11326 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
11327
11328 >>> s = FPSort(8, 24)
11329 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
11330 >>> print(x)
11331 fpFP(1, 127, 4194304)
11332 >>> xv = FPVal(-1.5, s)
11333 >>> print(xv)
11334 -1.5
11335 >>> slvr = Solver()
11336 >>> slvr.add(fpEQ(x, xv))
11337 >>> slvr.check()
11338 sat
11339 >>> xv = FPVal(+1.5, s)
11340 >>> print(xv)
11341 1.5
11342 >>> slvr = Solver()
11343 >>> slvr.add(fpEQ(x, xv))
11344 >>> slvr.check()
11345 unsat
11346 """
11347 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
11348 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
11349 ctx = _get_ctx(ctx)
11350 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
11351 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
11352
11353
11354def fpToFP(a1, a2=None, a3=None, ctx=None):
11355 """Create a Z3 floating-point conversion expression from other term sorts
11356 to floating-point.
11357
11358 From a bit-vector term in IEEE 754-2008 format:
11359 >>> x = FPVal(1.0, Float32())
11360 >>> x_bv = fpToIEEEBV(x)
11361 >>> simplify(fpToFP(x_bv, Float32()))
11362 1
11363
11364 From a floating-point term with different precision:
11365 >>> x = FPVal(1.0, Float32())
11366 >>> x_db = fpToFP(RNE(), x, Float64())
11367 >>> x_db.sort()
11368 FPSort(11, 53)
11369
11370 From a real term:
11371 >>> x_r = RealVal(1.5)
11372 >>> simplify(fpToFP(RNE(), x_r, Float32()))
11373 1.5
11374
11375 From a signed bit-vector term:
11376 >>> x_signed = BitVecVal(-5, BitVecSort(32))
11377 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
11378 -1.25*(2**2)
11379 """
11380 ctx = _get_ctx(ctx)
11381 if is_bv(a1) and is_fp_sort(a2):
11382 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
11383 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
11384 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
11385 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
11386 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
11387 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
11388 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
11389 else:
11390 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
11391
11392
11393def fpBVToFP(v, sort, ctx=None):
11394 """Create a Z3 floating-point conversion expression that represents the
11395 conversion from a bit-vector term to a floating-point term.
11396
11397 >>> x_bv = BitVecVal(0x3F800000, 32)
11398 >>> x_fp = fpBVToFP(x_bv, Float32())
11399 >>> x_fp
11400 fpToFP(1065353216)
11401 >>> simplify(x_fp)
11402 1
11403 """
11404 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
11405 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
11406 ctx = _get_ctx(ctx)
11407 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
11408
11409
11410def fpFPToFP(rm, v, sort, ctx=None):
11411 """Create a Z3 floating-point conversion expression that represents the
11412 conversion from a floating-point term to a floating-point term of different precision.
11413
11414 >>> x_sgl = FPVal(1.0, Float32())
11415 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
11416 >>> x_dbl
11417 fpToFP(RNE(), 1)
11418 >>> simplify(x_dbl)
11419 1
11420 >>> x_dbl.sort()
11421 FPSort(11, 53)
11422 """
11423 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11424 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
11425 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11426 ctx = _get_ctx(ctx)
11427 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11428
11429
11430def fpRealToFP(rm, v, sort, ctx=None):
11431 """Create a Z3 floating-point conversion expression that represents the
11432 conversion from a real term to a floating-point term.
11433
11434 >>> x_r = RealVal(1.5)
11435 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
11436 >>> x_fp
11437 fpToFP(RNE(), 3/2)
11438 >>> simplify(x_fp)
11439 1.5
11440 """
11441 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11442 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
11443 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11444 ctx = _get_ctx(ctx)
11445 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11446
11447
11448def fpSignedToFP(rm, v, sort, ctx=None):
11449 """Create a Z3 floating-point conversion expression that represents the
11450 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
11451
11452 >>> x_signed = BitVecVal(-5, BitVecSort(32))
11453 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
11454 >>> x_fp
11455 fpToFP(RNE(), 4294967291)
11456 >>> simplify(x_fp)
11457 -1.25*(2**2)
11458 """
11459 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11460 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
11461 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11462 ctx = _get_ctx(ctx)
11463 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11464
11465
11466def fpUnsignedToFP(rm, v, sort, ctx=None):
11467 """Create a Z3 floating-point conversion expression that represents the
11468 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
11469
11470 >>> x_signed = BitVecVal(-5, BitVecSort(32))
11471 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
11472 >>> x_fp
11473 fpToFPUnsigned(RNE(), 4294967291)
11474 >>> simplify(x_fp)
11475 1*(2**32)
11476 """
11477 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11478 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
11479 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11480 ctx = _get_ctx(ctx)
11481 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11482
11483
11484def fpToFPUnsigned(rm, x, s, ctx=None):
11485 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
11486 if z3_debug():
11487 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11488 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
11489 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
11490 ctx = _get_ctx(ctx)
11491 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
11492
11493
11494def fpToSBV(rm, x, s, ctx=None):
11495 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
11496
11497 >>> x = FP('x', FPSort(8, 24))
11498 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
11499 >>> print(is_fp(x))
11500 True
11501 >>> print(is_bv(y))
11502 True
11503 >>> print(is_fp(y))
11504 False
11505 >>> print(is_bv(x))
11506 False
11507 """
11508 if z3_debug():
11509 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11510 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11511 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11512 ctx = _get_ctx(ctx)
11513 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11514
11515
11516def fpToUBV(rm, x, s, ctx=None):
11517 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
11518
11519 >>> x = FP('x', FPSort(8, 24))
11520 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
11521 >>> print(is_fp(x))
11522 True
11523 >>> print(is_bv(y))
11524 True
11525 >>> print(is_fp(y))
11526 False
11527 >>> print(is_bv(x))
11528 False
11529 """
11530 if z3_debug():
11531 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11532 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11533 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11534 ctx = _get_ctx(ctx)
11535 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11536
11537
11538def fpToReal(x, ctx=None):
11539 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
11540
11541 >>> x = FP('x', FPSort(8, 24))
11542 >>> y = fpToReal(x)
11543 >>> print(is_fp(x))
11544 True
11545 >>> print(is_real(y))
11546 True
11547 >>> print(is_fp(y))
11548 False
11549 >>> print(is_real(x))
11550 False
11551 """
11552 if z3_debug():
11553 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11554 ctx = _get_ctx(ctx)
11555 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
11556
11557
11558def fpToIEEEBV(x, ctx=None):
11559 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
11560
11561 The size of the resulting bit-vector is automatically determined.
11562
11563 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
11564 knows only one NaN and it will always produce the same bit-vector representation of
11565 that NaN.
11566
11567 >>> x = FP('x', FPSort(8, 24))
11568 >>> y = fpToIEEEBV(x)
11569 >>> print(is_fp(x))
11570 True
11571 >>> print(is_bv(y))
11572 True
11573 >>> print(is_fp(y))
11574 False
11575 >>> print(is_bv(x))
11576 False
11577 """
11578 if z3_debug():
11579 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11580 ctx = _get_ctx(ctx)
11581 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
11582
11583
11584#########################################
11585#
11586# Strings, Sequences and Regular expressions
11587#
11588#########################################
11589
11590class SeqSortRef(SortRef):
11591 """Sequence sort."""
11592
11593 def is_string(self):
11594 """Determine if sort is a string
11595 >>> s = StringSort()
11596 >>> s.is_string()
11597 True
11598 >>> s = SeqSort(IntSort())
11599 >>> s.is_string()
11600 False
11601 """
11602 return Z3_is_string_sort(self.ctx_ref(), self.ast)
11603
11604 def basis(self):
11605 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11606
11607class CharSortRef(SortRef):
11608 """Character sort."""
11609
11610
11611def StringSort(ctx=None):
11612 """Create a string sort
11613 >>> s = StringSort()
11614 >>> print(s)
11615 String
11616 """
11617 ctx = _get_ctx(ctx)
11618 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
11619
11620def CharSort(ctx=None):
11621 """Create a character sort
11622 >>> ch = CharSort()
11623 >>> print(ch)
11624 Char
11625 """
11626 ctx = _get_ctx(ctx)
11627 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11628
11629
11630def SeqSort(s):
11631 """Create a sequence sort over elements provided in the argument
11632 >>> s = SeqSort(IntSort())
11633 >>> s == Unit(IntVal(1)).sort()
11634 True
11635 """
11636 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11637
11638
11639class SeqRef(ExprRef):
11640 """Sequence expression."""
11641
11642 def sort(self):
11643 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11644
11645 def __add__(self, other):
11646 return Concat(self, other)
11647
11648 def __radd__(self, other):
11649 return Concat(other, self)
11650
11651 def __pow__(self, other):
11652 return SeqPower(self, other)
11653
11654 def __getitem__(self, i):
11655 if _is_int(i):
11656 i = IntVal(i, self.ctx)
11657 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11658
11659 def at(self, i):
11660 if _is_int(i):
11661 i = IntVal(i, self.ctx)
11662 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11663
11664 def is_string(self):
11665 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11666
11667 def is_string_value(self):
11668 return Z3_is_string(self.ctx_ref(), self.as_ast())
11669
11670 def as_string(self):
11671 """Return a string representation of sequence expression."""
11672 if self.is_string_value():
11673 string_length = ctypes.c_uint()
11674 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11675 return string_at(chars, size=string_length.value).decode("latin-1")
11676 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11677
11678 def py_value(self):
11679 return self.as_string()
11680
11681 def __le__(self, other):
11682 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11683
11684 def __lt__(self, other):
11685 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11686
11687 def __ge__(self, other):
11688 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11689
11690 def __gt__(self, other):
11691 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11692
11693
11694def _coerce_char(ch, ctx=None):
11695 if isinstance(ch, str):
11696 ctx = _get_ctx(ctx)
11697 ch = CharVal(ch, ctx)
11698 if not is_expr(ch):
11699 raise Z3Exception("Character expression expected")
11700 return ch
11701
11702class CharRef(ExprRef):
11703 """Character expression."""
11704
11705 def __le__(self, other):
11706 other = _coerce_char(other, self.ctx)
11707 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11708
11709 def to_int(self):
11710 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11711
11712 def to_bv(self):
11713 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11714
11715 def is_digit(self):
11716 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11717
11718
11719def CharVal(ch, ctx=None):
11720 ctx = _get_ctx(ctx)
11721 if isinstance(ch, str):
11722 ch = ord(ch)
11723 if not isinstance(ch, int):
11724 raise Z3Exception("character value should be an ordinal")
11725 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11726
11727def CharFromBv(bv):
11728 if not is_expr(bv):
11729 raise Z3Exception("Bit-vector expression needed")
11730 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11731
11732def CharToBv(ch, ctx=None):
11733 ch = _coerce_char(ch, ctx)
11734 return ch.to_bv()
11735
11736def CharToInt(ch, ctx=None):
11737 ch = _coerce_char(ch, ctx)
11738 return ch.to_int()
11739
11740def CharIsDigit(ch, ctx=None):
11741 ch = _coerce_char(ch, ctx)
11742 return ch.is_digit()
11743
11744def _coerce_seq(s, ctx=None):
11745 if isinstance(s, str):
11746 ctx = _get_ctx(ctx)
11747 s = StringVal(s, ctx)
11748 if not is_expr(s):
11749 raise Z3Exception("Non-expression passed as a sequence")
11750 if not is_seq(s):
11751 raise Z3Exception("Non-sequence passed as a sequence")
11752 return s
11753
11754
11755def _get_ctx2(a, b, ctx=None):
11756 if is_expr(a):
11757 return a.ctx
11758 if is_expr(b):
11759 return b.ctx
11760 if ctx is None:
11761 ctx = main_ctx()
11762 return ctx
11763
11764
11765def is_seq(a):
11766 """Return `True` if `a` is a Z3 sequence expression.
11767 >>> print (is_seq(Unit(IntVal(0))))
11768 True
11769 >>> print (is_seq(StringVal("abc")))
11770 True
11771 """
11772 return isinstance(a, SeqRef)
11773
11774
11775def is_string(a: Any) -> bool:
11776 """Return `True` if `a` is a Z3 string expression.
11777 >>> print (is_string(StringVal("ab")))
11778 True
11779 """
11780 return isinstance(a, SeqRef) and a.is_string()
11781
11782
11783def is_string_value(a: Any) -> bool:
11784 """return 'True' if 'a' is a Z3 string constant expression.
11785 >>> print (is_string_value(StringVal("a")))
11786 True
11787 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11788 False
11789 """
11790 return isinstance(a, SeqRef) and a.is_string_value()
11791
11792def StringVal(s, ctx=None):
11793 """create a string expression"""
11794 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11795 ctx = _get_ctx(ctx)
11796 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11797
11798
11799def String(name, ctx=None):
11800 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11801
11802 >>> x = String('x')
11803 """
11804 ctx = _get_ctx(ctx)
11805 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11806
11807
11808def Strings(names, ctx=None):
11809 """Return a tuple of String constants. """
11810 ctx = _get_ctx(ctx)
11811 if isinstance(names, str):
11812 names = names.split(" ")
11813 return [String(name, ctx) for name in names]
11814
11815
11816def SubString(s, offset, length):
11817 """Extract substring or subsequence starting at offset.
11818
11819 This is a convenience function that redirects to Extract(s, offset, length).
11820
11821 >>> s = StringVal("hello world")
11822 >>> SubString(s, 6, 5) # Extract "world"
11823 str.substr("hello world", 6, 5)
11824 >>> simplify(SubString(StringVal("hello"), 1, 3))
11825 "ell"
11826 """
11827 return Extract(s, offset, length)
11828
11829
11830def SubSeq(s, offset, length):
11831 """Extract substring or subsequence starting at offset.
11832
11833 This is a convenience function that redirects to Extract(s, offset, length).
11834
11835 >>> s = StringVal("hello world")
11836 >>> SubSeq(s, 0, 5) # Extract "hello"
11837 str.substr("hello world", 0, 5)
11838 >>> simplify(SubSeq(StringVal("testing"), 2, 4))
11839 "stin"
11840 """
11841 return Extract(s, offset, length)
11842
11843
11844def Empty(s):
11845 """Create the empty sequence of the given sort
11846 >>> e = Empty(StringSort())
11847 >>> e2 = StringVal("")
11848 >>> print(e.eq(e2))
11849 True
11850 >>> e3 = Empty(SeqSort(IntSort()))
11851 >>> print(e3)
11852 Empty(Seq(Int))
11853 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11854 >>> print(e4)
11855 Empty(ReSort(Seq(Int)))
11856 """
11857 if isinstance(s, SeqSortRef):
11858 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11859 if isinstance(s, ReSortRef):
11860 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11861 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11862
11863
11864def Full(s):
11865 """Create the regular expression that accepts the universal language
11866 >>> e = Full(ReSort(SeqSort(IntSort())))
11867 >>> print(e)
11868 Full(ReSort(Seq(Int)))
11869 >>> e1 = Full(ReSort(StringSort()))
11870 >>> print(e1)
11871 Full(ReSort(String))
11872 """
11873 if isinstance(s, ReSortRef):
11874 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11875 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11876
11877
11878
11879def Unit(a):
11880 """Create a singleton sequence"""
11881 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11882
11883
11884def PrefixOf(a, b):
11885 """Check if 'a' is a prefix of 'b'
11886 >>> s1 = PrefixOf("ab", "abc")
11887 >>> simplify(s1)
11888 True
11889 >>> s2 = PrefixOf("bc", "abc")
11890 >>> simplify(s2)
11891 False
11892 """
11893 ctx = _get_ctx2(a, b)
11894 a = _coerce_seq(a, ctx)
11895 b = _coerce_seq(b, ctx)
11896 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11897
11898
11899def SuffixOf(a, b):
11900 """Check if 'a' is a suffix of 'b'
11901 >>> s1 = SuffixOf("ab", "abc")
11902 >>> simplify(s1)
11903 False
11904 >>> s2 = SuffixOf("bc", "abc")
11905 >>> simplify(s2)
11906 True
11907 """
11908 ctx = _get_ctx2(a, b)
11909 a = _coerce_seq(a, ctx)
11910 b = _coerce_seq(b, ctx)
11911 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11912
11913
11914def Contains(a, b):
11915 """Check if 'a' contains 'b'
11916 >>> s1 = Contains("abc", "ab")
11917 >>> simplify(s1)
11918 True
11919 >>> s2 = Contains("abc", "bc")
11920 >>> simplify(s2)
11921 True
11922 >>> x, y, z = Strings('x y z')
11923 >>> s3 = Contains(Concat(x,y,z), y)
11924 >>> simplify(s3)
11925 True
11926 """
11927 ctx = _get_ctx2(a, b)
11928 a = _coerce_seq(a, ctx)
11929 b = _coerce_seq(b, ctx)
11930 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11931
11932
11933def Replace(s, src, dst):
11934 """Replace the first occurrence of 'src' by 'dst' in 's'
11935 >>> r = Replace("aaa", "a", "b")
11936 >>> simplify(r)
11937 "baa"
11938 """
11939 ctx = _get_ctx2(dst, s)
11940 if ctx is None and is_expr(src):
11941 ctx = src.ctx
11942 src = _coerce_seq(src, ctx)
11943 dst = _coerce_seq(dst, ctx)
11944 s = _coerce_seq(s, ctx)
11945 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11946
11947
11948def IndexOf(s, substr, offset=None):
11949 """Retrieve the index of substring within a string starting at a specified offset.
11950 >>> simplify(IndexOf("abcabc", "bc", 0))
11951 1
11952 >>> simplify(IndexOf("abcabc", "bc", 2))
11953 4
11954 """
11955 if offset is None:
11956 offset = IntVal(0)
11957 ctx = None
11958 if is_expr(offset):
11959 ctx = offset.ctx
11960 ctx = _get_ctx2(s, substr, ctx)
11961 s = _coerce_seq(s, ctx)
11962 substr = _coerce_seq(substr, ctx)
11963 if _is_int(offset):
11964 offset = IntVal(offset, ctx)
11965 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11966
11967
11968def LastIndexOf(s, substr):
11969 """Retrieve the last index of substring within a string"""
11970 ctx = None
11971 ctx = _get_ctx2(s, substr, ctx)
11972 s = _coerce_seq(s, ctx)
11973 substr = _coerce_seq(substr, ctx)
11974 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11975
11976
11977def Length(s):
11978 """Obtain the length of a sequence 's'
11979 >>> l = Length(StringVal("abc"))
11980 >>> simplify(l)
11981 3
11982 """
11983 s = _coerce_seq(s)
11984 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11985
11986def SeqPower(s, n):
11987 """Concatenate the sequence 's' with itself 'n' times. It is the empty sequence for n <= 0
11988 >>> p = SeqPower(StringVal("ab"), 2)
11989 >>> simplify(p)
11990 "abab"
11991 """
11992 s = _coerce_seq(s)
11993 n = _py2expr(n, s.ctx)
11994 return SeqRef(Z3_mk_seq_power(s.ctx_ref(), s.as_ast(), n.as_ast()), s.ctx)
11995
11996def SeqMap(f, s):
11997 """Map function 'f' over sequence 's'"""
11998 ctx = _get_ctx2(f, s)
11999 s = _coerce_seq(s, ctx)
12000 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
12001
12002def SeqMapI(f, i, s):
12003 """Map function 'f' over sequence 's' at index 'i'"""
12004 ctx = _get_ctx2(f, s)
12005 s = _coerce_seq(s, ctx)
12006 if not is_expr(i):
12007 i = _py2expr(i)
12008 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
12009
12010def SeqFoldLeft(f, a, s):
12011 ctx = _get_ctx2(f, s)
12012 s = _coerce_seq(s, ctx)
12013 a = _py2expr(a)
12014 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
12015
12016def SeqFoldLeftI(f, i, a, s):
12017 ctx = _get_ctx2(f, s)
12018 s = _coerce_seq(s, ctx)
12019 a = _py2expr(a)
12020 i = _py2expr(i)
12021 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
12022
12023def StrToInt(s):
12024 """Convert string expression to integer
12025 >>> a = StrToInt("1")
12026 >>> simplify(1 == a)
12027 True
12028 >>> b = StrToInt("2")
12029 >>> simplify(1 == b)
12030 False
12031 >>> c = StrToInt(IntToStr(2))
12032 >>> simplify(1 == c)
12033 False
12034 """
12035 s = _coerce_seq(s)
12036 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
12037
12038
12039def IntToStr(s):
12040 """Convert integer expression to string"""
12041 if not is_expr(s):
12042 s = _py2expr(s)
12043 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
12044
12045
12046def StrToCode(s):
12047 """Convert a unit length string to integer code"""
12048 if not is_expr(s):
12049 s = _py2expr(s)
12050 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
12051
12052def StrFromCode(c):
12053 """Convert code to a string"""
12054 if not is_expr(c):
12055 c = _py2expr(c)
12056 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
12057
12058def Re(s, ctx=None):
12059 """The regular expression that accepts sequence 's'
12060 >>> s1 = Re("ab")
12061 >>> s2 = Re(StringVal("ab"))
12062 >>> s3 = Re(Unit(BoolVal(True)))
12063 """
12064 s = _coerce_seq(s, ctx)
12065 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
12066
12067
12068# Regular expressions
12069
12070class ReSortRef(SortRef):
12071 """Regular expression sort."""
12072
12073 def basis(self):
12074 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
12075
12076
12077def ReSort(s):
12078 if is_ast(s):
12079 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
12080 if s is None or isinstance(s, Context):
12081 ctx = _get_ctx(s)
12082 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
12083 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
12084
12085
12086class ReRef(ExprRef):
12087 """Regular expressions."""
12088
12089 def __add__(self, other):
12090 return Union(self, other)
12091
12092
12093def is_re(s):
12094 return isinstance(s, ReRef)
12095
12096
12097def InRe(s, re):
12098 """Create regular expression membership test
12099 >>> re = Union(Re("a"),Re("b"))
12100 >>> print (simplify(InRe("a", re)))
12101 True
12102 >>> print (simplify(InRe("b", re)))
12103 True
12104 >>> print (simplify(InRe("c", re)))
12105 False
12106 """
12107 s = _coerce_seq(s, re.ctx)
12108 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
12109
12110
12111def Union(*args):
12112 """Create union of regular expressions.
12113 >>> re = Union(Re("a"), Re("b"), Re("c"))
12114 >>> print (simplify(InRe("d", re)))
12115 False
12116 """
12117 args = _get_args(args)
12118 sz = len(args)
12119 if z3_debug():
12120 _z3_assert(sz > 0, "At least one argument expected.")
12121 arg0 = args[0]
12122 if is_finite_set(arg0):
12123 for a in args[1:]:
12124 if not is_finite_set(a):
12125 raise Z3Exception("All arguments must be regular expressions or finite sets.")
12126 arg0 = arg0 | a
12127 return arg0
12128 if z3_debug():
12129 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
12130 if sz == 1:
12131 return args[0]
12132 ctx = args[0].ctx
12133 v = (Ast * sz)()
12134 for i in range(sz):
12135 v[i] = args[i].as_ast()
12136 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
12137
12138
12139def Intersect(*args):
12140 """Create intersection of regular expressions.
12141 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
12142 """
12143 args = _get_args(args)
12144 sz = len(args)
12145 if z3_debug():
12146 _z3_assert(sz > 0, "At least one argument expected.")
12147 arg0 = args[0]
12148 if is_finite_set(arg0):
12149 for a in args[1:]:
12150 if not is_finite_set(a):
12151 raise Z3Exception("All arguments must be regular expressions or finite sets.")
12152 arg0 = arg0 & a
12153 return arg0
12154 if z3_debug():
12155 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
12156 if sz == 1:
12157 return args[0]
12158 ctx = args[0].ctx
12159 v = (Ast * sz)()
12160 for i in range(sz):
12161 v[i] = args[i].as_ast()
12162 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
12163
12164
12165def Plus(re):
12166 """Create the regular expression accepting one or more repetitions of argument.
12167 >>> re = Plus(Re("a"))
12168 >>> print(simplify(InRe("aa", re)))
12169 True
12170 >>> print(simplify(InRe("ab", re)))
12171 False
12172 >>> print(simplify(InRe("", re)))
12173 False
12174 """
12175 if z3_debug():
12176 _z3_assert(is_expr(re), "expression expected")
12177 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
12178
12179
12180def Option(re):
12181 """Create the regular expression that optionally accepts the argument.
12182 >>> re = Option(Re("a"))
12183 >>> print(simplify(InRe("a", re)))
12184 True
12185 >>> print(simplify(InRe("", re)))
12186 True
12187 >>> print(simplify(InRe("aa", re)))
12188 False
12189 """
12190 if z3_debug():
12191 _z3_assert(is_expr(re), "expression expected")
12192 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
12193
12194
12195def Complement(re):
12196 """Create the complement regular expression."""
12197 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
12198
12199
12200def Star(re):
12201 """Create the regular expression accepting zero or more repetitions of argument.
12202 >>> re = Star(Re("a"))
12203 >>> print(simplify(InRe("aa", re)))
12204 True
12205 >>> print(simplify(InRe("ab", re)))
12206 False
12207 >>> print(simplify(InRe("", re)))
12208 True
12209 """
12210 if z3_debug():
12211 _z3_assert(is_expr(re), "expression expected")
12212 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
12213
12214
12215def Loop(re, lo, hi=0):
12216 """Create the regular expression accepting between a lower and upper bound repetitions
12217 >>> re = Loop(Re("a"), 1, 3)
12218 >>> print(simplify(InRe("aa", re)))
12219 True
12220 >>> print(simplify(InRe("aaaa", re)))
12221 False
12222 >>> print(simplify(InRe("", re)))
12223 False
12224 """
12225 if z3_debug():
12226 _z3_assert(is_expr(re), "expression expected")
12227 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
12228
12229
12230def Range(lo, hi, ctx=None):
12231 """Create the range regular expression over two sequences of length 1
12232 >>> range = Range("a","z")
12233 >>> print(simplify(InRe("b", range)))
12234 True
12235 >>> print(simplify(InRe("bb", range)))
12236 False
12237 """
12238 lo = _coerce_seq(lo, ctx)
12239 hi = _coerce_seq(hi, ctx)
12240 if z3_debug():
12241 _z3_assert(is_expr(lo), "expression expected")
12242 _z3_assert(is_expr(hi), "expression expected")
12243 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
12244
12245def Diff(a, b, ctx=None):
12246 """Create the difference regular expression
12247 """
12248 if z3_debug():
12249 _z3_assert(is_expr(a), "expression expected")
12250 _z3_assert(is_expr(b), "expression expected")
12251 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
12252
12253def AllChar(regex_sort, ctx=None):
12254 """Create a regular expression that accepts all single character strings
12255 """
12256 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
12257
12258# Special Relations
12259
12260
12261def PartialOrder(a, index):
12262 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
12263
12264
12265def LinearOrder(a, index):
12266 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
12267
12268
12269def TreeOrder(a, index):
12270 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
12271
12272
12273def PiecewiseLinearOrder(a, index):
12274 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
12275
12276
12277def TransitiveClosure(f):
12278 """Given a binary relation R, such that the two arguments have the same sort
12279 create the transitive closure relation R+.
12280 The transitive closure R+ is a new relation.
12281 """
12282 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
12283
12284def to_Ast(ptr,):
12285 ast = Ast(ptr)
12286 super(ctypes.c_void_p, ast).__init__(ptr)
12287 return ast
12288
12289def to_ContextObj(ptr,):
12290 ctx = ContextObj(ptr)
12291 super(ctypes.c_void_p, ctx).__init__(ptr)
12292 return ctx
12293
12294def to_AstVectorObj(ptr,):
12295 v = AstVectorObj(ptr)
12296 super(ctypes.c_void_p, v).__init__(ptr)
12297 return v
12298
12299# NB. my-hacky-class only works for a single instance of OnClause
12300# it should be replaced with a proper correlation between OnClause
12301# and object references that can be passed over the FFI.
12302# for UserPropagator we use a global dictionary, which isn't great code.
12303
12304_my_hacky_class = None
12305def on_clause_eh(ctx, p, n, dep, clause):
12306 onc = _my_hacky_class
12307 p = _to_expr_ref(to_Ast(p), onc.ctx)
12308 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
12309 deps = [dep[i] for i in range(n)]
12310 onc.on_clause(p, deps, clause)
12311
12312_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
12313
12314class OnClause:
12315 def __init__(self, s, on_clause):
12316 self.s = s
12317 self.ctx = s.ctx
12318 self.on_clause = on_clause
12319 self.idx = 22
12320 global _my_hacky_class
12321 _my_hacky_class = self
12322 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
12323
12324
12325class PropClosures:
12326 def __init__(self):
12327 self.bases = {}
12328 self.lock = None
12329
12330 def set_threaded(self):
12331 if self.lock is None:
12332 import threading
12333 self.lock = threading.Lock()
12334
12335 def get(self, ctx):
12336 if self.lock:
12337 with self.lock:
12338 r = self.bases[ctx]
12339 else:
12340 r = self.bases[ctx]
12341 return r
12342
12343 def set(self, ctx, r):
12344 if self.lock:
12345 with self.lock:
12346 self.bases[ctx] = r
12347 else:
12348 self.bases[ctx] = r
12349
12350 def insert(self, r):
12351 if self.lock:
12352 with self.lock:
12353 id = len(self.bases) + 3
12354 self.bases[id] = r
12355 else:
12356 id = len(self.bases) + 3
12357 self.bases[id] = r
12358 return id
12359
12360
12361_prop_closures = None
12362
12363
12364def ensure_prop_closures():
12365 global _prop_closures
12366 if _prop_closures is None:
12367 _prop_closures = PropClosures()
12368
12369
12370def user_prop_push(ctx, cb):
12371 prop = _prop_closures.get(ctx)
12372 prop.cb = cb
12373 prop.push()
12374
12375
12376def user_prop_pop(ctx, cb, num_scopes):
12377 prop = _prop_closures.get(ctx)
12378 prop.cb = cb
12379 prop.pop(num_scopes)
12380
12381
12382def user_prop_fresh(ctx, _new_ctx):
12383 _prop_closures.set_threaded()
12384 prop = _prop_closures.get(ctx)
12385 nctx = Context()
12386 Z3_del_context(nctx.ctx)
12387 new_ctx = to_ContextObj(_new_ctx)
12388 nctx.ctx = new_ctx
12389 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
12390 nctx.owner = False
12391 new_prop = prop.fresh(nctx)
12392 _prop_closures.set(new_prop.id, new_prop)
12393 return new_prop.id
12394
12395
12396def user_prop_fixed(ctx, cb, id, value):
12397 prop = _prop_closures.get(ctx)
12398 old_cb = prop.cb
12399 prop.cb = cb
12400 id = _to_expr_ref(to_Ast(id), prop.ctx())
12401 value = _to_expr_ref(to_Ast(value), prop.ctx())
12402 prop.fixed(id, value)
12403 prop.cb = old_cb
12404
12405def user_prop_created(ctx, cb, id):
12406 prop = _prop_closures.get(ctx)
12407 old_cb = prop.cb
12408 prop.cb = cb
12409 id = _to_expr_ref(to_Ast(id), prop.ctx())
12410 prop.created(id)
12411 prop.cb = old_cb
12412
12413
12414def user_prop_final(ctx, cb):
12415 prop = _prop_closures.get(ctx)
12416 old_cb = prop.cb
12417 prop.cb = cb
12418 prop.final()
12419 prop.cb = old_cb
12420
12421def user_prop_eq(ctx, cb, x, y):
12422 prop = _prop_closures.get(ctx)
12423 old_cb = prop.cb
12424 prop.cb = cb
12425 x = _to_expr_ref(to_Ast(x), prop.ctx())
12426 y = _to_expr_ref(to_Ast(y), prop.ctx())
12427 prop.eq(x, y)
12428 prop.cb = old_cb
12429
12430def user_prop_diseq(ctx, cb, x, y):
12431 prop = _prop_closures.get(ctx)
12432 old_cb = prop.cb
12433 prop.cb = cb
12434 x = _to_expr_ref(to_Ast(x), prop.ctx())
12435 y = _to_expr_ref(to_Ast(y), prop.ctx())
12436 prop.diseq(x, y)
12437 prop.cb = old_cb
12438
12439def user_prop_decide(ctx, cb, t_ref, idx, phase):
12440 prop = _prop_closures.get(ctx)
12441 old_cb = prop.cb
12442 prop.cb = cb
12443 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
12444 prop.decide(t, idx, phase)
12445 prop.cb = old_cb
12446
12447def user_prop_binding(ctx, cb, q_ref, inst_ref):
12448 prop = _prop_closures.get(ctx)
12449 old_cb = prop.cb
12450 prop.cb = cb
12451 q = _to_expr_ref(to_Ast(q_ref), prop.ctx())
12452 inst = _to_expr_ref(to_Ast(inst_ref), prop.ctx())
12453 r = prop.binding(q, inst)
12454 prop.cb = old_cb
12455 return r
12456
12457
12458_user_prop_push = Z3_push_eh(user_prop_push)
12459_user_prop_pop = Z3_pop_eh(user_prop_pop)
12460_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
12461_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
12462_user_prop_created = Z3_created_eh(user_prop_created)
12463_user_prop_final = Z3_final_eh(user_prop_final)
12464_user_prop_eq = Z3_eq_eh(user_prop_eq)
12465_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
12466_user_prop_decide = Z3_decide_eh(user_prop_decide)
12467_user_prop_binding = Z3_on_binding_eh(user_prop_binding)
12468
12469
12470def PropagateFunction(name, *sig):
12471 """Create a function that gets tracked by user propagator.
12472 Every term headed by this function symbol is tracked.
12473 If a term is fixed and the fixed callback is registered a
12474 callback is invoked that the term headed by this function is fixed.
12475 """
12476 sig = _get_args(sig)
12477 if z3_debug():
12478 _z3_assert(len(sig) > 0, "At least two arguments expected")
12479 arity = len(sig) - 1
12480 rng = sig[arity]
12481 if z3_debug():
12482 _z3_assert(is_sort(rng), "Z3 sort expected")
12483 dom = (Sort * arity)()
12484 for i in range(arity):
12485 if z3_debug():
12486 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
12487 dom[i] = sig[i].ast
12488 ctx = rng.ctx
12489 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
12490
12491
12492
12493class UserPropagateBase:
12494
12495 #
12496 # Either solver is set or ctx is set.
12497 # Propagators that are created through callbacks
12498 # to "fresh" inherit the context of that is supplied
12499 # as argument to the callback.
12500 # This context should not be deleted. It is owned by the solver.
12501 #
12502 def __init__(self, s, ctx=None):
12503 assert s is None or ctx is None
12504 ensure_prop_closures()
12505 self.solver = s
12506 self._ctx = None
12507 self.fresh_ctx = None
12508 self.cb = None
12509 self.id = _prop_closures.insert(self)
12510 self.fixed = None
12511 self.final = None
12512 self.eq = None
12513 self.diseq = None
12514 self.decide = None
12515 self.created = None
12516 self.binding = None
12517 if ctx:
12518 self.fresh_ctx = ctx
12519 if s:
12520 Z3_solver_propagate_init(self.ctx_ref(),
12521 s.solver,
12522 ctypes.c_void_p(self.id),
12523 _user_prop_push,
12524 _user_prop_pop,
12525 _user_prop_fresh)
12526
12527 def __del__(self):
12528 if self._ctx:
12529 self._ctx.ctx = None
12530
12531 def ctx(self):
12532 if self.fresh_ctx:
12533 return self.fresh_ctx
12534 else:
12535 return self.solver.ctx
12536
12537 def ctx_ref(self):
12538 return self.ctx().ref()
12539
12540 def add_fixed(self, fixed):
12541 if self.fixed:
12542 raise Z3Exception("fixed callback already registered")
12543 if self._ctx:
12544 raise Z3Exception("context already initialized")
12545 if self.solver:
12546 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
12547 self.fixed = fixed
12548
12549 def add_created(self, created):
12550 if self.created:
12551 raise Z3Exception("created callback already registered")
12552 if self._ctx:
12553 raise Z3Exception("context already initialized")
12554 if self.solver:
12555 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
12556 self.created = created
12557
12558 def add_final(self, final):
12559 if self.final:
12560 raise Z3Exception("final callback already registered")
12561 if self._ctx:
12562 raise Z3Exception("context already initialized")
12563 if self.solver:
12564 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
12565 self.final = final
12566
12567 def add_eq(self, eq):
12568 if self.eq:
12569 raise Z3Exception("eq callback already registered")
12570 if self._ctx:
12571 raise Z3Exception("context already initialized")
12572 if self.solver:
12573 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
12574 self.eq = eq
12575
12576 def add_diseq(self, diseq):
12577 if self.diseq:
12578 raise Z3Exception("diseq callback already registered")
12579 if self._ctx:
12580 raise Z3Exception("context already initialized")
12581 if self.solver:
12582 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
12583 self.diseq = diseq
12584
12585 def add_decide(self, decide):
12586 if self.decide:
12587 raise Z3Exception("decide callback already registered")
12588 if self._ctx:
12589 raise Z3Exception("context already initialized")
12590 if self.solver:
12591 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
12592 self.decide = decide
12593
12594 def add_on_binding(self, binding):
12595 if self.binding:
12596 raise Z3Exception("binding callback already registered")
12597 if self._ctx:
12598 raise Z3Exception("context already initialized")
12599 if self.solver:
12600 Z3_solver_propagate_on_binding(self.ctx_ref(), self.solver.solver, _user_prop_binding)
12601 self.binding = binding
12602
12603 def push(self):
12604 raise Z3Exception("push needs to be overwritten")
12605
12606 def pop(self, num_scopes):
12607 raise Z3Exception("pop needs to be overwritten")
12608
12609 def fresh(self, new_ctx):
12610 raise Z3Exception("fresh needs to be overwritten")
12611
12612 def add(self, e):
12613 if self._ctx:
12614 raise Z3Exception("context already initialized")
12615 if self.solver:
12616 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
12617 else:
12618 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
12619
12620 #
12621 # Tell the solver to perform the next split on a given term
12622 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
12623 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
12624 #
12625 def next_split(self, t, idx, phase):
12626 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
12627
12628 #
12629 # Propagation can only be invoked as during a fixed or final callback.
12630 #
12631 def propagate(self, e, ids, eqs=[]):
12632 _ids, num_fixed = _to_ast_array(ids)
12633 num_eqs = len(eqs)
12634 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
12635 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
12636 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
12637 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
12638
12639 def conflict(self, deps = [], eqs = []):
12640 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
12641
12642
12643class FiniteFieldSortRef(SortRef):
12644 """A prime field. Use SolverFor('QF_FF') for incremental field solving."""
12645 def size(self):
12646 return int(Z3_get_finite_field_sort_size(self.ctx_ref(), self.ast))
12647
12648 def cast(self, value):
12649 if is_expr(value):
12650 if not self.eq(value.sort()):
12651 raise Z3Exception("finite-field sort mismatch")
12652 return value
12653 return FiniteFieldVal(value, self)
12654
12655
12656class FiniteFieldRef(ExprRef):
12657 def sort(self):
12658 return FiniteFieldSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
12659
12660 def as_long(self):
12661 if not Z3_is_numeral_ast(self.ctx_ref(), self.as_ast()):
12662 raise Z3Exception("finite-field numeral expected")
12663 return int(Z3_get_numeral_string(self.ctx_ref(), self.as_ast()))
12664
12665 def _binary(self, other, operation):
12666 other = self.sort().cast(other)
12667 args = (Ast * 2)(self.as_ast(), other.as_ast())
12668 return FiniteFieldRef(operation(self.ctx_ref(), 2, args), self.ctx)
12669
12670 def __add__(self, other):
12671 return self._binary(other, Z3_mk_ff_add)
12672
12673 def __radd__(self, other):
12674 return self + other
12675
12676 def __mul__(self, other):
12677 return self._binary(other, Z3_mk_ff_mul)
12678
12679 def __rmul__(self, other):
12680 return self * other
12681
12682 def __neg__(self):
12683 return FiniteFieldRef(Z3_mk_ff_neg(self.ctx_ref(), self.as_ast()), self.ctx)
12684
12685 def __sub__(self, other):
12686 return self + -self.sort().cast(other)
12687
12688 def __rsub__(self, other):
12689 return self.sort().cast(other) + -self
12690
12691 def __pow__(self, n):
12692 if not isinstance(n, int) or n < 0:
12693 raise Z3Exception("finite-field exponent must be a nonnegative integer")
12694 result, base = FiniteFieldVal(1, self.sort()), self
12695 while n:
12696 if n & 1:
12697 result = result * base
12698 n >>= 1
12699 if n:
12700 base = base * base
12701 return result
12702
12703
12704def FiniteFieldSort(prime, ctx=None):
12705 ctx = _get_ctx(ctx)
12706 return FiniteFieldSortRef(Z3_mk_finite_field_sort(ctx.ref(), str(prime)), ctx)
12707
12708
12709def FiniteFieldVal(value, field, ctx=None):
12710 if not isinstance(field, FiniteFieldSortRef):
12711 field = FiniteFieldSort(field, ctx)
12712 if not isinstance(value, (int, str)):
12713 raise Z3Exception("finite-field value must be an integer")
12714 return FiniteFieldRef(Z3_mk_numeral(field.ctx_ref(), str(value), field.ast), field.ctx)
12715
12716
12717def FiniteFieldElem(name, field, ctx=None):
12718 if not isinstance(field, FiniteFieldSortRef):
12719 field = FiniteFieldSort(field, ctx)
12720 return Const(name, field)
12721
12722
12723def FiniteFieldElems(names, field, ctx=None):
12724 if not isinstance(field, FiniteFieldSortRef):
12725 field = FiniteFieldSort(field, ctx)
12726 return [Const(name, field) for name in (names.split() if isinstance(names, str) else names)]
12727
12728
12729def FiniteFieldBitsum(*args):
12730 args = _get_args(args)
12731 if len(args) < 2 or not isinstance(args[0], FiniteFieldRef):
12732 raise Z3Exception("bitsum needs at least two field arguments")
12733 field = args[0].sort()
12734 values = [field.cast(a) for a in args]
12735 raw = (Ast * len(values))(*[a.as_ast() for a in values])
12736 return FiniteFieldRef(Z3_mk_ff_bitsum(field.ctx_ref(), len(values), raw), field.ctx)
approx(self, precision=10)
Definition z3py.py:3262
as_decimal(self, prec)
Definition z3py.py:3274
__rmod__(self, other)
Definition z3py.py:2733
__mod__(self, other)
Definition z3py.py:2718
__pow__(self, other)
Definition z3py.py:2642
__gt__(self, other)
Definition z3py.py:2791
__lt__(self, other)
Definition z3py.py:2778
__rtruediv__(self, other)
Definition z3py.py:2714
__rmul__(self, other)
Definition z3py.py:2609
__abs__(self)
Definition z3py.py:2817
__rsub__(self, other)
Definition z3py.py:2632
__add__(self, other)
Definition z3py.py:2571
__sub__(self, other)
Definition z3py.py:2619
is_real(self)
Definition z3py.py:2560
is_int(self)
Definition z3py.py:2546
__radd__(self, other)
Definition z3py.py:2584
__truediv__(self, other)
Definition z3py.py:2693
__le__(self, other)
Definition z3py.py:2765
__rpow__(self, other)
Definition z3py.py:2656
__pos__(self)
Definition z3py.py:2756
sort(self)
Definition z3py.py:2536
__mul__(self, other)
Definition z3py.py:2594
__rdiv__(self, other)
Definition z3py.py:2697
__ge__(self, other)
Definition z3py.py:2804
__neg__(self)
Definition z3py.py:2745
__div__(self, other)
Definition z3py.py:2670
Arithmetic.
Definition z3py.py:2441
subsort(self, other)
Definition z3py.py:2475
cast(self, val)
Definition z3py.py:2479
domain(self)
Definition z3py.py:4799
domain_n(self, i)
Definition z3py.py:4808
__getitem__(self, arg)
Definition z3py.py:4821
range(self)
Definition z3py.py:4812
sort(self)
Definition z3py.py:4790
default(self)
Definition z3py.py:4833
domain_n(self, i)
Definition z3py.py:4772
erase(self, k)
Definition z3py.py:6714
__deepcopy__(self, memo={})
Definition z3py.py:6651
__init__(self, m=None, ctx=None)
Definition z3py.py:6640
__repr__(self)
Definition z3py.py:6711
__len__(self)
Definition z3py.py:6658
keys(self)
Definition z3py.py:6743
__setitem__(self, k, v)
Definition z3py.py:6695
__contains__(self, key)
Definition z3py.py:6671
__del__(self)
Definition z3py.py:6654
__getitem__(self, key)
Definition z3py.py:6684
reset(self)
Definition z3py.py:6728
__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:6620
translate(self, other_ctx)
Definition z3py.py:6601
__repr__(self)
Definition z3py.py:6623
__len__(self)
Definition z3py.py:6493
__init__(self, v=None, ctx=None)
Definition z3py.py:6478
push(self, v)
Definition z3py.py:6553
__getitem__(self, i)
Definition z3py.py:6506
sexpr(self)
Definition z3py.py:6626
__del__(self)
Definition z3py.py:6489
__setitem__(self, i, v)
Definition z3py.py:6535
__contains__(self, item)
Definition z3py.py:6578
__copy__(self)
Definition z3py.py:6617
resize(self, sz)
Definition z3py.py:6565
as_binary_string(self)
Definition z3py.py:4112
as_signed_long(self)
Definition z3py.py:4086
as_string(self)
Definition z3py.py:4109
__and__(self, other)
Definition z3py.py:3776
__rmod__(self, other)
Definition z3py.py:3917
__rrshift__(self, other)
Definition z3py.py:4043
__mod__(self, other)
Definition z3py.py:3896
__or__(self, other)
Definition z3py.py:3753
__rlshift__(self, other)
Definition z3py.py:4057
__gt__(self, other)
Definition z3py.py:3967
__lt__(self, other)
Definition z3py.py:3951
__invert__(self)
Definition z3py.py:3842
__rtruediv__(self, other)
Definition z3py.py:3892
__rmul__(self, other)
Definition z3py.py:3720
__rxor__(self, other)
Definition z3py.py:3812
__ror__(self, other)
Definition z3py.py:3766
__rsub__(self, other)
Definition z3py.py:3743
__add__(self, other)
Definition z3py.py:3684
__sub__(self, other)
Definition z3py.py:3730
__radd__(self, other)
Definition z3py.py:3697
size(self)
Definition z3py.py:3673
__rand__(self, other)
Definition z3py.py:3789
__truediv__(self, other)
Definition z3py.py:3872
__le__(self, other)
Definition z3py.py:3935
__xor__(self, other)
Definition z3py.py:3799
__lshift__(self, other)
Definition z3py.py:4029
__pos__(self)
Definition z3py.py:3822
sort(self)
Definition z3py.py:3662
__mul__(self, other)
Definition z3py.py:3707
__rdiv__(self, other)
Definition z3py.py:3876
__ge__(self, other)
Definition z3py.py:3983
__neg__(self)
Definition z3py.py:3831
__rshift__(self, other)
Definition z3py.py:3999
__div__(self, other)
Definition z3py.py:3853
Bit-Vectors.
Definition z3py.py:3615
subsort(self, other)
Definition z3py.py:3627
cast(self, val)
Definition z3py.py:3630
__and__(self, other)
Definition z3py.py:1692
__or__(self, other)
Definition z3py.py:1695
__invert__(self)
Definition z3py.py:1701
__rmul__(self, other)
Definition z3py.py:1678
__add__(self, other)
Definition z3py.py:1670
py_value(self)
Definition z3py.py:1704
__radd__(self, other)
Definition z3py.py:1675
__xor__(self, other)
Definition z3py.py:1698
sort(self)
Definition z3py.py:1667
__mul__(self, other)
Definition z3py.py:1681
Booleans.
Definition z3py.py:1628
subsort(self, other)
Definition z3py.py:1654
is_bool(self)
Definition z3py.py:1660
cast(self, val)
Definition z3py.py:1631
__deepcopy__(self, memo={})
Definition z3py.py:7510
__eq__(self, other)
Definition z3py.py:7513
__ne__(self, other)
Definition z3py.py:7516
__init__(self, r)
Definition z3py.py:7507
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:5566
create(self)
Definition z3py.py:5605
__init__(self, name, ctx=None)
Definition z3py.py:5561
__repr__(self)
Definition z3py.py:5602
list constructors
Definition z3py.py:5564
declare(self, name, *args)
Definition z3py.py:5581
create_polymorphic(self, type_params)
Definition z3py.py:5621
declare_core(self, name, rec_name, *args)
Definition z3py.py:5571
update_field(self, field_accessor, new_value)
Definition z3py.py:5930
constructor(self, idx)
Definition z3py.py:5842
accessor(self, i, j)
Definition z3py.py:5889
num_constructors(self)
Definition z3py.py:5829
recognizer(self, idx)
Definition z3py.py:5861
Expressions.
Definition z3py.py:1022
update(self, *args)
Definition z3py.py:1178
as_ast(self)
Definition z3py.py:1033
__hash__(self)
Definition z3py.py:1079
kind(self)
Definition z3py.py:1119
children(self)
Definition z3py.py:1163
serialize(self)
Definition z3py.py:1205
get_id(self)
Definition z3py.py:1036
num_args(self)
Definition z3py.py:1126
__eq__(self, other)
Definition z3py.py:1062
__ne__(self, other)
Definition z3py.py:1083
from_string(self, s)
Definition z3py.py:1202
sort_kind(self)
Definition z3py.py:1051
arg(self, idx)
Definition z3py.py:1142
sort(self)
Definition z3py.py:1039
params(self)
Definition z3py.py:1101
decl(self)
Definition z3py.py:1104
__and__(self, other)
Definition z3py.py:5381
__or__(self, other)
Definition z3py.py:5377
__sub__(self, other)
Definition z3py.py:5385
Finite Sets.
Definition z3py.py:5309
subsort(self, other)
Definition z3py.py:5331
cast(self, val)
Definition z3py.py:5316
Function Declarations.
Definition z3py.py:779
as_func_decl(self)
Definition z3py.py:793
domain(self, i)
Definition z3py.py:817
as_ast(self)
Definition z3py.py:787
__call__(self, *args)
Definition z3py.py:880
arity(self)
Definition z3py.py:807
get_id(self)
Definition z3py.py:790
range(self)
Definition z3py.py:829
params(self)
Definition z3py.py:852
Definition z3py.py:6762
__deepcopy__(self, memo={})
Definition z3py.py:6770
ctx
Definition z3py.py:6767
__repr__(self)
Definition z3py.py:6867
num_args(self)
Definition z3py.py:6777
entry
Definition z3py.py:6766
value(self)
Definition z3py.py:6826
__init__(self, entry, ctx)
Definition z3py.py:6765
__del__(self)
Definition z3py.py:6773
as_list(self)
Definition z3py.py:6848
arg_value(self, idx)
Definition z3py.py:6795
__deepcopy__(self, memo={})
Definition z3py.py:6965
translate(self, other_ctx)
Definition z3py.py:6957
arity(self)
Definition z3py.py:6923
__repr__(self)
Definition z3py.py:6985
num_entries(self)
Definition z3py.py:6907
__init__(self, f, ctx)
Definition z3py.py:6874
__del__(self)
Definition z3py.py:6880
as_list(self)
Definition z3py.py:6968
else_value(self)
Definition z3py.py:6884
entry(self, idx)
Definition z3py.py:6937
__copy__(self)
Definition z3py.py:6962
__deepcopy__(self, memo={})
Definition z3py.py:6423
get(self, i)
Definition z3py.py:6279
prec(self)
Definition z3py.py:6223
translate(self, target)
Definition z3py.py:6397
append(self, *args)
Definition z3py.py:6324
as_expr(self)
Definition z3py.py:6446
assert_exprs(self, *args)
Definition z3py.py:6309
__repr__(self)
Definition z3py.py:6386
__len__(self)
Definition z3py.py:6266
inconsistent(self)
Definition z3py.py:6205
dimacs(self, include_names=True)
Definition z3py.py:6393
__getitem__(self, arg)
Definition z3py.py:6292
size(self)
Definition z3py.py:6253
precision(self)
Definition z3py.py:6244
simplify(self, *arguments, **keywords)
Definition z3py.py:6426
sexpr(self)
Definition z3py.py:6389
add(self, *args)
Definition z3py.py:6346
__del__(self)
Definition z3py.py:6183
convert_model(self, model)
Definition z3py.py:6357
insert(self, *args)
Definition z3py.py:6335
depth(self)
Definition z3py.py:6187
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:6173
__copy__(self)
Definition z3py.py:6420
as_binary_string(self)
Definition z3py.py:3147
py_value(self)
Definition z3py.py:3155
as_long(self)
Definition z3py.py:3126
as_string(self)
Definition z3py.py:3139
__deepcopy__(self, memo={})
Definition z3py.py:7333
eval(self, t, model_completion=False)
Definition z3py.py:7009
translate(self, target)
Definition z3py.py:7298
__getitem__(self, idx)
Definition z3py.py:7210
num_sorts(self)
Definition z3py.py:7135
get_universe(self, s)
Definition z3py.py:7190
get_sort(self, idx)
Definition z3py.py:7150
project(self, vars, fml)
Definition z3py.py:7306
__repr__(self)
Definition z3py.py:7002
__len__(self)
Definition z3py.py:7066
get_interp(self, decl)
Definition z3py.py:7083
__init__(self, m, ctx)
Definition z3py.py:6992
sexpr(self)
Definition z3py.py:7005
sorts(self)
Definition z3py.py:7173
__del__(self)
Definition z3py.py:6998
decls(self)
Definition z3py.py:7257
project_with_witness(self, vars, fml)
Definition z3py.py:7318
update_value(self, x, value)
Definition z3py.py:7276
evaluate(self, t, model_completion=False)
Definition z3py.py:7040
__copy__(self)
Definition z3py.py:7330
__deepcopy__(self, memo={})
Definition z3py.py:6117
__init__(self, descr, ctx=None)
Definition z3py.py:6111
get_kind(self, n)
Definition z3py.py:6139
get_documentation(self, n)
Definition z3py.py:6144
__getitem__(self, arg)
Definition z3py.py:6149
get_name(self, i)
Definition z3py.py:6134
Parameter Sets.
Definition z3py.py:6038
__deepcopy__(self, memo={})
Definition z3py.py:6052
validate(self, ds)
Definition z3py.py:6079
__repr__(self)
Definition z3py.py:6076
__init__(self, ctx=None, params=None)
Definition z3py.py:6044
set(self, name, val)
Definition z3py.py:6059
__del__(self)
Definition z3py.py:6055
Patterns.
Definition z3py.py:2064
as_ast(self)
Definition z3py.py:2069
get_id(self)
Definition z3py.py:2072
Quantifiers.
Definition z3py.py:2131
num_no_patterns(self)
Definition z3py.py:2249
no_pattern(self, idx)
Definition z3py.py:2253
num_patterns(self)
Definition z3py.py:2219
var_name(self, idx)
Definition z3py.py:2282
__getitem__(self, arg)
Definition z3py.py:2188
var_sort(self, idx)
Definition z3py.py:2298
pattern(self, idx)
Definition z3py.py:2231
numerator_as_long(self)
Definition z3py.py:3188
is_int_value(self)
Definition z3py.py:3218
as_fraction(self)
Definition z3py.py:3246
py_value(self)
Definition z3py.py:3255
numerator(self)
Definition z3py.py:3162
is_real(self)
Definition z3py.py:3215
as_long(self)
Definition z3py.py:3221
is_int(self)
Definition z3py.py:3212
denominator_as_long(self)
Definition z3py.py:3201
as_string(self)
Definition z3py.py:3237
denominator(self)
Definition z3py.py:3177
as_decimal(self, prec)
Definition z3py.py:3225
__init__(self, c, ctx)
Definition z3py.py:5639
__init__(self, c, ctx)
Definition z3py.py:5651
Strings, Sequences and Regular expressions.
Definition z3py.py:11590
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7554
assert_and_track(self, a, p)
Definition z3py.py:7723
num_scopes(self)
Definition z3py.py:7635
append(self, *args)
Definition z3py.py:7701
__iadd__(self, fml)
Definition z3py.py:7697
pop(self, num=1)
Definition z3py.py:7613
import_model_converter(self, other)
Definition z3py.py:7801
assert_exprs(self, *args)
Definition z3py.py:7667
model(self)
Definition z3py.py:7782
set(self, *args, **keys)
Definition z3py.py:7578
__enter__(self)
Definition z3py.py:7571
add(self, *args)
Definition z3py.py:7686
__del__(self)
Definition z3py.py:7567
int backtrack_level
Definition z3py.py:7557
insert(self, *args)
Definition z3py.py:7712
check(self, *assumptions)
Definition z3py.py:7753
push(self)
Definition z3py.py:7591
__exit__(self, *exc_info)
Definition z3py.py:7575
reset(self)
Definition z3py.py:7653
subsort(self, other)
Definition z3py.py:616
as_ast(self)
Definition z3py.py:593
__hash__(self)
Definition z3py.py:677
kind(self)
Definition z3py.py:599
__gt__(self, other)
Definition z3py.py:673
get_id(self)
Definition z3py.py:596
__eq__(self, other)
Definition z3py.py:649
__ne__(self, other)
Definition z3py.py:662
cast(self, val)
Definition z3py.py:624
name(self)
Definition z3py.py:639
Statistics.
Definition z3py.py:7363
__deepcopy__(self, memo={})
Definition z3py.py:7371
__getattr__(self, name)
Definition z3py.py:7466
__getitem__(self, idx)
Definition z3py.py:7410
__init__(self, stats, ctx)
Definition z3py.py:7366
__repr__(self)
Definition z3py.py:7378
__len__(self)
Definition z3py.py:7396
__del__(self)
Definition z3py.py:7374
get_key_value(self, key)
Definition z3py.py:7446
subsort(self, other)
Definition z3py.py:755
cast(self, val)
Definition z3py.py:758
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...
Z3_ast Z3_API Z3_func_decl_to_ast(Z3_context c, Z3_func_decl f)
Convert a Z3_func_decl into Z3_ast. This is just type casting.
void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a)
Add a constant interpretation.
Z3_ast Z3_API Z3_mk_bvadd(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement addition.
unsigned Z3_API Z3_algebraic_get_i(Z3_context c, Z3_ast a)
Return which root of the polynomial the algebraic number represents.
void Z3_API Z3_params_dec_ref(Z3_context c, Z3_params p)
Decrement the reference counter of the given parameter set.
Z3_ast Z3_API Z3_get_app_arg(Z3_context c, Z3_app a, unsigned i)
Return the i-th argument of the given application.
Z3_string Z3_API Z3_model_to_string(Z3_context c, Z3_model m)
Convert the given model into a string.
Z3_func_decl Z3_API Z3_mk_fresh_func_decl(Z3_context c, Z3_string prefix, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a fresh constant or function.
unsigned Z3_API Z3_ast_map_size(Z3_context c, Z3_ast_map m)
Return the size of the given map.
unsigned Z3_API Z3_param_descrs_size(Z3_context c, Z3_param_descrs p)
Return the number of parameters in the given parameter description set.
Z3_string Z3_API Z3_goal_to_dimacs_string(Z3_context c, Z3_goal g, bool include_names)
Convert a goal into a DIMACS formatted string. The goal must be in CNF. You can convert a goal to CNF...
Z3_ast Z3_API Z3_mk_lt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than.
Z3_ast Z3_API Z3_get_quantifier_no_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th no_pattern.
double Z3_API Z3_stats_get_double_value(Z3_context c, Z3_stats s, unsigned idx)
Return the double value of the given statistical data.
Z3_ast Z3_API Z3_mk_bvugt(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than.
unsigned Z3_API Z3_goal_depth(Z3_context c, Z3_goal g)
Return the depth of the given goal. It tracks how many transformations were applied to it.
Z3_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_pattern_to_ast(Z3_context c, Z3_pattern p)
Convert a Z3_pattern into Z3_ast. This is just type casting.
Z3_ast Z3_API Z3_mk_bvnot(Z3_context c, Z3_ast t1)
Bitwise negation.
Z3_ast Z3_API Z3_mk_bvurem(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned remainder.
void Z3_API Z3_mk_datatypes(Z3_context c, unsigned num_sorts, Z3_symbol const sort_names[], Z3_sort sorts[], Z3_constructor_list constructor_lists[])
Create mutually recursive datatypes.
unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f)
Return the arity (number of arguments) of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsub(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement subtraction.
Z3_ast Z3_API Z3_get_algebraic_number_upper(Z3_context c, Z3_ast a, unsigned precision)
Return a upper bound for the given real algebraic number. The interval isolating the number is smalle...
Z3_ast Z3_API Z3_mk_power(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 ^ arg2.
Z3_ast Z3_API Z3_mk_seq_concat(Z3_context c, unsigned n, Z3_ast const args[])
Concatenate sequences.
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c, Z3_symbol name, unsigned n, Z3_symbol const enum_names[], Z3_func_decl enum_consts[], Z3_func_decl enum_testers[])
Create a enumeration sort.
unsigned Z3_API Z3_get_bv_sort_size(Z3_context c, Z3_sort t)
Return the size of the given bit-vector sort.
Z3_ast Z3_API Z3_mk_set_member(Z3_context c, Z3_ast elem, Z3_ast set)
Check for set membership.
void Z3_API Z3_ast_vector_dec_ref(Z3_context c, Z3_ast_vector v)
Decrement the reference counter of the given AST vector.
void Z3_API Z3_func_interp_dec_ref(Z3_context c, Z3_func_interp f)
Decrement the reference counter of the given Z3_func_interp object.
void Z3_API Z3_params_inc_ref(Z3_context c, Z3_params p)
Increment the reference counter of the given parameter set.
void Z3_API Z3_set_error_handler(Z3_context c, Z3_error_handler h)
Register a Z3 error handler.
Z3_ast Z3_API Z3_mk_distinct(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing distinct(args[0], ..., args[num_args-1]).
Z3_config Z3_API Z3_mk_config(void)
Create a configuration object for the Z3 context object.
void Z3_API Z3_set_param_value(Z3_config c, Z3_string param_id, Z3_string param_value)
Set a configuration parameter.
Z3_sort Z3_API Z3_mk_bv_sort(Z3_context c, unsigned sz)
Create a bit-vector type of the given size.
Z3_ast Z3_API Z3_mk_bvult(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than.
void Z3_API Z3_ast_map_dec_ref(Z3_context c, Z3_ast_map m)
Decrement the reference counter of the given AST map.
Z3_string Z3_API Z3_params_to_string(Z3_context c, Z3_params p)
Convert a parameter set into a string. This function is mainly used for printing the contents of a pa...
Z3_param_descrs Z3_API Z3_get_global_param_descrs(Z3_context c)
Retrieve description of global parameters.
Z3_func_decl Z3_API Z3_model_get_const_decl(Z3_context c, Z3_model m, unsigned i)
Return the i-th constant in the given model.
Z3_ast Z3_API Z3_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_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_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_ast Z3_API Z3_sort_to_ast(Z3_context c, Z3_sort s)
Convert a Z3_sort into Z3_ast. This is just type casting.
Z3_func_entry Z3_API Z3_func_interp_get_entry(Z3_context c, Z3_func_interp f, unsigned i)
Return a "point" of the given function interpretation. It represents the value of f in a particular p...
Z3_func_decl Z3_API Z3_mk_rec_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a recursive function.
unsigned Z3_API Z3_get_ast_id(Z3_context c, Z3_ast t)
Return a unique identifier for t. The identifier is unique up to structural equality....
Z3_ast Z3_API Z3_mk_concat(Z3_context c, Z3_ast t1, Z3_ast t2)
Concatenate the given bit-vectors.
unsigned Z3_API Z3_get_quantifier_num_bound(Z3_context c, Z3_ast a)
Return number of bound variables of quantifier.
Z3_sort Z3_API Z3_get_decl_sort_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the sort value associated with a sort parameter.
Z3_constructor_list Z3_API Z3_mk_constructor_list(Z3_context c, unsigned num_constructors, Z3_constructor const constructors[])
Create list of constructors.
Z3_ast Z3_API Z3_mk_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_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_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:3293
RotateRight(a, b)
Definition z3py.py:4547
_symbol2py(ctx, s)
Definition z3py.py:140
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4197
BVSNegNoOverflow(a)
Definition z3py.py:4733
SetAdd(s, e)
Definition z3py.py:5227
SetSort(s)
Sets.
Definition z3py.py:5170
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1312
UGT(a, b)
Definition z3py.py:4418
is_probe(p)
Definition z3py.py:9460
SetDel(s, e)
Definition z3py.py:5240
bool is_le(Any a)
Definition z3py.py:3033
BoolSort(ctx=None)
Definition z3py.py:1834
is_bv_sort(s)
Definition z3py.py:3648
_ctx_from_ast_args(*args)
Definition z3py.py:542
RatVal(a, b, ctx=None)
Definition z3py.py:3385
_to_func_decl_ref(a, ctx)
Definition z3py.py:966
SetUnion(*args)
Definition z3py.py:5195
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5525
BitVec(name, bv, ctx=None)
Definition z3py.py:4214
EmptySet(s)
Definition z3py.py:5175
BVMulNoUnderflow(a, b)
Definition z3py.py:4747
CreateDatatypes(*ds)
Definition z3py.py:5660
is_func_decl(a)
Definition z3py.py:911
FiniteSetUnion(s1, s2)
Definition z3py.py:5418
get_as_array_func(n)
Definition z3py.py:7350
Distinct(*args)
Definition z3py.py:1517
RecAddDefinition(f, args, body)
Definition z3py.py:988
ToInt(a)
Definition z3py.py:3548
Implies(a, b, ctx=None)
Definition z3py.py:1928
UGE(a, b)
Definition z3py.py:4400
Ext(a, b)
Definition z3py.py:5109
_to_ast_array(args)
Definition z3py.py:554
bool is_sort(Any s)
Definition z3py.py:682
_check_bv_args(a, b)
Definition z3py.py:4359
RealSort(ctx=None)
Definition z3py.py:3325
IsSubset(a, b)
Definition z3py.py:5289
DeclareTypeVar(name, ctx=None)
Definition z3py.py:762
_get_args_ast_list(args)
Definition z3py.py:168
bool is_to_real(Any a)
Definition z3py.py:3093
_to_ref_array(ref, args)
Definition z3py.py:562
get_map_func(a)
Definition z3py.py:4915
is_finite_set(a)
Definition z3py.py:5350
_z3_check_cint_overflow(n, name)
Definition z3py.py:118
bool is_and(Any a)
Definition z3py.py:1764
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5981
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1343
is_select(a)
Definition z3py.py:5139
SignExt(n, a)
Definition z3py.py:4563
Int(name, ctx=None)
Definition z3py.py:3418
Bools(names, ctx=None)
Definition z3py.py:1883
_probe_and(args, ctx)
Definition z3py.py:9527
Int2BV(a, num_bits)
Definition z3py.py:4173
Lambda(vs, body)
Definition z3py.py:2414
_to_param_value(val)
Definition z3py.py:178
FreshFunction(*sig)
Definition z3py.py:947
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3499
BVRedOr(a)
Definition z3py.py:4652
is_finite_set_sort(s)
Definition z3py.py:5361
SRem(a, b)
Definition z3py.py:4478
FiniteSetFilter(f, set)
Definition z3py.py:5497
SortRef _sort(Context ctx, Any a)
Definition z3py.py:730
set_option(*args, **kws)
Definition z3py.py:328
ExprRef RealVar(int idx, ctx=None)
Definition z3py.py:1600
bool is_sub(Any a)
Definition z3py.py:2980
is_bv(a)
Definition z3py.py:4121
SetDifference(a, b)
Definition z3py.py:5263
bool is_arith_sort(Any s)
Definition z3py.py:2517
BitVecs(names, bv, ctx=None)
Definition z3py.py:4238
_check_same_sort(a, b, ctx=None)
Definition z3py.py:1299
bool is_mod(Any a)
Definition z3py.py:3021
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1899
FiniteSetEmpty(set_sort)
Definition z3py.py:5399
_has_probe(args)
Definition z3py.py:1984
IsMember(e, s)
Definition z3py.py:5276
get_param(name)
Definition z3py.py:334
BVAddNoUnderflow(a, b)
Definition z3py.py:4705
deserialize(st)
Definition z3py.py:1211
bool is_not(Any a)
Definition z3py.py:1800
BvXnor(a, b)
Definition z3py.py:4685
FiniteSetMap(f, set)
Definition z3py.py:5484
Extract(high, low, a)
Definition z3py.py:4305
Function(name, *sig)
Definition z3py.py:924
get_version()
Definition z3py.py:100
FreshConst(sort, prefix="c")
Definition z3py.py:1577
ULT(a, b)
Definition z3py.py:4382
EnumSort(name, values, ctx=None)
Definition z3py.py:6005
bool is_is_int(Any a)
Definition z3py.py:3081
_to_int_str(val)
Definition z3py.py:3342
is_algebraic_value(a)
Definition z3py.py:2942
is_bv_value(a)
Definition z3py.py:4135
BVSDivNoOverflow(a, b)
Definition z3py.py:4726
bool is_eq(Any a)
Definition z3py.py:1812
Context main_ctx()
Definition z3py.py:266
CreatePolymorphicDatatype(d, type_params)
Definition z3py.py:5756
BvNand(a, b)
Definition z3py.py:4659
SetIntersect(*args)
Definition z3py.py:5211
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9594
BV2Int(a, is_signed=False)
Definition z3py.py:4150
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3457
_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:3108
is_map(a)
Definition z3py.py:4890
Context _get_ctx(ctx)
Definition z3py.py:287
Or(*args)
Definition z3py.py:2025
is_re(s)
Definition z3py.py:12093
FiniteSetIntersect(s1, s2)
Definition z3py.py:5429
args2params(arguments, keywords, ctx=None)
Definition z3py.py:6084
bool is_idiv(Any a)
Definition z3py.py:3009
Consts(names, sort)
Definition z3py.py:1562
Cond(p, t1, t2, ctx=None)
Definition z3py.py:9577
_to_pattern(arg)
Definition z3py.py:2118
RealVarVector(int n, ctx=None)
Definition z3py.py:1610
is_arith(a)
Definition z3py.py:2829
bool is_true(Any a)
Definition z3py.py:1732
bool is_false(Any a)
Definition z3py.py:1750
bool is_int(a)
Definition z3py.py:2850
If(a, b, c, ctx=None)
Definition z3py.py:1494
bool eq(AstRef a, AstRef b)
Definition z3py.py:503
is_app_of(a, k)
Definition z3py.py:1481
is_app(a)
Definition z3py.py:1378
bool is_add(Any a)
Definition z3py.py:2956
z3_error_handler(c, e)
Definition z3py.py:184
None reset_params()
Definition z3py.py:322
Reals(names, ctx=None)
Definition z3py.py:3484
is_int_value(a)
Definition z3py.py:2896
set_param(*args, **kws)
Definition z3py.py:298
is_pattern(a)
Definition z3py.py:2076
_coerce_seq(s, ctx=None)
Definition z3py.py:11744
bool is_distinct(Any a)
Definition z3py.py:1822
bool is_lt(Any a)
Definition z3py.py:3045
FiniteSetRange(low, high)
Definition z3py.py:5510
ULE(a, b)
Definition z3py.py:4364
is_real(a)
Definition z3py.py:2869
Abs(arg)
Definition z3py.py:9755
FullSet(s)
Definition z3py.py:5186
to_symbol(s, ctx=None)
Definition z3py.py:132
FiniteSetMember(elem, set)
Definition z3py.py:5451
bool is_mul(Any a)
Definition z3py.py:2968
bool is_ast(Any a)
Definition z3py.py:482
_get_args(args)
Definition z3py.py:152
Singleton(elem)
Definition z3py.py:5409
And(*args)
Definition z3py.py:1992
RepeatBitVec(n, a)
Definition z3py.py:4621
FiniteSetDifference(s1, s2)
Definition z3py.py:5440
get_version_string()
Definition z3py.py:91
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3514
Array(name, *sorts)
Definition z3py.py:4974
Concat(*args)
Definition z3py.py:4259
_reduce(func, sequence, initial)
Definition z3py.py:1336
_is_algebraic(ctx, a)
Definition z3py.py:2892
Ints(names, ctx=None)
Definition z3py.py:3431
Select(a, *args)
Definition z3py.py:5048
Const(name, sort)
Definition z3py.py:1550
is_array_sort(a)
Definition z3py.py:4846
bool is_div(Any a)
Definition z3py.py:2992
ExprRef Var(int idx, SortRef s)
Definition z3py.py:1585
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4698
BvNor(a, b)
Definition z3py.py:4672
Real(name, ctx=None)
Definition z3py.py:3471
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1914
BitVecSort(sz, ctx=None)
Definition z3py.py:4182
open_log(fname)
Definition z3py.py:122
RecFunction(name, *sig)
Definition z3py.py:970
FiniteSetSize(set)
Definition z3py.py:5463
bool is_ge(Any a)
Definition z3py.py:3057
Model(ctx=None, eval={})
Definition z3py.py:7337
BVSubNoOverflow(a, b)
Definition z3py.py:4712
bool is_gt(Any a)
Definition z3py.py:3069
In(elem, set)
Definition z3py.py:5460
is_default(a)
Definition z3py.py:4906
is_K(a)
Definition z3py.py:4877
Bool(name, ctx=None)
Definition z3py.py:1871
_is_int(v)
Definition z3py.py:76
is_const_array(a)
Definition z3py.py:4864
Sqrt(a, ctx=None)
Definition z3py.py:3583
FiniteSetSort(elem_sort)
Definition z3py.py:5390
Default(a)
Definition z3py.py:5020
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:528
SetComplement(s)
Definition z3py.py:5253
is_as_array(n)
Definition z3py.py:7345
is_store(a)
Definition z3py.py:5152
FiniteSetSubset(s1, s2)
Definition z3py.py:5473
bool is_or(Any a)
Definition z3py.py:1776
is_quantifier(a)
Definition z3py.py:2326
_mk_bin(f, a, b)
Definition z3py.py:1541
K(dom, v)
Definition z3py.py:5087
Xor(a, b, ctx=None)
Definition z3py.py:1942
Store(a, *args)
Definition z3py.py:5031
bool is_array(Any a)
Definition z3py.py:4850
mk_not(a)
Definition z3py.py:1977
is_expr(a)
Definition z3py.py:1355
_array_select(ar, arg)
Definition z3py.py:4837
is_const(a)
Definition z3py.py:1404
BoolVal(val, ctx=None)
Definition z3py.py:1852
RealVal(val, ctx=None)
Definition z3py.py:3366
bool is_implies(Any a)
Definition z3py.py:1788
z3_debug()
Definition z3py.py:70
get_full_version()
Definition z3py.py:109
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3444
_coerce_expr_merge(s, a)
Definition z3py.py:1281
Context get_ctx(ctx)
Definition z3py.py:294
LShR(a, b)
Definition z3py.py:4499
ArraySort(*sig)
Definition z3py.py:4939
Map(f, *args)
Definition z3py.py:5064
is_rational_value(a)
Definition z3py.py:2920
_probe_or(args, ctx)
Definition z3py.py:9531
BVRedAnd(a)
Definition z3py.py:4645
Cbrt(a, ctx=None)
Definition z3py.py:3596
_to_expr_ref(a, ctx)
Definition z3py.py:1225
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5993
IntSort(ctx=None)
Definition z3py.py:3308
is_seq(a)
Definition z3py.py:11765
Not(a, ctx=None)
Definition z3py.py:1958
_to_sort_ref(s, ctx)
Definition z3py.py:695
enable_trace(msg)
Definition z3py.py:83
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2393
ToReal(a)
Definition z3py.py:3528
URem(a, b)
Definition z3py.py:4457
bool is_bool(Any a)
Definition z3py.py:1714
StringVal(s, ctx=None)
Definition z3py.py:11792
IsInt(a)
Definition z3py.py:3566
_is_numeral(ctx, a)
Definition z3py.py:2888
MultiPattern(*args)
Definition z3py.py:2094
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2375
ZeroExt(n, a)
Definition z3py.py:4593
_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:5956
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4719
UDiv(a, b)
Definition z3py.py:4436
Q(a, b, ctx=None)
Definition z3py.py:3405
Update(a, *args)
Definition z3py.py:4988
get_var_index(a)
Definition z3py.py:1448
append_log(s)
Definition z3py.py:127
AsArray(f)
Definition z3py.py:5121
is_var(a)
Definition z3py.py:1423
SortRef DeclareSort(name, ctx=None)
Definition z3py.py:734
IntVal(val, ctx=None)
Definition z3py.py:3354
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4740
RotateLeft(a, b)
Definition z3py.py:4531
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2340
_z3_assert(cond, msg)
Definition z3py.py:113