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 >>> c.set_ast_print_mode(Z3_PRINT_LOW_LEVEL)
255 >>> x = Int('x', c)
256 >>> print(x)
257 (Int 0)
258 >>> c.set_ast_print_mode(Z3_PRINT_SMTLIB2_COMPLIANT)
259 >>> print(x)
260 x
261 """
262 Z3_set_ast_print_mode(self.ref(), mode)
263
264
265# Global Z3 context
266_main_ctx = None
267
268
269def main_ctx() -> Context:
270 """Return a reference to the global Z3 context.
271
272 >>> x = Real('x')
273 >>> x.ctx == main_ctx()
274 True
275 >>> c = Context()
276 >>> c == main_ctx()
277 False
278 >>> x2 = Real('x', c)
279 >>> x2.ctx == c
280 True
281 >>> eq(x, x2)
282 False
283 """
284 global _main_ctx
285 if _main_ctx is None:
286 _main_ctx = Context()
287 return _main_ctx
288
289
290def _get_ctx(ctx) -> Context:
291 if ctx is None:
292 return main_ctx()
293 else:
294 return ctx
295
296
297def get_ctx(ctx) -> Context:
298 return _get_ctx(ctx)
299
300
301def set_param(*args, **kws):
302 """Set Z3 global (or module) parameters.
303
304 >>> set_param(precision=10)
305 """
306 if z3_debug():
307 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
308 new_kws = {}
309 for k in kws:
310 v = kws[k]
311 if not set_pp_option(k, v):
312 new_kws[k] = v
313 for key in new_kws:
314 value = new_kws[key]
315 Z3_global_param_set(str(key).upper(), _to_param_value(value))
316 prev = None
317 for a in args:
318 if prev is None:
319 prev = a
320 else:
322 prev = None
323
324
325def reset_params() -> None:
326 """Reset all global (or module) parameters.
327 """
329
330
331def set_option(*args, **kws):
332 """Alias for 'set_param' for backward compatibility.
333 """
334 return set_param(*args, **kws)
335
336
337def get_param(name):
338 """Return the value of a Z3 global (or module) parameter
339
340 >>> get_param('nlsat.reorder')
341 'true'
342 """
343 ptr = (ctypes.c_char_p * 1)()
344 if Z3_global_param_get(str(name), ptr):
345 r = z3core._to_pystr(ptr[0])
346 return r
347 raise Z3Exception("failed to retrieve value for '%s'" % name)
348
349
354
355# Mark objects that use pretty printer
356
357
359 """Superclass for all Z3 objects that have support for pretty printing."""
360
361 def use_pp(self):
362 return True
363
364 def _repr_html_(self):
365 in_html = in_html_mode()
366 set_html_mode(True)
367 res = repr(self)
368 set_html_mode(in_html)
369 return res
370
371
373 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
374
375 def __init__(self, ast, ctx=None):
376 self.ast = ast
377 self.ctx = _get_ctx(ctx)
378 Z3_inc_ref(self.ctx.ref(), self.as_ast())
379
380 def __del__(self):
381 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
382 Z3_dec_ref(self.ctx.ref(), self.as_ast())
383 self.ast = None
384
385 def __deepcopy__(self, memo={}):
386 return _to_ast_ref(self.ast, self.ctx)
387
388 def __str__(self):
389 return obj_to_string(self)
390
391 def __repr__(self):
392 return obj_to_string(self)
393
394 def __eq__(self, other):
395 return self.eq(other)
396
397 def __hash__(self):
398 return self.hash()
399
400 def __nonzero__(self):
401 return self.__bool__()
402
403 def __bool__(self):
404 if is_true(self):
405 return True
406 elif is_false(self):
407 return False
408 elif is_eq(self) and self.num_args() == 2:
409 return self.arg(0).eq(self.arg(1))
410 else:
411 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
412
413 def sexpr(self):
414 """Return a string representing the AST node in s-expression notation.
415
416 >>> x = Int('x')
417 >>> ((x + 1)*x).sexpr()
418 '(* (+ x 1) x)'
419 """
420 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
421
422 def as_ast(self):
423 """Return a pointer to the corresponding C Z3_ast object."""
424 return self.ast
425
426 def get_id(self):
427 """Return unique identifier for object. It can be used for hash-tables and maps."""
428 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
429
430 def ctx_ref(self):
431 """Return a reference to the C context where this AST node is stored."""
432 return self.ctx.ref()
433
434 def eq(self, other):
435 """Return `True` if `self` and `other` are structurally identical.
436
437 >>> x = Int('x')
438 >>> n1 = x + 1
439 >>> n2 = 1 + x
440 >>> n1.eq(n2)
441 False
442 >>> n1 = simplify(n1)
443 >>> n2 = simplify(n2)
444 >>> n1.eq(n2)
445 True
446 """
447 if z3_debug():
448 _z3_assert(is_ast(other), "Z3 AST expected")
449 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
450
451 def translate(self, target):
452 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
453
454 >>> c1 = Context()
455 >>> c2 = Context()
456 >>> x = Int('x', c1)
457 >>> y = Int('y', c2)
458 >>> # Nodes in different contexts can't be mixed.
459 >>> # However, we can translate nodes from one context to another.
460 >>> x.translate(c2) + y
461 x + y
462 """
463 if z3_debug():
464 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
465 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
466
467 def __copy__(self):
468 return self.translate(self.ctx)
469
470 def hash(self):
471 """Return a hashcode for the `self`.
472
473 >>> n1 = simplify(Int('x') + 1)
474 >>> n2 = simplify(2 + Int('x') - 1)
475 >>> n1.hash() == n2.hash()
476 True
477 """
478 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
479
480 def py_value(self):
481 """Return a Python value that is equivalent to `self`."""
482 return None
483
484
485def is_ast(a : Any) -> bool:
486 """Return `True` if `a` is an AST node.
487
488 >>> is_ast(10)
489 False
490 >>> is_ast(IntVal(10))
491 True
492 >>> is_ast(Int('x'))
493 True
494 >>> is_ast(BoolSort())
495 True
496 >>> is_ast(Function('f', IntSort(), IntSort()))
497 True
498 >>> is_ast("x")
499 False
500 >>> is_ast(Solver())
501 False
502 """
503 return isinstance(a, AstRef)
504
505
506def eq(a : AstRef, b : AstRef) -> bool:
507 """Return `True` if `a` and `b` are structurally identical AST nodes.
508
509 >>> x = Int('x')
510 >>> y = Int('y')
511 >>> eq(x, y)
512 False
513 >>> eq(x + 1, x + 1)
514 True
515 >>> eq(x + 1, 1 + x)
516 False
517 >>> eq(simplify(x + 1), simplify(1 + x))
518 True
519 """
520 if z3_debug():
521 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
522 return a.eq(b)
523
524
525def _ast_kind(ctx : Context, a : Any) -> int:
526 if is_ast(a):
527 a = a.as_ast()
528 return Z3_get_ast_kind(ctx.ref(), a)
529
530
531def _ctx_from_ast_arg_list(args, default_ctx=None):
532 ctx = None
533 for a in args:
534 if is_ast(a) or is_probe(a):
535 if ctx is None:
536 ctx = a.ctx
537 else:
538 if z3_debug():
539 _z3_assert(ctx == a.ctx, "Context mismatch")
540 if ctx is None:
541 ctx = default_ctx
542 return ctx
543
544
546 return _ctx_from_ast_arg_list(args)
547
548
550 sz = len(args)
551 _args = (FuncDecl * sz)()
552 for i in range(sz):
553 _args[i] = args[i].as_func_decl()
554 return _args, sz
555
556
558 sz = len(args)
559 _args = (Ast * sz)()
560 for i in range(sz):
561 _args[i] = args[i].as_ast()
562 return _args, sz
563
564
565def _to_ref_array(ref, args):
566 sz = len(args)
567 _args = (ref * sz)()
568 for i in range(sz):
569 _args[i] = args[i].as_ast()
570 return _args, sz
571
572
573def _to_ast_ref(a, ctx):
574 k = _ast_kind(ctx, a)
575 if k == Z3_SORT_AST:
576 return _to_sort_ref(a, ctx)
577 elif k == Z3_FUNC_DECL_AST:
578 return _to_func_decl_ref(a, ctx)
579 else:
580 return _to_expr_ref(a, ctx)
581
582
583
588
589def _sort_kind(ctx, s):
590 return Z3_get_sort_kind(ctx.ref(), s)
591
592
594 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
595
596 def as_ast(self):
597 return Z3_sort_to_ast(self.ctx_ref(), self.astast)
598
599 def get_id(self):
600 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
601
602 def kind(self):
603 """Return the Z3 internal kind of a sort.
604 This method can be used to test if `self` is one of the Z3 builtin sorts.
605
606 >>> b = BoolSort()
607 >>> b.kind() == Z3_BOOL_SORT
608 True
609 >>> b.kind() == Z3_INT_SORT
610 False
611 >>> A = ArraySort(IntSort(), IntSort())
612 >>> A.kind() == Z3_ARRAY_SORT
613 True
614 >>> A.kind() == Z3_INT_SORT
615 False
616 """
617 return _sort_kind(self.ctxctx, self.astast)
618
619 def subsort(self, other):
620 """Return `True` if `self` is a subsort of `other`.
621
622 >>> IntSort().subsort(RealSort())
623 True
624 """
625 return False
626
627 def cast(self, val):
628 """Try to cast `val` as an element of sort `self`.
629
630 This method is used in Z3Py to convert Python objects such as integers,
631 floats, longs and strings into Z3 expressions.
632
633 >>> x = Int('x')
634 >>> RealSort().cast(x)
635 ToReal(x)
636 """
637 if z3_debug():
638 _z3_assert(is_expr(val), "Z3 expression expected")
639 _z3_assert(self.eq(val.sort()), "Sort mismatch")
640 return val
641
642 def name(self):
643 """Return the name (string) of sort `self`.
644
645 >>> BoolSort().name()
646 'Bool'
647 >>> ArraySort(IntSort(), IntSort()).name()
648 'Array'
649 """
650 return _symbol2py(self.ctxctx, Z3_get_sort_name(self.ctx_ref(), self.astast))
651
652 def __eq__(self, other):
653 """Return `True` if `self` and `other` are the same Z3 sort.
654
655 >>> p = Bool('p')
656 >>> p.sort() == BoolSort()
657 True
658 >>> p.sort() == IntSort()
659 False
660 """
661 if other is None:
662 return False
663 return Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
664
665 def __ne__(self, other):
666 """Return `True` if `self` and `other` are not the same Z3 sort.
667
668 >>> p = Bool('p')
669 >>> p.sort() != BoolSort()
670 False
671 >>> p.sort() != IntSort()
672 True
673 """
674 return not Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
675
676 def __gt__(self, other):
677 """Create the function space Array(self, other)"""
678 return ArraySort(self, other)
679
680 def __hash__(self):
681 """ Hash code. """
682 return AstRef.__hash__(self)
683
684
685def is_sort(s : Any) -> bool:
686 """Return `True` if `s` is a Z3 sort.
687
688 >>> is_sort(IntSort())
689 True
690 >>> is_sort(Int('x'))
691 False
692 >>> is_expr(Int('x'))
693 True
694 """
695 return isinstance(s, SortRef)
696
697
698def _to_sort_ref(s, ctx):
699 if z3_debug():
700 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
701 k = _sort_kind(ctx, s)
702 if k == Z3_BOOL_SORT:
703 return BoolSortRef(s, ctx)
704 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
705 return ArithSortRef(s, ctx)
706 elif k == Z3_BV_SORT:
707 return BitVecSortRef(s, ctx)
708 elif k == Z3_ARRAY_SORT:
709 return ArraySortRef(s, ctx)
710 elif k == Z3_DATATYPE_SORT:
711 return DatatypeSortRef(s, ctx)
712 elif k == Z3_FINITE_DOMAIN_SORT:
713 return FiniteDomainSortRef(s, ctx)
714 elif k == Z3_FLOATING_POINT_SORT:
715 return FPSortRef(s, ctx)
716 elif k == Z3_ROUNDING_MODE_SORT:
717 return FPRMSortRef(s, ctx)
718 elif k == Z3_RE_SORT:
719 return ReSortRef(s, ctx)
720 elif k == Z3_SEQ_SORT:
721 return SeqSortRef(s, ctx)
722 elif k == Z3_CHAR_SORT:
723 return CharSortRef(s, ctx)
724 elif k == Z3_TYPE_VAR:
725 return TypeVarRef(s, ctx)
726 return SortRef(s, ctx)
727
728
729def _sort(ctx : Context, a : Any) -> SortRef:
730 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
731
732
733def DeclareSort(name, ctx= None) -> SortRef:
734 """Create a new uninterpreted sort named `name`.
735
736 If `ctx=None`, then the new sort is declared in the global Z3Py context.
737
738 >>> A = DeclareSort('A')
739 >>> a = Const('a', A)
740 >>> b = Const('b', A)
741 >>> a.sort() == A
742 True
743 >>> b.sort() == A
744 True
745 >>> a == b
746 a == b
747 """
748 ctx = _get_ctx(ctx)
749 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
750
752 """Type variable reference"""
753
754 def subsort(self, other):
755 return True
756
757 def cast(self, val):
758 return val
759
760
761def DeclareTypeVar(name, ctx=None):
762 """Create a new type variable named `name`.
763
764 If `ctx=None`, then the new sort is declared in the global Z3Py context.
765
766 """
767 ctx = _get_ctx(ctx)
768 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
769
770
771
776
777
779 """Function declaration. Every constant and function have an associated declaration.
780
781 The declaration assigns a name, a sort (i.e., type), and for function
782 the sort (i.e., type) of each of its arguments. Note that, in Z3,
783 a constant is a function with 0 arguments.
784 """
785
786 def as_ast(self):
787 return Z3_func_decl_to_ast(self.ctx_ref(), self.astast)
788
789 def get_id(self):
790 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
791
792 def as_func_decl(self):
793 return self.astast
794
795 def name(self):
796 """Return the name of the function declaration `self`.
797
798 >>> f = Function('f', IntSort(), IntSort())
799 >>> f.name()
800 'f'
801 >>> isinstance(f.name(), str)
802 True
803 """
804 return _symbol2py(self.ctxctx, Z3_get_decl_name(self.ctx_ref(), self.astast))
805
806 def arity(self):
807 """Return the number of arguments of a function declaration.
808 If `self` is a constant, then `self.arity()` is 0.
809
810 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
811 >>> f.arity()
812 2
813 """
814 return int(Z3_get_arity(self.ctx_ref(), self.astast))
815
816 def domain(self, i):
817 """Return the sort of the argument `i` of a function declaration.
818 This method assumes that `0 <= i < self.arity()`.
819
820 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
821 >>> f.domain(0)
822 Int
823 >>> f.domain(1)
824 Real
825 """
826 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.astast, i), self.ctxctx)
827
828 def range(self):
829 """Return the sort of the range of a function declaration.
830 For constants, this is the sort of the constant.
831
832 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
833 >>> f.range()
834 Bool
835 """
836 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.astast), self.ctxctx)
837
838 def kind(self):
839 """Return the internal kind of a function declaration.
840 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
841
842 >>> x = Int('x')
843 >>> d = (x + 1).decl()
844 >>> d.kind() == Z3_OP_ADD
845 True
846 >>> d.kind() == Z3_OP_MUL
847 False
848 """
849 return Z3_get_decl_kind(self.ctx_ref(), self.astast)
850
851 def params(self):
852 ctx = self.ctxctx
854 result = [None for i in range(n)]
855 for i in range(n):
856 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.astast, i)
857 if k == Z3_PARAMETER_INT:
858 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.astast, i)
859 elif k == Z3_PARAMETER_DOUBLE:
860 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.astast, i)
861 elif k == Z3_PARAMETER_RATIONAL:
862 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.astast, i)
863 elif k == Z3_PARAMETER_SYMBOL:
864 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.astast, i)
865 elif k == Z3_PARAMETER_SORT:
866 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.astast, i), ctx)
867 elif k == Z3_PARAMETER_AST:
868 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.astast, i), ctx)
869 elif k == Z3_PARAMETER_FUNC_DECL:
870 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.astast, i), ctx)
871 elif k == Z3_PARAMETER_INTERNAL:
872 result[i] = "internal parameter"
873 elif k == Z3_PARAMETER_ZSTRING:
874 result[i] = "internal string"
875 else:
876 assert(False)
877 return result
878
879 def __call__(self, *args):
880 """Create a Z3 application expression using the function `self`, and the given arguments.
881
882 The arguments must be Z3 expressions. This method assumes that
883 the sorts of the elements in `args` match the sorts of the
884 domain. Limited coercion is supported. For example, if
885 args[0] is a Python integer, and the function expects a Z3
886 integer, then the argument is automatically converted into a
887 Z3 integer.
888
889 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
890 >>> x = Int('x')
891 >>> y = Real('y')
892 >>> f(x, y)
893 f(x, y)
894 >>> f(x, x)
895 f(x, ToReal(x))
896 """
897 args = _get_args(args)
898 num = len(args)
899 _args = (Ast * num)()
900 saved = []
901 for i in range(num):
902 # self.domain(i).cast(args[i]) may create a new Z3 expression,
903 # then we must save in 'saved' to prevent it from being garbage collected.
904 tmp = self.domain(i).cast(args[i])
905 saved.append(tmp)
906 _args[i] = tmp.as_ast()
907 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.astast, len(args), _args), self.ctxctx)
908
909
911 """Return `True` if `a` is a Z3 function declaration.
912
913 >>> f = Function('f', IntSort(), IntSort())
914 >>> is_func_decl(f)
915 True
916 >>> x = Real('x')
917 >>> is_func_decl(x)
918 False
919 """
920 return isinstance(a, FuncDeclRef)
921
922
923def Function(name, *sig):
924 """Create a new Z3 uninterpreted function with the given sorts.
925
926 >>> f = Function('f', IntSort(), IntSort())
927 >>> f(f(0))
928 f(f(0))
929 """
930 sig = _get_args(sig)
931 if z3_debug():
932 _z3_assert(len(sig) > 0, "At least two arguments expected")
933 arity = len(sig) - 1
934 rng = sig[arity]
935 if z3_debug():
936 _z3_assert(is_sort(rng), "Z3 sort expected")
937 dom = (Sort * arity)()
938 for i in range(arity):
939 if z3_debug():
940 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
941 dom[i] = sig[i].ast
942 ctx = rng.ctx
943 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
944
945
947 """Create a new fresh Z3 uninterpreted function with the given sorts.
948 """
949 sig = _get_args(sig)
950 if z3_debug():
951 _z3_assert(len(sig) > 0, "At least two arguments expected")
952 arity = len(sig) - 1
953 rng = sig[arity]
954 if z3_debug():
955 _z3_assert(is_sort(rng), "Z3 sort expected")
956 dom = (z3.Sort * arity)()
957 for i in range(arity):
958 if z3_debug():
959 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
960 dom[i] = sig[i].ast
961 ctx = rng.ctx
962 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
963
964
966 return FuncDeclRef(a, ctx)
967
968
969def RecFunction(name, *sig):
970 """Create a new Z3 recursive with the given sorts."""
971 sig = _get_args(sig)
972 if z3_debug():
973 _z3_assert(len(sig) > 0, "At least two arguments expected")
974 arity = len(sig) - 1
975 rng = sig[arity]
976 if z3_debug():
977 _z3_assert(is_sort(rng), "Z3 sort expected")
978 dom = (Sort * arity)()
979 for i in range(arity):
980 if z3_debug():
981 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
982 dom[i] = sig[i].ast
983 ctx = rng.ctx
984 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
985
986
987def RecAddDefinition(f, args, body):
988 """Set the body of a recursive function.
989 Recursive definitions can be simplified if they are applied to ground
990 arguments.
991 >>> ctx = Context()
992 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
993 >>> n = Int('n', ctx)
994 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
995 >>> simplify(fac(5))
996 120
997 >>> s = Solver(ctx=ctx)
998 >>> s.add(fac(n) < 3)
999 >>> s.check()
1000 sat
1001 >>> s.model().eval(fac(5))
1002 120
1003 """
1004 if is_app(args):
1005 args = [args]
1006 ctx = body.ctx
1007 args = _get_args(args)
1008 n = len(args)
1009 _args = (Ast * n)()
1010 for i in range(n):
1011 _args[i] = args[i].ast
1012 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
1013
1014
1019
1020
1022 """Constraints, formulas and terms are expressions in Z3.
1023
1024 Expressions are ASTs. Every expression has a sort.
1025 There are three main kinds of expressions:
1026 function applications, quantifiers and bounded variables.
1027 A constant is a function application with 0 arguments.
1028 For quantifier free problems, all expressions are
1029 function applications.
1030 """
1031
1032 def as_ast(self):
1033 return self.astast
1034
1035 def get_id(self):
1036 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
1037
1038 def sort(self):
1039 """Return the sort of expression `self`.
1040
1041 >>> x = Int('x')
1042 >>> (x + 1).sort()
1043 Int
1044 >>> y = Real('y')
1045 >>> (x + y).sort()
1046 Real
1047 """
1048 return _sort(self.ctxctx, self.as_astas_ast())
1049
1050 def sort_kind(self):
1051 """Shorthand for `self.sort().kind()`.
1052
1053 >>> a = Array('a', IntSort(), IntSort())
1054 >>> a.sort_kind() == Z3_ARRAY_SORT
1055 True
1056 >>> a.sort_kind() == Z3_INT_SORT
1057 False
1058 """
1059 return self.sort().kind()
1060
1061 def __eq__(self, other):
1062 """Return a Z3 expression that represents the constraint `self == other`.
1063
1064 If `other` is `None`, then this method simply returns `False`.
1065
1066 >>> a = Int('a')
1067 >>> b = Int('b')
1068 >>> a == b
1069 a == b
1070 >>> a is None
1071 False
1072 """
1073 if other is None:
1074 return False
1075 a, b = _coerce_exprs(self, other)
1076 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctx)
1077
1078 def __hash__(self):
1079 """ Hash code. """
1080 return AstRef.__hash__(self)
1081
1082 def __ne__(self, other):
1083 """Return a Z3 expression that represents the constraint `self != other`.
1084
1085 If `other` is `None`, then this method simply returns `True`.
1086
1087 >>> a = Int('a')
1088 >>> b = Int('b')
1089 >>> a != b
1090 a != b
1091 >>> a is not None
1092 True
1093 """
1094 if other is None:
1095 return True
1096 a, b = _coerce_exprs(self, other)
1097 _args, sz = _to_ast_array((a, b))
1098 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctxctx)
1099
1100 def params(self):
1101 return self.decl().params()
1102
1103 def decl(self):
1104 """Return the Z3 function declaration associated with a Z3 application.
1105
1106 >>> f = Function('f', IntSort(), IntSort())
1107 >>> a = Int('a')
1108 >>> t = f(a)
1109 >>> eq(t.decl(), f)
1110 True
1111 >>> (a + 1).decl()
1112 +
1113 """
1114 if z3_debug():
1115 _z3_assert(is_app(self), "Z3 application expected")
1116 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_astas_ast()), self.ctxctx)
1117
1118 def kind(self):
1119 """Return the Z3 internal kind of a function application."""
1120 if z3_debug():
1121 _z3_assert(is_app(self), "Z3 application expected")
1123
1124
1125 def num_args(self):
1126 """Return the number of arguments of a Z3 application.
1127
1128 >>> a = Int('a')
1129 >>> b = Int('b')
1130 >>> (a + b).num_args()
1131 2
1132 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1133 >>> t = f(a, b, 0)
1134 >>> t.num_args()
1135 3
1136 """
1137 if z3_debug():
1138 _z3_assert(is_app(self), "Z3 application expected")
1139 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_astas_ast()))
1140
1141 def arg(self, idx):
1142 """Return argument `idx` of the application `self`.
1143
1144 This method assumes that `self` is a function application with at least `idx+1` arguments.
1145
1146 >>> a = Int('a')
1147 >>> b = Int('b')
1148 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1149 >>> t = f(a, b, 0)
1150 >>> t.arg(0)
1151 a
1152 >>> t.arg(1)
1153 b
1154 >>> t.arg(2)
1155 0
1156 """
1157 if z3_debug():
1158 _z3_assert(is_app(self), "Z3 application expected")
1159 _z3_assert(idx < self.num_args(), "Invalid argument index")
1160 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_astas_ast(), idx), self.ctxctx)
1161
1162 def children(self):
1163 """Return a list containing the children of the given expression
1164
1165 >>> a = Int('a')
1166 >>> b = Int('b')
1167 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1168 >>> t = f(a, b, 0)
1169 >>> t.children()
1170 [a, b, 0]
1171 """
1172 if is_app(self):
1173 return [self.arg(i) for i in range(self.num_args())]
1174 else:
1175 return []
1176
1177 def update(self, *args):
1178 """Update the arguments of the expression.
1179
1180 Return a new expression with the same function declaration and updated arguments.
1181 The number of new arguments must match the current number of arguments.
1182
1183 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1184 >>> a = Int('a')
1185 >>> b = Int('b')
1186 >>> c = Int('c')
1187 >>> t = f(a, b)
1188 >>> t.update(c, c)
1189 f(c, c)
1190 """
1191 if z3_debug():
1192 _z3_assert(is_app(self), "Z3 application expected")
1193 _z3_assert(len(args) == self.num_args(), "Number of arguments does not match")
1194 _z3_assert(all([is_expr(arg) for arg in args]), "Z3 expressions expected")
1195 num = len(args)
1196 _args = (Ast * num)()
1197 for i in range(num):
1198 _args[i] = args[i].as_ast()
1199 return _to_expr_ref(Z3_update_term(self.ctx_ref(), self.as_astas_ast(), num, _args), self.ctxctx)
1200
1201 def from_string(self, s):
1202 pass
1203
1204 def serialize(self):
1205 s = Solver()
1206 f = Function('F', self.sort(), BoolSort(self.ctx))
1207 s.add(f(self))
1208 return s.sexpr()
1209
1211 """inverse function to the serialize method on ExprRef.
1212 It is made available to make it easier for users to serialize expressions back and forth between
1213 strings. Solvers can be serialized using the 'sexpr()' method.
1214 """
1215 s = Solver()
1216 s.from_string(st)
1217 if len(s.assertions()) != 1:
1218 raise Z3Exception("single assertion expected")
1219 fml = s.assertions()[0]
1220 if fml.num_args() != 1:
1221 raise Z3Exception("dummy function 'F' expected")
1222 return fml.arg(0)
1223
1224def _to_expr_ref(a, ctx):
1225 if isinstance(a, Pattern):
1226 return PatternRef(a, ctx)
1227 ctx_ref = ctx.ref()
1228 k = Z3_get_ast_kind(ctx_ref, a)
1229 if k == Z3_QUANTIFIER_AST:
1230 return QuantifierRef(a, ctx)
1231 sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1232 if sk == Z3_BOOL_SORT:
1233 return BoolRef(a, ctx)
1234 if sk == Z3_INT_SORT:
1235 if k == Z3_NUMERAL_AST:
1236 return IntNumRef(a, ctx)
1237 return ArithRef(a, ctx)
1238 if sk == Z3_REAL_SORT:
1239 if k == Z3_NUMERAL_AST:
1240 return RatNumRef(a, ctx)
1241 if _is_algebraic(ctx, a):
1242 return AlgebraicNumRef(a, ctx)
1243 return ArithRef(a, ctx)
1244 if sk == Z3_BV_SORT:
1245 if k == Z3_NUMERAL_AST:
1246 return BitVecNumRef(a, ctx)
1247 else:
1248 return BitVecRef(a, ctx)
1249 if sk == Z3_ARRAY_SORT:
1250 return ArrayRef(a, ctx)
1251 if sk == Z3_DATATYPE_SORT:
1252 return DatatypeRef(a, ctx)
1253 if sk == Z3_FLOATING_POINT_SORT:
1254 if k == Z3_APP_AST and _is_numeral(ctx, a):
1255 return FPNumRef(a, ctx)
1256 else:
1257 return FPRef(a, ctx)
1258 if sk == Z3_FINITE_DOMAIN_SORT:
1259 if k == Z3_NUMERAL_AST:
1260 return FiniteDomainNumRef(a, ctx)
1261 else:
1262 return FiniteDomainRef(a, ctx)
1263 if sk == Z3_ROUNDING_MODE_SORT:
1264 return FPRMRef(a, ctx)
1265 if sk == Z3_SEQ_SORT:
1266 return SeqRef(a, ctx)
1267 if sk == Z3_CHAR_SORT:
1268 return CharRef(a, ctx)
1269 if sk == Z3_RE_SORT:
1270 return ReRef(a, ctx)
1271 return ExprRef(a, ctx)
1272
1273
1275 if is_expr(a):
1276 s1 = a.sort()
1277 if s is None:
1278 return s1
1279 if s1.eq(s):
1280 return s
1281 elif s.subsort(s1):
1282 return s1
1283 elif s1.subsort(s):
1284 return s
1285 else:
1286 if z3_debug():
1287 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1288 _z3_assert(False, "sort mismatch")
1289 else:
1290 return s
1291
1292def _check_same_sort(a, b, ctx=None):
1293 if not isinstance(a, ExprRef):
1294 return False
1295 if not isinstance(b, ExprRef):
1296 return False
1297 if ctx is None:
1298 ctx = a.ctx
1299
1300 a_sort = Z3_get_sort(ctx.ctx, a.ast)
1301 b_sort = Z3_get_sort(ctx.ctx, b.ast)
1302 return Z3_is_eq_sort(ctx.ctx, a_sort, b_sort)
1303
1304
1305def _coerce_exprs(a, b, ctx=None):
1306 if not is_expr(a) and not is_expr(b):
1307 a = _py2expr(a, ctx)
1308 b = _py2expr(b, ctx)
1309 if isinstance(a, str) and isinstance(b, SeqRef):
1310 a = StringVal(a, b.ctx)
1311 if isinstance(b, str) and isinstance(a, SeqRef):
1312 b = StringVal(b, a.ctx)
1313 if isinstance(a, float) and isinstance(b, ArithRef):
1314 a = RealVal(a, b.ctx)
1315 if isinstance(b, float) and isinstance(a, ArithRef):
1316 b = RealVal(b, a.ctx)
1317
1318 if _check_same_sort(a, b, ctx):
1319 return (a, b)
1320
1321 s = None
1322 s = _coerce_expr_merge(s, a)
1323 s = _coerce_expr_merge(s, b)
1324 a = s.cast(a)
1325 b = s.cast(b)
1326 return (a, b)
1327
1328
1329def _reduce(func, sequence, initial):
1330 result = initial
1331 for element in sequence:
1332 result = func(result, element)
1333 return result
1334
1335
1336def _coerce_expr_list(alist, ctx=None):
1337 has_expr = False
1338 for a in alist:
1339 if is_expr(a):
1340 has_expr = True
1341 break
1342 if not has_expr:
1343 alist = [_py2expr(a, ctx) for a in alist]
1344 s = _reduce(_coerce_expr_merge, alist, None)
1345 return [s.cast(a) for a in alist]
1346
1347
1348def is_expr(a):
1349 """Return `True` if `a` is a Z3 expression.
1350
1351 >>> a = Int('a')
1352 >>> is_expr(a)
1353 True
1354 >>> is_expr(a + 1)
1355 True
1356 >>> is_expr(IntSort())
1357 False
1358 >>> is_expr(1)
1359 False
1360 >>> is_expr(IntVal(1))
1361 True
1362 >>> x = Int('x')
1363 >>> is_expr(ForAll(x, x >= 0))
1364 True
1365 >>> is_expr(FPVal(1.0))
1366 True
1367 """
1368 return isinstance(a, ExprRef)
1369
1370
1371def is_app(a):
1372 """Return `True` if `a` is a Z3 function application.
1373
1374 Note that, constants are function applications with 0 arguments.
1375
1376 >>> a = Int('a')
1377 >>> is_app(a)
1378 True
1379 >>> is_app(a + 1)
1380 True
1381 >>> is_app(IntSort())
1382 False
1383 >>> is_app(1)
1384 False
1385 >>> is_app(IntVal(1))
1386 True
1387 >>> x = Int('x')
1388 >>> is_app(ForAll(x, x >= 0))
1389 False
1390 """
1391 if not isinstance(a, ExprRef):
1392 return False
1393 k = _ast_kind(a.ctx, a)
1394 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1395
1396
1398 """Return `True` if `a` is Z3 constant/variable expression.
1399
1400 >>> a = Int('a')
1401 >>> is_const(a)
1402 True
1403 >>> is_const(a + 1)
1404 False
1405 >>> is_const(1)
1406 False
1407 >>> is_const(IntVal(1))
1408 True
1409 >>> x = Int('x')
1410 >>> is_const(ForAll(x, x >= 0))
1411 False
1412 """
1413 return is_app(a) and a.num_args() == 0
1414
1415
1416def is_var(a):
1417 """Return `True` if `a` is variable.
1418
1419 Z3 uses de-Bruijn indices for representing bound variables in
1420 quantifiers.
1421
1422 >>> x = Int('x')
1423 >>> is_var(x)
1424 False
1425 >>> is_const(x)
1426 True
1427 >>> f = Function('f', IntSort(), IntSort())
1428 >>> # Z3 replaces x with bound variables when ForAll is executed.
1429 >>> q = ForAll(x, f(x) == x)
1430 >>> b = q.body()
1431 >>> b
1432 f(Var(0)) == Var(0)
1433 >>> b.arg(1)
1434 Var(0)
1435 >>> is_var(b.arg(1))
1436 True
1437 """
1438 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1439
1440
1442 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1443
1444 >>> x = Int('x')
1445 >>> y = Int('y')
1446 >>> is_var(x)
1447 False
1448 >>> is_const(x)
1449 True
1450 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1451 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1452 >>> q = ForAll([x, y], f(x, y) == x + y)
1453 >>> q.body()
1454 f(Var(1), Var(0)) == Var(1) + Var(0)
1455 >>> b = q.body()
1456 >>> b.arg(0)
1457 f(Var(1), Var(0))
1458 >>> v1 = b.arg(0).arg(0)
1459 >>> v2 = b.arg(0).arg(1)
1460 >>> v1
1461 Var(1)
1462 >>> v2
1463 Var(0)
1464 >>> get_var_index(v1)
1465 1
1466 >>> get_var_index(v2)
1467 0
1468 """
1469 if z3_debug():
1470 _z3_assert(is_var(a), "Z3 bound variable expected")
1471 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1472
1473
1474def is_app_of(a, k):
1475 """Return `True` if `a` is an application of the given kind `k`.
1476
1477 >>> x = Int('x')
1478 >>> n = x + 1
1479 >>> is_app_of(n, Z3_OP_ADD)
1480 True
1481 >>> is_app_of(n, Z3_OP_MUL)
1482 False
1483 """
1484 return is_app(a) and a.kind() == k
1485
1486
1487def If(a, b, c, ctx=None):
1488 """Create a Z3 if-then-else expression.
1489
1490 >>> x = Int('x')
1491 >>> y = Int('y')
1492 >>> max = If(x > y, x, y)
1493 >>> max
1494 If(x > y, x, y)
1495 >>> simplify(max)
1496 If(x <= y, y, x)
1497 """
1498 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1499 return Cond(a, b, c, ctx)
1500 else:
1501 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1502 s = BoolSort(ctx)
1503 a = s.cast(a)
1504 b, c = _coerce_exprs(b, c, ctx)
1505 if z3_debug():
1506 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1507 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1508
1509
1510def Distinct(*args):
1511 """Create a Z3 distinct expression.
1512
1513 >>> x = Int('x')
1514 >>> y = Int('y')
1515 >>> Distinct(x, y)
1516 x != y
1517 >>> z = Int('z')
1518 >>> Distinct(x, y, z)
1519 Distinct(x, y, z)
1520 >>> simplify(Distinct(x, y, z))
1521 Distinct(x, y, z)
1522 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1523 And(Not(x == y), Not(x == z), Not(y == z))
1524 """
1525 args = _get_args(args)
1526 ctx = _ctx_from_ast_arg_list(args)
1527 if z3_debug():
1528 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1529 args = _coerce_expr_list(args, ctx)
1530 _args, sz = _to_ast_array(args)
1531 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1532
1533
1534def _mk_bin(f, a, b):
1535 args = (Ast * 2)()
1536 if z3_debug():
1537 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1538 args[0] = a.as_ast()
1539 args[1] = b.as_ast()
1540 return f(a.ctx.ref(), 2, args)
1541
1542
1543def Const(name, sort):
1544 """Create a constant of the given sort.
1545
1546 >>> Const('x', IntSort())
1547 x
1548 """
1549 if z3_debug():
1550 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1551 ctx = sort.ctx
1552 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1553
1554
1555def Consts(names, sort):
1556 """Create several constants of the given sort.
1557
1558 `names` is a string containing the names of all constants to be created.
1559 Blank spaces separate the names of different constants.
1560
1561 >>> x, y, z = Consts('x y z', IntSort())
1562 >>> x + y + z
1563 x + y + z
1564 """
1565 if isinstance(names, str):
1566 names = names.split(" ")
1567 return [Const(name, sort) for name in names]
1568
1569
1570def FreshConst(sort, prefix="c"):
1571 """Create a fresh constant of a specified sort"""
1572 if z3_debug():
1573 _z3_assert(is_sort(sort), f"Z3 sort expected, got {type(sort)}")
1574 ctx = _get_ctx(sort.ctx)
1575 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1576
1577
1578def Var(idx : int, s : SortRef) -> ExprRef:
1579 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1580 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1581 declarations.
1582
1583 >>> Var(0, IntSort())
1584 Var(0)
1585 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1586 False
1587 """
1588 if z3_debug():
1589 _z3_assert(is_sort(s), "Z3 sort expected")
1590 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1591
1592
1593def RealVar(idx: int, ctx=None) -> ExprRef:
1594 """
1595 Create a real free variable. Free variables are used to create quantified formulas.
1596 They are also used to create polynomials.
1597
1598 >>> RealVar(0)
1599 Var(0)
1600 """
1601 return Var(idx, RealSort(ctx))
1602
1603def RealVarVector(n: int, ctx= None):
1604 """
1605 Create a list of Real free variables.
1606 The variables have ids: 0, 1, ..., n-1
1607
1608 >>> x0, x1, x2, x3 = RealVarVector(4)
1609 >>> x2
1610 Var(2)
1611 """
1612 return [RealVar(i, ctx) for i in range(n)]
1613
1614
1619
1620
1622 """Boolean sort."""
1623
1624 def cast(self, val):
1625 """Try to cast `val` as a Boolean.
1626
1627 >>> x = BoolSort().cast(True)
1628 >>> x
1629 True
1630 >>> is_expr(x)
1631 True
1632 >>> is_expr(True)
1633 False
1634 >>> x.sort()
1635 Bool
1636 """
1637 if isinstance(val, bool):
1638 return BoolVal(val, self.ctxctxctx)
1639 if z3_debug():
1640 if not is_expr(val):
1641 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1642 _z3_assert(is_expr(val), msg % (val, type(val)))
1643 if not self.eq(val.sort()):
1644 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1645 return val
1646
1647 def subsort(self, other):
1648 return isinstance(other, ArithSortRef)
1649
1650 def is_int(self):
1651 return True
1652
1653 def is_bool(self):
1654 return True
1655
1656
1658 """All Boolean expressions are instances of this class."""
1659
1660 def sort(self):
1662
1663 def __add__(self, other):
1664 if isinstance(other, BoolRef):
1665 other = If(other, 1, 0)
1666 return If(self, 1, 0) + other
1667
1668 def __radd__(self, other):
1669 return self + other
1670
1671 def __rmul__(self, other):
1672 return self * other
1673
1674 def __mul__(self, other):
1675 """Create the Z3 expression `self * other`.
1676 """
1677 if isinstance(other, int) and other == 1:
1678 return If(self, 1, 0)
1679 if isinstance(other, int) and other == 0:
1680 return IntVal(0, self.ctxctxctx)
1681 if isinstance(other, BoolRef):
1682 other = If(other, 1, 0)
1683 return If(self, other, 0)
1684
1685 def __and__(self, other):
1686 return And(self, other)
1687
1688 def __or__(self, other):
1689 return Or(self, other)
1690
1691 def __xor__(self, other):
1692 return Xor(self, other)
1693
1694 def __invert__(self):
1695 return Not(self)
1696
1697 def py_value(self):
1698 if is_true(self):
1699 return True
1700 if is_false(self):
1701 return False
1702 return None
1703
1704
1705
1706
1707def is_bool(a : Any) -> bool:
1708 """Return `True` if `a` is a Z3 Boolean expression.
1709
1710 >>> p = Bool('p')
1711 >>> is_bool(p)
1712 True
1713 >>> q = Bool('q')
1714 >>> is_bool(And(p, q))
1715 True
1716 >>> x = Real('x')
1717 >>> is_bool(x)
1718 False
1719 >>> is_bool(x == 0)
1720 True
1721 """
1722 return isinstance(a, BoolRef)
1723
1724
1725def is_true(a : Any) -> bool:
1726 """Return `True` if `a` is the Z3 true expression.
1727
1728 >>> p = Bool('p')
1729 >>> is_true(p)
1730 False
1731 >>> is_true(simplify(p == p))
1732 True
1733 >>> x = Real('x')
1734 >>> is_true(x == 0)
1735 False
1736 >>> # True is a Python Boolean expression
1737 >>> is_true(True)
1738 False
1739 """
1740 return is_app_of(a, Z3_OP_TRUE)
1741
1742
1743def is_false(a : Any) -> bool:
1744 """Return `True` if `a` is the Z3 false expression.
1745
1746 >>> p = Bool('p')
1747 >>> is_false(p)
1748 False
1749 >>> is_false(False)
1750 False
1751 >>> is_false(BoolVal(False))
1752 True
1753 """
1754 return is_app_of(a, Z3_OP_FALSE)
1755
1756
1757def is_and(a : Any) -> bool:
1758 """Return `True` if `a` is a Z3 and expression.
1759
1760 >>> p, q = Bools('p q')
1761 >>> is_and(And(p, q))
1762 True
1763 >>> is_and(Or(p, q))
1764 False
1765 """
1766 return is_app_of(a, Z3_OP_AND)
1767
1768
1769def is_or(a : Any) -> bool:
1770 """Return `True` if `a` is a Z3 or expression.
1771
1772 >>> p, q = Bools('p q')
1773 >>> is_or(Or(p, q))
1774 True
1775 >>> is_or(And(p, q))
1776 False
1777 """
1778 return is_app_of(a, Z3_OP_OR)
1779
1780
1781def is_implies(a : Any) -> bool:
1782 """Return `True` if `a` is a Z3 implication expression.
1783
1784 >>> p, q = Bools('p q')
1785 >>> is_implies(Implies(p, q))
1786 True
1787 >>> is_implies(And(p, q))
1788 False
1789 """
1790 return is_app_of(a, Z3_OP_IMPLIES)
1791
1792
1793def is_not(a : Any) -> bool:
1794 """Return `True` if `a` is a Z3 not expression.
1795
1796 >>> p = Bool('p')
1797 >>> is_not(p)
1798 False
1799 >>> is_not(Not(p))
1800 True
1801 """
1802 return is_app_of(a, Z3_OP_NOT)
1803
1804
1805def is_eq(a : Any) -> bool:
1806 """Return `True` if `a` is a Z3 equality expression.
1807
1808 >>> x, y = Ints('x y')
1809 >>> is_eq(x == y)
1810 True
1811 """
1812 return is_app_of(a, Z3_OP_EQ)
1813
1814
1815def is_distinct(a : Any) -> bool:
1816 """Return `True` if `a` is a Z3 distinct expression.
1817
1818 >>> x, y, z = Ints('x y z')
1819 >>> is_distinct(x == y)
1820 False
1821 >>> is_distinct(Distinct(x, y, z))
1822 True
1823 """
1824 return is_app_of(a, Z3_OP_DISTINCT)
1825
1826
1827def BoolSort(ctx=None):
1828 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1829
1830 >>> BoolSort()
1831 Bool
1832 >>> p = Const('p', BoolSort())
1833 >>> is_bool(p)
1834 True
1835 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1836 >>> r(0, 1)
1837 r(0, 1)
1838 >>> is_bool(r(0, 1))
1839 True
1840 """
1841 ctx = _get_ctx(ctx)
1842 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1843
1844
1845def BoolVal(val, ctx=None):
1846 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1847
1848 >>> BoolVal(True)
1849 True
1850 >>> is_true(BoolVal(True))
1851 True
1852 >>> is_true(True)
1853 False
1854 >>> is_false(BoolVal(False))
1855 True
1856 """
1857 ctx = _get_ctx(ctx)
1858 if val:
1859 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1860 else:
1861 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1862
1863
1864def Bool(name, ctx=None):
1865 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1866
1867 >>> p = Bool('p')
1868 >>> q = Bool('q')
1869 >>> And(p, q)
1870 And(p, q)
1871 """
1872 ctx = _get_ctx(ctx)
1873 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1874
1875
1876def Bools(names, ctx=None):
1877 """Return a tuple of Boolean constants.
1878
1879 `names` is a single string containing all names separated by blank spaces.
1880 If `ctx=None`, then the global context is used.
1881
1882 >>> p, q, r = Bools('p q r')
1883 >>> And(p, Or(q, r))
1884 And(p, Or(q, r))
1885 """
1886 ctx = _get_ctx(ctx)
1887 if isinstance(names, str):
1888 names = names.split(" ")
1889 return [Bool(name, ctx) for name in names]
1890
1891
1892def BoolVector(prefix, sz, ctx=None):
1893 """Return a list of Boolean constants of size `sz`.
1894
1895 The constants are named using the given prefix.
1896 If `ctx=None`, then the global context is used.
1897
1898 >>> P = BoolVector('p', 3)
1899 >>> P
1900 [p__0, p__1, p__2]
1901 >>> And(P)
1902 And(p__0, p__1, p__2)
1903 """
1904 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1905
1906
1907def FreshBool(prefix="b", ctx=None):
1908 """Return a fresh Boolean constant in the given context using the given prefix.
1909
1910 If `ctx=None`, then the global context is used.
1911
1912 >>> b1 = FreshBool()
1913 >>> b2 = FreshBool()
1914 >>> eq(b1, b2)
1915 False
1916 """
1917 ctx = _get_ctx(ctx)
1918 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1919
1920
1921def Implies(a, b, ctx=None):
1922 """Create a Z3 implies expression.
1923
1924 >>> p, q = Bools('p q')
1925 >>> Implies(p, q)
1926 Implies(p, q)
1927 """
1928 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1929 s = BoolSort(ctx)
1930 a = s.cast(a)
1931 b = s.cast(b)
1932 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1933
1934
1935def Xor(a, b, ctx=None):
1936 """Create a Z3 Xor expression.
1937
1938 >>> p, q = Bools('p q')
1939 >>> Xor(p, q)
1940 Xor(p, q)
1941 >>> simplify(Xor(p, q))
1942 Not(p == q)
1943 """
1944 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1945 s = BoolSort(ctx)
1946 a = s.cast(a)
1947 b = s.cast(b)
1948 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1949
1950
1951def Not(a, ctx=None):
1952 """Create a Z3 not expression or probe.
1953
1954 >>> p = Bool('p')
1955 >>> Not(Not(p))
1956 Not(Not(p))
1957 >>> simplify(Not(Not(p)))
1958 p
1959 """
1960 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1961 if is_probe(a):
1962 # Not is also used to build probes
1963 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1964 else:
1965 s = BoolSort(ctx)
1966 a = s.cast(a)
1967 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1968
1969
1970def mk_not(a):
1971 if is_not(a):
1972 return a.arg(0)
1973 else:
1974 return Not(a)
1975
1976
1977def _has_probe(args):
1978 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1979 for arg in args:
1980 if is_probe(arg):
1981 return True
1982 return False
1983
1984
1985def And(*args):
1986 """Create a Z3 and-expression or and-probe.
1987
1988 >>> p, q, r = Bools('p q r')
1989 >>> And(p, q, r)
1990 And(p, q, r)
1991 >>> P = BoolVector('p', 5)
1992 >>> And(P)
1993 And(p__0, p__1, p__2, p__3, p__4)
1994 """
1995 last_arg = None
1996 if len(args) > 0:
1997 last_arg = args[len(args) - 1]
1998 if isinstance(last_arg, Context):
1999 ctx = args[len(args) - 1]
2000 args = args[:len(args) - 1]
2001 elif len(args) == 1 and isinstance(args[0], AstVector):
2002 ctx = args[0].ctx
2003 args = [a for a in args[0]]
2004 else:
2005 ctx = None
2006 args = _get_args(args)
2007 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2008 if z3_debug():
2009 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2010 if _has_probe(args):
2011 return _probe_and(args, ctx)
2012 else:
2013 args = _coerce_expr_list(args, ctx)
2014 _args, sz = _to_ast_array(args)
2015 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
2016
2017
2018def Or(*args):
2019 """Create a Z3 or-expression or or-probe.
2020
2021 >>> p, q, r = Bools('p q r')
2022 >>> Or(p, q, r)
2023 Or(p, q, r)
2024 >>> P = BoolVector('p', 5)
2025 >>> Or(P)
2026 Or(p__0, p__1, p__2, p__3, p__4)
2027 """
2028 last_arg = None
2029 if len(args) > 0:
2030 last_arg = args[len(args) - 1]
2031 if isinstance(last_arg, Context):
2032 ctx = args[len(args) - 1]
2033 args = args[:len(args) - 1]
2034 elif len(args) == 1 and isinstance(args[0], AstVector):
2035 ctx = args[0].ctx
2036 args = [a for a in args[0]]
2037 else:
2038 ctx = None
2039 args = _get_args(args)
2040 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2041 if z3_debug():
2042 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2043 if _has_probe(args):
2044 return _probe_or(args, ctx)
2045 else:
2046 args = _coerce_expr_list(args, ctx)
2047 _args, sz = _to_ast_array(args)
2048 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
2049
2050
2055
2056
2058 """Patterns are hints for quantifier instantiation.
2059
2060 """
2061
2062 def as_ast(self):
2064
2065 def get_id(self):
2066 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2067
2068
2070 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
2071
2072 >>> f = Function('f', IntSort(), IntSort())
2073 >>> x = Int('x')
2074 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
2075 >>> q
2076 ForAll(x, f(x) == 0)
2077 >>> q.num_patterns()
2078 1
2079 >>> is_pattern(q.pattern(0))
2080 True
2081 >>> q.pattern(0)
2082 f(Var(0))
2083 """
2084 return isinstance(a, PatternRef)
2085
2086
2087def MultiPattern(*args):
2088 """Create a Z3 multi-pattern using the given expressions `*args`
2089
2090 >>> f = Function('f', IntSort(), IntSort())
2091 >>> g = Function('g', IntSort(), IntSort())
2092 >>> x = Int('x')
2093 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2094 >>> q
2095 ForAll(x, f(x) != g(x))
2096 >>> q.num_patterns()
2097 1
2098 >>> is_pattern(q.pattern(0))
2099 True
2100 >>> q.pattern(0)
2101 MultiPattern(f(Var(0)), g(Var(0)))
2102 """
2103 if z3_debug():
2104 _z3_assert(len(args) > 0, "At least one argument expected")
2105 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2106 ctx = args[0].ctx
2107 args, sz = _to_ast_array(args)
2108 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2109
2110
2112 if is_pattern(arg):
2113 return arg
2114 else:
2115 return MultiPattern(arg)
2116
2117
2122
2123
2125 """Universally and Existentially quantified formulas."""
2126
2127 def as_ast(self):
2128 return self.astastast
2129
2130 def get_id(self):
2131 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2132
2133 def sort(self):
2134 """Return the Boolean sort or sort of Lambda."""
2135 if self.is_lambda():
2137 return BoolSort(self.ctxctxctxctx)
2138
2139 def is_forall(self):
2140 """Return `True` if `self` is a universal quantifier.
2141
2142 >>> f = Function('f', IntSort(), IntSort())
2143 >>> x = Int('x')
2144 >>> q = ForAll(x, f(x) == 0)
2145 >>> q.is_forall()
2146 True
2147 >>> q = Exists(x, f(x) != 0)
2148 >>> q.is_forall()
2149 False
2150 """
2152
2153 def is_exists(self):
2154 """Return `True` if `self` is an existential quantifier.
2155
2156 >>> f = Function('f', IntSort(), IntSort())
2157 >>> x = Int('x')
2158 >>> q = ForAll(x, f(x) == 0)
2159 >>> q.is_exists()
2160 False
2161 >>> q = Exists(x, f(x) != 0)
2162 >>> q.is_exists()
2163 True
2164 """
2165 return Z3_is_quantifier_exists(self.ctx_ref(), self.astastast)
2166
2167 def is_lambda(self):
2168 """Return `True` if `self` is a lambda expression.
2169
2170 >>> f = Function('f', IntSort(), IntSort())
2171 >>> x = Int('x')
2172 >>> q = Lambda(x, f(x))
2173 >>> q.is_lambda()
2174 True
2175 >>> q = Exists(x, f(x) != 0)
2176 >>> q.is_lambda()
2177 False
2178 """
2179 return Z3_is_lambda(self.ctx_ref(), self.astastast)
2180
2181 def __getitem__(self, arg):
2182 """Return the Z3 expression `self[arg]`.
2183 """
2184 if z3_debug():
2185 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2186 return _array_select(self, arg)
2187
2188 def weight(self):
2189 """Return the weight annotation of `self`.
2190
2191 >>> f = Function('f', IntSort(), IntSort())
2192 >>> x = Int('x')
2193 >>> q = ForAll(x, f(x) == 0)
2194 >>> q.weight()
2195 1
2196 >>> q = ForAll(x, f(x) == 0, weight=10)
2197 >>> q.weight()
2198 10
2199 """
2200 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.astastast))
2201
2202 def skolem_id(self):
2203 """Return the skolem id of `self`.
2204 """
2206
2207 def qid(self):
2208 """Return the quantifier id of `self`.
2209 """
2211
2212 def num_patterns(self):
2213 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2214
2215 >>> f = Function('f', IntSort(), IntSort())
2216 >>> g = Function('g', IntSort(), IntSort())
2217 >>> x = Int('x')
2218 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2219 >>> q.num_patterns()
2220 2
2221 """
2222 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.astastast))
2223
2224 def pattern(self, idx):
2225 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2226
2227 >>> f = Function('f', IntSort(), IntSort())
2228 >>> g = Function('g', IntSort(), IntSort())
2229 >>> x = Int('x')
2230 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2231 >>> q.num_patterns()
2232 2
2233 >>> q.pattern(0)
2234 f(Var(0))
2235 >>> q.pattern(1)
2236 g(Var(0))
2237 """
2238 if z3_debug():
2239 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2241
2243 """Return the number of no-patterns."""
2245
2246 def no_pattern(self, idx):
2247 """Return a no-pattern."""
2248 if z3_debug():
2249 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2251
2252 def body(self):
2253 """Return the expression being quantified.
2254
2255 >>> f = Function('f', IntSort(), IntSort())
2256 >>> x = Int('x')
2257 >>> q = ForAll(x, f(x) == 0)
2258 >>> q.body()
2259 f(Var(0)) == 0
2260 """
2262
2263 def num_vars(self):
2264 """Return the number of variables bounded by this quantifier.
2265
2266 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2267 >>> x = Int('x')
2268 >>> y = Int('y')
2269 >>> q = ForAll([x, y], f(x, y) >= x)
2270 >>> q.num_vars()
2271 2
2272 """
2273 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.astastast))
2274
2275 def var_name(self, idx):
2276 """Return a string representing a name used when displaying the quantifier.
2277
2278 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2279 >>> x = Int('x')
2280 >>> y = Int('y')
2281 >>> q = ForAll([x, y], f(x, y) >= x)
2282 >>> q.var_name(0)
2283 'x'
2284 >>> q.var_name(1)
2285 'y'
2286 """
2287 if z3_debug():
2288 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2290
2291 def var_sort(self, idx):
2292 """Return the sort of a bound variable.
2293
2294 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2295 >>> x = Int('x')
2296 >>> y = Real('y')
2297 >>> q = ForAll([x, y], f(x, y) >= x)
2298 >>> q.var_sort(0)
2299 Int
2300 >>> q.var_sort(1)
2301 Real
2302 """
2303 if z3_debug():
2304 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2306
2307 def children(self):
2308 """Return a list containing a single element self.body()
2309
2310 >>> f = Function('f', IntSort(), IntSort())
2311 >>> x = Int('x')
2312 >>> q = ForAll(x, f(x) == 0)
2313 >>> q.children()
2314 [f(Var(0)) == 0]
2315 """
2316 return [self.body()]
2317
2318
2320 """Return `True` if `a` is a Z3 quantifier.
2321
2322 >>> f = Function('f', IntSort(), IntSort())
2323 >>> x = Int('x')
2324 >>> q = ForAll(x, f(x) == 0)
2325 >>> is_quantifier(q)
2326 True
2327 >>> is_quantifier(f(x))
2328 False
2329 """
2330 return isinstance(a, QuantifierRef)
2331
2332
2333def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2334 if z3_debug():
2335 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2336 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2337 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2338 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2339 if is_app(vs):
2340 ctx = vs.ctx
2341 vs = [vs]
2342 else:
2343 ctx = vs[0].ctx
2344 if not is_expr(body):
2345 body = BoolVal(body, ctx)
2346 num_vars = len(vs)
2347 if num_vars == 0:
2348 return body
2349 _vs = (Ast * num_vars)()
2350 for i in range(num_vars):
2351 # TODO: Check if is constant
2352 _vs[i] = vs[i].as_ast()
2353 patterns = [_to_pattern(p) for p in patterns]
2354 num_pats = len(patterns)
2355 _pats = (Pattern * num_pats)()
2356 for i in range(num_pats):
2357 _pats[i] = patterns[i].ast
2358 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2359 qid = to_symbol(qid, ctx)
2360 skid = to_symbol(skid, ctx)
2361 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2362 num_vars, _vs,
2363 num_pats, _pats,
2364 num_no_pats, _no_pats,
2365 body.as_ast()), ctx)
2366
2367
2368def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2369 """Create a Z3 forall formula.
2370
2371 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2372
2373 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2374 >>> x = Int('x')
2375 >>> y = Int('y')
2376 >>> ForAll([x, y], f(x, y) >= x)
2377 ForAll([x, y], f(x, y) >= x)
2378 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2379 ForAll([x, y], f(x, y) >= x)
2380 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2381 ForAll([x, y], f(x, y) >= x)
2382 """
2383 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2384
2385
2386def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2387 """Create a Z3 exists formula.
2388
2389 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2390
2391
2392 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2393 >>> x = Int('x')
2394 >>> y = Int('y')
2395 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2396 >>> q
2397 Exists([x, y], f(x, y) >= x)
2398 >>> is_quantifier(q)
2399 True
2400 >>> r = Tactic('nnf')(q).as_expr()
2401 >>> is_quantifier(r)
2402 False
2403 """
2404 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2405
2406
2407def Lambda(vs, body):
2408 """Create a Z3 lambda expression.
2409
2410 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2411 >>> mem0 = Array('mem0', IntSort(), IntSort())
2412 >>> lo, hi, e, i = Ints('lo hi e i')
2413 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2414 >>> mem1
2415 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2416 """
2417 ctx = body.ctx
2418 if is_app(vs):
2419 vs = [vs]
2420 num_vars = len(vs)
2421 _vs = (Ast * num_vars)()
2422 for i in range(num_vars):
2423 # TODO: Check if is constant
2424 _vs[i] = vs[i].as_ast()
2425 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2426
2427
2432
2433
2435 """Real and Integer sorts."""
2436
2437 def is_real(self):
2438 """Return `True` if `self` is of the sort Real.
2439
2440 >>> x = Real('x')
2441 >>> x.is_real()
2442 True
2443 >>> (x + 1).is_real()
2444 True
2445 >>> x = Int('x')
2446 >>> x.is_real()
2447 False
2448 """
2449 return self.kind() == Z3_REAL_SORT
2450
2451 def is_int(self):
2452 """Return `True` if `self` is of the sort Integer.
2453
2454 >>> x = Int('x')
2455 >>> x.is_int()
2456 True
2457 >>> (x + 1).is_int()
2458 True
2459 >>> x = Real('x')
2460 >>> x.is_int()
2461 False
2462 """
2463 return self.kind() == Z3_INT_SORT
2464
2465 def is_bool(self):
2466 return False
2467
2468 def subsort(self, other):
2469 """Return `True` if `self` is a subsort of `other`."""
2470 return self.is_int() and is_arith_sort(other) and other.is_real()
2471
2472 def cast(self, val):
2473 """Try to cast `val` as an Integer or Real.
2474
2475 >>> IntSort().cast(10)
2476 10
2477 >>> is_int(IntSort().cast(10))
2478 True
2479 >>> is_int(10)
2480 False
2481 >>> RealSort().cast(10)
2482 10
2483 >>> is_real(RealSort().cast(10))
2484 True
2485 """
2486 if is_expr(val):
2487 if z3_debug():
2488 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
2489 val_s = val.sort()
2490 if self.eq(val_s):
2491 return val
2492 if val_s.is_int() and self.is_real():
2493 return ToReal(val)
2494 if val_s.is_bool() and self.is_int():
2495 return If(val, 1, 0)
2496 if val_s.is_bool() and self.is_real():
2497 return ToReal(If(val, 1, 0))
2498 if z3_debug():
2499 _z3_assert(False, "Z3 Integer/Real expression expected")
2500 else:
2501 if self.is_int():
2502 return IntVal(val, self.ctxctxctx)
2503 if self.is_real():
2504 return RealVal(val, self.ctxctxctx)
2505 if z3_debug():
2506 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2507 _z3_assert(False, msg % self)
2508
2509
2510def is_arith_sort(s : Any) -> bool:
2511 """Return `True` if s is an arithmetical sort (type).
2512
2513 >>> is_arith_sort(IntSort())
2514 True
2515 >>> is_arith_sort(RealSort())
2516 True
2517 >>> is_arith_sort(BoolSort())
2518 False
2519 >>> n = Int('x') + 1
2520 >>> is_arith_sort(n.sort())
2521 True
2522 """
2523 return isinstance(s, ArithSortRef)
2524
2525
2527 """Integer and Real expressions."""
2528
2529 def sort(self):
2530 """Return the sort (type) of the arithmetical expression `self`.
2531
2532 >>> Int('x').sort()
2533 Int
2534 >>> (Real('x') + 1).sort()
2535 Real
2536 """
2538
2539 def is_int(self):
2540 """Return `True` if `self` is an integer expression.
2541
2542 >>> x = Int('x')
2543 >>> x.is_int()
2544 True
2545 >>> (x + 1).is_int()
2546 True
2547 >>> y = Real('y')
2548 >>> (x + y).is_int()
2549 False
2550 """
2551 return self.sortsort().is_int()
2552
2553 def is_real(self):
2554 """Return `True` if `self` is an real expression.
2555
2556 >>> x = Real('x')
2557 >>> x.is_real()
2558 True
2559 >>> (x + 1).is_real()
2560 True
2561 """
2562 return self.sortsort().is_real()
2563
2564 def __add__(self, other):
2565 """Create the Z3 expression `self + other`.
2566
2567 >>> x = Int('x')
2568 >>> y = Int('y')
2569 >>> x + y
2570 x + y
2571 >>> (x + y).sort()
2572 Int
2573 """
2574 a, b = _coerce_exprs(self, other)
2575 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctxctxctx)
2576
2577 def __radd__(self, other):
2578 """Create the Z3 expression `other + self`.
2579
2580 >>> x = Int('x')
2581 >>> 10 + x
2582 10 + x
2583 """
2584 a, b = _coerce_exprs(self, other)
2585 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctxctxctx)
2586
2587 def __mul__(self, other):
2588 """Create the Z3 expression `self * other`.
2589
2590 >>> x = Real('x')
2591 >>> y = Real('y')
2592 >>> x * y
2593 x*y
2594 >>> (x * y).sort()
2595 Real
2596 """
2597 if isinstance(other, BoolRef):
2598 return If(other, self, 0)
2599 a, b = _coerce_exprs(self, other)
2600 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctxctxctx)
2601
2602 def __rmul__(self, other):
2603 """Create the Z3 expression `other * self`.
2604
2605 >>> x = Real('x')
2606 >>> 10 * x
2607 10*x
2608 """
2609 a, b = _coerce_exprs(self, other)
2610 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctxctxctx)
2611
2612 def __sub__(self, other):
2613 """Create the Z3 expression `self - other`.
2614
2615 >>> x = Int('x')
2616 >>> y = Int('y')
2617 >>> x - y
2618 x - y
2619 >>> (x - y).sort()
2620 Int
2621 """
2622 a, b = _coerce_exprs(self, other)
2623 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctxctxctx)
2624
2625 def __rsub__(self, other):
2626 """Create the Z3 expression `other - self`.
2627
2628 >>> x = Int('x')
2629 >>> 10 - x
2630 10 - x
2631 """
2632 a, b = _coerce_exprs(self, other)
2633 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctxctxctx)
2634
2635 def __pow__(self, other):
2636 """Create the Z3 expression `self**other` (** is the power operator).
2637
2638 >>> x = Real('x')
2639 >>> x**3
2640 x**3
2641 >>> (x**3).sort()
2642 Real
2643 >>> simplify(IntVal(2)**8)
2644 256
2645 """
2646 a, b = _coerce_exprs(self, other)
2647 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2648
2649 def __rpow__(self, other):
2650 """Create the Z3 expression `other**self` (** is the power operator).
2651
2652 >>> x = Real('x')
2653 >>> 2**x
2654 2**x
2655 >>> (2**x).sort()
2656 Real
2657 >>> simplify(2**IntVal(8))
2658 256
2659 """
2660 a, b = _coerce_exprs(self, other)
2661 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2662
2663 def __div__(self, other):
2664 """Create the Z3 expression `other/self`.
2665
2666 >>> x = Int('x')
2667 >>> y = Int('y')
2668 >>> x/y
2669 x/y
2670 >>> (x/y).sort()
2671 Int
2672 >>> (x/y).sexpr()
2673 '(div x y)'
2674 >>> x = Real('x')
2675 >>> y = Real('y')
2676 >>> x/y
2677 x/y
2678 >>> (x/y).sort()
2679 Real
2680 >>> (x/y).sexpr()
2681 '(/ x y)'
2682 """
2683 a, b = _coerce_exprs(self, other)
2684 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2685
2686 def __truediv__(self, other):
2687 """Create the Z3 expression `other/self`."""
2688 return self.__div__(other)
2689
2690 def __rdiv__(self, other):
2691 """Create the Z3 expression `other/self`.
2692
2693 >>> x = Int('x')
2694 >>> 10/x
2695 10/x
2696 >>> (10/x).sexpr()
2697 '(div 10 x)'
2698 >>> x = Real('x')
2699 >>> 10/x
2700 10/x
2701 >>> (10/x).sexpr()
2702 '(/ 10.0 x)'
2703 """
2704 a, b = _coerce_exprs(self, other)
2705 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2706
2707 def __rtruediv__(self, other):
2708 """Create the Z3 expression `other/self`."""
2709 return self.__rdiv__(other)
2710
2711 def __mod__(self, other):
2712 """Create the Z3 expression `other%self`.
2713
2714 >>> x = Int('x')
2715 >>> y = Int('y')
2716 >>> x % y
2717 x%y
2718 >>> simplify(IntVal(10) % IntVal(3))
2719 1
2720 """
2721 a, b = _coerce_exprs(self, other)
2722 if z3_debug():
2723 _z3_assert(a.is_int(), "Z3 integer expression expected")
2724 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2725
2726 def __rmod__(self, other):
2727 """Create the Z3 expression `other%self`.
2728
2729 >>> x = Int('x')
2730 >>> 10 % x
2731 10%x
2732 """
2733 a, b = _coerce_exprs(self, other)
2734 if z3_debug():
2735 _z3_assert(a.is_int(), "Z3 integer expression expected")
2736 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2737
2738 def __neg__(self):
2739 """Return an expression representing `-self`.
2740
2741 >>> x = Int('x')
2742 >>> -x
2743 -x
2744 >>> simplify(-(-x))
2745 x
2746 """
2747 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
2748
2749 def __pos__(self):
2750 """Return `self`.
2751
2752 >>> x = Int('x')
2753 >>> +x
2754 x
2755 """
2756 return self
2757
2758 def __le__(self, other):
2759 """Create the Z3 expression `other <= self`.
2760
2761 >>> x, y = Ints('x y')
2762 >>> x <= y
2763 x <= y
2764 >>> y = Real('y')
2765 >>> x <= y
2766 ToReal(x) <= y
2767 """
2768 a, b = _coerce_exprs(self, other)
2769 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2770
2771 def __lt__(self, other):
2772 """Create the Z3 expression `other < self`.
2773
2774 >>> x, y = Ints('x y')
2775 >>> x < y
2776 x < y
2777 >>> y = Real('y')
2778 >>> x < y
2779 ToReal(x) < y
2780 """
2781 a, b = _coerce_exprs(self, other)
2782 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2783
2784 def __gt__(self, other):
2785 """Create the Z3 expression `other > self`.
2786
2787 >>> x, y = Ints('x y')
2788 >>> x > y
2789 x > y
2790 >>> y = Real('y')
2791 >>> x > y
2792 ToReal(x) > y
2793 """
2794 a, b = _coerce_exprs(self, other)
2795 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2796
2797 def __ge__(self, other):
2798 """Create the Z3 expression `other >= self`.
2799
2800 >>> x, y = Ints('x y')
2801 >>> x >= y
2802 x >= y
2803 >>> y = Real('y')
2804 >>> x >= y
2805 ToReal(x) >= y
2806 """
2807 a, b = _coerce_exprs(self, other)
2808 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2809
2810
2812 """Return `True` if `a` is an arithmetical expression.
2813
2814 >>> x = Int('x')
2815 >>> is_arith(x)
2816 True
2817 >>> is_arith(x + 1)
2818 True
2819 >>> is_arith(1)
2820 False
2821 >>> is_arith(IntVal(1))
2822 True
2823 >>> y = Real('y')
2824 >>> is_arith(y)
2825 True
2826 >>> is_arith(y + 1)
2827 True
2828 """
2829 return isinstance(a, ArithRef)
2830
2831
2832def is_int(a) -> bool:
2833 """Return `True` if `a` is an integer expression.
2834
2835 >>> x = Int('x')
2836 >>> is_int(x + 1)
2837 True
2838 >>> is_int(1)
2839 False
2840 >>> is_int(IntVal(1))
2841 True
2842 >>> y = Real('y')
2843 >>> is_int(y)
2844 False
2845 >>> is_int(y + 1)
2846 False
2847 """
2848 return is_arith(a) and a.is_int()
2849
2850
2851def is_real(a):
2852 """Return `True` if `a` is a real expression.
2853
2854 >>> x = Int('x')
2855 >>> is_real(x + 1)
2856 False
2857 >>> y = Real('y')
2858 >>> is_real(y)
2859 True
2860 >>> is_real(y + 1)
2861 True
2862 >>> is_real(1)
2863 False
2864 >>> is_real(RealVal(1))
2865 True
2866 """
2867 return is_arith(a) and a.is_real()
2868
2869
2870def _is_numeral(ctx, a):
2871 return Z3_is_numeral_ast(ctx.ref(), a)
2872
2873
2874def _is_algebraic(ctx, a):
2875 return Z3_is_algebraic_number(ctx.ref(), a)
2876
2877
2879 """Return `True` if `a` is an integer value of sort Int.
2880
2881 >>> is_int_value(IntVal(1))
2882 True
2883 >>> is_int_value(1)
2884 False
2885 >>> is_int_value(Int('x'))
2886 False
2887 >>> n = Int('x') + 1
2888 >>> n
2889 x + 1
2890 >>> n.arg(1)
2891 1
2892 >>> is_int_value(n.arg(1))
2893 True
2894 >>> is_int_value(RealVal("1/3"))
2895 False
2896 >>> is_int_value(RealVal(1))
2897 False
2898 """
2899 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2900
2901
2903 """Return `True` if `a` is rational value of sort Real.
2904
2905 >>> is_rational_value(RealVal(1))
2906 True
2907 >>> is_rational_value(RealVal("3/5"))
2908 True
2909 >>> is_rational_value(IntVal(1))
2910 False
2911 >>> is_rational_value(1)
2912 False
2913 >>> n = Real('x') + 1
2914 >>> n.arg(1)
2915 1
2916 >>> is_rational_value(n.arg(1))
2917 True
2918 >>> is_rational_value(Real('x'))
2919 False
2920 """
2921 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2922
2923
2925 """Return `True` if `a` is an algebraic value of sort Real.
2926
2927 >>> is_algebraic_value(RealVal("3/5"))
2928 False
2929 >>> n = simplify(Sqrt(2))
2930 >>> n
2931 1.4142135623?
2932 >>> is_algebraic_value(n)
2933 True
2934 """
2935 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2936
2937
2938def is_add(a : Any) -> bool:
2939 """Return `True` if `a` is an expression of the form b + c.
2940
2941 >>> x, y = Ints('x y')
2942 >>> is_add(x + y)
2943 True
2944 >>> is_add(x - y)
2945 False
2946 """
2947 return is_app_of(a, Z3_OP_ADD)
2948
2949
2950def is_mul(a : Any) -> bool:
2951 """Return `True` if `a` is an expression of the form b * c.
2952
2953 >>> x, y = Ints('x y')
2954 >>> is_mul(x * y)
2955 True
2956 >>> is_mul(x - y)
2957 False
2958 """
2959 return is_app_of(a, Z3_OP_MUL)
2960
2961
2962def is_sub(a : Any) -> bool:
2963 """Return `True` if `a` is an expression of the form b - c.
2964
2965 >>> x, y = Ints('x y')
2966 >>> is_sub(x - y)
2967 True
2968 >>> is_sub(x + y)
2969 False
2970 """
2971 return is_app_of(a, Z3_OP_SUB)
2972
2973
2974def is_div(a : Any) -> bool:
2975 """Return `True` if `a` is an expression of the form b / c.
2976
2977 >>> x, y = Reals('x y')
2978 >>> is_div(x / y)
2979 True
2980 >>> is_div(x + y)
2981 False
2982 >>> x, y = Ints('x y')
2983 >>> is_div(x / y)
2984 False
2985 >>> is_idiv(x / y)
2986 True
2987 """
2988 return is_app_of(a, Z3_OP_DIV)
2989
2990
2991def is_idiv(a : Any) -> bool:
2992 """Return `True` if `a` is an expression of the form b div c.
2993
2994 >>> x, y = Ints('x y')
2995 >>> is_idiv(x / y)
2996 True
2997 >>> is_idiv(x + y)
2998 False
2999 """
3000 return is_app_of(a, Z3_OP_IDIV)
3001
3002
3003def is_mod(a : Any) -> bool:
3004 """Return `True` if `a` is an expression of the form b % c.
3005
3006 >>> x, y = Ints('x y')
3007 >>> is_mod(x % y)
3008 True
3009 >>> is_mod(x + y)
3010 False
3011 """
3012 return is_app_of(a, Z3_OP_MOD)
3013
3014
3015def is_le(a : Any) -> bool:
3016 """Return `True` if `a` is an expression of the form b <= c.
3017
3018 >>> x, y = Ints('x y')
3019 >>> is_le(x <= y)
3020 True
3021 >>> is_le(x < y)
3022 False
3023 """
3024 return is_app_of(a, Z3_OP_LE)
3025
3026
3027def is_lt(a : Any) -> bool:
3028 """Return `True` if `a` is an expression of the form b < c.
3029
3030 >>> x, y = Ints('x y')
3031 >>> is_lt(x < y)
3032 True
3033 >>> is_lt(x == y)
3034 False
3035 """
3036 return is_app_of(a, Z3_OP_LT)
3037
3038
3039def is_ge(a : Any) -> bool:
3040 """Return `True` if `a` is an expression of the form b >= c.
3041
3042 >>> x, y = Ints('x y')
3043 >>> is_ge(x >= y)
3044 True
3045 >>> is_ge(x == y)
3046 False
3047 """
3048 return is_app_of(a, Z3_OP_GE)
3049
3050
3051def is_gt(a : Any) -> bool:
3052 """Return `True` if `a` is an expression of the form b > c.
3053
3054 >>> x, y = Ints('x y')
3055 >>> is_gt(x > y)
3056 True
3057 >>> is_gt(x == y)
3058 False
3059 """
3060 return is_app_of(a, Z3_OP_GT)
3061
3062
3063def is_is_int(a : Any) -> bool:
3064 """Return `True` if `a` is an expression of the form IsInt(b).
3065
3066 >>> x = Real('x')
3067 >>> is_is_int(IsInt(x))
3068 True
3069 >>> is_is_int(x)
3070 False
3071 """
3072 return is_app_of(a, Z3_OP_IS_INT)
3073
3074
3075def is_to_real(a : Any) -> bool:
3076 """Return `True` if `a` is an expression of the form ToReal(b).
3077
3078 >>> x = Int('x')
3079 >>> n = ToReal(x)
3080 >>> n
3081 ToReal(x)
3082 >>> is_to_real(n)
3083 True
3084 >>> is_to_real(x)
3085 False
3086 """
3087 return is_app_of(a, Z3_OP_TO_REAL)
3088
3089
3090def is_to_int(a : Any) -> bool:
3091 """Return `True` if `a` is an expression of the form ToInt(b).
3092
3093 >>> x = Real('x')
3094 >>> n = ToInt(x)
3095 >>> n
3096 ToInt(x)
3097 >>> is_to_int(n)
3098 True
3099 >>> is_to_int(x)
3100 False
3101 """
3102 return is_app_of(a, Z3_OP_TO_INT)
3103
3104
3106 """Integer values."""
3107
3108 def as_long(self):
3109 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3110
3111 >>> v = IntVal(1)
3112 >>> v + 1
3113 1 + 1
3114 >>> v.as_long() + 1
3115 2
3116 """
3117 if z3_debug():
3118 _z3_assert(self.is_int(), "Integer value expected")
3119 return int(self.as_string())
3120
3121 def as_string(self):
3122 """Return a Z3 integer numeral as a Python string.
3123 >>> v = IntVal(100)
3124 >>> v.as_string()
3125 '100'
3126 """
3127 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3128
3130 """Return a Z3 integer numeral as a Python binary string.
3131 >>> v = IntVal(10)
3132 >>> v.as_binary_string()
3133 '1010'
3134 """
3136
3137 def py_value(self):
3138 return self.as_long()
3139
3140
3142 """Rational values."""
3143
3144 def numerator(self):
3145 """ Return the numerator of a Z3 rational numeral.
3146
3147 >>> is_rational_value(RealVal("3/5"))
3148 True
3149 >>> n = RealVal("3/5")
3150 >>> n.numerator()
3151 3
3152 >>> is_rational_value(Q(3,5))
3153 True
3154 >>> Q(3,5).numerator()
3155 3
3156 """
3158
3159 def denominator(self):
3160 """ Return the denominator of a Z3 rational numeral.
3161
3162 >>> is_rational_value(Q(3,5))
3163 True
3164 >>> n = Q(3,5)
3165 >>> n.denominator()
3166 5
3167 """
3168 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctxctx)
3169
3171 """ Return the numerator as a Python long.
3172
3173 >>> v = RealVal(10000000000)
3174 >>> v
3175 10000000000
3176 >>> v + 1
3177 10000000000 + 1
3178 >>> v.numerator_as_long() + 1 == 10000000001
3179 True
3180 """
3181 return self.numerator().as_long()
3182
3184 """ Return the denominator as a Python long.
3185
3186 >>> v = RealVal("1/3")
3187 >>> v
3188 1/3
3189 >>> v.denominator_as_long()
3190 3
3191 """
3192 return self.denominator().as_long()
3193
3194 def is_int(self):
3195 return False
3196
3197 def is_real(self):
3198 return True
3199
3200 def is_int_value(self):
3201 return self.denominator().is_int() and self.denominator_as_long() == 1
3202
3203 def as_long(self):
3204 _z3_assert(self.is_int_value(), "Expected integer fraction")
3205 return self.numerator_as_long()
3206
3207 def as_decimal(self, prec):
3208 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3209
3210 >>> v = RealVal("1/5")
3211 >>> v.as_decimal(3)
3212 '0.2'
3213 >>> v = RealVal("1/3")
3214 >>> v.as_decimal(3)
3215 '0.333?'
3216 """
3217 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3218
3219 def as_string(self):
3220 """Return a Z3 rational numeral as a Python string.
3221
3222 >>> v = Q(3,6)
3223 >>> v.as_string()
3224 '1/2'
3225 """
3226 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3227
3228 def as_fraction(self):
3229 """Return a Z3 rational as a Python Fraction object.
3230
3231 >>> v = RealVal("1/5")
3232 >>> v.as_fraction()
3233 Fraction(1, 5)
3234 """
3235 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3236
3237 def py_value(self):
3238 return Z3_get_numeral_double(self.ctx_ref(), self.as_astas_ast())
3239
3240
3242 """Algebraic irrational values."""
3243
3244 def approx(self, precision=10):
3245 """Return a Z3 rational number that approximates the algebraic number `self`.
3246 The result `r` is such that |r - self| <= 1/10^precision
3247
3248 >>> x = simplify(Sqrt(2))
3249 >>> x.approx(20)
3250 6838717160008073720548335/4835703278458516698824704
3251 >>> x.approx(5)
3252 2965821/2097152
3253 """
3255
3256 def as_decimal(self, prec):
3257 """Return a string representation of the algebraic number `self` in decimal notation
3258 using `prec` decimal places.
3259
3260 >>> x = simplify(Sqrt(2))
3261 >>> x.as_decimal(10)
3262 '1.4142135623?'
3263 >>> x.as_decimal(20)
3264 '1.41421356237309504880?'
3265 """
3266 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3267
3268 def poly(self):
3270
3271 def index(self):
3272 return Z3_algebraic_get_i(self.ctx_ref(), self.as_astas_ast())
3273
3274
3275def _py2expr(a, ctx=None):
3276 if isinstance(a, bool):
3277 return BoolVal(a, ctx)
3278 if _is_int(a):
3279 return IntVal(a, ctx)
3280 if isinstance(a, float):
3281 return RealVal(a, ctx)
3282 if isinstance(a, str):
3283 return StringVal(a, ctx)
3284 if is_expr(a):
3285 return a
3286 if z3_debug():
3287 _z3_assert(False, "Python bool, int, long or float expected")
3288
3289
3290def IntSort(ctx=None):
3291 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3292
3293 >>> IntSort()
3294 Int
3295 >>> x = Const('x', IntSort())
3296 >>> is_int(x)
3297 True
3298 >>> x.sort() == IntSort()
3299 True
3300 >>> x.sort() == BoolSort()
3301 False
3302 """
3303 ctx = _get_ctx(ctx)
3304 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3305
3306
3307def RealSort(ctx=None):
3308 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3309
3310 >>> RealSort()
3311 Real
3312 >>> x = Const('x', RealSort())
3313 >>> is_real(x)
3314 True
3315 >>> is_int(x)
3316 False
3317 >>> x.sort() == RealSort()
3318 True
3319 """
3320 ctx = _get_ctx(ctx)
3321 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3322
3323
3325 if isinstance(val, float):
3326 return str(int(val))
3327 elif isinstance(val, bool):
3328 if val:
3329 return "1"
3330 else:
3331 return "0"
3332 else:
3333 return str(val)
3334
3335
3336def IntVal(val, ctx=None):
3337 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3338
3339 >>> IntVal(1)
3340 1
3341 >>> IntVal("100")
3342 100
3343 """
3344 ctx = _get_ctx(ctx)
3345 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3346
3347
3348def RealVal(val, ctx=None):
3349 """Return a Z3 real value.
3350
3351 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3352 If `ctx=None`, then the global context is used.
3353
3354 >>> RealVal(1)
3355 1
3356 >>> RealVal(1).sort()
3357 Real
3358 >>> RealVal("3/5")
3359 3/5
3360 >>> RealVal("1.5")
3361 3/2
3362 """
3363 ctx = _get_ctx(ctx)
3364 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3365
3366
3367def RatVal(a, b, ctx=None):
3368 """Return a Z3 rational a/b.
3369
3370 If `ctx=None`, then the global context is used.
3371
3372 >>> RatVal(3,5)
3373 3/5
3374 >>> RatVal(3,5).sort()
3375 Real
3376 """
3377 if z3_debug():
3378 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3379 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3380 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3381
3382
3383def Q(a, b, ctx=None):
3384 """Return a Z3 rational a/b.
3385
3386 If `ctx=None`, then the global context is used.
3387
3388 >>> Q(3,5)
3389 3/5
3390 >>> Q(3,5).sort()
3391 Real
3392 """
3393 return simplify(RatVal(a, b, ctx=ctx))
3394
3395
3396def Int(name, ctx=None):
3397 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3398
3399 >>> x = Int('x')
3400 >>> is_int(x)
3401 True
3402 >>> is_int(x + 1)
3403 True
3404 """
3405 ctx = _get_ctx(ctx)
3406 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3407
3408
3409def Ints(names, ctx=None):
3410 """Return a tuple of Integer constants.
3411
3412 >>> x, y, z = Ints('x y z')
3413 >>> Sum(x, y, z)
3414 x + y + z
3415 """
3416 ctx = _get_ctx(ctx)
3417 if isinstance(names, str):
3418 names = names.split(" ")
3419 return [Int(name, ctx) for name in names]
3420
3421
3422def IntVector(prefix, sz, ctx=None):
3423 """Return a list of integer constants of size `sz`.
3424
3425 >>> X = IntVector('x', 3)
3426 >>> X
3427 [x__0, x__1, x__2]
3428 >>> Sum(X)
3429 x__0 + x__1 + x__2
3430 """
3431 ctx = _get_ctx(ctx)
3432 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3433
3434
3435def FreshInt(prefix="x", ctx=None):
3436 """Return a fresh integer constant in the given context using the given prefix.
3437
3438 >>> x = FreshInt()
3439 >>> y = FreshInt()
3440 >>> eq(x, y)
3441 False
3442 >>> x.sort()
3443 Int
3444 """
3445 ctx = _get_ctx(ctx)
3446 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3447
3448
3449def Real(name, ctx=None):
3450 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3451
3452 >>> x = Real('x')
3453 >>> is_real(x)
3454 True
3455 >>> is_real(x + 1)
3456 True
3457 """
3458 ctx = _get_ctx(ctx)
3459 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3460
3461
3462def Reals(names, ctx=None):
3463 """Return a tuple of real constants.
3464
3465 >>> x, y, z = Reals('x y z')
3466 >>> Sum(x, y, z)
3467 x + y + z
3468 >>> Sum(x, y, z).sort()
3469 Real
3470 """
3471 ctx = _get_ctx(ctx)
3472 if isinstance(names, str):
3473 names = names.split(" ")
3474 return [Real(name, ctx) for name in names]
3475
3476
3477def RealVector(prefix, sz, ctx=None):
3478 """Return a list of real constants of size `sz`.
3479
3480 >>> X = RealVector('x', 3)
3481 >>> X
3482 [x__0, x__1, x__2]
3483 >>> Sum(X)
3484 x__0 + x__1 + x__2
3485 >>> Sum(X).sort()
3486 Real
3487 """
3488 ctx = _get_ctx(ctx)
3489 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3490
3491
3492def FreshReal(prefix="b", ctx=None):
3493 """Return a fresh real constant in the given context using the given prefix.
3494
3495 >>> x = FreshReal()
3496 >>> y = FreshReal()
3497 >>> eq(x, y)
3498 False
3499 >>> x.sort()
3500 Real
3501 """
3502 ctx = _get_ctx(ctx)
3503 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3504
3505
3506def ToReal(a):
3507 """ Return the Z3 expression ToReal(a).
3508
3509 >>> x = Int('x')
3510 >>> x.sort()
3511 Int
3512 >>> n = ToReal(x)
3513 >>> n
3514 ToReal(x)
3515 >>> n.sort()
3516 Real
3517 """
3518 ctx = a.ctx
3519 if isinstance(a, BoolRef):
3520 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3521 if z3_debug():
3522 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3523 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3524
3525
3526def ToInt(a):
3527 """ Return the Z3 expression ToInt(a).
3528
3529 >>> x = Real('x')
3530 >>> x.sort()
3531 Real
3532 >>> n = ToInt(x)
3533 >>> n
3534 ToInt(x)
3535 >>> n.sort()
3536 Int
3537 """
3538 if z3_debug():
3539 _z3_assert(a.is_real(), "Z3 real expression expected.")
3540 ctx = a.ctx
3541 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3542
3543
3544def IsInt(a):
3545 """ Return the Z3 predicate IsInt(a).
3546
3547 >>> x = Real('x')
3548 >>> IsInt(x + "1/2")
3549 IsInt(x + 1/2)
3550 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3551 [x = 1/2]
3552 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3553 no solution
3554 """
3555 if z3_debug():
3556 _z3_assert(a.is_real(), "Z3 real expression expected.")
3557 ctx = a.ctx
3558 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3559
3560
3561def Sqrt(a, ctx=None):
3562 """ Return a Z3 expression which represents the square root of a.
3563
3564 >>> x = Real('x')
3565 >>> Sqrt(x)
3566 x**(1/2)
3567 """
3568 if not is_expr(a):
3569 ctx = _get_ctx(ctx)
3570 a = RealVal(a, ctx)
3571 return a ** "1/2"
3572
3573
3574def Cbrt(a, ctx=None):
3575 """ Return a Z3 expression which represents the cubic root of a.
3576
3577 >>> x = Real('x')
3578 >>> Cbrt(x)
3579 x**(1/3)
3580 """
3581 if not is_expr(a):
3582 ctx = _get_ctx(ctx)
3583 a = RealVal(a, ctx)
3584 return a ** "1/3"
3585
3586
3591
3592
3594 """Bit-vector sort."""
3595
3596 def size(self):
3597 """Return the size (number of bits) of the bit-vector sort `self`.
3598
3599 >>> b = BitVecSort(32)
3600 >>> b.size()
3601 32
3602 """
3603 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.astastast))
3604
3605 def subsort(self, other):
3606 return is_bv_sort(other) and self.size() < other.size()
3607
3608 def cast(self, val):
3609 """Try to cast `val` as a Bit-Vector.
3610
3611 >>> b = BitVecSort(32)
3612 >>> b.cast(10)
3613 10
3614 >>> b.cast(10).sexpr()
3615 '#x0000000a'
3616 """
3617 if is_expr(val):
3618 if z3_debug():
3619 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
3620 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3621 return val
3622 else:
3623 return BitVecVal(val, self)
3624
3625
3627 """Return True if `s` is a Z3 bit-vector sort.
3628
3629 >>> is_bv_sort(BitVecSort(32))
3630 True
3631 >>> is_bv_sort(IntSort())
3632 False
3633 """
3634 return isinstance(s, BitVecSortRef)
3635
3636
3638 """Bit-vector expressions."""
3639
3640 def sort(self):
3641 """Return the sort of the bit-vector expression `self`.
3642
3643 >>> x = BitVec('x', 32)
3644 >>> x.sort()
3645 BitVec(32)
3646 >>> x.sort() == BitVecSort(32)
3647 True
3648 """
3650
3651 def size(self):
3652 """Return the number of bits of the bit-vector expression `self`.
3653
3654 >>> x = BitVec('x', 32)
3655 >>> (x + 1).size()
3656 32
3657 >>> Concat(x, x).size()
3658 64
3659 """
3660 return self.sortsort().size()
3661
3662 def __add__(self, other):
3663 """Create the Z3 expression `self + other`.
3664
3665 >>> x = BitVec('x', 32)
3666 >>> y = BitVec('y', 32)
3667 >>> x + y
3668 x + y
3669 >>> (x + y).sort()
3670 BitVec(32)
3671 """
3672 a, b = _coerce_exprs(self, other)
3673 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3674
3675 def __radd__(self, other):
3676 """Create the Z3 expression `other + self`.
3677
3678 >>> x = BitVec('x', 32)
3679 >>> 10 + x
3680 10 + x
3681 """
3682 a, b = _coerce_exprs(self, other)
3683 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3684
3685 def __mul__(self, other):
3686 """Create the Z3 expression `self * other`.
3687
3688 >>> x = BitVec('x', 32)
3689 >>> y = BitVec('y', 32)
3690 >>> x * y
3691 x*y
3692 >>> (x * y).sort()
3693 BitVec(32)
3694 """
3695 a, b = _coerce_exprs(self, other)
3696 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3697
3698 def __rmul__(self, other):
3699 """Create the Z3 expression `other * self`.
3700
3701 >>> x = BitVec('x', 32)
3702 >>> 10 * x
3703 10*x
3704 """
3705 a, b = _coerce_exprs(self, other)
3706 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3707
3708 def __sub__(self, other):
3709 """Create the Z3 expression `self - other`.
3710
3711 >>> x = BitVec('x', 32)
3712 >>> y = BitVec('y', 32)
3713 >>> x - y
3714 x - y
3715 >>> (x - y).sort()
3716 BitVec(32)
3717 """
3718 a, b = _coerce_exprs(self, other)
3719 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3720
3721 def __rsub__(self, other):
3722 """Create the Z3 expression `other - self`.
3723
3724 >>> x = BitVec('x', 32)
3725 >>> 10 - x
3726 10 - x
3727 """
3728 a, b = _coerce_exprs(self, other)
3729 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3730
3731 def __or__(self, other):
3732 """Create the Z3 expression bitwise-or `self | other`.
3733
3734 >>> x = BitVec('x', 32)
3735 >>> y = BitVec('y', 32)
3736 >>> x | y
3737 x | y
3738 >>> (x | y).sort()
3739 BitVec(32)
3740 """
3741 a, b = _coerce_exprs(self, other)
3742 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3743
3744 def __ror__(self, other):
3745 """Create the Z3 expression bitwise-or `other | self`.
3746
3747 >>> x = BitVec('x', 32)
3748 >>> 10 | x
3749 10 | x
3750 """
3751 a, b = _coerce_exprs(self, other)
3752 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3753
3754 def __and__(self, other):
3755 """Create the Z3 expression bitwise-and `self & other`.
3756
3757 >>> x = BitVec('x', 32)
3758 >>> y = BitVec('y', 32)
3759 >>> x & y
3760 x & y
3761 >>> (x & y).sort()
3762 BitVec(32)
3763 """
3764 a, b = _coerce_exprs(self, other)
3765 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3766
3767 def __rand__(self, other):
3768 """Create the Z3 expression bitwise-or `other & self`.
3769
3770 >>> x = BitVec('x', 32)
3771 >>> 10 & x
3772 10 & x
3773 """
3774 a, b = _coerce_exprs(self, other)
3775 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3776
3777 def __xor__(self, other):
3778 """Create the Z3 expression bitwise-xor `self ^ other`.
3779
3780 >>> x = BitVec('x', 32)
3781 >>> y = BitVec('y', 32)
3782 >>> x ^ y
3783 x ^ y
3784 >>> (x ^ y).sort()
3785 BitVec(32)
3786 """
3787 a, b = _coerce_exprs(self, other)
3788 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3789
3790 def __rxor__(self, other):
3791 """Create the Z3 expression bitwise-xor `other ^ self`.
3792
3793 >>> x = BitVec('x', 32)
3794 >>> 10 ^ x
3795 10 ^ x
3796 """
3797 a, b = _coerce_exprs(self, other)
3798 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3799
3800 def __pos__(self):
3801 """Return `self`.
3802
3803 >>> x = BitVec('x', 32)
3804 >>> +x
3805 x
3806 """
3807 return self
3808
3809 def __neg__(self):
3810 """Return an expression representing `-self`.
3811
3812 >>> x = BitVec('x', 32)
3813 >>> -x
3814 -x
3815 >>> simplify(-(-x))
3816 x
3817 """
3818 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3819
3820 def __invert__(self):
3821 """Create the Z3 expression bitwise-not `~self`.
3822
3823 >>> x = BitVec('x', 32)
3824 >>> ~x
3825 ~x
3826 >>> simplify(~(~x))
3827 x
3828 """
3829 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3830
3831 def __div__(self, other):
3832 """Create the Z3 expression (signed) division `self / other`.
3833
3834 Use the function UDiv() for unsigned division.
3835
3836 >>> x = BitVec('x', 32)
3837 >>> y = BitVec('y', 32)
3838 >>> x / y
3839 x/y
3840 >>> (x / y).sort()
3841 BitVec(32)
3842 >>> (x / y).sexpr()
3843 '(bvsdiv x y)'
3844 >>> UDiv(x, y).sexpr()
3845 '(bvudiv x y)'
3846 """
3847 a, b = _coerce_exprs(self, other)
3848 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3849
3850 def __truediv__(self, other):
3851 """Create the Z3 expression (signed) division `self / other`."""
3852 return self.__div__(other)
3853
3854 def __rdiv__(self, other):
3855 """Create the Z3 expression (signed) division `other / self`.
3856
3857 Use the function UDiv() for unsigned division.
3858
3859 >>> x = BitVec('x', 32)
3860 >>> 10 / x
3861 10/x
3862 >>> (10 / x).sexpr()
3863 '(bvsdiv #x0000000a x)'
3864 >>> UDiv(10, x).sexpr()
3865 '(bvudiv #x0000000a x)'
3866 """
3867 a, b = _coerce_exprs(self, other)
3868 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3869
3870 def __rtruediv__(self, other):
3871 """Create the Z3 expression (signed) division `other / self`."""
3872 return self.__rdiv__(other)
3873
3874 def __mod__(self, other):
3875 """Create the Z3 expression (signed) mod `self % other`.
3876
3877 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3878
3879 >>> x = BitVec('x', 32)
3880 >>> y = BitVec('y', 32)
3881 >>> x % y
3882 x%y
3883 >>> (x % y).sort()
3884 BitVec(32)
3885 >>> (x % y).sexpr()
3886 '(bvsmod x y)'
3887 >>> URem(x, y).sexpr()
3888 '(bvurem x y)'
3889 >>> SRem(x, y).sexpr()
3890 '(bvsrem x y)'
3891 """
3892 a, b = _coerce_exprs(self, other)
3893 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3894
3895 def __rmod__(self, other):
3896 """Create the Z3 expression (signed) mod `other % self`.
3897
3898 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3899
3900 >>> x = BitVec('x', 32)
3901 >>> 10 % x
3902 10%x
3903 >>> (10 % x).sexpr()
3904 '(bvsmod #x0000000a x)'
3905 >>> URem(10, x).sexpr()
3906 '(bvurem #x0000000a x)'
3907 >>> SRem(10, x).sexpr()
3908 '(bvsrem #x0000000a x)'
3909 """
3910 a, b = _coerce_exprs(self, other)
3911 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3912
3913 def __le__(self, other):
3914 """Create the Z3 expression (signed) `other <= self`.
3915
3916 Use the function ULE() for unsigned less than or equal to.
3917
3918 >>> x, y = BitVecs('x y', 32)
3919 >>> x <= y
3920 x <= y
3921 >>> (x <= y).sexpr()
3922 '(bvsle x y)'
3923 >>> ULE(x, y).sexpr()
3924 '(bvule x y)'
3925 """
3926 a, b = _coerce_exprs(self, other)
3927 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3928
3929 def __lt__(self, other):
3930 """Create the Z3 expression (signed) `other < self`.
3931
3932 Use the function ULT() for unsigned less than.
3933
3934 >>> x, y = BitVecs('x y', 32)
3935 >>> x < y
3936 x < y
3937 >>> (x < y).sexpr()
3938 '(bvslt x y)'
3939 >>> ULT(x, y).sexpr()
3940 '(bvult x y)'
3941 """
3942 a, b = _coerce_exprs(self, other)
3943 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3944
3945 def __gt__(self, other):
3946 """Create the Z3 expression (signed) `other > self`.
3947
3948 Use the function UGT() for unsigned greater than.
3949
3950 >>> x, y = BitVecs('x y', 32)
3951 >>> x > y
3952 x > y
3953 >>> (x > y).sexpr()
3954 '(bvsgt x y)'
3955 >>> UGT(x, y).sexpr()
3956 '(bvugt x y)'
3957 """
3958 a, b = _coerce_exprs(self, other)
3959 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3960
3961 def __ge__(self, other):
3962 """Create the Z3 expression (signed) `other >= self`.
3963
3964 Use the function UGE() for unsigned greater than or equal to.
3965
3966 >>> x, y = BitVecs('x y', 32)
3967 >>> x >= y
3968 x >= y
3969 >>> (x >= y).sexpr()
3970 '(bvsge x y)'
3971 >>> UGE(x, y).sexpr()
3972 '(bvuge x y)'
3973 """
3974 a, b = _coerce_exprs(self, other)
3975 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3976
3977 def __rshift__(self, other):
3978 """Create the Z3 expression (arithmetical) right shift `self >> other`
3979
3980 Use the function LShR() for the right logical shift
3981
3982 >>> x, y = BitVecs('x y', 32)
3983 >>> x >> y
3984 x >> y
3985 >>> (x >> y).sexpr()
3986 '(bvashr x y)'
3987 >>> LShR(x, y).sexpr()
3988 '(bvlshr x y)'
3989 >>> BitVecVal(4, 3)
3990 4
3991 >>> BitVecVal(4, 3).as_signed_long()
3992 -4
3993 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3994 -2
3995 >>> simplify(BitVecVal(4, 3) >> 1)
3996 6
3997 >>> simplify(LShR(BitVecVal(4, 3), 1))
3998 2
3999 >>> simplify(BitVecVal(2, 3) >> 1)
4000 1
4001 >>> simplify(LShR(BitVecVal(2, 3), 1))
4002 1
4003 """
4004 a, b = _coerce_exprs(self, other)
4005 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
4006
4007 def __lshift__(self, other):
4008 """Create the Z3 expression left shift `self << other`
4009
4010 >>> x, y = BitVecs('x y', 32)
4011 >>> x << y
4012 x << y
4013 >>> (x << y).sexpr()
4014 '(bvshl x y)'
4015 >>> simplify(BitVecVal(2, 3) << 1)
4016 4
4017 """
4018 a, b = _coerce_exprs(self, other)
4019 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
4020
4021 def __rrshift__(self, other):
4022 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
4023
4024 Use the function LShR() for the right logical shift
4025
4026 >>> x = BitVec('x', 32)
4027 >>> 10 >> x
4028 10 >> x
4029 >>> (10 >> x).sexpr()
4030 '(bvashr #x0000000a x)'
4031 """
4032 a, b = _coerce_exprs(self, other)
4033 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
4034
4035 def __rlshift__(self, other):
4036 """Create the Z3 expression left shift `other << self`.
4037
4038 Use the function LShR() for the right logical shift
4039
4040 >>> x = BitVec('x', 32)
4041 >>> 10 << x
4042 10 << x
4043 >>> (10 << x).sexpr()
4044 '(bvshl #x0000000a x)'
4045 """
4046 a, b = _coerce_exprs(self, other)
4047 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
4048
4049
4051 """Bit-vector values."""
4052
4053 def as_long(self):
4054 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4055
4056 >>> v = BitVecVal(0xbadc0de, 32)
4057 >>> v
4058 195936478
4059 >>> print("0x%.8x" % v.as_long())
4060 0x0badc0de
4061 """
4062 return int(self.as_string())
4063
4065 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4066 The most significant bit is assumed to be the sign.
4067
4068 >>> BitVecVal(4, 3).as_signed_long()
4069 -4
4070 >>> BitVecVal(7, 3).as_signed_long()
4071 -1
4072 >>> BitVecVal(3, 3).as_signed_long()
4073 3
4074 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4075 -1
4076 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4077 -1
4078 """
4079 sz = self.size()
4080 val = self.as_long()
4081 if val >= 2**(sz - 1):
4082 val = val - 2**sz
4083 if val < -2**(sz - 1):
4084 val = val + 2**sz
4085 return int(val)
4086
4087 def as_string(self):
4088 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
4089
4092
4093 def py_value(self):
4094 """Return the Python value of a Z3 bit-vector numeral."""
4095 return self.as_long()
4096
4097
4098
4099def is_bv(a):
4100 """Return `True` if `a` is a Z3 bit-vector expression.
4101
4102 >>> b = BitVec('b', 32)
4103 >>> is_bv(b)
4104 True
4105 >>> is_bv(b + 10)
4106 True
4107 >>> is_bv(Int('x'))
4108 False
4109 """
4110 return isinstance(a, BitVecRef)
4111
4112
4114 """Return `True` if `a` is a Z3 bit-vector numeral value.
4115
4116 >>> b = BitVec('b', 32)
4117 >>> is_bv_value(b)
4118 False
4119 >>> b = BitVecVal(10, 32)
4120 >>> b
4121 10
4122 >>> is_bv_value(b)
4123 True
4124 """
4125 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4126
4127
4128def BV2Int(a, is_signed=False):
4129 """Return the Z3 expression BV2Int(a).
4130
4131 >>> b = BitVec('b', 3)
4132 >>> BV2Int(b).sort()
4133 Int
4134 >>> x = Int('x')
4135 >>> x > BV2Int(b)
4136 x > BV2Int(b)
4137 >>> x > BV2Int(b, is_signed=False)
4138 x > BV2Int(b)
4139 >>> x > BV2Int(b, is_signed=True)
4140 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4141 >>> solve(x > BV2Int(b), b == 1, x < 3)
4142 [x = 2, b = 1]
4143 """
4144 if z3_debug():
4145 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4146 ctx = a.ctx
4147 # investigate problem with bv2int
4148 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4149
4150
4151def Int2BV(a, num_bits):
4152 """Return the z3 expression Int2BV(a, num_bits).
4153 It is a bit-vector of width num_bits and represents the
4154 modulo of a by 2^num_bits
4155 """
4156 ctx = a.ctx
4157 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4158
4159
4160def BitVecSort(sz, ctx=None):
4161 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4162
4163 >>> Byte = BitVecSort(8)
4164 >>> Word = BitVecSort(16)
4165 >>> Byte
4166 BitVec(8)
4167 >>> x = Const('x', Byte)
4168 >>> eq(x, BitVec('x', 8))
4169 True
4170 """
4171 ctx = _get_ctx(ctx)
4172 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4173
4174
4175def BitVecVal(val, bv, ctx=None):
4176 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4177
4178 >>> v = BitVecVal(10, 32)
4179 >>> v
4180 10
4181 >>> print("0x%.8x" % v.as_long())
4182 0x0000000a
4183 """
4184 if is_bv_sort(bv):
4185 ctx = bv.ctx
4186 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4187 else:
4188 ctx = _get_ctx(ctx)
4189 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4190
4191
4192def BitVec(name, bv, ctx=None):
4193 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4194 If `ctx=None`, then the global context is used.
4195
4196 >>> x = BitVec('x', 16)
4197 >>> is_bv(x)
4198 True
4199 >>> x.size()
4200 16
4201 >>> x.sort()
4202 BitVec(16)
4203 >>> word = BitVecSort(16)
4204 >>> x2 = BitVec('x', word)
4205 >>> eq(x, x2)
4206 True
4207 """
4208 if isinstance(bv, BitVecSortRef):
4209 ctx = bv.ctx
4210 else:
4211 ctx = _get_ctx(ctx)
4212 bv = BitVecSort(bv, ctx)
4213 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4214
4215
4216def BitVecs(names, bv, ctx=None):
4217 """Return a tuple of bit-vector constants of size bv.
4218
4219 >>> x, y, z = BitVecs('x y z', 16)
4220 >>> x.size()
4221 16
4222 >>> x.sort()
4223 BitVec(16)
4224 >>> Sum(x, y, z)
4225 0 + x + y + z
4226 >>> Product(x, y, z)
4227 1*x*y*z
4228 >>> simplify(Product(x, y, z))
4229 x*y*z
4230 """
4231 ctx = _get_ctx(ctx)
4232 if isinstance(names, str):
4233 names = names.split(" ")
4234 return [BitVec(name, bv, ctx) for name in names]
4235
4236
4237def Concat(*args):
4238 """Create a Z3 bit-vector concatenation expression.
4239
4240 >>> v = BitVecVal(1, 4)
4241 >>> Concat(v, v+1, v)
4242 Concat(Concat(1, 1 + 1), 1)
4243 >>> simplify(Concat(v, v+1, v))
4244 289
4245 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4246 121
4247 """
4248 args = _get_args(args)
4249 sz = len(args)
4250 if z3_debug():
4251 _z3_assert(sz >= 2, "At least two arguments expected.")
4252
4253 ctx = None
4254 for a in args:
4255 if is_expr(a):
4256 ctx = a.ctx
4257 break
4258 if is_seq(args[0]) or isinstance(args[0], str):
4259 args = [_coerce_seq(s, ctx) for s in args]
4260 if z3_debug():
4261 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4262 v = (Ast * sz)()
4263 for i in range(sz):
4264 v[i] = args[i].as_ast()
4265 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4266
4267 if is_re(args[0]):
4268 if z3_debug():
4269 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4270 v = (Ast * sz)()
4271 for i in range(sz):
4272 v[i] = args[i].as_ast()
4273 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4274
4275 if z3_debug():
4276 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4277 r = args[0]
4278 for i in range(sz - 1):
4279 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4280 return r
4281
4282
4283def Extract(high, low, a):
4284 """Create a Z3 bit-vector extraction expression or sequence extraction expression.
4285
4286 Extract is overloaded to work with both bit-vectors and sequences:
4287
4288 **Bit-vector extraction**: Extract(high, low, bitvector)
4289 Extracts bits from position `high` down to position `low` (both inclusive).
4290 - high: int - the highest bit position to extract (0-indexed from right)
4291 - low: int - the lowest bit position to extract (0-indexed from right)
4292 - bitvector: BitVecRef - the bit-vector to extract from
4293 Returns a new bit-vector containing bits [high:low]
4294
4295 **Sequence extraction**: Extract(sequence, offset, length)
4296 Extracts a subsequence starting at the given offset with the specified length.
4297 The functions SubString and SubSeq are redirected to this form of Extract.
4298 - sequence: SeqRef or str - the sequence to extract from
4299 - offset: int - the starting position (0-indexed)
4300 - length: int - the number of elements to extract
4301 Returns a new sequence containing the extracted subsequence
4302
4303 >>> # Bit-vector extraction examples
4304 >>> x = BitVec('x', 8)
4305 >>> Extract(6, 2, x) # Extract bits 6 down to 2 (5 bits total)
4306 Extract(6, 2, x)
4307 >>> Extract(6, 2, x).sort() # Result is a 5-bit vector
4308 BitVec(5)
4309 >>> Extract(7, 0, x) # Extract all 8 bits
4310 Extract(7, 0, x)
4311 >>> Extract(3, 3, x) # Extract single bit at position 3
4312 Extract(3, 3, x)
4313
4314 >>> # Sequence extraction examples
4315 >>> s = StringVal("hello")
4316 >>> Extract(s, 1, 3) # Extract 3 characters starting at position 1
4317 str.substr("hello", 1, 3)
4318 >>> simplify(Extract(StringVal("abcd"), 2, 1)) # Extract 1 character at position 2
4319 "c"
4320 >>> simplify(Extract(StringVal("abcd"), 0, 2)) # Extract first 2 characters
4321 "ab"
4322 """
4323 if isinstance(high, str):
4324 high = StringVal(high)
4325 if is_seq(high):
4326 s = high
4327 offset, length = _coerce_exprs(low, a, s.ctx)
4328 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4329 if z3_debug():
4330 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4331 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4332 "First and second arguments must be non negative integers")
4333 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4334 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4335
4336
4338 if z3_debug():
4339 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4340
4341
4342def ULE(a, b):
4343 """Create the Z3 expression (unsigned) `other <= self`.
4344
4345 Use the operator <= for signed less than or equal to.
4346
4347 >>> x, y = BitVecs('x y', 32)
4348 >>> ULE(x, y)
4349 ULE(x, y)
4350 >>> (x <= y).sexpr()
4351 '(bvsle x y)'
4352 >>> ULE(x, y).sexpr()
4353 '(bvule x y)'
4354 """
4355 _check_bv_args(a, b)
4356 a, b = _coerce_exprs(a, b)
4357 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4358
4359
4360def ULT(a, b):
4361 """Create the Z3 expression (unsigned) `other < self`.
4362
4363 Use the operator < for signed less than.
4364
4365 >>> x, y = BitVecs('x y', 32)
4366 >>> ULT(x, y)
4367 ULT(x, y)
4368 >>> (x < y).sexpr()
4369 '(bvslt x y)'
4370 >>> ULT(x, y).sexpr()
4371 '(bvult x y)'
4372 """
4373 _check_bv_args(a, b)
4374 a, b = _coerce_exprs(a, b)
4375 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4376
4377
4378def UGE(a, b):
4379 """Create the Z3 expression (unsigned) `other >= self`.
4380
4381 Use the operator >= for signed greater than or equal to.
4382
4383 >>> x, y = BitVecs('x y', 32)
4384 >>> UGE(x, y)
4385 UGE(x, y)
4386 >>> (x >= y).sexpr()
4387 '(bvsge x y)'
4388 >>> UGE(x, y).sexpr()
4389 '(bvuge x y)'
4390 """
4391 _check_bv_args(a, b)
4392 a, b = _coerce_exprs(a, b)
4393 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4394
4395
4396def UGT(a, b):
4397 """Create the Z3 expression (unsigned) `other > self`.
4398
4399 Use the operator > for signed greater than.
4400
4401 >>> x, y = BitVecs('x y', 32)
4402 >>> UGT(x, y)
4403 UGT(x, y)
4404 >>> (x > y).sexpr()
4405 '(bvsgt x y)'
4406 >>> UGT(x, y).sexpr()
4407 '(bvugt x y)'
4408 """
4409 _check_bv_args(a, b)
4410 a, b = _coerce_exprs(a, b)
4411 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4412
4413
4414def UDiv(a, b):
4415 """Create the Z3 expression (unsigned) division `self / other`.
4416
4417 Use the operator / for signed division.
4418
4419 >>> x = BitVec('x', 32)
4420 >>> y = BitVec('y', 32)
4421 >>> UDiv(x, y)
4422 UDiv(x, y)
4423 >>> UDiv(x, y).sort()
4424 BitVec(32)
4425 >>> (x / y).sexpr()
4426 '(bvsdiv x y)'
4427 >>> UDiv(x, y).sexpr()
4428 '(bvudiv x y)'
4429 """
4430 _check_bv_args(a, b)
4431 a, b = _coerce_exprs(a, b)
4432 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4433
4434
4435def URem(a, b):
4436 """Create the Z3 expression (unsigned) remainder `self % other`.
4437
4438 Use the operator % for signed modulus, and SRem() for signed remainder.
4439
4440 >>> x = BitVec('x', 32)
4441 >>> y = BitVec('y', 32)
4442 >>> URem(x, y)
4443 URem(x, y)
4444 >>> URem(x, y).sort()
4445 BitVec(32)
4446 >>> (x % y).sexpr()
4447 '(bvsmod x y)'
4448 >>> URem(x, y).sexpr()
4449 '(bvurem x y)'
4450 """
4451 _check_bv_args(a, b)
4452 a, b = _coerce_exprs(a, b)
4453 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4454
4455
4456def SRem(a, b):
4457 """Create the Z3 expression signed remainder.
4458
4459 Use the operator % for signed modulus, and URem() for unsigned remainder.
4460
4461 >>> x = BitVec('x', 32)
4462 >>> y = BitVec('y', 32)
4463 >>> SRem(x, y)
4464 SRem(x, y)
4465 >>> SRem(x, y).sort()
4466 BitVec(32)
4467 >>> (x % y).sexpr()
4468 '(bvsmod x y)'
4469 >>> SRem(x, y).sexpr()
4470 '(bvsrem x y)'
4471 """
4472 _check_bv_args(a, b)
4473 a, b = _coerce_exprs(a, b)
4474 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4475
4476
4477def LShR(a, b):
4478 """Create the Z3 expression logical right shift.
4479
4480 Use the operator >> for the arithmetical right shift.
4481
4482 >>> x, y = BitVecs('x y', 32)
4483 >>> LShR(x, y)
4484 LShR(x, y)
4485 >>> (x >> y).sexpr()
4486 '(bvashr x y)'
4487 >>> LShR(x, y).sexpr()
4488 '(bvlshr x y)'
4489 >>> BitVecVal(4, 3)
4490 4
4491 >>> BitVecVal(4, 3).as_signed_long()
4492 -4
4493 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4494 -2
4495 >>> simplify(BitVecVal(4, 3) >> 1)
4496 6
4497 >>> simplify(LShR(BitVecVal(4, 3), 1))
4498 2
4499 >>> simplify(BitVecVal(2, 3) >> 1)
4500 1
4501 >>> simplify(LShR(BitVecVal(2, 3), 1))
4502 1
4503 """
4504 _check_bv_args(a, b)
4505 a, b = _coerce_exprs(a, b)
4506 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4507
4508
4509def RotateLeft(a, b):
4510 """Return an expression representing `a` rotated to the left `b` times.
4511
4512 >>> a, b = BitVecs('a b', 16)
4513 >>> RotateLeft(a, b)
4514 RotateLeft(a, b)
4515 >>> simplify(RotateLeft(a, 0))
4516 a
4517 >>> simplify(RotateLeft(a, 16))
4518 a
4519 """
4520 _check_bv_args(a, b)
4521 a, b = _coerce_exprs(a, b)
4522 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4523
4524
4525def RotateRight(a, b):
4526 """Return an expression representing `a` rotated to the right `b` times.
4527
4528 >>> a, b = BitVecs('a b', 16)
4529 >>> RotateRight(a, b)
4530 RotateRight(a, b)
4531 >>> simplify(RotateRight(a, 0))
4532 a
4533 >>> simplify(RotateRight(a, 16))
4534 a
4535 """
4536 _check_bv_args(a, b)
4537 a, b = _coerce_exprs(a, b)
4538 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4539
4540
4541def SignExt(n, a):
4542 """Return a bit-vector expression with `n` extra sign-bits.
4543
4544 >>> x = BitVec('x', 16)
4545 >>> n = SignExt(8, x)
4546 >>> n.size()
4547 24
4548 >>> n
4549 SignExt(8, x)
4550 >>> n.sort()
4551 BitVec(24)
4552 >>> v0 = BitVecVal(2, 2)
4553 >>> v0
4554 2
4555 >>> v0.size()
4556 2
4557 >>> v = simplify(SignExt(6, v0))
4558 >>> v
4559 254
4560 >>> v.size()
4561 8
4562 >>> print("%.x" % v.as_long())
4563 fe
4564 """
4565 if z3_debug():
4566 _z3_assert(_is_int(n), "First argument must be an integer")
4567 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4568 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4569
4570
4571def ZeroExt(n, a):
4572 """Return a bit-vector expression with `n` extra zero-bits.
4573
4574 >>> x = BitVec('x', 16)
4575 >>> n = ZeroExt(8, x)
4576 >>> n.size()
4577 24
4578 >>> n
4579 ZeroExt(8, x)
4580 >>> n.sort()
4581 BitVec(24)
4582 >>> v0 = BitVecVal(2, 2)
4583 >>> v0
4584 2
4585 >>> v0.size()
4586 2
4587 >>> v = simplify(ZeroExt(6, v0))
4588 >>> v
4589 2
4590 >>> v.size()
4591 8
4592 """
4593 if z3_debug():
4594 _z3_assert(_is_int(n), "First argument must be an integer")
4595 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4596 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4597
4598
4600 """Return an expression representing `n` copies of `a`.
4601
4602 >>> x = BitVec('x', 8)
4603 >>> n = RepeatBitVec(4, x)
4604 >>> n
4605 RepeatBitVec(4, x)
4606 >>> n.size()
4607 32
4608 >>> v0 = BitVecVal(10, 4)
4609 >>> print("%.x" % v0.as_long())
4610 a
4611 >>> v = simplify(RepeatBitVec(4, v0))
4612 >>> v.size()
4613 16
4614 >>> print("%.x" % v.as_long())
4615 aaaa
4616 """
4617 if z3_debug():
4618 _z3_assert(_is_int(n), "First argument must be an integer")
4619 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4620 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4621
4622
4624 """Return the reduction-and expression of `a`."""
4625 if z3_debug():
4626 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4627 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4628
4629
4630def BVRedOr(a):
4631 """Return the reduction-or expression of `a`."""
4632 if z3_debug():
4633 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4634 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4635
4636
4637def BVAddNoOverflow(a, b, signed):
4638 """A predicate the determines that bit-vector addition does not overflow"""
4639 _check_bv_args(a, b)
4640 a, b = _coerce_exprs(a, b)
4641 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4642
4643
4645 """A predicate the determines that signed bit-vector addition does not underflow"""
4646 _check_bv_args(a, b)
4647 a, b = _coerce_exprs(a, b)
4648 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4649
4650
4652 """A predicate the determines that bit-vector subtraction does not overflow"""
4653 _check_bv_args(a, b)
4654 a, b = _coerce_exprs(a, b)
4655 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4656
4657
4658def BVSubNoUnderflow(a, b, signed):
4659 """A predicate the determines that bit-vector subtraction does not underflow"""
4660 _check_bv_args(a, b)
4661 a, b = _coerce_exprs(a, b)
4662 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4663
4664
4666 """A predicate the determines that bit-vector signed division does not overflow"""
4667 _check_bv_args(a, b)
4668 a, b = _coerce_exprs(a, b)
4669 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4670
4671
4673 """A predicate the determines that bit-vector unary negation does not overflow"""
4674 if z3_debug():
4675 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4676 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4677
4678
4679def BVMulNoOverflow(a, b, signed):
4680 """A predicate the determines that bit-vector multiplication does not overflow"""
4681 _check_bv_args(a, b)
4682 a, b = _coerce_exprs(a, b)
4683 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4684
4685
4687 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4688 _check_bv_args(a, b)
4689 a, b = _coerce_exprs(a, b)
4690 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4691
4692
4693
4698
4700 """Array sorts."""
4701
4702 def domain(self):
4703 """Return the domain of the array sort `self`.
4704
4705 >>> A = ArraySort(IntSort(), BoolSort())
4706 >>> A.domain()
4707 Int
4708 """
4710
4711 def domain_n(self, i):
4712 """Return the domain of the array sort `self`.
4713 """
4715
4716 def range(self):
4717 """Return the range of the array sort `self`.
4718
4719 >>> A = ArraySort(IntSort(), BoolSort())
4720 >>> A.range()
4721 Bool
4722 """
4724
4725
4727 """Array expressions. """
4728
4729 def sort(self):
4730 """Return the array sort of the array expression `self`.
4731
4732 >>> a = Array('a', IntSort(), BoolSort())
4733 >>> a.sort()
4734 Array(Int, Bool)
4735 """
4737
4738 def domain(self):
4739 """Shorthand for `self.sort().domain()`.
4740
4741 >>> a = Array('a', IntSort(), BoolSort())
4742 >>> a.domain()
4743 Int
4744 """
4745 return self.sortsort().domain()
4746
4747 def domain_n(self, i):
4748 """Shorthand for self.sort().domain_n(i)`."""
4749 return self.sortsort().domain_n(i)
4750
4751 def range(self):
4752 """Shorthand for `self.sort().range()`.
4753
4754 >>> a = Array('a', IntSort(), BoolSort())
4755 >>> a.range()
4756 Bool
4757 """
4758 return self.sortsort().range()
4759
4760 def __getitem__(self, arg):
4761 """Return the Z3 expression `self[arg]`.
4762
4763 >>> a = Array('a', IntSort(), BoolSort())
4764 >>> i = Int('i')
4765 >>> a[i]
4766 a[i]
4767 >>> a[i].sexpr()
4768 '(select a i)'
4769 """
4770 return _array_select(self, arg)
4771
4772 def default(self):
4773 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
4774
4775
4776def _array_select(ar, arg):
4777 if isinstance(arg, tuple):
4778 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4779 _args, sz = _to_ast_array(args)
4780 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4781 arg = ar.sort().domain().cast(arg)
4782 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4783
4784
4786 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4787
4788
4789def is_array(a : Any) -> bool:
4790 """Return `True` if `a` is a Z3 array expression.
4791
4792 >>> a = Array('a', IntSort(), IntSort())
4793 >>> is_array(a)
4794 True
4795 >>> is_array(Store(a, 0, 1))
4796 True
4797 >>> is_array(a[0])
4798 False
4799 """
4800 return isinstance(a, ArrayRef)
4801
4802
4804 """Return `True` if `a` is a Z3 constant array.
4805
4806 >>> a = K(IntSort(), 10)
4807 >>> is_const_array(a)
4808 True
4809 >>> a = Array('a', IntSort(), IntSort())
4810 >>> is_const_array(a)
4811 False
4812 """
4813 return is_app_of(a, Z3_OP_CONST_ARRAY)
4814
4815
4816def is_K(a):
4817 """Return `True` if `a` is a Z3 constant array.
4818
4819 >>> a = K(IntSort(), 10)
4820 >>> is_K(a)
4821 True
4822 >>> a = Array('a', IntSort(), IntSort())
4823 >>> is_K(a)
4824 False
4825 """
4826 return is_app_of(a, Z3_OP_CONST_ARRAY)
4827
4828
4829def is_map(a):
4830 """Return `True` if `a` is a Z3 map array expression.
4831
4832 >>> f = Function('f', IntSort(), IntSort())
4833 >>> b = Array('b', IntSort(), IntSort())
4834 >>> a = Map(f, b)
4835 >>> a
4836 Map(f, b)
4837 >>> is_map(a)
4838 True
4839 >>> is_map(b)
4840 False
4841 """
4842 return is_app_of(a, Z3_OP_ARRAY_MAP)
4843
4844
4846 """Return `True` if `a` is a Z3 default array expression.
4847 >>> d = Default(K(IntSort(), 10))
4848 >>> is_default(d)
4849 True
4850 """
4851 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4852
4853
4855 """Return the function declaration associated with a Z3 map array expression.
4856
4857 >>> f = Function('f', IntSort(), IntSort())
4858 >>> b = Array('b', IntSort(), IntSort())
4859 >>> a = Map(f, b)
4860 >>> eq(f, get_map_func(a))
4861 True
4862 >>> get_map_func(a)
4863 f
4864 >>> get_map_func(a)(0)
4865 f(0)
4866 """
4867 if z3_debug():
4868 _z3_assert(is_map(a), "Z3 array map expression expected.")
4869 return FuncDeclRef(
4871 a.ctx_ref(),
4872 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4873 ),
4874 ctx=a.ctx,
4875 )
4876
4877
4878def ArraySort(*sig):
4879 """Return the Z3 array sort with the given domain and range sorts.
4880
4881 >>> A = ArraySort(IntSort(), BoolSort())
4882 >>> A
4883 Array(Int, Bool)
4884 >>> A.domain()
4885 Int
4886 >>> A.range()
4887 Bool
4888 >>> AA = ArraySort(IntSort(), A)
4889 >>> AA
4890 Array(Int, Array(Int, Bool))
4891 """
4892 sig = _get_args(sig)
4893 if z3_debug():
4894 _z3_assert(len(sig) > 1, "At least two arguments expected")
4895 arity = len(sig) - 1
4896 r = sig[arity]
4897 d = sig[0]
4898 if z3_debug():
4899 for s in sig:
4900 _z3_assert(is_sort(s), "Z3 sort expected")
4901 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4902 ctx = d.ctx
4903 if len(sig) == 2:
4904 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4905 dom = (Sort * arity)()
4906 for i in range(arity):
4907 dom[i] = sig[i].ast
4908 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4909
4910
4911def Array(name, *sorts):
4912 """Return an array constant named `name` with the given domain and range sorts.
4913
4914 >>> a = Array('a', IntSort(), IntSort())
4915 >>> a.sort()
4916 Array(Int, Int)
4917 >>> a[0]
4918 a[0]
4919 """
4920 s = ArraySort(sorts)
4921 ctx = s.ctx
4922 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4923
4924
4925def Update(a, *args):
4926 """Return a Z3 store array expression.
4927
4928 >>> a = Array('a', IntSort(), IntSort())
4929 >>> i, v = Ints('i v')
4930 >>> s = Update(a, i, v)
4931 >>> s.sort()
4932 Array(Int, Int)
4933 >>> prove(s[i] == v)
4934 proved
4935 >>> j = Int('j')
4936 >>> prove(Implies(i != j, s[j] == a[j]))
4937 proved
4938 """
4939 if z3_debug():
4940 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4941 args = _get_args(args)
4942 ctx = a.ctx
4943 if len(args) <= 1:
4944 raise Z3Exception("array update requires index and value arguments")
4945 if len(args) == 2:
4946 i = args[0]
4947 v = args[1]
4948 i = a.sort().domain().cast(i)
4949 v = a.sort().range().cast(v)
4950 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4951 v = a.sort().range().cast(args[-1])
4952 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4953 _args, sz = _to_ast_array(idxs)
4954 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4955
4956
4957def Default(a):
4958 """ Return a default value for array expression.
4959 >>> b = K(IntSort(), 1)
4960 >>> prove(Default(b) == 1)
4961 proved
4962 """
4963 if z3_debug():
4964 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4965 return a.default()
4966
4967
4968def Store(a, *args):
4969 """Return a Z3 store array expression.
4970
4971 >>> a = Array('a', IntSort(), IntSort())
4972 >>> i, v = Ints('i v')
4973 >>> s = Store(a, i, v)
4974 >>> s.sort()
4975 Array(Int, Int)
4976 >>> prove(s[i] == v)
4977 proved
4978 >>> j = Int('j')
4979 >>> prove(Implies(i != j, s[j] == a[j]))
4980 proved
4981 """
4982 return Update(a, args)
4983
4984
4985def Select(a, *args):
4986 """Return a Z3 select array expression.
4987
4988 >>> a = Array('a', IntSort(), IntSort())
4989 >>> i = Int('i')
4990 >>> Select(a, i)
4991 a[i]
4992 >>> eq(Select(a, i), a[i])
4993 True
4994 """
4995 args = _get_args(args)
4996 if z3_debug():
4997 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4998 return a[args]
4999
5000
5001def Map(f, *args):
5002 """Return a Z3 map array expression.
5003
5004 >>> f = Function('f', IntSort(), IntSort(), IntSort())
5005 >>> a1 = Array('a1', IntSort(), IntSort())
5006 >>> a2 = Array('a2', IntSort(), IntSort())
5007 >>> b = Map(f, a1, a2)
5008 >>> b
5009 Map(f, a1, a2)
5010 >>> prove(b[0] == f(a1[0], a2[0]))
5011 proved
5012 """
5013 args = _get_args(args)
5014 if z3_debug():
5015 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
5016 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
5017 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
5018 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
5019 _args, sz = _to_ast_array(args)
5020 ctx = f.ctx
5021 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
5022
5023
5024def K(dom, v):
5025 """Return a Z3 constant array expression.
5026
5027 >>> a = K(IntSort(), 10)
5028 >>> a
5029 K(Int, 10)
5030 >>> a.sort()
5031 Array(Int, Int)
5032 >>> i = Int('i')
5033 >>> a[i]
5034 K(Int, 10)[i]
5035 >>> simplify(a[i])
5036 10
5037 """
5038 if z3_debug():
5039 _z3_assert(is_sort(dom), "Z3 sort expected")
5040 ctx = dom.ctx
5041 if not is_expr(v):
5042 v = _py2expr(v, ctx)
5043 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
5044
5045
5046def Ext(a, b):
5047 """Return extensionality index for one-dimensional arrays.
5048 >> a, b = Consts('a b', SetSort(IntSort()))
5049 >> Ext(a, b)
5050 Ext(a, b)
5051 """
5052 ctx = a.ctx
5053 if z3_debug():
5054 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
5055 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5056
5058 """Return `True` if `a` is a Z3 array select application.
5059
5060 >>> a = Array('a', IntSort(), IntSort())
5061 >>> is_select(a)
5062 False
5063 >>> i = Int('i')
5064 >>> is_select(a[i])
5065 True
5066 """
5067 return is_app_of(a, Z3_OP_SELECT)
5068
5069
5071 """Return `True` if `a` is a Z3 array store application.
5072
5073 >>> a = Array('a', IntSort(), IntSort())
5074 >>> is_store(a)
5075 False
5076 >>> is_store(Store(a, 0, 1))
5077 True
5078 """
5079 return is_app_of(a, Z3_OP_STORE)
5080
5081
5086
5087
5088def SetSort(s):
5089 """ Create a set sort over element sort s"""
5090 return ArraySort(s, BoolSort())
5091
5092
5094 """Create the empty set
5095 >>> EmptySet(IntSort())
5096 K(Int, False)
5097 """
5098 ctx = s.ctx
5099 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5100
5101
5102def FullSet(s):
5103 """Create the full set
5104 >>> FullSet(IntSort())
5105 K(Int, True)
5106 """
5107 ctx = s.ctx
5108 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5109
5110
5111def SetUnion(*args):
5112 """ Take the union of sets
5113 >>> a = Const('a', SetSort(IntSort()))
5114 >>> b = Const('b', SetSort(IntSort()))
5115 >>> SetUnion(a, b)
5116 union(a, b)
5117 """
5118 args = _get_args(args)
5119 ctx = _ctx_from_ast_arg_list(args)
5120 _args, sz = _to_ast_array(args)
5121 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5122
5123
5124def SetIntersect(*args):
5125 """ Take the union of sets
5126 >>> a = Const('a', SetSort(IntSort()))
5127 >>> b = Const('b', SetSort(IntSort()))
5128 >>> SetIntersect(a, b)
5129 intersection(a, b)
5130 """
5131 args = _get_args(args)
5132 ctx = _ctx_from_ast_arg_list(args)
5133 _args, sz = _to_ast_array(args)
5134 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5135
5136
5137def SetAdd(s, e):
5138 """ Add element e to set s
5139 >>> a = Const('a', SetSort(IntSort()))
5140 >>> SetAdd(a, 1)
5141 Store(a, 1, True)
5142 """
5143 ctx = _ctx_from_ast_arg_list([s, e])
5144 e = _py2expr(e, ctx)
5145 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5146
5147
5148def SetDel(s, e):
5149 """ Remove element e to set s
5150 >>> a = Const('a', SetSort(IntSort()))
5151 >>> SetDel(a, 1)
5152 Store(a, 1, False)
5153 """
5154 ctx = _ctx_from_ast_arg_list([s, e])
5155 e = _py2expr(e, ctx)
5156 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5157
5158
5160 """ The complement of set s
5161 >>> a = Const('a', SetSort(IntSort()))
5162 >>> SetComplement(a)
5163 complement(a)
5164 """
5165 ctx = s.ctx
5166 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5167
5168
5170 """ The set difference of a and b
5171 >>> a = Const('a', SetSort(IntSort()))
5172 >>> b = Const('b', SetSort(IntSort()))
5173 >>> SetDifference(a, b)
5174 setminus(a, b)
5175 """
5176 ctx = _ctx_from_ast_arg_list([a, b])
5177 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5178
5179
5180def IsMember(e, s):
5181 """ Check if e is a member of set s
5182 >>> a = Const('a', SetSort(IntSort()))
5183 >>> IsMember(1, a)
5184 a[1]
5185 """
5186 ctx = _ctx_from_ast_arg_list([s, e])
5187 e = _py2expr(e, ctx)
5188 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5189
5190
5191def IsSubset(a, b):
5192 """ Check if a is a subset of b
5193 >>> a = Const('a', SetSort(IntSort()))
5194 >>> b = Const('b', SetSort(IntSort()))
5195 >>> IsSubset(a, b)
5196 subset(a, b)
5197 """
5198 ctx = _ctx_from_ast_arg_list([a, b])
5199 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5200
5201
5202
5207
5209 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5210 if not isinstance(acc, tuple):
5211 return False
5212 if len(acc) != 2:
5213 return False
5214 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5215
5216
5218 """Helper class for declaring Z3 datatypes.
5219
5220 >>> List = Datatype('List')
5221 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5222 >>> List.declare('nil')
5223 >>> List = List.create()
5224 >>> # List is now a Z3 declaration
5225 >>> List.nil
5226 nil
5227 >>> List.cons(10, List.nil)
5228 cons(10, nil)
5229 >>> List.cons(10, List.nil).sort()
5230 List
5231 >>> cons = List.cons
5232 >>> nil = List.nil
5233 >>> car = List.car
5234 >>> cdr = List.cdr
5235 >>> n = cons(1, cons(0, nil))
5236 >>> n
5237 cons(1, cons(0, nil))
5238 >>> simplify(cdr(n))
5239 cons(0, nil)
5240 >>> simplify(car(n))
5241 1
5242 """
5243
5244 def __init__(self, name, ctx=None):
5245 self.ctx = _get_ctx(ctx)
5246 self.name = name
5248
5249 def __deepcopy__(self, memo={}):
5250 r = Datatype(self.name, self.ctx)
5251 r.constructors = copy.deepcopy(self.constructors)
5252 return r
5253
5254 def declare_core(self, name, rec_name, *args):
5255 if z3_debug():
5256 _z3_assert(isinstance(name, str), "String expected")
5257 _z3_assert(isinstance(rec_name, str), "String expected")
5258 _z3_assert(
5259 all([_valid_accessor(a) for a in args]),
5260 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5261 )
5262 self.constructors.append((name, rec_name, args))
5263
5264 def declare(self, name, *args):
5265 """Declare constructor named `name` with the given accessors `args`.
5266 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5267 or a reference to the datatypes being declared.
5268
5269 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5270 declares the constructor named `cons` that builds a new List using an integer and a List.
5271 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5272 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5273 we use the method create() to create the actual datatype in Z3.
5274
5275 >>> List = Datatype('List')
5276 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5277 >>> List.declare('nil')
5278 >>> List = List.create()
5279 """
5280 if z3_debug():
5281 _z3_assert(isinstance(name, str), "String expected")
5282 _z3_assert(name != "", "Constructor name cannot be empty")
5283 return self.declare_core(name, "is-" + name, *args)
5284
5285 def __repr__(self):
5286 return "Datatype(%s, %s)" % (self.name, self.constructors)
5287
5288 def create(self):
5289 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5290
5291 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5292
5293 >>> List = Datatype('List')
5294 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5295 >>> List.declare('nil')
5296 >>> List = List.create()
5297 >>> List.nil
5298 nil
5299 >>> List.cons(10, List.nil)
5300 cons(10, nil)
5301 """
5302 return CreateDatatypes([self])[0]
5303
5304
5306 """Auxiliary object used to create Z3 datatypes."""
5307
5308 def __init__(self, c, ctx):
5309 self.c = c
5310 self.ctx = ctx
5311
5312 def __del__(self):
5313 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5314 Z3_del_constructor(self.ctx.ref(), self.c)
5315
5316
5318 """Auxiliary object used to create Z3 datatypes."""
5319
5320 def __init__(self, c, ctx):
5321 self.c = c
5322 self.ctx = ctx
5323
5324 def __del__(self):
5325 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5326 Z3_del_constructor_list(self.ctx.ref(), self.c)
5327
5328
5330 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5331
5332 In the following example we define a Tree-List using two mutually recursive datatypes.
5333
5334 >>> TreeList = Datatype('TreeList')
5335 >>> Tree = Datatype('Tree')
5336 >>> # Tree has two constructors: leaf and node
5337 >>> Tree.declare('leaf', ('val', IntSort()))
5338 >>> # a node contains a list of trees
5339 >>> Tree.declare('node', ('children', TreeList))
5340 >>> TreeList.declare('nil')
5341 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5342 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5343 >>> Tree.val(Tree.leaf(10))
5344 val(leaf(10))
5345 >>> simplify(Tree.val(Tree.leaf(10)))
5346 10
5347 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5348 >>> n1
5349 node(cons(leaf(10), cons(leaf(20), nil)))
5350 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5351 >>> simplify(n2 == n1)
5352 False
5353 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5354 True
5355 """
5356 ds = _get_args(ds)
5357 if z3_debug():
5358 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5359 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5360 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5361 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5362 ctx = ds[0].ctx
5363 num = len(ds)
5364 names = (Symbol * num)()
5365 out = (Sort * num)()
5366 clists = (ConstructorList * num)()
5367 to_delete = []
5368 for i in range(num):
5369 d = ds[i]
5370 names[i] = to_symbol(d.name, ctx)
5371 num_cs = len(d.constructors)
5372 cs = (Constructor * num_cs)()
5373 for j in range(num_cs):
5374 c = d.constructors[j]
5375 cname = to_symbol(c[0], ctx)
5376 rname = to_symbol(c[1], ctx)
5377 fs = c[2]
5378 num_fs = len(fs)
5379 fnames = (Symbol * num_fs)()
5380 sorts = (Sort * num_fs)()
5381 refs = (ctypes.c_uint * num_fs)()
5382 for k in range(num_fs):
5383 fname = fs[k][0]
5384 ftype = fs[k][1]
5385 fnames[k] = to_symbol(fname, ctx)
5386 if isinstance(ftype, Datatype):
5387 if z3_debug():
5388 _z3_assert(
5389 ds.count(ftype) == 1,
5390 "One and only one occurrence of each datatype is expected",
5391 )
5392 sorts[k] = None
5393 refs[k] = ds.index(ftype)
5394 else:
5395 if z3_debug():
5396 _z3_assert(is_sort(ftype), "Z3 sort expected")
5397 sorts[k] = ftype.ast
5398 refs[k] = 0
5399 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5400 to_delete.append(ScopedConstructor(cs[j], ctx))
5401 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5402 to_delete.append(ScopedConstructorList(clists[i], ctx))
5403 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5404 result = []
5405 # Create a field for every constructor, recognizer and accessor
5406 for i in range(num):
5407 dref = DatatypeSortRef(out[i], ctx)
5408 num_cs = dref.num_constructors()
5409 for j in range(num_cs):
5410 cref = dref.constructor(j)
5411 cref_name = cref.name()
5412 cref_arity = cref.arity()
5413 if cref.arity() == 0:
5414 cref = cref()
5415 setattr(dref, cref_name, cref)
5416 rref = dref.recognizer(j)
5417 setattr(dref, "is_" + cref_name, rref)
5418 for k in range(cref_arity):
5419 aref = dref.accessor(j, k)
5420 setattr(dref, aref.name(), aref)
5421 result.append(dref)
5422 return tuple(result)
5423
5424
5426 """Datatype sorts."""
5427
5429 """Return the number of constructors in the given Z3 datatype.
5430
5431 >>> List = Datatype('List')
5432 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5433 >>> List.declare('nil')
5434 >>> List = List.create()
5435 >>> # List is now a Z3 declaration
5436 >>> List.num_constructors()
5437 2
5438 """
5440
5441 def constructor(self, idx):
5442 """Return a constructor of the datatype `self`.
5443
5444 >>> List = Datatype('List')
5445 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5446 >>> List.declare('nil')
5447 >>> List = List.create()
5448 >>> # List is now a Z3 declaration
5449 >>> List.num_constructors()
5450 2
5451 >>> List.constructor(0)
5452 cons
5453 >>> List.constructor(1)
5454 nil
5455 """
5456 if z3_debug():
5457 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5459
5460 def recognizer(self, idx):
5461 """In Z3, each constructor has an associated recognizer predicate.
5462
5463 If the constructor is named `name`, then the recognizer `is_name`.
5464
5465 >>> List = Datatype('List')
5466 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5467 >>> List.declare('nil')
5468 >>> List = List.create()
5469 >>> # List is now a Z3 declaration
5470 >>> List.num_constructors()
5471 2
5472 >>> List.recognizer(0)
5473 is(cons)
5474 >>> List.recognizer(1)
5475 is(nil)
5476 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5477 False
5478 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5479 True
5480 >>> l = Const('l', List)
5481 >>> simplify(List.is_cons(l))
5482 is(cons, l)
5483 """
5484 if z3_debug():
5485 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5487
5488 def accessor(self, i, j):
5489 """In Z3, each constructor has 0 or more accessor.
5490 The number of accessors is equal to the arity of the constructor.
5491
5492 >>> List = Datatype('List')
5493 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5494 >>> List.declare('nil')
5495 >>> List = List.create()
5496 >>> List.num_constructors()
5497 2
5498 >>> List.constructor(0)
5499 cons
5500 >>> num_accs = List.constructor(0).arity()
5501 >>> num_accs
5502 2
5503 >>> List.accessor(0, 0)
5504 car
5505 >>> List.accessor(0, 1)
5506 cdr
5507 >>> List.constructor(1)
5508 nil
5509 >>> num_accs = List.constructor(1).arity()
5510 >>> num_accs
5511 0
5512 """
5513 if z3_debug():
5514 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5515 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5516 return FuncDeclRef(
5518 ctx=self.ctxctxctx,
5519 )
5520
5521
5523 """Datatype expressions."""
5524
5525 def sort(self):
5526 """Return the datatype sort of the datatype expression `self`."""
5528
5529def DatatypeSort(name, params=None, ctx=None):
5530 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype.
5531
5532 Args:
5533 name: name of the datatype sort
5534 params: optional list/tuple of sort parameters for parametric datatypes
5535 ctx: Z3 context (optional)
5536
5537 Example:
5538 >>> # Non-parametric datatype
5539 >>> TreeRef = DatatypeSort('Tree')
5540 >>> # Parametric datatype with one parameter
5541 >>> ListIntRef = DatatypeSort('List', [IntSort()])
5542 >>> # Parametric datatype with multiple parameters
5543 >>> PairRef = DatatypeSort('Pair', [IntSort(), BoolSort()])
5544 """
5545 ctx = _get_ctx(ctx)
5546 if params is None or len(params) == 0:
5547 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), 0, (Sort * 0)()), ctx)
5548 else:
5549 _params = (Sort * len(params))()
5550 for i in range(len(params)):
5551 _params[i] = params[i].ast
5552 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), len(params), _params), ctx)
5553
5554def TupleSort(name, sorts, ctx=None):
5555 """Create a named tuple sort base on a set of underlying sorts
5556 Example:
5557 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5558 """
5559 tuple = Datatype(name, ctx)
5560 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5561 tuple.declare(name, *projects)
5562 tuple = tuple.create()
5563 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5564
5565
5566def DisjointSum(name, sorts, ctx=None):
5567 """Create a named tagged union sort base on a set of underlying sorts
5568 Example:
5569 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5570 """
5571 sum = Datatype(name, ctx)
5572 for i in range(len(sorts)):
5573 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5574 sum = sum.create()
5575 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5576
5577
5578def EnumSort(name, values, ctx=None):
5579 """Return a new enumeration sort named `name` containing the given values.
5580
5581 The result is a pair (sort, list of constants).
5582 Example:
5583 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5584 """
5585 if z3_debug():
5586 _z3_assert(isinstance(name, str), "Name must be a string")
5587 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5588 _z3_assert(len(values) > 0, "At least one value expected")
5589 ctx = _get_ctx(ctx)
5590 num = len(values)
5591 _val_names = (Symbol * num)()
5592 for i in range(num):
5593 _val_names[i] = to_symbol(values[i], ctx)
5594 _values = (FuncDecl * num)()
5595 _testers = (FuncDecl * num)()
5596 name = to_symbol(name, ctx)
5597 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5598 V = []
5599 for i in range(num):
5600 V.append(FuncDeclRef(_values[i], ctx))
5601 V = [a() for a in V]
5602 return S, V
5603
5604
5609
5610
5612 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5613
5614 Consider using the function `args2params` to create instances of this object.
5615 """
5616
5617 def __init__(self, ctx=None, params=None):
5618 self.ctx = _get_ctx(ctx)
5619 if params is None:
5620 self.params = Z3_mk_params(self.ctx.ref())
5621 else:
5622 self.params = params
5623 Z3_params_inc_ref(self.ctx.ref(), self.params)
5624
5625 def __deepcopy__(self, memo={}):
5626 return ParamsRef(self.ctx, self.params)
5627
5628 def __del__(self):
5629 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5630 Z3_params_dec_ref(self.ctx.ref(), self.params)
5631
5632 def set(self, name, val):
5633 """Set parameter name with value val."""
5634 if z3_debug():
5635 _z3_assert(isinstance(name, str), "parameter name must be a string")
5636 name_sym = to_symbol(name, self.ctx)
5637 if isinstance(val, bool):
5638 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5639 elif _is_int(val):
5640 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5641 elif isinstance(val, float):
5642 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5643 elif isinstance(val, str):
5644 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5645 else:
5646 if z3_debug():
5647 _z3_assert(False, "invalid parameter value")
5648
5649 def __repr__(self):
5650 return Z3_params_to_string(self.ctx.ref(), self.params)
5651
5652 def validate(self, ds):
5653 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5654 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5655
5656
5657def args2params(arguments, keywords, ctx=None):
5658 """Convert python arguments into a Z3_params object.
5659 A ':' is added to the keywords, and '_' is replaced with '-'
5660
5661 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5662 (params model true relevancy 2 elim_and true)
5663 """
5664 if z3_debug():
5665 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5666 prev = None
5667 r = ParamsRef(ctx)
5668 for a in arguments:
5669 if prev is None:
5670 prev = a
5671 else:
5672 r.set(prev, a)
5673 prev = None
5674 for k in keywords:
5675 v = keywords[k]
5676 r.set(k, v)
5677 return r
5678
5679
5681 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5682 """
5683
5684 def __init__(self, descr, ctx=None):
5685 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5686 self.ctx = _get_ctx(ctx)
5687 self.descr = descr
5688 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5689
5690 def __deepcopy__(self, memo={}):
5691 return ParamsDescrsRef(self.descr, self.ctx)
5692
5693 def __del__(self):
5694 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5695 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5696
5697 def size(self):
5698 """Return the size of in the parameter description `self`.
5699 """
5700 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5701
5702 def __len__(self):
5703 """Return the size of in the parameter description `self`.
5704 """
5705 return self.size()
5706
5707 def get_name(self, i):
5708 """Return the i-th parameter name in the parameter description `self`.
5709 """
5710 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5711
5712 def get_kind(self, n):
5713 """Return the kind of the parameter named `n`.
5714 """
5715 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5716
5717 def get_documentation(self, n):
5718 """Return the documentation string of the parameter named `n`.
5719 """
5720 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5721
5722 def __getitem__(self, arg):
5723 if _is_int(arg):
5724 return self.get_name(arg)
5725 else:
5726 return self.get_kind(arg)
5727
5728 def __repr__(self):
5729 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5730
5731
5736
5737
5739 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5740
5741 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5742 A goal has a solution if one of its subgoals has a solution.
5743 A goal is unsatisfiable if all subgoals are unsatisfiable.
5744 """
5745
5746 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5747 if z3_debug():
5748 _z3_assert(goal is None or ctx is not None,
5749 "If goal is different from None, then ctx must be also different from None")
5750 self.ctx = _get_ctx(ctx)
5751 self.goal = goal
5752 if self.goal is None:
5753 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5754 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5755
5756 def __del__(self):
5757 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5758 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5759
5760 def depth(self):
5761 """Return the depth of the goal `self`.
5762 The depth corresponds to the number of tactics applied to `self`.
5763
5764 >>> x, y = Ints('x y')
5765 >>> g = Goal()
5766 >>> g.add(x == 0, y >= x + 1)
5767 >>> g.depth()
5768 0
5769 >>> r = Then('simplify', 'solve-eqs')(g)
5770 >>> # r has 1 subgoal
5771 >>> len(r)
5772 1
5773 >>> r[0].depth()
5774 2
5775 """
5776 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5777
5778 def inconsistent(self):
5779 """Return `True` if `self` contains the `False` constraints.
5780
5781 >>> x, y = Ints('x y')
5782 >>> g = Goal()
5783 >>> g.inconsistent()
5784 False
5785 >>> g.add(x == 0, x == 1)
5786 >>> g
5787 [x == 0, x == 1]
5788 >>> g.inconsistent()
5789 False
5790 >>> g2 = Tactic('propagate-values')(g)[0]
5791 >>> g2.inconsistent()
5792 True
5793 """
5794 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5795
5796 def prec(self):
5797 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5798
5799 >>> g = Goal()
5800 >>> g.prec() == Z3_GOAL_PRECISE
5801 True
5802 >>> x, y = Ints('x y')
5803 >>> g.add(x == y + 1)
5804 >>> g.prec() == Z3_GOAL_PRECISE
5805 True
5806 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5807 >>> g2 = t(g)[0]
5808 >>> g2
5809 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5810 >>> g2.prec() == Z3_GOAL_PRECISE
5811 False
5812 >>> g2.prec() == Z3_GOAL_UNDER
5813 True
5814 """
5815 return Z3_goal_precision(self.ctx.ref(), self.goal)
5816
5817 def precision(self):
5818 """Alias for `prec()`.
5819
5820 >>> g = Goal()
5821 >>> g.precision() == Z3_GOAL_PRECISE
5822 True
5823 """
5824 return self.prec()
5825
5826 def size(self):
5827 """Return the number of constraints in the goal `self`.
5828
5829 >>> g = Goal()
5830 >>> g.size()
5831 0
5832 >>> x, y = Ints('x y')
5833 >>> g.add(x == 0, y > x)
5834 >>> g.size()
5835 2
5836 """
5837 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5838
5839 def __len__(self):
5840 """Return the number of constraints in the goal `self`.
5841
5842 >>> g = Goal()
5843 >>> len(g)
5844 0
5845 >>> x, y = Ints('x y')
5846 >>> g.add(x == 0, y > x)
5847 >>> len(g)
5848 2
5849 """
5850 return self.size()
5851
5852 def get(self, i):
5853 """Return a constraint in the goal `self`.
5854
5855 >>> g = Goal()
5856 >>> x, y = Ints('x y')
5857 >>> g.add(x == 0, y > x)
5858 >>> g.get(0)
5859 x == 0
5860 >>> g.get(1)
5861 y > x
5862 """
5863 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5864
5865 def __getitem__(self, arg):
5866 """Return a constraint in the goal `self`.
5867
5868 >>> g = Goal()
5869 >>> x, y = Ints('x y')
5870 >>> g.add(x == 0, y > x)
5871 >>> g[0]
5872 x == 0
5873 >>> g[1]
5874 y > x
5875 """
5876 if arg >= len(self):
5877 raise IndexError
5878 return self.get(arg)
5879
5880 def assert_exprs(self, *args):
5881 """Assert constraints into the goal.
5882
5883 >>> x = Int('x')
5884 >>> g = Goal()
5885 >>> g.assert_exprs(x > 0, x < 2)
5886 >>> g
5887 [x > 0, x < 2]
5888 """
5889 args = _get_args(args)
5890 s = BoolSort(self.ctx)
5891 for arg in args:
5892 arg = s.cast(arg)
5893 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5894
5895 def append(self, *args):
5896 """Add constraints.
5897
5898 >>> x = Int('x')
5899 >>> g = Goal()
5900 >>> g.append(x > 0, x < 2)
5901 >>> g
5902 [x > 0, x < 2]
5903 """
5904 self.assert_exprs(*args)
5905
5906 def insert(self, *args):
5907 """Add constraints.
5908
5909 >>> x = Int('x')
5910 >>> g = Goal()
5911 >>> g.insert(x > 0, x < 2)
5912 >>> g
5913 [x > 0, x < 2]
5914 """
5915 self.assert_exprs(*args)
5916
5917 def add(self, *args):
5918 """Add constraints.
5919
5920 >>> x = Int('x')
5921 >>> g = Goal()
5922 >>> g.add(x > 0, x < 2)
5923 >>> g
5924 [x > 0, x < 2]
5925 """
5926 self.assert_exprs(*args)
5927
5928 def convert_model(self, model):
5929 """Retrieve model from a satisfiable goal
5930 >>> a, b = Ints('a b')
5931 >>> g = Goal()
5932 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5933 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5934 >>> r = t(g)
5935 >>> r[0]
5936 [Or(b == 0, b == 1), Not(0 <= b)]
5937 >>> r[1]
5938 [Or(b == 0, b == 1), Not(1 <= b)]
5939 >>> # Remark: the subgoal r[0] is unsatisfiable
5940 >>> # Creating a solver for solving the second subgoal
5941 >>> s = Solver()
5942 >>> s.add(r[1])
5943 >>> s.check()
5944 sat
5945 >>> s.model()
5946 [b = 0]
5947 >>> # Model s.model() does not assign a value to `a`
5948 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5949 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5950 >>> r[1].convert_model(s.model())
5951 [b = 0, a = 1]
5952 """
5953 if z3_debug():
5954 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5955 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5956
5957 def __repr__(self):
5958 return obj_to_string(self)
5959
5960 def sexpr(self):
5961 """Return a textual representation of the s-expression representing the goal."""
5962 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5963
5964 def dimacs(self, include_names=True):
5965 """Return a textual representation of the goal in DIMACS format."""
5966 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5967
5968 def translate(self, target):
5969 """Copy goal `self` to context `target`.
5970
5971 >>> x = Int('x')
5972 >>> g = Goal()
5973 >>> g.add(x > 10)
5974 >>> g
5975 [x > 10]
5976 >>> c2 = Context()
5977 >>> g2 = g.translate(c2)
5978 >>> g2
5979 [x > 10]
5980 >>> g.ctx == main_ctx()
5981 True
5982 >>> g2.ctx == c2
5983 True
5984 >>> g2.ctx == main_ctx()
5985 False
5986 """
5987 if z3_debug():
5988 _z3_assert(isinstance(target, Context), "target must be a context")
5989 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5990
5991 def __copy__(self):
5992 return self.translate(self.ctx)
5993
5994 def __deepcopy__(self, memo={}):
5995 return self.translate(self.ctx)
5996
5997 def simplify(self, *arguments, **keywords):
5998 """Return a new simplified goal.
5999
6000 This method is essentially invoking the simplify tactic.
6001
6002 >>> g = Goal()
6003 >>> x = Int('x')
6004 >>> g.add(x + 1 >= 2)
6005 >>> g
6006 [x + 1 >= 2]
6007 >>> g2 = g.simplify()
6008 >>> g2
6009 [x >= 1]
6010 >>> # g was not modified
6011 >>> g
6012 [x + 1 >= 2]
6013 """
6014 t = Tactic("simplify")
6015 return t.apply(self, *arguments, **keywords)[0]
6016
6017 def as_expr(self):
6018 """Return goal `self` as a single Z3 expression.
6019
6020 >>> x = Int('x')
6021 >>> g = Goal()
6022 >>> g.as_expr()
6023 True
6024 >>> g.add(x > 1)
6025 >>> g.as_expr()
6026 x > 1
6027 >>> g.add(x < 10)
6028 >>> g.as_expr()
6029 And(x > 1, x < 10)
6030 """
6031 sz = len(self)
6032 if sz == 0:
6033 return BoolVal(True, self.ctx)
6034 elif sz == 1:
6035 return self.get(0)
6036 else:
6037 return And([self.get(i) for i in range(len(self))], self.ctx)
6038
6039
6044
6045
6047 """A collection (vector) of ASTs."""
6048
6049 def __init__(self, v=None, ctx=None):
6050 self.vector = None
6051 if v is None:
6052 self.ctx = _get_ctx(ctx)
6053 self.vector = Z3_mk_ast_vector(self.ctx.ref())
6054 else:
6055 self.vector = v
6056 assert ctx is not None
6057 self.ctx = ctx
6058 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
6059
6060 def __del__(self):
6061 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
6062 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
6063
6064 def __len__(self):
6065 """Return the size of the vector `self`.
6066
6067 >>> A = AstVector()
6068 >>> len(A)
6069 0
6070 >>> A.push(Int('x'))
6071 >>> A.push(Int('x'))
6072 >>> len(A)
6073 2
6074 """
6075 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
6076
6077 def __getitem__(self, i):
6078 """Return the AST at position `i`.
6079
6080 >>> A = AstVector()
6081 >>> A.push(Int('x') + 1)
6082 >>> A.push(Int('y'))
6083 >>> A[0]
6084 x + 1
6085 >>> A[1]
6086 y
6087 """
6088
6089 if isinstance(i, int):
6090 if i < 0:
6091 i += self.__len__()
6092
6093 if i >= self.__len__():
6094 raise IndexError
6095 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
6096
6097 elif isinstance(i, slice):
6098 result = []
6099 for ii in range(*i.indices(self.__len__())):
6100 result.append(_to_ast_ref(
6101 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6102 self.ctx,
6103 ))
6104 return result
6105
6106 def __setitem__(self, i, v):
6107 """Update AST at position `i`.
6108
6109 >>> A = AstVector()
6110 >>> A.push(Int('x') + 1)
6111 >>> A.push(Int('y'))
6112 >>> A[0]
6113 x + 1
6114 >>> A[0] = Int('x')
6115 >>> A[0]
6116 x
6117 """
6118 if i >= self.__len__():
6119 raise IndexError
6120 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6121
6122 def push(self, v):
6123 """Add `v` in the end of the vector.
6124
6125 >>> A = AstVector()
6126 >>> len(A)
6127 0
6128 >>> A.push(Int('x'))
6129 >>> len(A)
6130 1
6131 """
6132 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6133
6134 def resize(self, sz):
6135 """Resize the vector to `sz` elements.
6136
6137 >>> A = AstVector()
6138 >>> A.resize(10)
6139 >>> len(A)
6140 10
6141 >>> for i in range(10): A[i] = Int('x')
6142 >>> A[5]
6143 x
6144 """
6145 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6146
6147 def __contains__(self, item):
6148 """Return `True` if the vector contains `item`.
6149
6150 >>> x = Int('x')
6151 >>> A = AstVector()
6152 >>> x in A
6153 False
6154 >>> A.push(x)
6155 >>> x in A
6156 True
6157 >>> (x+1) in A
6158 False
6159 >>> A.push(x+1)
6160 >>> (x+1) in A
6161 True
6162 >>> A
6163 [x, x + 1]
6164 """
6165 for elem in self:
6166 if elem.eq(item):
6167 return True
6168 return False
6169
6170 def translate(self, other_ctx):
6171 """Copy vector `self` to context `other_ctx`.
6172
6173 >>> x = Int('x')
6174 >>> A = AstVector()
6175 >>> A.push(x)
6176 >>> c2 = Context()
6177 >>> B = A.translate(c2)
6178 >>> B
6179 [x]
6180 """
6181 return AstVector(
6182 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6183 ctx=other_ctx,
6184 )
6185
6186 def __copy__(self):
6187 return self.translate(self.ctx)
6188
6189 def __deepcopy__(self, memo={}):
6190 return self.translate(self.ctx)
6191
6192 def __repr__(self):
6193 return obj_to_string(self)
6194
6195 def sexpr(self):
6196 """Return a textual representation of the s-expression representing the vector."""
6197 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6198
6199
6204
6205
6207 """A mapping from ASTs to ASTs."""
6208
6209 def __init__(self, m=None, ctx=None):
6210 self.map = None
6211 if m is None:
6212 self.ctx = _get_ctx(ctx)
6213 self.map = Z3_mk_ast_map(self.ctx.ref())
6214 else:
6215 self.map = m
6216 assert ctx is not None
6217 self.ctx = ctx
6218 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6219
6220 def __deepcopy__(self, memo={}):
6221 return AstMap(self.map, self.ctx)
6222
6223 def __del__(self):
6224 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6225 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6226
6227 def __len__(self):
6228 """Return the size of the map.
6229
6230 >>> M = AstMap()
6231 >>> len(M)
6232 0
6233 >>> x = Int('x')
6234 >>> M[x] = IntVal(1)
6235 >>> len(M)
6236 1
6237 """
6238 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6239
6240 def __contains__(self, key):
6241 """Return `True` if the map contains key `key`.
6242
6243 >>> M = AstMap()
6244 >>> x = Int('x')
6245 >>> M[x] = x + 1
6246 >>> x in M
6247 True
6248 >>> x+1 in M
6249 False
6250 """
6251 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6252
6253 def __getitem__(self, key):
6254 """Retrieve the value associated with key `key`.
6255
6256 >>> M = AstMap()
6257 >>> x = Int('x')
6258 >>> M[x] = x + 1
6259 >>> M[x]
6260 x + 1
6261 """
6262 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6263
6264 def __setitem__(self, k, v):
6265 """Add/Update key `k` with value `v`.
6266
6267 >>> M = AstMap()
6268 >>> x = Int('x')
6269 >>> M[x] = x + 1
6270 >>> len(M)
6271 1
6272 >>> M[x]
6273 x + 1
6274 >>> M[x] = IntVal(1)
6275 >>> M[x]
6276 1
6277 """
6278 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6279
6280 def __repr__(self):
6281 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6282
6283 def erase(self, k):
6284 """Remove the entry associated with key `k`.
6285
6286 >>> M = AstMap()
6287 >>> x = Int('x')
6288 >>> M[x] = x + 1
6289 >>> len(M)
6290 1
6291 >>> M.erase(x)
6292 >>> len(M)
6293 0
6294 """
6295 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6296
6297 def reset(self):
6298 """Remove all entries from the map.
6299
6300 >>> M = AstMap()
6301 >>> x = Int('x')
6302 >>> M[x] = x + 1
6303 >>> M[x+x] = IntVal(1)
6304 >>> len(M)
6305 2
6306 >>> M.reset()
6307 >>> len(M)
6308 0
6309 """
6310 Z3_ast_map_reset(self.ctx.ref(), self.map)
6311
6312 def keys(self):
6313 """Return an AstVector containing all keys in the map.
6314
6315 >>> M = AstMap()
6316 >>> x = Int('x')
6317 >>> M[x] = x + 1
6318 >>> M[x+x] = IntVal(1)
6319 >>> M.keys()
6320 [x, x + x]
6321 """
6322 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6323
6324
6329
6330
6332 """Store the value of the interpretation of a function in a particular point."""
6333
6334 def __init__(self, entry, ctx):
6335 self.entry = entry
6336 self.ctx = ctx
6337 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6338
6339 def __deepcopy__(self, memo={}):
6340 return FuncEntry(self.entry, self.ctx)
6341
6342 def __del__(self):
6343 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6344 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6345
6346 def num_args(self):
6347 """Return the number of arguments in the given entry.
6348
6349 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6350 >>> s = Solver()
6351 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6352 >>> s.check()
6353 sat
6354 >>> m = s.model()
6355 >>> f_i = m[f]
6356 >>> f_i.num_entries()
6357 1
6358 >>> e = f_i.entry(0)
6359 >>> e.num_args()
6360 2
6361 """
6362 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6363
6364 def arg_value(self, idx):
6365 """Return the value of argument `idx`.
6366
6367 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6368 >>> s = Solver()
6369 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6370 >>> s.check()
6371 sat
6372 >>> m = s.model()
6373 >>> f_i = m[f]
6374 >>> f_i.num_entries()
6375 1
6376 >>> e = f_i.entry(0)
6377 >>> e
6378 [1, 2, 20]
6379 >>> e.num_args()
6380 2
6381 >>> e.arg_value(0)
6382 1
6383 >>> e.arg_value(1)
6384 2
6385 >>> try:
6386 ... e.arg_value(2)
6387 ... except IndexError:
6388 ... print("index error")
6389 index error
6390 """
6391 if idx >= self.num_args():
6392 raise IndexError
6393 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6394
6395 def value(self):
6396 """Return the value of the function at point `self`.
6397
6398 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6399 >>> s = Solver()
6400 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6401 >>> s.check()
6402 sat
6403 >>> m = s.model()
6404 >>> f_i = m[f]
6405 >>> f_i.num_entries()
6406 1
6407 >>> e = f_i.entry(0)
6408 >>> e
6409 [1, 2, 20]
6410 >>> e.num_args()
6411 2
6412 >>> e.value()
6413 20
6414 """
6415 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6416
6417 def as_list(self):
6418 """Return entry `self` as a Python list.
6419 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6420 >>> s = Solver()
6421 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6422 >>> s.check()
6423 sat
6424 >>> m = s.model()
6425 >>> f_i = m[f]
6426 >>> f_i.num_entries()
6427 1
6428 >>> e = f_i.entry(0)
6429 >>> e.as_list()
6430 [1, 2, 20]
6431 """
6432 args = [self.arg_value(i) for i in range(self.num_args())]
6433 args.append(self.value())
6434 return args
6435
6436 def __repr__(self):
6437 return repr(self.as_list())
6438
6439
6441 """Stores the interpretation of a function in a Z3 model."""
6442
6443 def __init__(self, f, ctx):
6444 self.f = f
6445 self.ctx = ctx
6446 if self.f is not None:
6447 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6448
6449 def __del__(self):
6450 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6451 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6452
6453 def else_value(self):
6454 """
6455 Return the `else` value for a function interpretation.
6456 Return None if Z3 did not specify the `else` value for
6457 this object.
6458
6459 >>> f = Function('f', IntSort(), IntSort())
6460 >>> s = Solver()
6461 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6462 >>> s.check()
6463 sat
6464 >>> m = s.model()
6465 >>> m[f]
6466 [2 -> 0, else -> 1]
6467 >>> m[f].else_value()
6468 1
6469 """
6470 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6471 if r:
6472 return _to_expr_ref(r, self.ctx)
6473 else:
6474 return None
6475
6476 def num_entries(self):
6477 """Return the number of entries/points in the function interpretation `self`.
6478
6479 >>> f = Function('f', IntSort(), IntSort())
6480 >>> s = Solver()
6481 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6482 >>> s.check()
6483 sat
6484 >>> m = s.model()
6485 >>> m[f]
6486 [2 -> 0, else -> 1]
6487 >>> m[f].num_entries()
6488 1
6489 """
6490 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6491
6492 def arity(self):
6493 """Return the number of arguments for each entry in the function interpretation `self`.
6494
6495 >>> f = Function('f', IntSort(), IntSort())
6496 >>> s = Solver()
6497 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6498 >>> s.check()
6499 sat
6500 >>> m = s.model()
6501 >>> m[f].arity()
6502 1
6503 """
6504 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6505
6506 def entry(self, idx):
6507 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6508
6509 >>> f = Function('f', IntSort(), IntSort())
6510 >>> s = Solver()
6511 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6512 >>> s.check()
6513 sat
6514 >>> m = s.model()
6515 >>> m[f]
6516 [2 -> 0, else -> 1]
6517 >>> m[f].num_entries()
6518 1
6519 >>> m[f].entry(0)
6520 [2, 0]
6521 """
6522 if idx >= self.num_entries():
6523 raise IndexError
6524 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6525
6526 def translate(self, other_ctx):
6527 """Copy model 'self' to context 'other_ctx'.
6528 """
6529 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6530
6531 def __copy__(self):
6532 return self.translate(self.ctx)
6533
6534 def __deepcopy__(self, memo={}):
6535 return self.translate(self.ctx)
6536
6537 def as_list(self):
6538 """Return the function interpretation as a Python list.
6539 >>> f = Function('f', IntSort(), IntSort())
6540 >>> s = Solver()
6541 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6542 >>> s.check()
6543 sat
6544 >>> m = s.model()
6545 >>> m[f]
6546 [2 -> 0, else -> 1]
6547 >>> m[f].as_list()
6548 [[2, 0], 1]
6549 """
6550 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6551 r.append(self.else_value())
6552 return r
6553
6554 def __repr__(self):
6555 return obj_to_string(self)
6556
6557
6559 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6560
6561 def __init__(self, m, ctx):
6562 assert ctx is not None
6563 self.model = m
6564 self.ctx = ctx
6565 Z3_model_inc_ref(self.ctx.ref(), self.model)
6566
6567 def __del__(self):
6568 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6569 Z3_model_dec_ref(self.ctx.ref(), self.model)
6570
6571 def __repr__(self):
6572 return obj_to_string(self)
6573
6574 def sexpr(self):
6575 """Return a textual representation of the s-expression representing the model."""
6576 return Z3_model_to_string(self.ctx.ref(), self.model)
6577
6578 def eval(self, t, model_completion=False):
6579 """Evaluate the expression `t` in the model `self`.
6580 If `model_completion` is enabled, then a default interpretation is automatically added
6581 for symbols that do not have an interpretation in the model `self`.
6582
6583 >>> x = Int('x')
6584 >>> s = Solver()
6585 >>> s.add(x > 0, x < 2)
6586 >>> s.check()
6587 sat
6588 >>> m = s.model()
6589 >>> m.eval(x + 1)
6590 2
6591 >>> m.eval(x == 1)
6592 True
6593 >>> y = Int('y')
6594 >>> m.eval(y + x)
6595 1 + y
6596 >>> m.eval(y)
6597 y
6598 >>> m.eval(y, model_completion=True)
6599 0
6600 >>> # Now, m contains an interpretation for y
6601 >>> m.eval(y + x)
6602 1
6603 """
6604 r = (Ast * 1)()
6605 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6606 return _to_expr_ref(r[0], self.ctx)
6607 raise Z3Exception("failed to evaluate expression in the model")
6608
6609 def evaluate(self, t, model_completion=False):
6610 """Alias for `eval`.
6611
6612 >>> x = Int('x')
6613 >>> s = Solver()
6614 >>> s.add(x > 0, x < 2)
6615 >>> s.check()
6616 sat
6617 >>> m = s.model()
6618 >>> m.evaluate(x + 1)
6619 2
6620 >>> m.evaluate(x == 1)
6621 True
6622 >>> y = Int('y')
6623 >>> m.evaluate(y + x)
6624 1 + y
6625 >>> m.evaluate(y)
6626 y
6627 >>> m.evaluate(y, model_completion=True)
6628 0
6629 >>> # Now, m contains an interpretation for y
6630 >>> m.evaluate(y + x)
6631 1
6632 """
6633 return self.eval(t, model_completion)
6634
6635 def __len__(self):
6636 """Return the number of constant and function declarations in the model `self`.
6637
6638 >>> f = Function('f', IntSort(), IntSort())
6639 >>> x = Int('x')
6640 >>> s = Solver()
6641 >>> s.add(x > 0, f(x) != x)
6642 >>> s.check()
6643 sat
6644 >>> m = s.model()
6645 >>> len(m)
6646 2
6647 """
6648 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6649 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6650 return num_consts + num_funcs
6651
6652 def get_interp(self, decl):
6653 """Return the interpretation for a given declaration or constant.
6654
6655 >>> f = Function('f', IntSort(), IntSort())
6656 >>> x = Int('x')
6657 >>> s = Solver()
6658 >>> s.add(x > 0, x < 2, f(x) == 0)
6659 >>> s.check()
6660 sat
6661 >>> m = s.model()
6662 >>> m[x]
6663 1
6664 >>> m[f]
6665 [else -> 0]
6666 """
6667 if z3_debug():
6668 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6669 if is_const(decl):
6670 decl = decl.decl()
6671 try:
6672 if decl.arity() == 0:
6673 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6674 if _r.value is None:
6675 return None
6676 r = _to_expr_ref(_r, self.ctx)
6677 if is_as_array(r):
6678 fi = self.get_interp(get_as_array_func(r))
6679 if fi is None:
6680 return fi
6681 e = fi.else_value()
6682 if e is None:
6683 return fi
6684 if fi.arity() != 1:
6685 return fi
6686 srt = decl.range()
6687 dom = srt.domain()
6688 e = K(dom, e)
6689 i = 0
6690 sz = fi.num_entries()
6691 n = fi.arity()
6692 while i < sz:
6693 fe = fi.entry(i)
6694 e = Store(e, fe.arg_value(0), fe.value())
6695 i += 1
6696 return e
6697 else:
6698 return r
6699 else:
6700 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6701 except Z3Exception:
6702 return None
6703
6704 def num_sorts(self):
6705 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6706
6707 >>> A = DeclareSort('A')
6708 >>> a, b = Consts('a b', A)
6709 >>> s = Solver()
6710 >>> s.add(a != b)
6711 >>> s.check()
6712 sat
6713 >>> m = s.model()
6714 >>> m.num_sorts()
6715 1
6716 """
6717 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6718
6719 def get_sort(self, idx):
6720 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6721
6722 >>> A = DeclareSort('A')
6723 >>> B = DeclareSort('B')
6724 >>> a1, a2 = Consts('a1 a2', A)
6725 >>> b1, b2 = Consts('b1 b2', B)
6726 >>> s = Solver()
6727 >>> s.add(a1 != a2, b1 != b2)
6728 >>> s.check()
6729 sat
6730 >>> m = s.model()
6731 >>> m.num_sorts()
6732 2
6733 >>> m.get_sort(0)
6734 A
6735 >>> m.get_sort(1)
6736 B
6737 """
6738 if idx >= self.num_sorts():
6739 raise IndexError
6740 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6741
6742 def sorts(self):
6743 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6744
6745 >>> A = DeclareSort('A')
6746 >>> B = DeclareSort('B')
6747 >>> a1, a2 = Consts('a1 a2', A)
6748 >>> b1, b2 = Consts('b1 b2', B)
6749 >>> s = Solver()
6750 >>> s.add(a1 != a2, b1 != b2)
6751 >>> s.check()
6752 sat
6753 >>> m = s.model()
6754 >>> m.sorts()
6755 [A, B]
6756 """
6757 return [self.get_sort(i) for i in range(self.num_sorts())]
6758
6759 def get_universe(self, s):
6760 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6761
6762 >>> A = DeclareSort('A')
6763 >>> a, b = Consts('a b', A)
6764 >>> s = Solver()
6765 >>> s.add(a != b)
6766 >>> s.check()
6767 sat
6768 >>> m = s.model()
6769 >>> m.get_universe(A)
6770 [A!val!1, A!val!0]
6771 """
6772 if z3_debug():
6773 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6774 try:
6775 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6776 except Z3Exception:
6777 return None
6778
6779 def __getitem__(self, idx):
6780 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6781 If `idx` is a declaration, then the actual interpretation is returned.
6782
6783 The elements can be retrieved using position or the actual declaration.
6784
6785 >>> f = Function('f', IntSort(), IntSort())
6786 >>> x = Int('x')
6787 >>> s = Solver()
6788 >>> s.add(x > 0, x < 2, f(x) == 0)
6789 >>> s.check()
6790 sat
6791 >>> m = s.model()
6792 >>> len(m)
6793 2
6794 >>> m[0]
6795 x
6796 >>> m[1]
6797 f
6798 >>> m[x]
6799 1
6800 >>> m[f]
6801 [else -> 0]
6802 >>> for d in m: print("%s -> %s" % (d, m[d]))
6803 x -> 1
6804 f -> [else -> 0]
6805 """
6806 if _is_int(idx):
6807 if idx >= len(self):
6808 raise IndexError
6809 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6810 if (idx < num_consts):
6811 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6812 else:
6813 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6814 if isinstance(idx, FuncDeclRef):
6815 return self.get_interp(idx)
6816 if is_const(idx):
6817 return self.get_interp(idx.decl())
6818 if isinstance(idx, SortRef):
6819 return self.get_universe(idx)
6820 if z3_debug():
6821 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6822 return None
6823
6824 def decls(self):
6825 """Return a list with all symbols that have an interpretation in the model `self`.
6826 >>> f = Function('f', IntSort(), IntSort())
6827 >>> x = Int('x')
6828 >>> s = Solver()
6829 >>> s.add(x > 0, x < 2, f(x) == 0)
6830 >>> s.check()
6831 sat
6832 >>> m = s.model()
6833 >>> m.decls()
6834 [x, f]
6835 """
6836 r = []
6837 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6838 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6839 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6840 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6841 return r
6842
6843 def update_value(self, x, value):
6844 """Update the interpretation of a constant"""
6845 if is_expr(x):
6846 x = x.decl()
6847 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6848 fi1 = value.f
6849 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6850 fi2 = FuncInterp(fi2, x.ctx)
6851 for i in range(value.num_entries()):
6852 e = value.entry(i)
6853 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6854 v = AstVector()
6855 for j in range(n):
6856 v.push(e.arg_value(j))
6857 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6858 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6859 return
6860 if not is_func_decl(x) or x.arity() != 0:
6861 raise Z3Exception("Expecting 0-ary function or constant expression")
6862 value = _py2expr(value)
6863 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6864
6865 def translate(self, target):
6866 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6867 """
6868 if z3_debug():
6869 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6870 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6871 return ModelRef(model, target)
6872
6873 def project(self, vars, fml):
6874 """Perform model-based projection on fml with respect to vars.
6875 Assume that the model satisfies fml. Then compute a projection fml_p, such
6876 that vars do not occur free in fml_p, fml_p is true in the model and
6877 fml_p => exists vars . fml
6878 """
6879 ctx = self.ctx.ref()
6880 _vars = (Ast * len(vars))()
6881 for i in range(len(vars)):
6882 _vars[i] = vars[i].as_ast()
6883 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6884
6885 def project_with_witness(self, vars, fml):
6886 """Perform model-based projection, but also include realizer terms for the projected variables"""
6887 ctx = self.ctx.ref()
6888 _vars = (Ast * len(vars))()
6889 for i in range(len(vars)):
6890 _vars[i] = vars[i].as_ast()
6891 defs = AstMap()
6892 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6893 result = _to_expr_ref(result, self.ctx)
6894 return result, defs
6895
6896
6897 def __copy__(self):
6898 return self.translate(self.ctx)
6899
6900 def __deepcopy__(self, memo={}):
6901 return self.translate(self.ctx)
6902
6903
6904def Model(ctx=None, eval = {}):
6905 ctx = _get_ctx(ctx)
6906 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6907 for k, v in eval.items():
6908 mdl.update_value(k, v)
6909 return mdl
6910
6911
6913 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6914 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6915
6916
6918 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6919 if z3_debug():
6920 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6921 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6922
6923
6928
6929
6931 """Statistics for `Solver.check()`."""
6932
6933 def __init__(self, stats, ctx):
6934 self.stats = stats
6935 self.ctx = ctx
6936 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6937
6938 def __deepcopy__(self, memo={}):
6939 return Statistics(self.stats, self.ctx)
6940
6941 def __del__(self):
6942 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6943 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6944
6945 def __repr__(self):
6946 if in_html_mode():
6947 out = io.StringIO()
6948 even = True
6949 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6950 for k, v in self:
6951 if even:
6952 out.write(u('<tr style="background-color:#CFCFCF">'))
6953 even = False
6954 else:
6955 out.write(u("<tr>"))
6956 even = True
6957 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6958 out.write(u("</table>"))
6959 return out.getvalue()
6960 else:
6961 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6962
6963 def __len__(self):
6964 """Return the number of statistical counters.
6965
6966 >>> x = Int('x')
6967 >>> s = Then('simplify', 'nlsat').solver()
6968 >>> s.add(x > 0)
6969 >>> s.check()
6970 sat
6971 >>> st = s.statistics()
6972 >>> len(st)
6973 7
6974 """
6975 return int(Z3_stats_size(self.ctx.ref(), self.stats))
6976
6977 def __getitem__(self, idx):
6978 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6979
6980 >>> x = Int('x')
6981 >>> s = Then('simplify', 'nlsat').solver()
6982 >>> s.add(x > 0)
6983 >>> s.check()
6984 sat
6985 >>> st = s.statistics()
6986 >>> len(st)
6987 7
6988 >>> st[0]
6989 ('nlsat propagations', 2)
6990 >>> st[1]
6991 ('nlsat restarts', 1)
6992 """
6993 if idx >= len(self):
6994 raise IndexError
6995 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6996 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6997 else:
6998 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6999 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
7000
7001 def keys(self):
7002 """Return the list of statistical counters.
7003
7004 >>> x = Int('x')
7005 >>> s = Then('simplify', 'nlsat').solver()
7006 >>> s.add(x > 0)
7007 >>> s.check()
7008 sat
7009 >>> st = s.statistics()
7010 """
7011 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
7012
7013 def get_key_value(self, key):
7014 """Return the value of a particular statistical counter.
7015
7016 >>> x = Int('x')
7017 >>> s = Then('simplify', 'nlsat').solver()
7018 >>> s.add(x > 0)
7019 >>> s.check()
7020 sat
7021 >>> st = s.statistics()
7022 >>> st.get_key_value('nlsat propagations')
7023 2
7024 """
7025 for idx in range(len(self)):
7026 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
7027 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7028 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7029 else:
7030 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7031 raise Z3Exception("unknown key")
7032
7033 def __getattr__(self, name):
7034 """Access the value of statistical using attributes.
7035
7036 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
7037 we should use '_' (e.g., 'nlsat_propagations').
7038
7039 >>> x = Int('x')
7040 >>> s = Then('simplify', 'nlsat').solver()
7041 >>> s.add(x > 0)
7042 >>> s.check()
7043 sat
7044 >>> st = s.statistics()
7045 >>> st.nlsat_propagations
7046 2
7047 >>> st.nlsat_stages
7048 2
7049 """
7050 key = name.replace("_", " ")
7051 try:
7052 return self.get_key_value(key)
7053 except Z3Exception:
7054 raise AttributeError
7055
7056
7061
7062
7064 """Represents the result of a satisfiability check: sat, unsat, unknown.
7065
7066 >>> s = Solver()
7067 >>> s.check()
7068 sat
7069 >>> r = s.check()
7070 >>> isinstance(r, CheckSatResult)
7071 True
7072 """
7073
7074 def __init__(self, r):
7075 self.r = r
7076
7077 def __deepcopy__(self, memo={}):
7078 return CheckSatResult(self.r)
7079
7080 def __eq__(self, other):
7081 return isinstance(other, CheckSatResult) and self.r == other.r
7082
7083 def __ne__(self, other):
7084 return not self.__eq__(other)
7085
7086 def __repr__(self):
7087 if in_html_mode():
7088 if self.r == Z3_L_TRUE:
7089 return "<b>sat</b>"
7090 elif self.r == Z3_L_FALSE:
7091 return "<b>unsat</b>"
7092 else:
7093 return "<b>unknown</b>"
7094 else:
7095 if self.r == Z3_L_TRUE:
7096 return "sat"
7097 elif self.r == Z3_L_FALSE:
7098 return "unsat"
7099 else:
7100 return "unknown"
7101
7102 def _repr_html_(self):
7103 in_html = in_html_mode()
7104 set_html_mode(True)
7105 res = repr(self)
7106 set_html_mode(in_html)
7107 return res
7108
7109
7110sat = CheckSatResult(Z3_L_TRUE)
7111unsat = CheckSatResult(Z3_L_FALSE)
7112unknown = CheckSatResult(Z3_L_UNDEF)
7113
7114
7116 """
7117 Solver API provides methods for implementing the main SMT 2.0 commands:
7118 push, pop, check, get-model, etc.
7119 """
7120
7121 def __init__(self, solver=None, ctx=None, logFile=None):
7122 assert solver is None or ctx is not None
7123 self.ctx = _get_ctx(ctx)
7124 self.backtrack_level = 4000000000
7125 self.solver = None
7126 if solver is None:
7127 self.solver = Z3_mk_solver(self.ctx.ref())
7128 else:
7129 self.solver = solver
7130 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7131 if logFile is not None:
7132 self.set("smtlib2_log", logFile)
7133
7134 def __del__(self):
7135 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7136 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7137
7138 def __enter__(self):
7139 self.push()
7140 return self
7141
7142 def __exit__(self, *exc_info):
7143 self.pop()
7144
7145 def set(self, *args, **keys):
7146 """Set a configuration option.
7147 The method `help()` return a string containing all available options.
7148
7149 >>> s = Solver()
7150 >>> # The option MBQI can be set using three different approaches.
7151 >>> s.set(mbqi=True)
7152 >>> s.set('MBQI', True)
7153 >>> s.set(':mbqi', True)
7154 """
7155 p = args2params(args, keys, self.ctx)
7156 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7157
7158 def push(self):
7159 """Create a backtracking point.
7160
7161 >>> x = Int('x')
7162 >>> s = Solver()
7163 >>> s.add(x > 0)
7164 >>> s
7165 [x > 0]
7166 >>> s.push()
7167 >>> s.add(x < 1)
7168 >>> s
7169 [x > 0, x < 1]
7170 >>> s.check()
7171 unsat
7172 >>> s.pop()
7173 >>> s.check()
7174 sat
7175 >>> s
7176 [x > 0]
7177 """
7178 Z3_solver_push(self.ctx.ref(), self.solver)
7179
7180 def pop(self, num=1):
7181 """Backtrack \\c num backtracking points.
7182
7183 >>> x = Int('x')
7184 >>> s = Solver()
7185 >>> s.add(x > 0)
7186 >>> s
7187 [x > 0]
7188 >>> s.push()
7189 >>> s.add(x < 1)
7190 >>> s
7191 [x > 0, x < 1]
7192 >>> s.check()
7193 unsat
7194 >>> s.pop()
7195 >>> s.check()
7196 sat
7197 >>> s
7198 [x > 0]
7199 """
7200 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7201
7202 def num_scopes(self):
7203 """Return the current number of backtracking points.
7204
7205 >>> s = Solver()
7206 >>> s.num_scopes()
7207 0
7208 >>> s.push()
7209 >>> s.num_scopes()
7210 1
7211 >>> s.push()
7212 >>> s.num_scopes()
7213 2
7214 >>> s.pop()
7215 >>> s.num_scopes()
7216 1
7217 """
7218 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7219
7220 def reset(self):
7221 """Remove all asserted constraints and backtracking points created using `push()`.
7222
7223 >>> x = Int('x')
7224 >>> s = Solver()
7225 >>> s.add(x > 0)
7226 >>> s
7227 [x > 0]
7228 >>> s.reset()
7229 >>> s
7230 []
7231 """
7232 Z3_solver_reset(self.ctx.ref(), self.solver)
7233
7234 def assert_exprs(self, *args):
7235 """Assert constraints into the solver.
7236
7237 >>> x = Int('x')
7238 >>> s = Solver()
7239 >>> s.assert_exprs(x > 0, x < 2)
7240 >>> s
7241 [x > 0, x < 2]
7242 """
7243 args = _get_args(args)
7244 s = BoolSort(self.ctx)
7245 for arg in args:
7246 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7247 for f in arg:
7248 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7249 else:
7250 arg = s.cast(arg)
7251 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7252
7253 def add(self, *args):
7254 """Assert constraints into the solver.
7255
7256 >>> x = Int('x')
7257 >>> s = Solver()
7258 >>> s.add(x > 0, x < 2)
7259 >>> s
7260 [x > 0, x < 2]
7261 """
7262 self.assert_exprs(*args)
7263
7264 def __iadd__(self, fml):
7265 self.add(fml)
7266 return self
7267
7268 def append(self, *args):
7269 """Assert constraints into the solver.
7270
7271 >>> x = Int('x')
7272 >>> s = Solver()
7273 >>> s.append(x > 0, x < 2)
7274 >>> s
7275 [x > 0, x < 2]
7276 """
7277 self.assert_exprs(*args)
7278
7279 def insert(self, *args):
7280 """Assert constraints into the solver.
7281
7282 >>> x = Int('x')
7283 >>> s = Solver()
7284 >>> s.insert(x > 0, x < 2)
7285 >>> s
7286 [x > 0, x < 2]
7287 """
7288 self.assert_exprs(*args)
7289
7290 def assert_and_track(self, a, p):
7291 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7292
7293 If `p` is a string, it will be automatically converted into a Boolean constant.
7294
7295 >>> x = Int('x')
7296 >>> p3 = Bool('p3')
7297 >>> s = Solver()
7298 >>> s.set(unsat_core=True)
7299 >>> s.assert_and_track(x > 0, 'p1')
7300 >>> s.assert_and_track(x != 1, 'p2')
7301 >>> s.assert_and_track(x < 0, p3)
7302 >>> print(s.check())
7303 unsat
7304 >>> c = s.unsat_core()
7305 >>> len(c)
7306 2
7307 >>> Bool('p1') in c
7308 True
7309 >>> Bool('p2') in c
7310 False
7311 >>> p3 in c
7312 True
7313 """
7314 if isinstance(p, str):
7315 p = Bool(p, self.ctx)
7316 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7317 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7318 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7319
7320 def check(self, *assumptions):
7321 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7322
7323 >>> x = Int('x')
7324 >>> s = Solver()
7325 >>> s.check()
7326 sat
7327 >>> s.add(x > 0, x < 2)
7328 >>> s.check()
7329 sat
7330 >>> s.model().eval(x)
7331 1
7332 >>> s.add(x < 1)
7333 >>> s.check()
7334 unsat
7335 >>> s.reset()
7336 >>> s.add(2**x == 4)
7337 >>> s.check()
7338 sat
7339 """
7340 s = BoolSort(self.ctx)
7341 assumptions = _get_args(assumptions)
7342 num = len(assumptions)
7343 _assumptions = (Ast * num)()
7344 for i in range(num):
7345 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7346 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7347 return CheckSatResult(r)
7348
7349 def model(self):
7350 """Return a model for the last `check()`.
7351
7352 This function raises an exception if
7353 a model is not available (e.g., last `check()` returned unsat).
7354
7355 >>> s = Solver()
7356 >>> a = Int('a')
7357 >>> s.add(a + 2 == 0)
7358 >>> s.check()
7359 sat
7360 >>> s.model()
7361 [a = -2]
7362 """
7363 try:
7364 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7365 except Z3Exception:
7366 raise Z3Exception("model is not available")
7367
7368 def import_model_converter(self, other):
7369 """Import model converter from other into the current solver"""
7370 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7371
7372 def interrupt(self):
7373 """Interrupt the execution of the solver object.
7374 Remarks: This ensures that the interrupt applies only
7375 to the given solver object and it applies only if it is running.
7376 """
7377 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7378
7379 def unsat_core(self):
7380 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7381
7382 These are the assumptions Z3 used in the unsatisfiability proof.
7383 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7384 They may be also used to "retract" assumptions. Note that, assumptions are not really
7385 "soft constraints", but they can be used to implement them.
7386
7387 >>> p1, p2, p3 = Bools('p1 p2 p3')
7388 >>> x, y = Ints('x y')
7389 >>> s = Solver()
7390 >>> s.add(Implies(p1, x > 0))
7391 >>> s.add(Implies(p2, y > x))
7392 >>> s.add(Implies(p2, y < 1))
7393 >>> s.add(Implies(p3, y > -3))
7394 >>> s.check(p1, p2, p3)
7395 unsat
7396 >>> core = s.unsat_core()
7397 >>> len(core)
7398 2
7399 >>> p1 in core
7400 True
7401 >>> p2 in core
7402 True
7403 >>> p3 in core
7404 False
7405 >>> # "Retracting" p2
7406 >>> s.check(p1, p3)
7407 sat
7408 """
7409 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7410
7411 def consequences(self, assumptions, variables):
7412 """Determine fixed values for the variables based on the solver state and assumptions.
7413 >>> s = Solver()
7414 >>> a, b, c, d = Bools('a b c d')
7415 >>> s.add(Implies(a,b), Implies(b, c))
7416 >>> s.consequences([a],[b,c,d])
7417 (sat, [Implies(a, b), Implies(a, c)])
7418 >>> s.consequences([Not(c),d],[a,b,c,d])
7419 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7420 """
7421 if isinstance(assumptions, list):
7422 _asms = AstVector(None, self.ctx)
7423 for a in assumptions:
7424 _asms.push(a)
7425 assumptions = _asms
7426 if isinstance(variables, list):
7427 _vars = AstVector(None, self.ctx)
7428 for a in variables:
7429 _vars.push(a)
7430 variables = _vars
7431 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7432 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7433 consequences = AstVector(None, self.ctx)
7434 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7435 variables.vector, consequences.vector)
7436 sz = len(consequences)
7437 consequences = [consequences[i] for i in range(sz)]
7438 return CheckSatResult(r), consequences
7439
7440 def from_file(self, filename):
7441 """Parse assertions from a file"""
7442 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7443
7444 def from_string(self, s):
7445 """Parse assertions from a string"""
7446 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7447
7448 def cube(self, vars=None):
7449 """Get set of cubes
7450 The method takes an optional set of variables that restrict which
7451 variables may be used as a starting point for cubing.
7452 If vars is not None, then the first case split is based on a variable in
7453 this set.
7454 """
7455 self.cube_vs = AstVector(None, self.ctx)
7456 if vars is not None:
7457 for v in vars:
7458 self.cube_vs.push(v)
7459 while True:
7460 lvl = self.backtrack_level
7461 self.backtrack_level = 4000000000
7462 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7463 if (len(r) == 1 and is_false(r[0])):
7464 return
7465 yield r
7466 if (len(r) == 0):
7467 return
7468
7469 def cube_vars(self):
7470 """Access the set of variables that were touched by the most recently generated cube.
7471 This set of variables can be used as a starting point for additional cubes.
7472 The idea is that variables that appear in clauses that are reduced by the most recent
7473 cube are likely more useful to cube on."""
7474 return self.cube_vs
7475
7476 def root(self, t):
7477 """Retrieve congruence closure root of the term t relative to the current search state
7478 The function primarily works for SimpleSolver. Terms and variables that are
7479 eliminated during pre-processing are not visible to the congruence closure.
7480 """
7481 t = _py2expr(t, self.ctx)
7482 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7483
7484 def next(self, t):
7485 """Retrieve congruence closure sibling of the term t relative to the current search state
7486 The function primarily works for SimpleSolver. Terms and variables that are
7487 eliminated during pre-processing are not visible to the congruence closure.
7488 """
7489 t = _py2expr(t, self.ctx)
7490 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7491
7492 def explain_congruent(self, a, b):
7493 """Explain congruence of a and b relative to the current search state"""
7494 a = _py2expr(a, self.ctx)
7495 b = _py2expr(b, self.ctx)
7496 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7497
7498
7499 def solve_for(self, ts):
7500 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7501 vars = AstVector(ctx=self.ctx);
7502 terms = AstVector(ctx=self.ctx);
7503 guards = AstVector(ctx=self.ctx);
7504 for t in ts:
7505 t = _py2expr(t, self.ctx)
7506 vars.push(t)
7507 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7508 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7509
7510
7511 def proof(self):
7512 """Return a proof for the last `check()`. Proof construction must be enabled."""
7513 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7514
7515 def assertions(self):
7516 """Return an AST vector containing all added constraints.
7517
7518 >>> s = Solver()
7519 >>> s.assertions()
7520 []
7521 >>> a = Int('a')
7522 >>> s.add(a > 0)
7523 >>> s.add(a < 10)
7524 >>> s.assertions()
7525 [a > 0, a < 10]
7526 """
7527 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7528
7529 def units(self):
7530 """Return an AST vector containing all currently inferred units.
7531 """
7532 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7533
7534 def non_units(self):
7535 """Return an AST vector containing all atomic formulas in solver state that are not units.
7536 """
7537 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7538
7539 def trail_levels(self):
7540 """Return trail and decision levels of the solver state after a check() call.
7541 """
7542 trail = self.trail()
7543 levels = (ctypes.c_uint * len(trail))()
7544 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7545 return trail, levels
7546
7547 def set_initial_value(self, var, value):
7548 """initialize the solver's state by setting the initial value of var to value
7549 """
7550 s = var.sort()
7551 value = s.cast(value)
7552 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7553
7554 def trail(self):
7555 """Return trail of the solver state after a check() call.
7556 """
7557 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7558
7559 def statistics(self):
7560 """Return statistics for the last `check()`.
7561
7562 >>> s = SimpleSolver()
7563 >>> x = Int('x')
7564 >>> s.add(x > 0)
7565 >>> s.check()
7566 sat
7567 >>> st = s.statistics()
7568 >>> st.get_key_value('final checks')
7569 1
7570 >>> len(st) > 0
7571 True
7572 >>> st[0] != 0
7573 True
7574 """
7575 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7576
7577 def reason_unknown(self):
7578 """Return a string describing why the last `check()` returned `unknown`.
7579
7580 >>> x = Int('x')
7581 >>> s = SimpleSolver()
7582 >>> s.add(x == 2**x)
7583 >>> s.check()
7584 unknown
7585 >>> s.reason_unknown()
7586 '(incomplete (theory arithmetic))'
7587 """
7588 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7589
7590 def help(self):
7591 """Display a string describing all available options."""
7592 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7593
7594 def param_descrs(self):
7595 """Return the parameter description set."""
7596 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7597
7598 def __repr__(self):
7599 """Return a formatted string with all added constraints."""
7600 return obj_to_string(self)
7601
7602 def translate(self, target):
7603 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7604
7605 >>> c1 = Context()
7606 >>> c2 = Context()
7607 >>> s1 = Solver(ctx=c1)
7608 >>> s2 = s1.translate(c2)
7609 """
7610 if z3_debug():
7611 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7612 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7613 return Solver(solver, target)
7614
7615 def __copy__(self):
7616 return self.translate(self.ctx)
7617
7618 def __deepcopy__(self, memo={}):
7619 return self.translate(self.ctx)
7620
7621 def sexpr(self):
7622 """Return a formatted string (in Lisp-like format) with all added constraints.
7623 We say the string is in s-expression format.
7624
7625 >>> x = Int('x')
7626 >>> s = Solver()
7627 >>> s.add(x > 0)
7628 >>> s.add(x < 2)
7629 >>> r = s.sexpr()
7630 """
7631 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7632
7633 def dimacs(self, include_names=True):
7634 """Return a textual representation of the solver in DIMACS format."""
7635 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7636
7637 def to_smt2(self):
7638 """return SMTLIB2 formatted benchmark for solver's assertions"""
7639 es = self.assertions()
7640 sz = len(es)
7641 sz1 = sz
7642 if sz1 > 0:
7643 sz1 -= 1
7644 v = (Ast * sz1)()
7645 for i in range(sz1):
7646 v[i] = es[i].as_ast()
7647 if sz > 0:
7648 e = es[sz1].as_ast()
7649 else:
7650 e = BoolVal(True, self.ctx).as_ast()
7651 return Z3_benchmark_to_smtlib_string(
7652 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7653 )
7654
7655
7656def SolverFor(logic, ctx=None, logFile=None):
7657 """Create a solver customized for the given logic.
7658
7659 The parameter `logic` is a string. It should be contains
7660 the name of a SMT-LIB logic.
7661 See http://www.smtlib.org/ for the name of all available logics.
7662
7663 >>> s = SolverFor("QF_LIA")
7664 >>> x = Int('x')
7665 >>> s.add(x > 0)
7666 >>> s.add(x < 2)
7667 >>> s.check()
7668 sat
7669 >>> s.model()
7670 [x = 1]
7671 """
7672 ctx = _get_ctx(ctx)
7673 logic = to_symbol(logic)
7674 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7675
7676
7677def SimpleSolver(ctx=None, logFile=None):
7678 """Return a simple general purpose solver with limited amount of preprocessing.
7679
7680 >>> s = SimpleSolver()
7681 >>> x = Int('x')
7682 >>> s.add(x > 0)
7683 >>> s.check()
7684 sat
7685 """
7686 ctx = _get_ctx(ctx)
7687 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7688
7689#########################################
7690#
7691# Fixedpoint
7692#
7693#########################################
7694
7695
7696class Fixedpoint(Z3PPObject):
7697 """Fixedpoint API provides methods for solving with recursive predicates"""
7698
7699 def __init__(self, fixedpoint=None, ctx=None):
7700 assert fixedpoint is None or ctx is not None
7701 self.ctx = _get_ctx(ctx)
7702 self.fixedpoint = None
7703 if fixedpoint is None:
7704 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7705 else:
7706 self.fixedpoint = fixedpoint
7707 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7708 self.vars = []
7709
7710 def __deepcopy__(self, memo={}):
7711 return FixedPoint(self.fixedpoint, self.ctx)
7712
7713 def __del__(self):
7714 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7715 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7716
7717 def set(self, *args, **keys):
7718 """Set a configuration option. The method `help()` return a string containing all available options.
7719 """
7720 p = args2params(args, keys, self.ctx)
7721 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7722
7723 def help(self):
7724 """Display a string describing all available options."""
7725 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7726
7727 def param_descrs(self):
7728 """Return the parameter description set."""
7729 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7730
7731 def assert_exprs(self, *args):
7732 """Assert constraints as background axioms for the fixedpoint solver."""
7733 args = _get_args(args)
7734 s = BoolSort(self.ctx)
7735 for arg in args:
7736 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7737 for f in arg:
7738 f = self.abstract(f)
7739 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7740 else:
7741 arg = s.cast(arg)
7742 arg = self.abstract(arg)
7743 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7744
7745 def add(self, *args):
7746 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7747 self.assert_exprs(*args)
7748
7749 def __iadd__(self, fml):
7750 self.add(fml)
7751 return self
7752
7753 def append(self, *args):
7754 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7755 self.assert_exprs(*args)
7756
7757 def insert(self, *args):
7758 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7759 self.assert_exprs(*args)
7760
7761 def add_rule(self, head, body=None, name=None):
7762 """Assert rules defining recursive predicates to the fixedpoint solver.
7763 >>> a = Bool('a')
7764 >>> b = Bool('b')
7765 >>> s = Fixedpoint()
7766 >>> s.register_relation(a.decl())
7767 >>> s.register_relation(b.decl())
7768 >>> s.fact(a)
7769 >>> s.rule(b, a)
7770 >>> s.query(b)
7771 sat
7772 """
7773 if name is None:
7774 name = ""
7775 name = to_symbol(name, self.ctx)
7776 if body is None:
7777 head = self.abstract(head)
7778 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7779 else:
7780 body = _get_args(body)
7781 f = self.abstract(Implies(And(body, self.ctx), head))
7782 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7783
7784 def rule(self, head, body=None, name=None):
7785 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7786 self.add_rule(head, body, name)
7787
7788 def fact(self, head, name=None):
7789 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7790 self.add_rule(head, None, name)
7791
7792 def query(self, *query):
7793 """Query the fixedpoint engine whether formula is derivable.
7794 You can also pass an tuple or list of recursive predicates.
7795 """
7796 query = _get_args(query)
7797 sz = len(query)
7798 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7799 _decls = (FuncDecl * sz)()
7800 i = 0
7801 for q in query:
7802 _decls[i] = q.ast
7803 i = i + 1
7804 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7805 else:
7806 if sz == 1:
7807 query = query[0]
7808 else:
7809 query = And(query, self.ctx)
7810 query = self.abstract(query, False)
7811 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7812 return CheckSatResult(r)
7813
7814 def query_from_lvl(self, lvl, *query):
7815 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7816 """
7817 query = _get_args(query)
7818 sz = len(query)
7819 if sz >= 1 and isinstance(query[0], FuncDecl):
7820 _z3_assert(False, "unsupported")
7821 else:
7822 if sz == 1:
7823 query = query[0]
7824 else:
7825 query = And(query)
7826 query = self.abstract(query, False)
7827 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7828 return CheckSatResult(r)
7829
7830 def update_rule(self, head, body, name):
7831 """update rule"""
7832 if name is None:
7833 name = ""
7834 name = to_symbol(name, self.ctx)
7835 body = _get_args(body)
7836 f = self.abstract(Implies(And(body, self.ctx), head))
7837 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7838
7839 def get_answer(self):
7840 """Retrieve answer from last query call."""
7841 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7842 return _to_expr_ref(r, self.ctx)
7843
7844 def get_ground_sat_answer(self):
7845 """Retrieve a ground cex from last query call."""
7846 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7847 return _to_expr_ref(r, self.ctx)
7848
7849 def get_rules_along_trace(self):
7850 """retrieve rules along the counterexample trace"""
7851 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7852
7853 def get_rule_names_along_trace(self):
7854 """retrieve rule names along the counterexample trace"""
7855 # this is a hack as I don't know how to return a list of symbols from C++;
7856 # obtain names as a single string separated by semicolons
7857 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7858 # split into individual names
7859 return names.split(";")
7860
7861 def get_num_levels(self, predicate):
7862 """Retrieve number of levels used for predicate in PDR engine"""
7863 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7864
7865 def get_cover_delta(self, level, predicate):
7866 """Retrieve properties known about predicate for the level'th unfolding.
7867 -1 is treated as the limit (infinity)
7868 """
7869 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7870 return _to_expr_ref(r, self.ctx)
7871
7872 def add_cover(self, level, predicate, property):
7873 """Add property to predicate for the level'th unfolding.
7874 -1 is treated as infinity (infinity)
7875 """
7876 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7877
7878 def register_relation(self, *relations):
7879 """Register relation as recursive"""
7880 relations = _get_args(relations)
7881 for f in relations:
7882 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7883
7884 def set_predicate_representation(self, f, *representations):
7885 """Control how relation is represented"""
7886 representations = _get_args(representations)
7887 representations = [to_symbol(s) for s in representations]
7888 sz = len(representations)
7889 args = (Symbol * sz)()
7890 for i in range(sz):
7891 args[i] = representations[i]
7892 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7893
7894 def parse_string(self, s):
7895 """Parse rules and queries from a string"""
7896 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7897
7898 def parse_file(self, f):
7899 """Parse rules and queries from a file"""
7900 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7901
7902 def get_rules(self):
7903 """retrieve rules that have been added to fixedpoint context"""
7904 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7905
7906 def get_assertions(self):
7907 """retrieve assertions that have been added to fixedpoint context"""
7908 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7909
7910 def __repr__(self):
7911 """Return a formatted string with all added rules and constraints."""
7912 return self.sexpr()
7913
7914 def sexpr(self):
7915 """Return a formatted string (in Lisp-like format) with all added constraints.
7916 We say the string is in s-expression format.
7917 """
7918 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7919
7920 def to_string(self, queries):
7921 """Return a formatted string (in Lisp-like format) with all added constraints.
7922 We say the string is in s-expression format.
7923 Include also queries.
7924 """
7925 args, len = _to_ast_array(queries)
7926 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7927
7928 def statistics(self):
7929 """Return statistics for the last `query()`.
7930 """
7931 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7932
7933 def reason_unknown(self):
7934 """Return a string describing why the last `query()` returned `unknown`.
7935 """
7936 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7937
7938 def declare_var(self, *vars):
7939 """Add variable or several variables.
7940 The added variable or variables will be bound in the rules
7941 and queries
7942 """
7943 vars = _get_args(vars)
7944 for v in vars:
7945 self.vars += [v]
7946
7947 def abstract(self, fml, is_forall=True):
7948 if self.vars == []:
7949 return fml
7950 if is_forall:
7951 return ForAll(self.vars, fml)
7952 else:
7953 return Exists(self.vars, fml)
7954
7955
7956#########################################
7957#
7958# Finite domains
7959#
7960#########################################
7961
7962class FiniteDomainSortRef(SortRef):
7963 """Finite domain sort."""
7964
7965 def size(self):
7966 """Return the size of the finite domain sort"""
7967 r = (ctypes.c_ulonglong * 1)()
7968 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7969 return r[0]
7970 else:
7971 raise Z3Exception("Failed to retrieve finite domain sort size")
7972
7973
7974def FiniteDomainSort(name, sz, ctx=None):
7975 """Create a named finite domain sort of a given size sz"""
7976 if not isinstance(name, Symbol):
7977 name = to_symbol(name)
7978 ctx = _get_ctx(ctx)
7979 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7980
7981
7982def is_finite_domain_sort(s):
7983 """Return True if `s` is a Z3 finite-domain sort.
7984
7985 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7986 True
7987 >>> is_finite_domain_sort(IntSort())
7988 False
7989 """
7990 return isinstance(s, FiniteDomainSortRef)
7991
7992
7993class FiniteDomainRef(ExprRef):
7994 """Finite-domain expressions."""
7995
7996 def sort(self):
7997 """Return the sort of the finite-domain expression `self`."""
7998 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7999
8000 def as_string(self):
8001 """Return a Z3 floating point expression as a Python string."""
8002 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
8003
8004
8005def is_finite_domain(a):
8006 """Return `True` if `a` is a Z3 finite-domain expression.
8007
8008 >>> s = FiniteDomainSort('S', 100)
8009 >>> b = Const('b', s)
8010 >>> is_finite_domain(b)
8011 True
8012 >>> is_finite_domain(Int('x'))
8013 False
8014 """
8015 return isinstance(a, FiniteDomainRef)
8016
8017
8018class FiniteDomainNumRef(FiniteDomainRef):
8019 """Integer values."""
8020
8021 def as_long(self):
8022 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
8023
8024 >>> s = FiniteDomainSort('S', 100)
8025 >>> v = FiniteDomainVal(3, s)
8026 >>> v
8027 3
8028 >>> v.as_long() + 1
8029 4
8030 """
8031 return int(self.as_string())
8032
8033 def as_string(self):
8034 """Return a Z3 finite-domain numeral as a Python string.
8035
8036 >>> s = FiniteDomainSort('S', 100)
8037 >>> v = FiniteDomainVal(42, s)
8038 >>> v.as_string()
8039 '42'
8040 """
8041 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
8042
8043
8044def FiniteDomainVal(val, sort, ctx=None):
8045 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
8046
8047 >>> s = FiniteDomainSort('S', 256)
8048 >>> FiniteDomainVal(255, s)
8049 255
8050 >>> FiniteDomainVal('100', s)
8051 100
8052 """
8053 if z3_debug():
8054 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
8055 ctx = sort.ctx
8056 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
8057
8058
8059def is_finite_domain_value(a):
8060 """Return `True` if `a` is a Z3 finite-domain value.
8061
8062 >>> s = FiniteDomainSort('S', 100)
8063 >>> b = Const('b', s)
8064 >>> is_finite_domain_value(b)
8065 False
8066 >>> b = FiniteDomainVal(10, s)
8067 >>> b
8068 10
8069 >>> is_finite_domain_value(b)
8070 True
8071 """
8072 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
8073
8074
8075#########################################
8076#
8077# Optimize
8078#
8079#########################################
8080
8081class OptimizeObjective:
8082 def __init__(self, opt, value, is_max):
8083 self._opt = opt
8084 self._value = value
8085 self._is_max = is_max
8086
8087 def lower(self):
8088 opt = self._opt
8089 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8090
8091 def upper(self):
8092 opt = self._opt
8093 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8094
8095 def lower_values(self):
8096 opt = self._opt
8097 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8098
8099 def upper_values(self):
8100 opt = self._opt
8101 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8102
8103 def value(self):
8104 if self._is_max:
8105 return self.upper()
8106 else:
8107 return self.lower()
8108
8109 def __str__(self):
8110 return "%s:%s" % (self._value, self._is_max)
8111
8112
8113_on_models = {}
8114
8115
8116def _global_on_model(ctx):
8117 (fn, mdl) = _on_models[ctx]
8118 fn(mdl)
8119
8120
8121_on_model_eh = on_model_eh_type(_global_on_model)
8122
8123
8124class Optimize(Z3PPObject):
8125 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8126
8127 def __init__(self, optimize=None, ctx=None):
8128 self.ctx = _get_ctx(ctx)
8129 if optimize is None:
8130 self.optimize = Z3_mk_optimize(self.ctx.ref())
8131 else:
8132 self.optimize = optimize
8133 self._on_models_id = None
8134 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8135
8136 def __deepcopy__(self, memo={}):
8137 return Optimize(self.optimize, self.ctx)
8138
8139 def __del__(self):
8140 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8141 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8142 if self._on_models_id is not None:
8143 del _on_models[self._on_models_id]
8144
8145 def __enter__(self):
8146 self.push()
8147 return self
8148
8149 def __exit__(self, *exc_info):
8150 self.pop()
8151
8152 def set(self, *args, **keys):
8153 """Set a configuration option.
8154 The method `help()` return a string containing all available options.
8155 """
8156 p = args2params(args, keys, self.ctx)
8157 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8158
8159 def help(self):
8160 """Display a string describing all available options."""
8161 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8162
8163 def param_descrs(self):
8164 """Return the parameter description set."""
8165 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8166
8167 def assert_exprs(self, *args):
8168 """Assert constraints as background axioms for the optimize solver."""
8169 args = _get_args(args)
8170 s = BoolSort(self.ctx)
8171 for arg in args:
8172 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8173 for f in arg:
8174 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8175 else:
8176 arg = s.cast(arg)
8177 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8178
8179 def add(self, *args):
8180 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8181 self.assert_exprs(*args)
8182
8183 def __iadd__(self, fml):
8184 self.add(fml)
8185 return self
8186
8187 def assert_and_track(self, a, p):
8188 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8189
8190 If `p` is a string, it will be automatically converted into a Boolean constant.
8191
8192 >>> x = Int('x')
8193 >>> p3 = Bool('p3')
8194 >>> s = Optimize()
8195 >>> s.assert_and_track(x > 0, 'p1')
8196 >>> s.assert_and_track(x != 1, 'p2')
8197 >>> s.assert_and_track(x < 0, p3)
8198 >>> print(s.check())
8199 unsat
8200 >>> c = s.unsat_core()
8201 >>> len(c)
8202 2
8203 >>> Bool('p1') in c
8204 True
8205 >>> Bool('p2') in c
8206 False
8207 >>> p3 in c
8208 True
8209 """
8210 if isinstance(p, str):
8211 p = Bool(p, self.ctx)
8212 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8213 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8214 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8215
8216 def add_soft(self, arg, weight="1", id=None):
8217 """Add soft constraint with optional weight and optional identifier.
8218 If no weight is supplied, then the penalty for violating the soft constraint
8219 is 1.
8220 Soft constraints are grouped by identifiers. Soft constraints that are
8221 added without identifiers are grouped by default.
8222 """
8223 if _is_int(weight):
8224 weight = "%d" % weight
8225 elif isinstance(weight, float):
8226 weight = "%f" % weight
8227 if not isinstance(weight, str):
8228 raise Z3Exception("weight should be a string or an integer")
8229 if id is None:
8230 id = ""
8231 id = to_symbol(id, self.ctx)
8232
8233 def asoft(a):
8234 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8235 return OptimizeObjective(self, v, False)
8236 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8237 return [asoft(a) for a in arg]
8238 return asoft(arg)
8239
8240 def set_initial_value(self, var, value):
8241 """initialize the solver's state by setting the initial value of var to value
8242 """
8243 s = var.sort()
8244 value = s.cast(value)
8245 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8246
8247 def maximize(self, arg):
8248 """Add objective function to maximize."""
8249 return OptimizeObjective(
8250 self,
8251 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8252 is_max=True,
8253 )
8254
8255 def minimize(self, arg):
8256 """Add objective function to minimize."""
8257 return OptimizeObjective(
8258 self,
8259 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8260 is_max=False,
8261 )
8262
8263 def push(self):
8264 """create a backtracking point for added rules, facts and assertions"""
8265 Z3_optimize_push(self.ctx.ref(), self.optimize)
8266
8267 def pop(self):
8268 """restore to previously created backtracking point"""
8269 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8270
8271 def check(self, *assumptions):
8272 """Check consistency and produce optimal values."""
8273 assumptions = _get_args(assumptions)
8274 num = len(assumptions)
8275 _assumptions = (Ast * num)()
8276 for i in range(num):
8277 _assumptions[i] = assumptions[i].as_ast()
8278 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8279
8280 def reason_unknown(self):
8281 """Return a string that describes why the last `check()` returned `unknown`."""
8282 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8283
8284 def model(self):
8285 """Return a model for the last check()."""
8286 try:
8287 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8288 except Z3Exception:
8289 raise Z3Exception("model is not available")
8290
8291 def unsat_core(self):
8292 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8293
8294 def lower(self, obj):
8295 if not isinstance(obj, OptimizeObjective):
8296 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8297 return obj.lower()
8298
8299 def upper(self, obj):
8300 if not isinstance(obj, OptimizeObjective):
8301 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8302 return obj.upper()
8303
8304 def lower_values(self, obj):
8305 if not isinstance(obj, OptimizeObjective):
8306 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8307 return obj.lower_values()
8308
8309 def upper_values(self, obj):
8310 if not isinstance(obj, OptimizeObjective):
8311 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8312 return obj.upper_values()
8313
8314 def from_file(self, filename):
8315 """Parse assertions and objectives from a file"""
8316 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8317
8318 def from_string(self, s):
8319 """Parse assertions and objectives from a string"""
8320 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8321
8322 def assertions(self):
8323 """Return an AST vector containing all added constraints."""
8324 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8325
8326 def objectives(self):
8327 """returns set of objective functions"""
8328 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8329
8330 def __repr__(self):
8331 """Return a formatted string with all added rules and constraints."""
8332 return self.sexpr()
8333
8334 def sexpr(self):
8335 """Return a formatted string (in Lisp-like format) with all added constraints.
8336 We say the string is in s-expression format.
8337 """
8338 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8339
8340 def statistics(self):
8341 """Return statistics for the last check`.
8342 """
8343 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8344
8345 def set_on_model(self, on_model):
8346 """Register a callback that is invoked with every incremental improvement to
8347 objective values. The callback takes a model as argument.
8348 The life-time of the model is limited to the callback so the
8349 model has to be (deep) copied if it is to be used after the callback
8350 """
8351 id = len(_on_models) + 41
8352 mdl = Model(self.ctx)
8353 _on_models[id] = (on_model, mdl)
8354 self._on_models_id = id
8355 Z3_optimize_register_model_eh(
8356 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8357 )
8358
8359
8360#########################################
8361#
8362# ApplyResult
8363#
8364#########################################
8365class ApplyResult(Z3PPObject):
8366 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8367 It also contains model and proof converters.
8368 """
8369
8370 def __init__(self, result, ctx):
8371 self.result = result
8372 self.ctx = ctx
8373 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8374
8375 def __deepcopy__(self, memo={}):
8376 return ApplyResult(self.result, self.ctx)
8377
8378 def __del__(self):
8379 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8380 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8381
8382 def __len__(self):
8383 """Return the number of subgoals in `self`.
8384
8385 >>> a, b = Ints('a b')
8386 >>> g = Goal()
8387 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8388 >>> t = Tactic('split-clause')
8389 >>> r = t(g)
8390 >>> len(r)
8391 2
8392 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8393 >>> len(t(g))
8394 4
8395 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8396 >>> len(t(g))
8397 1
8398 """
8399 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8400
8401 def __getitem__(self, idx):
8402 """Return one of the subgoals stored in ApplyResult object `self`.
8403
8404 >>> a, b = Ints('a b')
8405 >>> g = Goal()
8406 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8407 >>> t = Tactic('split-clause')
8408 >>> r = t(g)
8409 >>> r[0]
8410 [a == 0, Or(b == 0, b == 1), a > b]
8411 >>> r[1]
8412 [a == 1, Or(b == 0, b == 1), a > b]
8413 """
8414 if idx >= len(self):
8415 raise IndexError
8416 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8417
8418 def __repr__(self):
8419 return obj_to_string(self)
8420
8421 def sexpr(self):
8422 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8423 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8424
8425 def as_expr(self):
8426 """Return a Z3 expression consisting of all subgoals.
8427
8428 >>> x = Int('x')
8429 >>> g = Goal()
8430 >>> g.add(x > 1)
8431 >>> g.add(Or(x == 2, x == 3))
8432 >>> r = Tactic('simplify')(g)
8433 >>> r
8434 [[Not(x <= 1), Or(x == 2, x == 3)]]
8435 >>> r.as_expr()
8436 And(Not(x <= 1), Or(x == 2, x == 3))
8437 >>> r = Tactic('split-clause')(g)
8438 >>> r
8439 [[x > 1, x == 2], [x > 1, x == 3]]
8440 >>> r.as_expr()
8441 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8442 """
8443 sz = len(self)
8444 if sz == 0:
8445 return BoolVal(False, self.ctx)
8446 elif sz == 1:
8447 return self[0].as_expr()
8448 else:
8449 return Or([self[i].as_expr() for i in range(len(self))])
8450
8451#########################################
8452#
8453# Simplifiers
8454#
8455#########################################
8456
8457class Simplifier:
8458 """Simplifiers act as pre-processing utilities for solvers.
8459 Build a custom simplifier and add it to a solver"""
8460
8461 def __init__(self, simplifier, ctx=None):
8462 self.ctx = _get_ctx(ctx)
8463 self.simplifier = None
8464 if isinstance(simplifier, SimplifierObj):
8465 self.simplifier = simplifier
8466 elif isinstance(simplifier, list):
8467 simps = [Simplifier(s, ctx) for s in simplifier]
8468 self.simplifier = simps[0].simplifier
8469 for i in range(1, len(simps)):
8470 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8471 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8472 return
8473 else:
8474 if z3_debug():
8475 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8476 try:
8477 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8478 except Z3Exception:
8479 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8480 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8481
8482 def __deepcopy__(self, memo={}):
8483 return Simplifier(self.simplifier, self.ctx)
8484
8485 def __del__(self):
8486 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8487 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8488
8489 def using_params(self, *args, **keys):
8490 """Return a simplifier that uses the given configuration options"""
8491 p = args2params(args, keys, self.ctx)
8492 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8493
8494 def add(self, solver):
8495 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8496 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8497
8498 def help(self):
8499 """Display a string containing a description of the available options for the `self` simplifier."""
8500 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8501
8502 def param_descrs(self):
8503 """Return the parameter description set."""
8504 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8505
8506
8507#########################################
8508#
8509# Tactics
8510#
8511#########################################
8512
8513
8514class Tactic:
8515 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8516 A Tactic can be converted into a Solver using the method solver().
8517
8518 Several combinators are available for creating new tactics using the built-in ones:
8519 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8520 """
8521
8522 def __init__(self, tactic, ctx=None):
8523 self.ctx = _get_ctx(ctx)
8524 self.tactic = None
8525 if isinstance(tactic, TacticObj):
8526 self.tactic = tactic
8527 else:
8528 if z3_debug():
8529 _z3_assert(isinstance(tactic, str), "tactic name expected")
8530 try:
8531 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8532 except Z3Exception:
8533 raise Z3Exception("unknown tactic '%s'" % tactic)
8534 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8535
8536 def __deepcopy__(self, memo={}):
8537 return Tactic(self.tactic, self.ctx)
8538
8539 def __del__(self):
8540 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8541 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8542
8543 def solver(self, logFile=None):
8544 """Create a solver using the tactic `self`.
8545
8546 The solver supports the methods `push()` and `pop()`, but it
8547 will always solve each `check()` from scratch.
8548
8549 >>> t = Then('simplify', 'nlsat')
8550 >>> s = t.solver()
8551 >>> x = Real('x')
8552 >>> s.add(x**2 == 2, x > 0)
8553 >>> s.check()
8554 sat
8555 >>> s.model()
8556 [x = 1.4142135623?]
8557 """
8558 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8559
8560 def apply(self, goal, *arguments, **keywords):
8561 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8562
8563 >>> x, y = Ints('x y')
8564 >>> t = Tactic('solve-eqs')
8565 >>> t.apply(And(x == 0, y >= x + 1))
8566 [[y >= 1]]
8567 """
8568 if z3_debug():
8569 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8570 goal = _to_goal(goal)
8571 if len(arguments) > 0 or len(keywords) > 0:
8572 p = args2params(arguments, keywords, self.ctx)
8573 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8574 else:
8575 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8576
8577 def __call__(self, goal, *arguments, **keywords):
8578 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8579
8580 >>> x, y = Ints('x y')
8581 >>> t = Tactic('solve-eqs')
8582 >>> t(And(x == 0, y >= x + 1))
8583 [[y >= 1]]
8584 """
8585 return self.apply(goal, *arguments, **keywords)
8586
8587 def help(self):
8588 """Display a string containing a description of the available options for the `self` tactic."""
8589 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8590
8591 def param_descrs(self):
8592 """Return the parameter description set."""
8593 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8594
8595
8596def _to_goal(a):
8597 if isinstance(a, BoolRef):
8598 goal = Goal(ctx=a.ctx)
8599 goal.add(a)
8600 return goal
8601 else:
8602 return a
8603
8604
8605def _to_tactic(t, ctx=None):
8606 if isinstance(t, Tactic):
8607 return t
8608 else:
8609 return Tactic(t, ctx)
8610
8611
8612def _and_then(t1, t2, ctx=None):
8613 t1 = _to_tactic(t1, ctx)
8614 t2 = _to_tactic(t2, ctx)
8615 if z3_debug():
8616 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8617 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8618
8619
8620def _or_else(t1, t2, ctx=None):
8621 t1 = _to_tactic(t1, ctx)
8622 t2 = _to_tactic(t2, ctx)
8623 if z3_debug():
8624 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8625 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8626
8627
8628def AndThen(*ts, **ks):
8629 """Return a tactic that applies the tactics in `*ts` in sequence.
8630
8631 >>> x, y = Ints('x y')
8632 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8633 >>> t(And(x == 0, y > x + 1))
8634 [[Not(y <= 1)]]
8635 >>> t(And(x == 0, y > x + 1)).as_expr()
8636 Not(y <= 1)
8637 """
8638 if z3_debug():
8639 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8640 ctx = ks.get("ctx", None)
8641 num = len(ts)
8642 r = ts[0]
8643 for i in range(num - 1):
8644 r = _and_then(r, ts[i + 1], ctx)
8645 return r
8646
8647
8648def Then(*ts, **ks):
8649 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8650
8651 >>> x, y = Ints('x y')
8652 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8653 >>> t(And(x == 0, y > x + 1))
8654 [[Not(y <= 1)]]
8655 >>> t(And(x == 0, y > x + 1)).as_expr()
8656 Not(y <= 1)
8657 """
8658 return AndThen(*ts, **ks)
8659
8660
8661def OrElse(*ts, **ks):
8662 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8663
8664 >>> x = Int('x')
8665 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8666 >>> # Tactic split-clause fails if there is no clause in the given goal.
8667 >>> t(x == 0)
8668 [[x == 0]]
8669 >>> t(Or(x == 0, x == 1))
8670 [[x == 0], [x == 1]]
8671 """
8672 if z3_debug():
8673 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8674 ctx = ks.get("ctx", None)
8675 num = len(ts)
8676 r = ts[0]
8677 for i in range(num - 1):
8678 r = _or_else(r, ts[i + 1], ctx)
8679 return r
8680
8681
8682def ParOr(*ts, **ks):
8683 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8684
8685 >>> x = Int('x')
8686 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8687 >>> t(x + 1 == 2)
8688 [[x == 1]]
8689 """
8690 if z3_debug():
8691 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8692 ctx = _get_ctx(ks.get("ctx", None))
8693 ts = [_to_tactic(t, ctx) for t in ts]
8694 sz = len(ts)
8695 _args = (TacticObj * sz)()
8696 for i in range(sz):
8697 _args[i] = ts[i].tactic
8698 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8699
8700
8701def ParThen(t1, t2, ctx=None):
8702 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8703 The subgoals are processed in parallel.
8704
8705 >>> x, y = Ints('x y')
8706 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8707 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8708 [[x == 1, y == 2], [x == 2, y == 3]]
8709 """
8710 t1 = _to_tactic(t1, ctx)
8711 t2 = _to_tactic(t2, ctx)
8712 if z3_debug():
8713 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8714 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8715
8716
8717def ParAndThen(t1, t2, ctx=None):
8718 """Alias for ParThen(t1, t2, ctx)."""
8719 return ParThen(t1, t2, ctx)
8720
8721
8722def With(t, *args, **keys):
8723 """Return a tactic that applies tactic `t` using the given configuration options.
8724
8725 >>> x, y = Ints('x y')
8726 >>> t = With(Tactic('simplify'), som=True)
8727 >>> t((x + 1)*(y + 2) == 0)
8728 [[2*x + y + x*y == -2]]
8729 """
8730 ctx = keys.pop("ctx", None)
8731 t = _to_tactic(t, ctx)
8732 p = args2params(args, keys, t.ctx)
8733 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8734
8735
8736def WithParams(t, p):
8737 """Return a tactic that applies tactic `t` using the given configuration options.
8738
8739 >>> x, y = Ints('x y')
8740 >>> p = ParamsRef()
8741 >>> p.set("som", True)
8742 >>> t = WithParams(Tactic('simplify'), p)
8743 >>> t((x + 1)*(y + 2) == 0)
8744 [[2*x + y + x*y == -2]]
8745 """
8746 t = _to_tactic(t, None)
8747 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8748
8749
8750def Repeat(t, max=4294967295, ctx=None):
8751 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8752 or the maximum number of iterations `max` is reached.
8753
8754 >>> x, y = Ints('x y')
8755 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8756 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8757 >>> r = t(c)
8758 >>> for subgoal in r: print(subgoal)
8759 [x == 0, y == 0, x > y]
8760 [x == 0, y == 1, x > y]
8761 [x == 1, y == 0, x > y]
8762 [x == 1, y == 1, x > y]
8763 >>> t = Then(t, Tactic('propagate-values'))
8764 >>> t(c)
8765 [[x == 1, y == 0]]
8766 """
8767 t = _to_tactic(t, ctx)
8768 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8769
8770
8771def TryFor(t, ms, ctx=None):
8772 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8773
8774 If `t` does not terminate in `ms` milliseconds, then it fails.
8775 """
8776 t = _to_tactic(t, ctx)
8777 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8778
8779
8780def tactics(ctx=None):
8781 """Return a list of all available tactics in Z3.
8782
8783 >>> l = tactics()
8784 >>> l.count('simplify') == 1
8785 True
8786 """
8787 ctx = _get_ctx(ctx)
8788 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8789
8790
8791def tactic_description(name, ctx=None):
8792 """Return a short description for the tactic named `name`.
8793
8794 >>> d = tactic_description('simplify')
8795 """
8796 ctx = _get_ctx(ctx)
8797 return Z3_tactic_get_descr(ctx.ref(), name)
8798
8799
8800def describe_tactics():
8801 """Display a (tabular) description of all available tactics in Z3."""
8802 if in_html_mode():
8803 even = True
8804 print('<table border="1" cellpadding="2" cellspacing="0">')
8805 for t in tactics():
8806 if even:
8807 print('<tr style="background-color:#CFCFCF">')
8808 even = False
8809 else:
8810 print("<tr>")
8811 even = True
8812 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8813 print("</table>")
8814 else:
8815 for t in tactics():
8816 print("%s : %s" % (t, tactic_description(t)))
8817
8818
8819class Probe:
8820 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8821 to decide which solver and/or preprocessing step will be used.
8822 """
8823
8824 def __init__(self, probe, ctx=None):
8825 self.ctx = _get_ctx(ctx)
8826 self.probe = None
8827 if isinstance(probe, ProbeObj):
8828 self.probe = probe
8829 elif isinstance(probe, float):
8830 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8831 elif _is_int(probe):
8832 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8833 elif isinstance(probe, bool):
8834 if probe:
8835 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8836 else:
8837 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8838 else:
8839 if z3_debug():
8840 _z3_assert(isinstance(probe, str), "probe name expected")
8841 try:
8842 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8843 except Z3Exception:
8844 raise Z3Exception("unknown probe '%s'" % probe)
8845 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8846
8847 def __deepcopy__(self, memo={}):
8848 return Probe(self.probe, self.ctx)
8849
8850 def __del__(self):
8851 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8852 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8853
8854 def __lt__(self, other):
8855 """Return a probe that evaluates to "true" when the value returned by `self`
8856 is less than the value returned by `other`.
8857
8858 >>> p = Probe('size') < 10
8859 >>> x = Int('x')
8860 >>> g = Goal()
8861 >>> g.add(x > 0)
8862 >>> g.add(x < 10)
8863 >>> p(g)
8864 1.0
8865 """
8866 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8867
8868 def __gt__(self, other):
8869 """Return a probe that evaluates to "true" when the value returned by `self`
8870 is greater than the value returned by `other`.
8871
8872 >>> p = Probe('size') > 10
8873 >>> x = Int('x')
8874 >>> g = Goal()
8875 >>> g.add(x > 0)
8876 >>> g.add(x < 10)
8877 >>> p(g)
8878 0.0
8879 """
8880 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8881
8882 def __le__(self, other):
8883 """Return a probe that evaluates to "true" when the value returned by `self`
8884 is less than or equal to the value returned by `other`.
8885
8886 >>> p = Probe('size') <= 2
8887 >>> x = Int('x')
8888 >>> g = Goal()
8889 >>> g.add(x > 0)
8890 >>> g.add(x < 10)
8891 >>> p(g)
8892 1.0
8893 """
8894 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8895
8896 def __ge__(self, other):
8897 """Return a probe that evaluates to "true" when the value returned by `self`
8898 is greater than or equal to the value returned by `other`.
8899
8900 >>> p = Probe('size') >= 2
8901 >>> x = Int('x')
8902 >>> g = Goal()
8903 >>> g.add(x > 0)
8904 >>> g.add(x < 10)
8905 >>> p(g)
8906 1.0
8907 """
8908 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8909
8910 def __eq__(self, other):
8911 """Return a probe that evaluates to "true" when the value returned by `self`
8912 is equal to the value returned by `other`.
8913
8914 >>> p = Probe('size') == 2
8915 >>> x = Int('x')
8916 >>> g = Goal()
8917 >>> g.add(x > 0)
8918 >>> g.add(x < 10)
8919 >>> p(g)
8920 1.0
8921 """
8922 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8923
8924 def __ne__(self, other):
8925 """Return a probe that evaluates to "true" when the value returned by `self`
8926 is not equal to the value returned by `other`.
8927
8928 >>> p = Probe('size') != 2
8929 >>> x = Int('x')
8930 >>> g = Goal()
8931 >>> g.add(x > 0)
8932 >>> g.add(x < 10)
8933 >>> p(g)
8934 0.0
8935 """
8936 p = self.__eq__(other)
8937 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8938
8939 def __call__(self, goal):
8940 """Evaluate the probe `self` in the given goal.
8941
8942 >>> p = Probe('size')
8943 >>> x = Int('x')
8944 >>> g = Goal()
8945 >>> g.add(x > 0)
8946 >>> g.add(x < 10)
8947 >>> p(g)
8948 2.0
8949 >>> g.add(x < 20)
8950 >>> p(g)
8951 3.0
8952 >>> p = Probe('num-consts')
8953 >>> p(g)
8954 1.0
8955 >>> p = Probe('is-propositional')
8956 >>> p(g)
8957 0.0
8958 >>> p = Probe('is-qflia')
8959 >>> p(g)
8960 1.0
8961 """
8962 if z3_debug():
8963 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8964 goal = _to_goal(goal)
8965 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8966
8967
8968def is_probe(p):
8969 """Return `True` if `p` is a Z3 probe.
8970
8971 >>> is_probe(Int('x'))
8972 False
8973 >>> is_probe(Probe('memory'))
8974 True
8975 """
8976 return isinstance(p, Probe)
8977
8978
8979def _to_probe(p, ctx=None):
8980 if is_probe(p):
8981 return p
8982 else:
8983 return Probe(p, ctx)
8984
8985
8986def probes(ctx=None):
8987 """Return a list of all available probes in Z3.
8988
8989 >>> l = probes()
8990 >>> l.count('memory') == 1
8991 True
8992 """
8993 ctx = _get_ctx(ctx)
8994 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8995
8996
8997def probe_description(name, ctx=None):
8998 """Return a short description for the probe named `name`.
8999
9000 >>> d = probe_description('memory')
9001 """
9002 ctx = _get_ctx(ctx)
9003 return Z3_probe_get_descr(ctx.ref(), name)
9004
9005
9006def describe_probes():
9007 """Display a (tabular) description of all available probes in Z3."""
9008 if in_html_mode():
9009 even = True
9010 print('<table border="1" cellpadding="2" cellspacing="0">')
9011 for p in probes():
9012 if even:
9013 print('<tr style="background-color:#CFCFCF">')
9014 even = False
9015 else:
9016 print("<tr>")
9017 even = True
9018 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
9019 print("</table>")
9020 else:
9021 for p in probes():
9022 print("%s : %s" % (p, probe_description(p)))
9023
9024
9025def _probe_nary(f, args, ctx):
9026 if z3_debug():
9027 _z3_assert(len(args) > 0, "At least one argument expected")
9028 num = len(args)
9029 r = _to_probe(args[0], ctx)
9030 for i in range(num - 1):
9031 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
9032 return r
9033
9034
9035def _probe_and(args, ctx):
9036 return _probe_nary(Z3_probe_and, args, ctx)
9037
9038
9039def _probe_or(args, ctx):
9040 return _probe_nary(Z3_probe_or, args, ctx)
9041
9042
9043def FailIf(p, ctx=None):
9044 """Return a tactic that fails if the probe `p` evaluates to true.
9045 Otherwise, it returns the input goal unmodified.
9046
9047 In the following example, the tactic applies 'simplify' if and only if there are
9048 more than 2 constraints in the goal.
9049
9050 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
9051 >>> x, y = Ints('x y')
9052 >>> g = Goal()
9053 >>> g.add(x > 0)
9054 >>> g.add(y > 0)
9055 >>> t(g)
9056 [[x > 0, y > 0]]
9057 >>> g.add(x == y + 1)
9058 >>> t(g)
9059 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9060 """
9061 p = _to_probe(p, ctx)
9062 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
9063
9064
9065def When(p, t, ctx=None):
9066 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
9067 Otherwise, it returns the input goal unmodified.
9068
9069 >>> t = When(Probe('size') > 2, Tactic('simplify'))
9070 >>> x, y = Ints('x y')
9071 >>> g = Goal()
9072 >>> g.add(x > 0)
9073 >>> g.add(y > 0)
9074 >>> t(g)
9075 [[x > 0, y > 0]]
9076 >>> g.add(x == y + 1)
9077 >>> t(g)
9078 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9079 """
9080 p = _to_probe(p, ctx)
9081 t = _to_tactic(t, ctx)
9082 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
9083
9084
9085def Cond(p, t1, t2, ctx=None):
9086 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
9087
9088 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
9089 """
9090 p = _to_probe(p, ctx)
9091 t1 = _to_tactic(t1, ctx)
9092 t2 = _to_tactic(t2, ctx)
9093 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
9094
9095#########################################
9096#
9097# Utils
9098#
9099#########################################
9100
9101
9102def simplify(a, *arguments, **keywords):
9103 """Simplify the expression `a` using the given options.
9104
9105 This function has many options. Use `help_simplify` to obtain the complete list.
9106
9107 >>> x = Int('x')
9108 >>> y = Int('y')
9109 >>> simplify(x + 1 + y + x + 1)
9110 2 + 2*x + y
9111 >>> simplify((x + 1)*(y + 1), som=True)
9112 1 + x + y + x*y
9113 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9114 And(Not(x == y), Not(x == 1), Not(y == 1))
9115 >>> simplify(And(x == 0, y == 1), elim_and=True)
9116 Not(Or(Not(x == 0), Not(y == 1)))
9117 """
9118 if z3_debug():
9119 _z3_assert(is_expr(a), "Z3 expression expected")
9120 if len(arguments) > 0 or len(keywords) > 0:
9121 p = args2params(arguments, keywords, a.ctx)
9122 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9123 else:
9124 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9125
9126
9127def help_simplify():
9128 """Return a string describing all options available for Z3 `simplify` procedure."""
9129 print(Z3_simplify_get_help(main_ctx().ref()))
9130
9131
9132def simplify_param_descrs():
9133 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9134 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9135
9136
9137def substitute(t, *m):
9138 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9139 Every occurrence in t of from is replaced with to.
9140
9141 >>> x = Int('x')
9142 >>> y = Int('y')
9143 >>> substitute(x + 1, (x, y + 1))
9144 y + 1 + 1
9145 >>> f = Function('f', IntSort(), IntSort())
9146 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9147 1 + 1
9148 """
9149 if isinstance(m, tuple):
9150 m1 = _get_args(m)
9151 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9152 m = m1
9153 if z3_debug():
9154 _z3_assert(is_expr(t), "Z3 expression expected")
9155 _z3_assert(
9156 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9157 "Z3 invalid substitution, expression pairs expected.")
9158 _z3_assert(
9159 all([p[0].sort().eq(p[1].sort()) for p in m]),
9160 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9161 num = len(m)
9162 _from = (Ast * num)()
9163 _to = (Ast * num)()
9164 for i in range(num):
9165 _from[i] = m[i][0].as_ast()
9166 _to[i] = m[i][1].as_ast()
9167 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9168
9169
9170def substitute_vars(t, *m):
9171 """Substitute the free variables in t with the expression in m.
9172
9173 >>> v0 = Var(0, IntSort())
9174 >>> v1 = Var(1, IntSort())
9175 >>> x = Int('x')
9176 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9177 >>> # replace v0 with x+1 and v1 with x
9178 >>> substitute_vars(f(v0, v1), x + 1, x)
9179 f(x + 1, x)
9180 """
9181 if z3_debug():
9182 _z3_assert(is_expr(t), "Z3 expression expected")
9183 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9184 num = len(m)
9185 _to = (Ast * num)()
9186 for i in range(num):
9187 _to[i] = m[i].as_ast()
9188 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9189
9190def substitute_funs(t, *m):
9191 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9192 Every occurrence in to of the function from is replaced with the expression to.
9193 The expression to can have free variables, that refer to the arguments of from.
9194 For examples, see
9195 """
9196 if isinstance(m, tuple):
9197 m1 = _get_args(m)
9198 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9199 m = m1
9200 if z3_debug():
9201 _z3_assert(is_expr(t), "Z3 expression expected")
9202 _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.")
9203 num = len(m)
9204 _from = (FuncDecl * num)()
9205 _to = (Ast * num)()
9206 for i in range(num):
9207 _from[i] = m[i][0].as_func_decl()
9208 _to[i] = m[i][1].as_ast()
9209 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9210
9211
9212def Sum(*args):
9213 """Create the sum of the Z3 expressions.
9214
9215 >>> a, b, c = Ints('a b c')
9216 >>> Sum(a, b, c)
9217 a + b + c
9218 >>> Sum([a, b, c])
9219 a + b + c
9220 >>> A = IntVector('a', 5)
9221 >>> Sum(A)
9222 a__0 + a__1 + a__2 + a__3 + a__4
9223 """
9224 args = _get_args(args)
9225 if len(args) == 0:
9226 return 0
9227 ctx = _ctx_from_ast_arg_list(args)
9228 if ctx is None:
9229 return _reduce(lambda a, b: a + b, args, 0)
9230 args = _coerce_expr_list(args, ctx)
9231 if is_bv(args[0]):
9232 return _reduce(lambda a, b: a + b, args, 0)
9233 else:
9234 _args, sz = _to_ast_array(args)
9235 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9236
9237
9238def Product(*args):
9239 """Create the product of the Z3 expressions.
9240
9241 >>> a, b, c = Ints('a b c')
9242 >>> Product(a, b, c)
9243 a*b*c
9244 >>> Product([a, b, c])
9245 a*b*c
9246 >>> A = IntVector('a', 5)
9247 >>> Product(A)
9248 a__0*a__1*a__2*a__3*a__4
9249 """
9250 args = _get_args(args)
9251 if len(args) == 0:
9252 return 1
9253 ctx = _ctx_from_ast_arg_list(args)
9254 if ctx is None:
9255 return _reduce(lambda a, b: a * b, args, 1)
9256 args = _coerce_expr_list(args, ctx)
9257 if is_bv(args[0]):
9258 return _reduce(lambda a, b: a * b, args, 1)
9259 else:
9260 _args, sz = _to_ast_array(args)
9261 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9262
9263def Abs(arg):
9264 """Create the absolute value of an arithmetic expression"""
9265 return If(arg > 0, arg, -arg)
9266
9267
9268def AtMost(*args):
9269 """Create an at-most Pseudo-Boolean k constraint.
9270
9271 >>> a, b, c = Bools('a b c')
9272 >>> f = AtMost(a, b, c, 2)
9273 """
9274 args = _get_args(args)
9275 if z3_debug():
9276 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9277 ctx = _ctx_from_ast_arg_list(args)
9278 if z3_debug():
9279 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9280 args1 = _coerce_expr_list(args[:-1], ctx)
9281 k = args[-1]
9282 _args, sz = _to_ast_array(args1)
9283 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9284
9285
9286def AtLeast(*args):
9287 """Create an at-least Pseudo-Boolean k constraint.
9288
9289 >>> a, b, c = Bools('a b c')
9290 >>> f = AtLeast(a, b, c, 2)
9291 """
9292 args = _get_args(args)
9293 if z3_debug():
9294 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9295 ctx = _ctx_from_ast_arg_list(args)
9296 if z3_debug():
9297 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9298 args1 = _coerce_expr_list(args[:-1], ctx)
9299 k = args[-1]
9300 _args, sz = _to_ast_array(args1)
9301 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9302
9303
9304def _reorder_pb_arg(arg):
9305 a, b = arg
9306 if not _is_int(b) and _is_int(a):
9307 return b, a
9308 return arg
9309
9310
9311def _pb_args_coeffs(args, default_ctx=None):
9312 args = _get_args_ast_list(args)
9313 if len(args) == 0:
9314 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9315 args = [_reorder_pb_arg(arg) for arg in args]
9316 args, coeffs = zip(*args)
9317 if z3_debug():
9318 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9319 ctx = _ctx_from_ast_arg_list(args)
9320 if z3_debug():
9321 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9322 args = _coerce_expr_list(args, ctx)
9323 _args, sz = _to_ast_array(args)
9324 _coeffs = (ctypes.c_int * len(coeffs))()
9325 for i in range(len(coeffs)):
9326 _z3_check_cint_overflow(coeffs[i], "coefficient")
9327 _coeffs[i] = coeffs[i]
9328 return ctx, sz, _args, _coeffs, args
9329
9330
9331def PbLe(args, k):
9332 """Create a Pseudo-Boolean inequality k constraint.
9333
9334 >>> a, b, c = Bools('a b c')
9335 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9336 """
9337 _z3_check_cint_overflow(k, "k")
9338 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9339 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9340
9341
9342def PbGe(args, k):
9343 """Create a Pseudo-Boolean inequality k constraint.
9344
9345 >>> a, b, c = Bools('a b c')
9346 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9347 """
9348 _z3_check_cint_overflow(k, "k")
9349 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9350 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9351
9352
9353def PbEq(args, k, ctx=None):
9354 """Create a Pseudo-Boolean equality k constraint.
9355
9356 >>> a, b, c = Bools('a b c')
9357 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9358 """
9359 _z3_check_cint_overflow(k, "k")
9360 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9361 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9362
9363
9364def solve(*args, **keywords):
9365 """Solve the constraints `*args`.
9366
9367 This is a simple function for creating demonstrations. It creates a solver,
9368 configure it using the options in `keywords`, adds the constraints
9369 in `args`, and invokes check.
9370
9371 >>> a = Int('a')
9372 >>> solve(a > 0, a < 2)
9373 [a = 1]
9374 """
9375 show = keywords.pop("show", False)
9376 s = Solver()
9377 s.set(**keywords)
9378 s.add(*args)
9379 if show:
9380 print(s)
9381 r = s.check()
9382 if r == unsat:
9383 print("no solution")
9384 elif r == unknown:
9385 print("failed to solve")
9386 try:
9387 print(s.model())
9388 except Z3Exception:
9389 return
9390 else:
9391 print(s.model())
9392
9393
9394def solve_using(s, *args, **keywords):
9395 """Solve the constraints `*args` using solver `s`.
9396
9397 This is a simple function for creating demonstrations. It is similar to `solve`,
9398 but it uses the given solver `s`.
9399 It configures solver `s` using the options in `keywords`, adds the constraints
9400 in `args`, and invokes check.
9401 """
9402 show = keywords.pop("show", False)
9403 if z3_debug():
9404 _z3_assert(isinstance(s, Solver), "Solver object expected")
9405 s.set(**keywords)
9406 s.add(*args)
9407 if show:
9408 print("Problem:")
9409 print(s)
9410 r = s.check()
9411 if r == unsat:
9412 print("no solution")
9413 elif r == unknown:
9414 print("failed to solve")
9415 try:
9416 print(s.model())
9417 except Z3Exception:
9418 return
9419 else:
9420 if show:
9421 print("Solution:")
9422 print(s.model())
9423
9424
9425def prove(claim, show=False, **keywords):
9426 """Try to prove the given claim.
9427
9428 This is a simple function for creating demonstrations. It tries to prove
9429 `claim` by showing the negation is unsatisfiable.
9430
9431 >>> p, q = Bools('p q')
9432 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9433 proved
9434 """
9435 if z3_debug():
9436 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9437 s = Solver()
9438 s.set(**keywords)
9439 s.add(Not(claim))
9440 if show:
9441 print(s)
9442 r = s.check()
9443 if r == unsat:
9444 print("proved")
9445 elif r == unknown:
9446 print("failed to prove")
9447 print(s.model())
9448 else:
9449 print("counterexample")
9450 print(s.model())
9451
9452
9453def _solve_html(*args, **keywords):
9454 """Version of function `solve` that renders HTML output."""
9455 show = keywords.pop("show", False)
9456 s = Solver()
9457 s.set(**keywords)
9458 s.add(*args)
9459 if show:
9460 print("<b>Problem:</b>")
9461 print(s)
9462 r = s.check()
9463 if r == unsat:
9464 print("<b>no solution</b>")
9465 elif r == unknown:
9466 print("<b>failed to solve</b>")
9467 try:
9468 print(s.model())
9469 except Z3Exception:
9470 return
9471 else:
9472 if show:
9473 print("<b>Solution:</b>")
9474 print(s.model())
9475
9476
9477def _solve_using_html(s, *args, **keywords):
9478 """Version of function `solve_using` that renders HTML."""
9479 show = keywords.pop("show", False)
9480 if z3_debug():
9481 _z3_assert(isinstance(s, Solver), "Solver object expected")
9482 s.set(**keywords)
9483 s.add(*args)
9484 if show:
9485 print("<b>Problem:</b>")
9486 print(s)
9487 r = s.check()
9488 if r == unsat:
9489 print("<b>no solution</b>")
9490 elif r == unknown:
9491 print("<b>failed to solve</b>")
9492 try:
9493 print(s.model())
9494 except Z3Exception:
9495 return
9496 else:
9497 if show:
9498 print("<b>Solution:</b>")
9499 print(s.model())
9500
9501
9502def _prove_html(claim, show=False, **keywords):
9503 """Version of function `prove` that renders HTML."""
9504 if z3_debug():
9505 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9506 s = Solver()
9507 s.set(**keywords)
9508 s.add(Not(claim))
9509 if show:
9510 print(s)
9511 r = s.check()
9512 if r == unsat:
9513 print("<b>proved</b>")
9514 elif r == unknown:
9515 print("<b>failed to prove</b>")
9516 print(s.model())
9517 else:
9518 print("<b>counterexample</b>")
9519 print(s.model())
9520
9521
9522def _dict2sarray(sorts, ctx):
9523 sz = len(sorts)
9524 _names = (Symbol * sz)()
9525 _sorts = (Sort * sz)()
9526 i = 0
9527 for k in sorts:
9528 v = sorts[k]
9529 if z3_debug():
9530 _z3_assert(isinstance(k, str), "String expected")
9531 _z3_assert(is_sort(v), "Z3 sort expected")
9532 _names[i] = to_symbol(k, ctx)
9533 _sorts[i] = v.ast
9534 i = i + 1
9535 return sz, _names, _sorts
9536
9537
9538def _dict2darray(decls, ctx):
9539 sz = len(decls)
9540 _names = (Symbol * sz)()
9541 _decls = (FuncDecl * sz)()
9542 i = 0
9543 for k in decls:
9544 v = decls[k]
9545 if z3_debug():
9546 _z3_assert(isinstance(k, str), "String expected")
9547 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9548 _names[i] = to_symbol(k, ctx)
9549 if is_const(v):
9550 _decls[i] = v.decl().ast
9551 else:
9552 _decls[i] = v.ast
9553 i = i + 1
9554 return sz, _names, _decls
9555
9556class ParserContext:
9557 def __init__(self, ctx= None):
9558 self.ctx = _get_ctx(ctx)
9559 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9560 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9561
9562 def __del__(self):
9563 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9564 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9565 self.pctx = None
9566
9567 def add_sort(self, sort):
9568 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9569
9570 def add_decl(self, decl):
9571 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9572
9573 def from_string(self, s):
9574 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9575
9576def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9577 """Parse a string in SMT 2.0 format using the given sorts and decls.
9578
9579 The arguments sorts and decls are Python dictionaries used to initialize
9580 the symbol table used for the SMT 2.0 parser.
9581
9582 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9583 [x > 0, x < 10]
9584 >>> x, y = Ints('x y')
9585 >>> f = Function('f', IntSort(), IntSort())
9586 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9587 [x + f(y) > 0]
9588 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9589 [a > 0]
9590 """
9591 ctx = _get_ctx(ctx)
9592 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9593 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9594 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9595
9596
9597def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9598 """Parse a file in SMT 2.0 format using the given sorts and decls.
9599
9600 This function is similar to parse_smt2_string().
9601 """
9602 ctx = _get_ctx(ctx)
9603 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9604 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9605 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9606
9607
9608#########################################
9609#
9610# Floating-Point Arithmetic
9611#
9612#########################################
9613
9614
9615# Global default rounding mode
9616_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9617_dflt_fpsort_ebits = 11
9618_dflt_fpsort_sbits = 53
9619
9620
9621def get_default_rounding_mode(ctx=None):
9622 """Retrieves the global default rounding mode."""
9623 global _dflt_rounding_mode
9624 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9625 return RTZ(ctx)
9626 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9627 return RTN(ctx)
9628 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9629 return RTP(ctx)
9630 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9631 return RNE(ctx)
9632 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9633 return RNA(ctx)
9634
9635
9636_ROUNDING_MODES = frozenset({
9637 Z3_OP_FPA_RM_TOWARD_ZERO,
9638 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9639 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9640 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9641 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9642})
9643
9644
9645def set_default_rounding_mode(rm, ctx=None):
9646 global _dflt_rounding_mode
9647 if is_fprm_value(rm):
9648 _dflt_rounding_mode = rm.kind()
9649 else:
9650 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9651 _dflt_rounding_mode = rm
9652
9653
9654def get_default_fp_sort(ctx=None):
9655 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9656
9657
9658def set_default_fp_sort(ebits, sbits, ctx=None):
9659 global _dflt_fpsort_ebits
9660 global _dflt_fpsort_sbits
9661 _dflt_fpsort_ebits = ebits
9662 _dflt_fpsort_sbits = sbits
9663
9664
9665def _dflt_rm(ctx=None):
9666 return get_default_rounding_mode(ctx)
9667
9668
9669def _dflt_fps(ctx=None):
9670 return get_default_fp_sort(ctx)
9671
9672
9673def _coerce_fp_expr_list(alist, ctx):
9674 first_fp_sort = None
9675 for a in alist:
9676 if is_fp(a):
9677 if first_fp_sort is None:
9678 first_fp_sort = a.sort()
9679 elif first_fp_sort == a.sort():
9680 pass # OK, same as before
9681 else:
9682 # we saw at least 2 different float sorts; something will
9683 # throw a sort mismatch later, for now assume None.
9684 first_fp_sort = None
9685 break
9686
9687 r = []
9688 for i in range(len(alist)):
9689 a = alist[i]
9690 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9691 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9692 r.append(FPVal(a, None, first_fp_sort, ctx))
9693 else:
9694 r.append(a)
9695 return _coerce_expr_list(r, ctx)
9696
9697
9698# FP Sorts
9699
9700class FPSortRef(SortRef):
9701 """Floating-point sort."""
9702
9703 def ebits(self):
9704 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9705 >>> b = FPSort(8, 24)
9706 >>> b.ebits()
9707 8
9708 """
9709 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9710
9711 def sbits(self):
9712 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9713 >>> b = FPSort(8, 24)
9714 >>> b.sbits()
9715 24
9716 """
9717 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9718
9719 def cast(self, val):
9720 """Try to cast `val` as a floating-point expression.
9721 >>> b = FPSort(8, 24)
9722 >>> b.cast(1.0)
9723 1
9724 >>> b.cast(1.0).sexpr()
9725 '(fp #b0 #x7f #b00000000000000000000000)'
9726 """
9727 if is_expr(val):
9728 if z3_debug():
9729 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9730 return val
9731 else:
9732 return FPVal(val, None, self, self.ctx)
9733
9734
9735def Float16(ctx=None):
9736 """Floating-point 16-bit (half) sort."""
9737 ctx = _get_ctx(ctx)
9738 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9739
9740
9741def FloatHalf(ctx=None):
9742 """Floating-point 16-bit (half) sort."""
9743 ctx = _get_ctx(ctx)
9744 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9745
9746
9747def Float32(ctx=None):
9748 """Floating-point 32-bit (single) sort."""
9749 ctx = _get_ctx(ctx)
9750 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9751
9752
9753def FloatSingle(ctx=None):
9754 """Floating-point 32-bit (single) sort."""
9755 ctx = _get_ctx(ctx)
9756 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9757
9758
9759def Float64(ctx=None):
9760 """Floating-point 64-bit (double) sort."""
9761 ctx = _get_ctx(ctx)
9762 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9763
9764
9765def FloatDouble(ctx=None):
9766 """Floating-point 64-bit (double) sort."""
9767 ctx = _get_ctx(ctx)
9768 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9769
9770
9771def Float128(ctx=None):
9772 """Floating-point 128-bit (quadruple) sort."""
9773 ctx = _get_ctx(ctx)
9774 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9775
9776
9777def FloatQuadruple(ctx=None):
9778 """Floating-point 128-bit (quadruple) sort."""
9779 ctx = _get_ctx(ctx)
9780 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9781
9782
9783class FPRMSortRef(SortRef):
9784 """"Floating-point rounding mode sort."""
9785
9786
9787def is_fp_sort(s):
9788 """Return True if `s` is a Z3 floating-point sort.
9789
9790 >>> is_fp_sort(FPSort(8, 24))
9791 True
9792 >>> is_fp_sort(IntSort())
9793 False
9794 """
9795 return isinstance(s, FPSortRef)
9796
9797
9798def is_fprm_sort(s):
9799 """Return True if `s` is a Z3 floating-point rounding mode sort.
9800
9801 >>> is_fprm_sort(FPSort(8, 24))
9802 False
9803 >>> is_fprm_sort(RNE().sort())
9804 True
9805 """
9806 return isinstance(s, FPRMSortRef)
9807
9808# FP Expressions
9809
9810
9811class FPRef(ExprRef):
9812 """Floating-point expressions."""
9813
9814 def sort(self):
9815 """Return the sort of the floating-point expression `self`.
9816
9817 >>> x = FP('1.0', FPSort(8, 24))
9818 >>> x.sort()
9819 FPSort(8, 24)
9820 >>> x.sort() == FPSort(8, 24)
9821 True
9822 """
9823 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9824
9825 def ebits(self):
9826 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9827 >>> b = FPSort(8, 24)
9828 >>> b.ebits()
9829 8
9830 """
9831 return self.sort().ebits()
9832
9833 def sbits(self):
9834 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9835 >>> b = FPSort(8, 24)
9836 >>> b.sbits()
9837 24
9838 """
9839 return self.sort().sbits()
9840
9841 def as_string(self):
9842 """Return a Z3 floating point expression as a Python string."""
9843 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9844
9845 def __le__(self, other):
9846 return fpLEQ(self, other, self.ctx)
9847
9848 def __lt__(self, other):
9849 return fpLT(self, other, self.ctx)
9850
9851 def __ge__(self, other):
9852 return fpGEQ(self, other, self.ctx)
9853
9854 def __gt__(self, other):
9855 return fpGT(self, other, self.ctx)
9856
9857 def __add__(self, other):
9858 """Create the Z3 expression `self + other`.
9859
9860 >>> x = FP('x', FPSort(8, 24))
9861 >>> y = FP('y', FPSort(8, 24))
9862 >>> x + y
9863 x + y
9864 >>> (x + y).sort()
9865 FPSort(8, 24)
9866 """
9867 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9868 return fpAdd(_dflt_rm(), a, b, self.ctx)
9869
9870 def __radd__(self, other):
9871 """Create the Z3 expression `other + self`.
9872
9873 >>> x = FP('x', FPSort(8, 24))
9874 >>> 10 + x
9875 1.25*(2**3) + x
9876 """
9877 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9878 return fpAdd(_dflt_rm(), a, b, self.ctx)
9879
9880 def __sub__(self, other):
9881 """Create the Z3 expression `self - other`.
9882
9883 >>> x = FP('x', FPSort(8, 24))
9884 >>> y = FP('y', FPSort(8, 24))
9885 >>> x - y
9886 x - y
9887 >>> (x - y).sort()
9888 FPSort(8, 24)
9889 """
9890 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9891 return fpSub(_dflt_rm(), a, b, self.ctx)
9892
9893 def __rsub__(self, other):
9894 """Create the Z3 expression `other - self`.
9895
9896 >>> x = FP('x', FPSort(8, 24))
9897 >>> 10 - x
9898 1.25*(2**3) - x
9899 """
9900 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9901 return fpSub(_dflt_rm(), a, b, self.ctx)
9902
9903 def __mul__(self, other):
9904 """Create the Z3 expression `self * other`.
9905
9906 >>> x = FP('x', FPSort(8, 24))
9907 >>> y = FP('y', FPSort(8, 24))
9908 >>> x * y
9909 x * y
9910 >>> (x * y).sort()
9911 FPSort(8, 24)
9912 >>> 10 * y
9913 1.25*(2**3) * y
9914 """
9915 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9916 return fpMul(_dflt_rm(), a, b, self.ctx)
9917
9918 def __rmul__(self, other):
9919 """Create the Z3 expression `other * self`.
9920
9921 >>> x = FP('x', FPSort(8, 24))
9922 >>> y = FP('y', FPSort(8, 24))
9923 >>> x * y
9924 x * y
9925 >>> x * 10
9926 x * 1.25*(2**3)
9927 """
9928 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9929 return fpMul(_dflt_rm(), a, b, self.ctx)
9930
9931 def __pos__(self):
9932 """Create the Z3 expression `+self`."""
9933 return self
9934
9935 def __neg__(self):
9936 """Create the Z3 expression `-self`.
9937
9938 >>> x = FP('x', Float32())
9939 >>> -x
9940 -x
9941 """
9942 return fpNeg(self)
9943
9944 def __div__(self, other):
9945 """Create the Z3 expression `self / other`.
9946
9947 >>> x = FP('x', FPSort(8, 24))
9948 >>> y = FP('y', FPSort(8, 24))
9949 >>> x / y
9950 x / y
9951 >>> (x / y).sort()
9952 FPSort(8, 24)
9953 >>> 10 / y
9954 1.25*(2**3) / y
9955 """
9956 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9957 return fpDiv(_dflt_rm(), a, b, self.ctx)
9958
9959 def __rdiv__(self, other):
9960 """Create the Z3 expression `other / self`.
9961
9962 >>> x = FP('x', FPSort(8, 24))
9963 >>> y = FP('y', FPSort(8, 24))
9964 >>> x / y
9965 x / y
9966 >>> x / 10
9967 x / 1.25*(2**3)
9968 """
9969 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9970 return fpDiv(_dflt_rm(), a, b, self.ctx)
9971
9972 def __truediv__(self, other):
9973 """Create the Z3 expression division `self / other`."""
9974 return self.__div__(other)
9975
9976 def __rtruediv__(self, other):
9977 """Create the Z3 expression division `other / self`."""
9978 return self.__rdiv__(other)
9979
9980 def __mod__(self, other):
9981 """Create the Z3 expression mod `self % other`."""
9982 return fpRem(self, other)
9983
9984 def __rmod__(self, other):
9985 """Create the Z3 expression mod `other % self`."""
9986 return fpRem(other, self)
9987
9988
9989class FPRMRef(ExprRef):
9990 """Floating-point rounding mode expressions"""
9991
9992 def as_string(self):
9993 """Return a Z3 floating point expression as a Python string."""
9994 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9995
9996
9997def RoundNearestTiesToEven(ctx=None):
9998 ctx = _get_ctx(ctx)
9999 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10000
10001
10002def RNE(ctx=None):
10003 ctx = _get_ctx(ctx)
10004 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10005
10006
10007def RoundNearestTiesToAway(ctx=None):
10008 ctx = _get_ctx(ctx)
10009 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10010
10011
10012def RNA(ctx=None):
10013 ctx = _get_ctx(ctx)
10014 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10015
10016
10017def RoundTowardPositive(ctx=None):
10018 ctx = _get_ctx(ctx)
10019 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10020
10021
10022def RTP(ctx=None):
10023 ctx = _get_ctx(ctx)
10024 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10025
10026
10027def RoundTowardNegative(ctx=None):
10028 ctx = _get_ctx(ctx)
10029 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10030
10031
10032def RTN(ctx=None):
10033 ctx = _get_ctx(ctx)
10034 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10035
10036
10037def RoundTowardZero(ctx=None):
10038 ctx = _get_ctx(ctx)
10039 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10040
10041
10042def RTZ(ctx=None):
10043 ctx = _get_ctx(ctx)
10044 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10045
10046
10047def is_fprm(a):
10048 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
10049
10050 >>> rm = RNE()
10051 >>> is_fprm(rm)
10052 True
10053 >>> rm = 1.0
10054 >>> is_fprm(rm)
10055 False
10056 """
10057 return isinstance(a, FPRMRef)
10058
10059
10060def is_fprm_value(a):
10061 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
10062 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
10063
10064# FP Numerals
10065
10066
10067class FPNumRef(FPRef):
10068 """The sign of the numeral.
10069
10070 >>> x = FPVal(+1.0, FPSort(8, 24))
10071 >>> x.sign()
10072 False
10073 >>> x = FPVal(-1.0, FPSort(8, 24))
10074 >>> x.sign()
10075 True
10076 """
10077
10078 def sign(self):
10079 num = ctypes.c_bool()
10080 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
10081 if nsign is False:
10082 raise Z3Exception("error retrieving the sign of a numeral.")
10083 return num.value != 0
10084
10085 """The sign of a floating-point numeral as a bit-vector expression.
10086
10087 Remark: NaN's are invalid arguments.
10088 """
10089
10090 def sign_as_bv(self):
10091 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10092
10093 """The significand of the numeral.
10094
10095 >>> x = FPVal(2.5, FPSort(8, 24))
10096 >>> x.significand()
10097 1.25
10098 """
10099
10100 def significand(self):
10101 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10102
10103 """The significand of the numeral as a long.
10104
10105 >>> x = FPVal(2.5, FPSort(8, 24))
10106 >>> x.significand_as_long()
10107 1.25
10108 """
10109
10110 def significand_as_long(self):
10111 ptr = (ctypes.c_ulonglong * 1)()
10112 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10113 raise Z3Exception("error retrieving the significand of a numeral.")
10114 return ptr[0]
10115
10116 """The significand of the numeral as a bit-vector expression.
10117
10118 Remark: NaN are invalid arguments.
10119 """
10120
10121 def significand_as_bv(self):
10122 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10123
10124 """The exponent of the numeral.
10125
10126 >>> x = FPVal(2.5, FPSort(8, 24))
10127 >>> x.exponent()
10128 1
10129 """
10130
10131 def exponent(self, biased=True):
10132 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10133
10134 """The exponent of the numeral as a long.
10135
10136 >>> x = FPVal(2.5, FPSort(8, 24))
10137 >>> x.exponent_as_long()
10138 1
10139 """
10140
10141 def exponent_as_long(self, biased=True):
10142 ptr = (ctypes.c_longlong * 1)()
10143 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10144 raise Z3Exception("error retrieving the exponent of a numeral.")
10145 return ptr[0]
10146
10147 """The exponent of the numeral as a bit-vector expression.
10148
10149 Remark: NaNs are invalid arguments.
10150 """
10151
10152 def exponent_as_bv(self, biased=True):
10153 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10154
10155 """Indicates whether the numeral is a NaN."""
10156
10157 def isNaN(self):
10158 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10159
10160 """Indicates whether the numeral is +oo or -oo."""
10161
10162 def isInf(self):
10163 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10164
10165 """Indicates whether the numeral is +zero or -zero."""
10166
10167 def isZero(self):
10168 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10169
10170 """Indicates whether the numeral is normal."""
10171
10172 def isNormal(self):
10173 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10174
10175 """Indicates whether the numeral is subnormal."""
10176
10177 def isSubnormal(self):
10178 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10179
10180 """Indicates whether the numeral is positive."""
10181
10182 def isPositive(self):
10183 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10184
10185 """Indicates whether the numeral is negative."""
10186
10187 def isNegative(self):
10188 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10189
10190 """
10191 The string representation of the numeral.
10192
10193 >>> x = FPVal(20, FPSort(8, 24))
10194 >>> x.as_string()
10195 1.25*(2**4)
10196 """
10197
10198 def as_string(self):
10199 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10200 return ("FPVal(%s, %s)" % (s, self.sort()))
10201
10202 def py_value(self):
10203 bv = simplify(fpToIEEEBV(self))
10204 binary = bv.py_value()
10205 if not isinstance(binary, int):
10206 return None
10207 # Decode the IEEE 754 binary representation
10208 import struct
10209 bytes_rep = binary.to_bytes(8, byteorder='big')
10210 return struct.unpack('>d', bytes_rep)[0]
10211
10212
10213def is_fp(a):
10214 """Return `True` if `a` is a Z3 floating-point expression.
10215
10216 >>> b = FP('b', FPSort(8, 24))
10217 >>> is_fp(b)
10218 True
10219 >>> is_fp(b + 1.0)
10220 True
10221 >>> is_fp(Int('x'))
10222 False
10223 """
10224 return isinstance(a, FPRef)
10225
10226
10227def is_fp_value(a):
10228 """Return `True` if `a` is a Z3 floating-point numeral value.
10229
10230 >>> b = FP('b', FPSort(8, 24))
10231 >>> is_fp_value(b)
10232 False
10233 >>> b = FPVal(1.0, FPSort(8, 24))
10234 >>> b
10235 1
10236 >>> is_fp_value(b)
10237 True
10238 """
10239 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10240
10241
10242def FPSort(ebits, sbits, ctx=None):
10243 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10244
10245 >>> Single = FPSort(8, 24)
10246 >>> Double = FPSort(11, 53)
10247 >>> Single
10248 FPSort(8, 24)
10249 >>> x = Const('x', Single)
10250 >>> eq(x, FP('x', FPSort(8, 24)))
10251 True
10252 """
10253 ctx = _get_ctx(ctx)
10254 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10255
10256
10257def _to_float_str(val, exp=0):
10258 if isinstance(val, float):
10259 if math.isnan(val):
10260 res = "NaN"
10261 elif val == 0.0:
10262 sone = math.copysign(1.0, val)
10263 if sone < 0.0:
10264 return "-0.0"
10265 else:
10266 return "+0.0"
10267 elif val == float("+inf"):
10268 res = "+oo"
10269 elif val == float("-inf"):
10270 res = "-oo"
10271 else:
10272 v = val.as_integer_ratio()
10273 num = v[0]
10274 den = v[1]
10275 rvs = str(num) + "/" + str(den)
10276 res = rvs + "p" + _to_int_str(exp)
10277 elif isinstance(val, bool):
10278 if val:
10279 res = "1.0"
10280 else:
10281 res = "0.0"
10282 elif _is_int(val):
10283 res = str(val)
10284 elif isinstance(val, str):
10285 inx = val.find("*(2**")
10286 if inx == -1:
10287 res = val
10288 elif val[-1] == ")":
10289 res = val[0:inx]
10290 exp = str(int(val[inx + 5:-1]) + int(exp))
10291 else:
10292 _z3_assert(False, "String does not have floating-point numeral form.")
10293 elif z3_debug():
10294 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10295 if exp == 0:
10296 return res
10297 else:
10298 return res + "p" + exp
10299
10300
10301def fpNaN(s):
10302 """Create a Z3 floating-point NaN term.
10303
10304 >>> s = FPSort(8, 24)
10305 >>> set_fpa_pretty(True)
10306 >>> fpNaN(s)
10307 NaN
10308 >>> pb = get_fpa_pretty()
10309 >>> set_fpa_pretty(False)
10310 >>> fpNaN(s)
10311 fpNaN(FPSort(8, 24))
10312 >>> set_fpa_pretty(pb)
10313 """
10314 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10315 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10316
10317
10318def fpPlusInfinity(s):
10319 """Create a Z3 floating-point +oo term.
10320
10321 >>> s = FPSort(8, 24)
10322 >>> pb = get_fpa_pretty()
10323 >>> set_fpa_pretty(True)
10324 >>> fpPlusInfinity(s)
10325 +oo
10326 >>> set_fpa_pretty(False)
10327 >>> fpPlusInfinity(s)
10328 fpPlusInfinity(FPSort(8, 24))
10329 >>> set_fpa_pretty(pb)
10330 """
10331 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10332 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10333
10334
10335def fpMinusInfinity(s):
10336 """Create a Z3 floating-point -oo term."""
10337 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10338 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10339
10340
10341def fpInfinity(s, negative):
10342 """Create a Z3 floating-point +oo or -oo term."""
10343 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10344 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10345 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10346
10347
10348def fpPlusZero(s):
10349 """Create a Z3 floating-point +0.0 term."""
10350 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10351 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10352
10353
10354def fpMinusZero(s):
10355 """Create a Z3 floating-point -0.0 term."""
10356 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10357 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10358
10359
10360def fpZero(s, negative):
10361 """Create a Z3 floating-point +0.0 or -0.0 term."""
10362 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10363 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10364 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10365
10366
10367def FPVal(sig, exp=None, fps=None, ctx=None):
10368 """Return a floating-point value of value `val` and sort `fps`.
10369 If `ctx=None`, then the global context is used.
10370
10371 >>> v = FPVal(20.0, FPSort(8, 24))
10372 >>> v
10373 1.25*(2**4)
10374 >>> print("0x%.8x" % v.exponent_as_long(False))
10375 0x00000004
10376 >>> v = FPVal(2.25, FPSort(8, 24))
10377 >>> v
10378 1.125*(2**1)
10379 >>> v = FPVal(-2.25, FPSort(8, 24))
10380 >>> v
10381 -1.125*(2**1)
10382 >>> FPVal(-0.0, FPSort(8, 24))
10383 -0.0
10384 >>> FPVal(0.0, FPSort(8, 24))
10385 +0.0
10386 >>> FPVal(+0.0, FPSort(8, 24))
10387 +0.0
10388 """
10389 ctx = _get_ctx(ctx)
10390 if is_fp_sort(exp):
10391 fps = exp
10392 exp = None
10393 elif fps is None:
10394 fps = _dflt_fps(ctx)
10395 _z3_assert(is_fp_sort(fps), "sort mismatch")
10396 if exp is None:
10397 exp = 0
10398 val = _to_float_str(sig)
10399 if val == "NaN" or val == "nan":
10400 return fpNaN(fps)
10401 elif val == "-0.0":
10402 return fpMinusZero(fps)
10403 elif val == "0.0" or val == "+0.0":
10404 return fpPlusZero(fps)
10405 elif val == "+oo" or val == "+inf" or val == "+Inf":
10406 return fpPlusInfinity(fps)
10407 elif val == "-oo" or val == "-inf" or val == "-Inf":
10408 return fpMinusInfinity(fps)
10409 else:
10410 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10411
10412
10413def FP(name, fpsort, ctx=None):
10414 """Return a floating-point constant named `name`.
10415 `fpsort` is the floating-point sort.
10416 If `ctx=None`, then the global context is used.
10417
10418 >>> x = FP('x', FPSort(8, 24))
10419 >>> is_fp(x)
10420 True
10421 >>> x.ebits()
10422 8
10423 >>> x.sort()
10424 FPSort(8, 24)
10425 >>> word = FPSort(8, 24)
10426 >>> x2 = FP('x', word)
10427 >>> eq(x, x2)
10428 True
10429 """
10430 if isinstance(fpsort, FPSortRef) and ctx is None:
10431 ctx = fpsort.ctx
10432 else:
10433 ctx = _get_ctx(ctx)
10434 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10435
10436
10437def FPs(names, fpsort, ctx=None):
10438 """Return an array of floating-point constants.
10439
10440 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10441 >>> x.sort()
10442 FPSort(8, 24)
10443 >>> x.sbits()
10444 24
10445 >>> x.ebits()
10446 8
10447 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10448 (x + y) * z
10449 """
10450 ctx = _get_ctx(ctx)
10451 if isinstance(names, str):
10452 names = names.split(" ")
10453 return [FP(name, fpsort, ctx) for name in names]
10454
10455
10456def fpAbs(a, ctx=None):
10457 """Create a Z3 floating-point absolute value expression.
10458
10459 >>> s = FPSort(8, 24)
10460 >>> rm = RNE()
10461 >>> x = FPVal(1.0, s)
10462 >>> fpAbs(x)
10463 fpAbs(1)
10464 >>> y = FPVal(-20.0, s)
10465 >>> y
10466 -1.25*(2**4)
10467 >>> fpAbs(y)
10468 fpAbs(-1.25*(2**4))
10469 >>> fpAbs(-1.25*(2**4))
10470 fpAbs(-1.25*(2**4))
10471 >>> fpAbs(x).sort()
10472 FPSort(8, 24)
10473 """
10474 ctx = _get_ctx(ctx)
10475 [a] = _coerce_fp_expr_list([a], ctx)
10476 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10477
10478
10479def fpNeg(a, ctx=None):
10480 """Create a Z3 floating-point addition expression.
10481
10482 >>> s = FPSort(8, 24)
10483 >>> rm = RNE()
10484 >>> x = FP('x', s)
10485 >>> fpNeg(x)
10486 -x
10487 >>> fpNeg(x).sort()
10488 FPSort(8, 24)
10489 """
10490 ctx = _get_ctx(ctx)
10491 [a] = _coerce_fp_expr_list([a], ctx)
10492 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10493
10494
10495def _mk_fp_unary(f, rm, a, ctx):
10496 ctx = _get_ctx(ctx)
10497 [a] = _coerce_fp_expr_list([a], ctx)
10498 if z3_debug():
10499 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10500 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10501 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10502
10503
10504def _mk_fp_unary_pred(f, a, ctx):
10505 ctx = _get_ctx(ctx)
10506 [a] = _coerce_fp_expr_list([a], ctx)
10507 if z3_debug():
10508 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10509 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10510
10511
10512def _mk_fp_bin(f, rm, a, b, ctx):
10513 ctx = _get_ctx(ctx)
10514 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10515 if z3_debug():
10516 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10517 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10518 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10519
10520
10521def _mk_fp_bin_norm(f, a, b, ctx):
10522 ctx = _get_ctx(ctx)
10523 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10524 if z3_debug():
10525 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10526 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10527
10528
10529def _mk_fp_bin_pred(f, a, b, ctx):
10530 ctx = _get_ctx(ctx)
10531 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10532 if z3_debug():
10533 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10534 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10535
10536
10537def _mk_fp_tern(f, rm, a, b, c, ctx):
10538 ctx = _get_ctx(ctx)
10539 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10540 if z3_debug():
10541 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10542 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10543 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10544 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10545
10546
10547def fpAdd(rm, a, b, ctx=None):
10548 """Create a Z3 floating-point addition expression.
10549
10550 >>> s = FPSort(8, 24)
10551 >>> rm = RNE()
10552 >>> x = FP('x', s)
10553 >>> y = FP('y', s)
10554 >>> fpAdd(rm, x, y)
10555 x + y
10556 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10557 fpAdd(RTZ(), x, y)
10558 >>> fpAdd(rm, x, y).sort()
10559 FPSort(8, 24)
10560 """
10561 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10562
10563
10564def fpSub(rm, a, b, ctx=None):
10565 """Create a Z3 floating-point subtraction expression.
10566
10567 >>> s = FPSort(8, 24)
10568 >>> rm = RNE()
10569 >>> x = FP('x', s)
10570 >>> y = FP('y', s)
10571 >>> fpSub(rm, x, y)
10572 x - y
10573 >>> fpSub(rm, x, y).sort()
10574 FPSort(8, 24)
10575 """
10576 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10577
10578
10579def fpMul(rm, a, b, ctx=None):
10580 """Create a Z3 floating-point multiplication expression.
10581
10582 >>> s = FPSort(8, 24)
10583 >>> rm = RNE()
10584 >>> x = FP('x', s)
10585 >>> y = FP('y', s)
10586 >>> fpMul(rm, x, y)
10587 x * y
10588 >>> fpMul(rm, x, y).sort()
10589 FPSort(8, 24)
10590 """
10591 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10592
10593
10594def fpDiv(rm, a, b, ctx=None):
10595 """Create a Z3 floating-point division expression.
10596
10597 >>> s = FPSort(8, 24)
10598 >>> rm = RNE()
10599 >>> x = FP('x', s)
10600 >>> y = FP('y', s)
10601 >>> fpDiv(rm, x, y)
10602 x / y
10603 >>> fpDiv(rm, x, y).sort()
10604 FPSort(8, 24)
10605 """
10606 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10607
10608
10609def fpRem(a, b, ctx=None):
10610 """Create a Z3 floating-point remainder expression.
10611
10612 >>> s = FPSort(8, 24)
10613 >>> x = FP('x', s)
10614 >>> y = FP('y', s)
10615 >>> fpRem(x, y)
10616 fpRem(x, y)
10617 >>> fpRem(x, y).sort()
10618 FPSort(8, 24)
10619 """
10620 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10621
10622
10623def fpMin(a, b, ctx=None):
10624 """Create a Z3 floating-point minimum expression.
10625
10626 >>> s = FPSort(8, 24)
10627 >>> rm = RNE()
10628 >>> x = FP('x', s)
10629 >>> y = FP('y', s)
10630 >>> fpMin(x, y)
10631 fpMin(x, y)
10632 >>> fpMin(x, y).sort()
10633 FPSort(8, 24)
10634 """
10635 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10636
10637
10638def fpMax(a, b, ctx=None):
10639 """Create a Z3 floating-point maximum expression.
10640
10641 >>> s = FPSort(8, 24)
10642 >>> rm = RNE()
10643 >>> x = FP('x', s)
10644 >>> y = FP('y', s)
10645 >>> fpMax(x, y)
10646 fpMax(x, y)
10647 >>> fpMax(x, y).sort()
10648 FPSort(8, 24)
10649 """
10650 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10651
10652
10653def fpFMA(rm, a, b, c, ctx=None):
10654 """Create a Z3 floating-point fused multiply-add expression.
10655 """
10656 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10657
10658
10659def fpSqrt(rm, a, ctx=None):
10660 """Create a Z3 floating-point square root expression.
10661 """
10662 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10663
10664
10665def fpRoundToIntegral(rm, a, ctx=None):
10666 """Create a Z3 floating-point roundToIntegral expression.
10667 """
10668 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10669
10670
10671def fpIsNaN(a, ctx=None):
10672 """Create a Z3 floating-point isNaN expression.
10673
10674 >>> s = FPSort(8, 24)
10675 >>> x = FP('x', s)
10676 >>> y = FP('y', s)
10677 >>> fpIsNaN(x)
10678 fpIsNaN(x)
10679 """
10680 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10681
10682
10683def fpIsInf(a, ctx=None):
10684 """Create a Z3 floating-point isInfinite expression.
10685
10686 >>> s = FPSort(8, 24)
10687 >>> x = FP('x', s)
10688 >>> fpIsInf(x)
10689 fpIsInf(x)
10690 """
10691 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10692
10693
10694def fpIsZero(a, ctx=None):
10695 """Create a Z3 floating-point isZero expression.
10696 """
10697 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10698
10699
10700def fpIsNormal(a, ctx=None):
10701 """Create a Z3 floating-point isNormal expression.
10702 """
10703 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10704
10705
10706def fpIsSubnormal(a, ctx=None):
10707 """Create a Z3 floating-point isSubnormal expression.
10708 """
10709 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10710
10711
10712def fpIsNegative(a, ctx=None):
10713 """Create a Z3 floating-point isNegative expression.
10714 """
10715 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10716
10717
10718def fpIsPositive(a, ctx=None):
10719 """Create a Z3 floating-point isPositive expression.
10720 """
10721 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10722
10723
10724def _check_fp_args(a, b):
10725 if z3_debug():
10726 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10727
10728
10729def fpLT(a, b, ctx=None):
10730 """Create the Z3 floating-point expression `other < self`.
10731
10732 >>> x, y = FPs('x y', FPSort(8, 24))
10733 >>> fpLT(x, y)
10734 x < y
10735 >>> (x < y).sexpr()
10736 '(fp.lt x y)'
10737 """
10738 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10739
10740
10741def fpLEQ(a, b, ctx=None):
10742 """Create the Z3 floating-point expression `other <= self`.
10743
10744 >>> x, y = FPs('x y', FPSort(8, 24))
10745 >>> fpLEQ(x, y)
10746 x <= y
10747 >>> (x <= y).sexpr()
10748 '(fp.leq x y)'
10749 """
10750 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10751
10752
10753def fpGT(a, b, ctx=None):
10754 """Create the Z3 floating-point expression `other > self`.
10755
10756 >>> x, y = FPs('x y', FPSort(8, 24))
10757 >>> fpGT(x, y)
10758 x > y
10759 >>> (x > y).sexpr()
10760 '(fp.gt x y)'
10761 """
10762 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10763
10764
10765def fpGEQ(a, b, ctx=None):
10766 """Create the Z3 floating-point expression `other >= self`.
10767
10768 >>> x, y = FPs('x y', FPSort(8, 24))
10769 >>> fpGEQ(x, y)
10770 x >= y
10771 >>> (x >= y).sexpr()
10772 '(fp.geq x y)'
10773 """
10774 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10775
10776
10777def fpEQ(a, b, ctx=None):
10778 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10779
10780 >>> x, y = FPs('x y', FPSort(8, 24))
10781 >>> fpEQ(x, y)
10782 fpEQ(x, y)
10783 >>> fpEQ(x, y).sexpr()
10784 '(fp.eq x y)'
10785 """
10786 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10787
10788
10789def fpNEQ(a, b, ctx=None):
10790 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10791
10792 >>> x, y = FPs('x y', FPSort(8, 24))
10793 >>> fpNEQ(x, y)
10794 Not(fpEQ(x, y))
10795 >>> (x != y).sexpr()
10796 '(distinct x y)'
10797 """
10798 return Not(fpEQ(a, b, ctx))
10799
10800
10801def fpFP(sgn, exp, sig, ctx=None):
10802 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10803
10804 >>> s = FPSort(8, 24)
10805 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10806 >>> print(x)
10807 fpFP(1, 127, 4194304)
10808 >>> xv = FPVal(-1.5, s)
10809 >>> print(xv)
10810 -1.5
10811 >>> slvr = Solver()
10812 >>> slvr.add(fpEQ(x, xv))
10813 >>> slvr.check()
10814 sat
10815 >>> xv = FPVal(+1.5, s)
10816 >>> print(xv)
10817 1.5
10818 >>> slvr = Solver()
10819 >>> slvr.add(fpEQ(x, xv))
10820 >>> slvr.check()
10821 unsat
10822 """
10823 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10824 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10825 ctx = _get_ctx(ctx)
10826 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10827 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10828
10829
10830def fpToFP(a1, a2=None, a3=None, ctx=None):
10831 """Create a Z3 floating-point conversion expression from other term sorts
10832 to floating-point.
10833
10834 From a bit-vector term in IEEE 754-2008 format:
10835 >>> x = FPVal(1.0, Float32())
10836 >>> x_bv = fpToIEEEBV(x)
10837 >>> simplify(fpToFP(x_bv, Float32()))
10838 1
10839
10840 From a floating-point term with different precision:
10841 >>> x = FPVal(1.0, Float32())
10842 >>> x_db = fpToFP(RNE(), x, Float64())
10843 >>> x_db.sort()
10844 FPSort(11, 53)
10845
10846 From a real term:
10847 >>> x_r = RealVal(1.5)
10848 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10849 1.5
10850
10851 From a signed bit-vector term:
10852 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10853 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10854 -1.25*(2**2)
10855 """
10856 ctx = _get_ctx(ctx)
10857 if is_bv(a1) and is_fp_sort(a2):
10858 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10859 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10860 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10861 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10862 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10863 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10864 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10865 else:
10866 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10867
10868
10869def fpBVToFP(v, sort, ctx=None):
10870 """Create a Z3 floating-point conversion expression that represents the
10871 conversion from a bit-vector term to a floating-point term.
10872
10873 >>> x_bv = BitVecVal(0x3F800000, 32)
10874 >>> x_fp = fpBVToFP(x_bv, Float32())
10875 >>> x_fp
10876 fpToFP(1065353216)
10877 >>> simplify(x_fp)
10878 1
10879 """
10880 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10881 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10882 ctx = _get_ctx(ctx)
10883 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10884
10885
10886def fpFPToFP(rm, v, sort, ctx=None):
10887 """Create a Z3 floating-point conversion expression that represents the
10888 conversion from a floating-point term to a floating-point term of different precision.
10889
10890 >>> x_sgl = FPVal(1.0, Float32())
10891 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10892 >>> x_dbl
10893 fpToFP(RNE(), 1)
10894 >>> simplify(x_dbl)
10895 1
10896 >>> x_dbl.sort()
10897 FPSort(11, 53)
10898 """
10899 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10900 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10901 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10902 ctx = _get_ctx(ctx)
10903 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10904
10905
10906def fpRealToFP(rm, v, sort, ctx=None):
10907 """Create a Z3 floating-point conversion expression that represents the
10908 conversion from a real term to a floating-point term.
10909
10910 >>> x_r = RealVal(1.5)
10911 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10912 >>> x_fp
10913 fpToFP(RNE(), 3/2)
10914 >>> simplify(x_fp)
10915 1.5
10916 """
10917 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10918 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10919 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10920 ctx = _get_ctx(ctx)
10921 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10922
10923
10924def fpSignedToFP(rm, v, sort, ctx=None):
10925 """Create a Z3 floating-point conversion expression that represents the
10926 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10927
10928 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10929 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10930 >>> x_fp
10931 fpToFP(RNE(), 4294967291)
10932 >>> simplify(x_fp)
10933 -1.25*(2**2)
10934 """
10935 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10936 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10937 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10938 ctx = _get_ctx(ctx)
10939 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10940
10941
10942def fpUnsignedToFP(rm, v, sort, ctx=None):
10943 """Create a Z3 floating-point conversion expression that represents the
10944 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10945
10946 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10947 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10948 >>> x_fp
10949 fpToFPUnsigned(RNE(), 4294967291)
10950 >>> simplify(x_fp)
10951 1*(2**32)
10952 """
10953 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10954 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10955 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10956 ctx = _get_ctx(ctx)
10957 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10958
10959
10960def fpToFPUnsigned(rm, x, s, ctx=None):
10961 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10962 if z3_debug():
10963 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10964 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10965 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10966 ctx = _get_ctx(ctx)
10967 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10968
10969
10970def fpToSBV(rm, x, s, ctx=None):
10971 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10972
10973 >>> x = FP('x', FPSort(8, 24))
10974 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10975 >>> print(is_fp(x))
10976 True
10977 >>> print(is_bv(y))
10978 True
10979 >>> print(is_fp(y))
10980 False
10981 >>> print(is_bv(x))
10982 False
10983 """
10984 if z3_debug():
10985 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10986 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10987 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10988 ctx = _get_ctx(ctx)
10989 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10990
10991
10992def fpToUBV(rm, x, s, ctx=None):
10993 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10994
10995 >>> x = FP('x', FPSort(8, 24))
10996 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10997 >>> print(is_fp(x))
10998 True
10999 >>> print(is_bv(y))
11000 True
11001 >>> print(is_fp(y))
11002 False
11003 >>> print(is_bv(x))
11004 False
11005 """
11006 if z3_debug():
11007 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11008 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11009 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11010 ctx = _get_ctx(ctx)
11011 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11012
11013
11014def fpToReal(x, ctx=None):
11015 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
11016
11017 >>> x = FP('x', FPSort(8, 24))
11018 >>> y = fpToReal(x)
11019 >>> print(is_fp(x))
11020 True
11021 >>> print(is_real(y))
11022 True
11023 >>> print(is_fp(y))
11024 False
11025 >>> print(is_real(x))
11026 False
11027 """
11028 if z3_debug():
11029 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11030 ctx = _get_ctx(ctx)
11031 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
11032
11033
11034def fpToIEEEBV(x, ctx=None):
11035 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
11036
11037 The size of the resulting bit-vector is automatically determined.
11038
11039 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
11040 knows only one NaN and it will always produce the same bit-vector representation of
11041 that NaN.
11042
11043 >>> x = FP('x', FPSort(8, 24))
11044 >>> y = fpToIEEEBV(x)
11045 >>> print(is_fp(x))
11046 True
11047 >>> print(is_bv(y))
11048 True
11049 >>> print(is_fp(y))
11050 False
11051 >>> print(is_bv(x))
11052 False
11053 """
11054 if z3_debug():
11055 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11056 ctx = _get_ctx(ctx)
11057 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
11058
11059
11060#########################################
11061#
11062# Strings, Sequences and Regular expressions
11063#
11064#########################################
11065
11066class SeqSortRef(SortRef):
11067 """Sequence sort."""
11068
11069 def is_string(self):
11070 """Determine if sort is a string
11071 >>> s = StringSort()
11072 >>> s.is_string()
11073 True
11074 >>> s = SeqSort(IntSort())
11075 >>> s.is_string()
11076 False
11077 """
11078 return Z3_is_string_sort(self.ctx_ref(), self.ast)
11079
11080 def basis(self):
11081 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11082
11083class CharSortRef(SortRef):
11084 """Character sort."""
11085
11086
11087def StringSort(ctx=None):
11088 """Create a string sort
11089 >>> s = StringSort()
11090 >>> print(s)
11091 String
11092 """
11093 ctx = _get_ctx(ctx)
11094 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
11095
11096def CharSort(ctx=None):
11097 """Create a character sort
11098 >>> ch = CharSort()
11099 >>> print(ch)
11100 Char
11101 """
11102 ctx = _get_ctx(ctx)
11103 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11104
11105
11106def SeqSort(s):
11107 """Create a sequence sort over elements provided in the argument
11108 >>> s = SeqSort(IntSort())
11109 >>> s == Unit(IntVal(1)).sort()
11110 True
11111 """
11112 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11113
11114
11115class SeqRef(ExprRef):
11116 """Sequence expression."""
11117
11118 def sort(self):
11119 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11120
11121 def __add__(self, other):
11122 return Concat(self, other)
11123
11124 def __radd__(self, other):
11125 return Concat(other, self)
11126
11127 def __getitem__(self, i):
11128 if _is_int(i):
11129 i = IntVal(i, self.ctx)
11130 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11131
11132 def at(self, i):
11133 if _is_int(i):
11134 i = IntVal(i, self.ctx)
11135 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11136
11137 def is_string(self):
11138 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11139
11140 def is_string_value(self):
11141 return Z3_is_string(self.ctx_ref(), self.as_ast())
11142
11143 def as_string(self):
11144 """Return a string representation of sequence expression."""
11145 if self.is_string_value():
11146 string_length = ctypes.c_uint()
11147 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11148 return string_at(chars, size=string_length.value).decode("latin-1")
11149 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11150
11151 def py_value(self):
11152 return self.as_string()
11153
11154 def __le__(self, other):
11155 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11156
11157 def __lt__(self, other):
11158 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11159
11160 def __ge__(self, other):
11161 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11162
11163 def __gt__(self, other):
11164 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11165
11166
11167def _coerce_char(ch, ctx=None):
11168 if isinstance(ch, str):
11169 ctx = _get_ctx(ctx)
11170 ch = CharVal(ch, ctx)
11171 if not is_expr(ch):
11172 raise Z3Exception("Character expression expected")
11173 return ch
11174
11175class CharRef(ExprRef):
11176 """Character expression."""
11177
11178 def __le__(self, other):
11179 other = _coerce_char(other, self.ctx)
11180 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11181
11182 def to_int(self):
11183 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11184
11185 def to_bv(self):
11186 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11187
11188 def is_digit(self):
11189 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11190
11191
11192def CharVal(ch, ctx=None):
11193 ctx = _get_ctx(ctx)
11194 if isinstance(ch, str):
11195 ch = ord(ch)
11196 if not isinstance(ch, int):
11197 raise Z3Exception("character value should be an ordinal")
11198 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11199
11200def CharFromBv(bv):
11201 if not is_expr(bv):
11202 raise Z3Exception("Bit-vector expression needed")
11203 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11204
11205def CharToBv(ch, ctx=None):
11206 ch = _coerce_char(ch, ctx)
11207 return ch.to_bv()
11208
11209def CharToInt(ch, ctx=None):
11210 ch = _coerce_char(ch, ctx)
11211 return ch.to_int()
11212
11213def CharIsDigit(ch, ctx=None):
11214 ch = _coerce_char(ch, ctx)
11215 return ch.is_digit()
11216
11217def _coerce_seq(s, ctx=None):
11218 if isinstance(s, str):
11219 ctx = _get_ctx(ctx)
11220 s = StringVal(s, ctx)
11221 if not is_expr(s):
11222 raise Z3Exception("Non-expression passed as a sequence")
11223 if not is_seq(s):
11224 raise Z3Exception("Non-sequence passed as a sequence")
11225 return s
11226
11227
11228def _get_ctx2(a, b, ctx=None):
11229 if is_expr(a):
11230 return a.ctx
11231 if is_expr(b):
11232 return b.ctx
11233 if ctx is None:
11234 ctx = main_ctx()
11235 return ctx
11236
11237
11238def is_seq(a):
11239 """Return `True` if `a` is a Z3 sequence expression.
11240 >>> print (is_seq(Unit(IntVal(0))))
11241 True
11242 >>> print (is_seq(StringVal("abc")))
11243 True
11244 """
11245 return isinstance(a, SeqRef)
11246
11247
11248def is_string(a: Any) -> bool:
11249 """Return `True` if `a` is a Z3 string expression.
11250 >>> print (is_string(StringVal("ab")))
11251 True
11252 """
11253 return isinstance(a, SeqRef) and a.is_string()
11254
11255
11256def is_string_value(a: Any) -> bool:
11257 """return 'True' if 'a' is a Z3 string constant expression.
11258 >>> print (is_string_value(StringVal("a")))
11259 True
11260 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11261 False
11262 """
11263 return isinstance(a, SeqRef) and a.is_string_value()
11264
11265def StringVal(s, ctx=None):
11266 """create a string expression"""
11267 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11268 ctx = _get_ctx(ctx)
11269 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11270
11271
11272def String(name, ctx=None):
11273 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11274
11275 >>> x = String('x')
11276 """
11277 ctx = _get_ctx(ctx)
11278 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11279
11280
11281def Strings(names, ctx=None):
11282 """Return a tuple of String constants. """
11283 ctx = _get_ctx(ctx)
11284 if isinstance(names, str):
11285 names = names.split(" ")
11286 return [String(name, ctx) for name in names]
11287
11288
11289def SubString(s, offset, length):
11290 """Extract substring or subsequence starting at offset.
11291
11292 This is a convenience function that redirects to Extract(s, offset, length).
11293
11294 >>> s = StringVal("hello world")
11295 >>> SubString(s, 6, 5) # Extract "world"
11296 str.substr("hello world", 6, 5)
11297 >>> simplify(SubString(StringVal("hello"), 1, 3))
11298 "ell"
11299 """
11300 return Extract(s, offset, length)
11301
11302
11303def SubSeq(s, offset, length):
11304 """Extract substring or subsequence starting at offset.
11305
11306 This is a convenience function that redirects to Extract(s, offset, length).
11307
11308 >>> s = StringVal("hello world")
11309 >>> SubSeq(s, 0, 5) # Extract "hello"
11310 str.substr("hello world", 0, 5)
11311 >>> simplify(SubSeq(StringVal("testing"), 2, 4))
11312 "stin"
11313 """
11314 return Extract(s, offset, length)
11315
11316
11317def Empty(s):
11318 """Create the empty sequence of the given sort
11319 >>> e = Empty(StringSort())
11320 >>> e2 = StringVal("")
11321 >>> print(e.eq(e2))
11322 True
11323 >>> e3 = Empty(SeqSort(IntSort()))
11324 >>> print(e3)
11325 Empty(Seq(Int))
11326 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11327 >>> print(e4)
11328 Empty(ReSort(Seq(Int)))
11329 """
11330 if isinstance(s, SeqSortRef):
11331 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11332 if isinstance(s, ReSortRef):
11333 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11334 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11335
11336
11337def Full(s):
11338 """Create the regular expression that accepts the universal language
11339 >>> e = Full(ReSort(SeqSort(IntSort())))
11340 >>> print(e)
11341 Full(ReSort(Seq(Int)))
11342 >>> e1 = Full(ReSort(StringSort()))
11343 >>> print(e1)
11344 Full(ReSort(String))
11345 """
11346 if isinstance(s, ReSortRef):
11347 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11348 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11349
11350
11351
11352def Unit(a):
11353 """Create a singleton sequence"""
11354 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11355
11356
11357def PrefixOf(a, b):
11358 """Check if 'a' is a prefix of 'b'
11359 >>> s1 = PrefixOf("ab", "abc")
11360 >>> simplify(s1)
11361 True
11362 >>> s2 = PrefixOf("bc", "abc")
11363 >>> simplify(s2)
11364 False
11365 """
11366 ctx = _get_ctx2(a, b)
11367 a = _coerce_seq(a, ctx)
11368 b = _coerce_seq(b, ctx)
11369 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11370
11371
11372def SuffixOf(a, b):
11373 """Check if 'a' is a suffix of 'b'
11374 >>> s1 = SuffixOf("ab", "abc")
11375 >>> simplify(s1)
11376 False
11377 >>> s2 = SuffixOf("bc", "abc")
11378 >>> simplify(s2)
11379 True
11380 """
11381 ctx = _get_ctx2(a, b)
11382 a = _coerce_seq(a, ctx)
11383 b = _coerce_seq(b, ctx)
11384 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11385
11386
11387def Contains(a, b):
11388 """Check if 'a' contains 'b'
11389 >>> s1 = Contains("abc", "ab")
11390 >>> simplify(s1)
11391 True
11392 >>> s2 = Contains("abc", "bc")
11393 >>> simplify(s2)
11394 True
11395 >>> x, y, z = Strings('x y z')
11396 >>> s3 = Contains(Concat(x,y,z), y)
11397 >>> simplify(s3)
11398 True
11399 """
11400 ctx = _get_ctx2(a, b)
11401 a = _coerce_seq(a, ctx)
11402 b = _coerce_seq(b, ctx)
11403 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11404
11405
11406def Replace(s, src, dst):
11407 """Replace the first occurrence of 'src' by 'dst' in 's'
11408 >>> r = Replace("aaa", "a", "b")
11409 >>> simplify(r)
11410 "baa"
11411 """
11412 ctx = _get_ctx2(dst, s)
11413 if ctx is None and is_expr(src):
11414 ctx = src.ctx
11415 src = _coerce_seq(src, ctx)
11416 dst = _coerce_seq(dst, ctx)
11417 s = _coerce_seq(s, ctx)
11418 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11419
11420
11421def IndexOf(s, substr, offset=None):
11422 """Retrieve the index of substring within a string starting at a specified offset.
11423 >>> simplify(IndexOf("abcabc", "bc", 0))
11424 1
11425 >>> simplify(IndexOf("abcabc", "bc", 2))
11426 4
11427 """
11428 if offset is None:
11429 offset = IntVal(0)
11430 ctx = None
11431 if is_expr(offset):
11432 ctx = offset.ctx
11433 ctx = _get_ctx2(s, substr, ctx)
11434 s = _coerce_seq(s, ctx)
11435 substr = _coerce_seq(substr, ctx)
11436 if _is_int(offset):
11437 offset = IntVal(offset, ctx)
11438 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11439
11440
11441def LastIndexOf(s, substr):
11442 """Retrieve the last index of substring within a string"""
11443 ctx = None
11444 ctx = _get_ctx2(s, substr, ctx)
11445 s = _coerce_seq(s, ctx)
11446 substr = _coerce_seq(substr, ctx)
11447 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11448
11449
11450def Length(s):
11451 """Obtain the length of a sequence 's'
11452 >>> l = Length(StringVal("abc"))
11453 >>> simplify(l)
11454 3
11455 """
11456 s = _coerce_seq(s)
11457 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11458
11459def SeqMap(f, s):
11460 """Map function 'f' over sequence 's'"""
11461 ctx = _get_ctx2(f, s)
11462 s = _coerce_seq(s, ctx)
11463 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11464
11465def SeqMapI(f, i, s):
11466 """Map function 'f' over sequence 's' at index 'i'"""
11467 ctx = _get_ctx2(f, s)
11468 s = _coerce_seq(s, ctx)
11469 if not is_expr(i):
11470 i = _py2expr(i)
11471 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11472
11473def SeqFoldLeft(f, a, s):
11474 ctx = _get_ctx2(f, s)
11475 s = _coerce_seq(s, ctx)
11476 a = _py2expr(a)
11477 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11478
11479def SeqFoldLeftI(f, i, a, s):
11480 ctx = _get_ctx2(f, s)
11481 s = _coerce_seq(s, ctx)
11482 a = _py2expr(a)
11483 i = _py2expr(i)
11484 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11485
11486def StrToInt(s):
11487 """Convert string expression to integer
11488 >>> a = StrToInt("1")
11489 >>> simplify(1 == a)
11490 True
11491 >>> b = StrToInt("2")
11492 >>> simplify(1 == b)
11493 False
11494 >>> c = StrToInt(IntToStr(2))
11495 >>> simplify(1 == c)
11496 False
11497 """
11498 s = _coerce_seq(s)
11499 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11500
11501
11502def IntToStr(s):
11503 """Convert integer expression to string"""
11504 if not is_expr(s):
11505 s = _py2expr(s)
11506 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11507
11508
11509def StrToCode(s):
11510 """Convert a unit length string to integer code"""
11511 if not is_expr(s):
11512 s = _py2expr(s)
11513 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11514
11515def StrFromCode(c):
11516 """Convert code to a string"""
11517 if not is_expr(c):
11518 c = _py2expr(c)
11519 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11520
11521def Re(s, ctx=None):
11522 """The regular expression that accepts sequence 's'
11523 >>> s1 = Re("ab")
11524 >>> s2 = Re(StringVal("ab"))
11525 >>> s3 = Re(Unit(BoolVal(True)))
11526 """
11527 s = _coerce_seq(s, ctx)
11528 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11529
11530
11531# Regular expressions
11532
11533class ReSortRef(SortRef):
11534 """Regular expression sort."""
11535
11536 def basis(self):
11537 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11538
11539
11540def ReSort(s):
11541 if is_ast(s):
11542 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11543 if s is None or isinstance(s, Context):
11544 ctx = _get_ctx(s)
11545 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11546 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11547
11548
11549class ReRef(ExprRef):
11550 """Regular expressions."""
11551
11552 def __add__(self, other):
11553 return Union(self, other)
11554
11555
11556def is_re(s):
11557 return isinstance(s, ReRef)
11558
11559
11560def InRe(s, re):
11561 """Create regular expression membership test
11562 >>> re = Union(Re("a"),Re("b"))
11563 >>> print (simplify(InRe("a", re)))
11564 True
11565 >>> print (simplify(InRe("b", re)))
11566 True
11567 >>> print (simplify(InRe("c", re)))
11568 False
11569 """
11570 s = _coerce_seq(s, re.ctx)
11571 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11572
11573
11574def Union(*args):
11575 """Create union of regular expressions.
11576 >>> re = Union(Re("a"), Re("b"), Re("c"))
11577 >>> print (simplify(InRe("d", re)))
11578 False
11579 """
11580 args = _get_args(args)
11581 sz = len(args)
11582 if z3_debug():
11583 _z3_assert(sz > 0, "At least one argument expected.")
11584 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11585 if sz == 1:
11586 return args[0]
11587 ctx = args[0].ctx
11588 v = (Ast * sz)()
11589 for i in range(sz):
11590 v[i] = args[i].as_ast()
11591 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11592
11593
11594def Intersect(*args):
11595 """Create intersection of regular expressions.
11596 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11597 """
11598 args = _get_args(args)
11599 sz = len(args)
11600 if z3_debug():
11601 _z3_assert(sz > 0, "At least one argument expected.")
11602 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11603 if sz == 1:
11604 return args[0]
11605 ctx = args[0].ctx
11606 v = (Ast * sz)()
11607 for i in range(sz):
11608 v[i] = args[i].as_ast()
11609 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11610
11611
11612def Plus(re):
11613 """Create the regular expression accepting one or more repetitions of argument.
11614 >>> re = Plus(Re("a"))
11615 >>> print(simplify(InRe("aa", re)))
11616 True
11617 >>> print(simplify(InRe("ab", re)))
11618 False
11619 >>> print(simplify(InRe("", re)))
11620 False
11621 """
11622 if z3_debug():
11623 _z3_assert(is_expr(re), "expression expected")
11624 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11625
11626
11627def Option(re):
11628 """Create the regular expression that optionally accepts the argument.
11629 >>> re = Option(Re("a"))
11630 >>> print(simplify(InRe("a", re)))
11631 True
11632 >>> print(simplify(InRe("", re)))
11633 True
11634 >>> print(simplify(InRe("aa", re)))
11635 False
11636 """
11637 if z3_debug():
11638 _z3_assert(is_expr(re), "expression expected")
11639 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11640
11641
11642def Complement(re):
11643 """Create the complement regular expression."""
11644 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11645
11646
11647def Star(re):
11648 """Create the regular expression accepting zero or more repetitions of argument.
11649 >>> re = Star(Re("a"))
11650 >>> print(simplify(InRe("aa", re)))
11651 True
11652 >>> print(simplify(InRe("ab", re)))
11653 False
11654 >>> print(simplify(InRe("", re)))
11655 True
11656 """
11657 if z3_debug():
11658 _z3_assert(is_expr(re), "expression expected")
11659 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11660
11661
11662def Loop(re, lo, hi=0):
11663 """Create the regular expression accepting between a lower and upper bound repetitions
11664 >>> re = Loop(Re("a"), 1, 3)
11665 >>> print(simplify(InRe("aa", re)))
11666 True
11667 >>> print(simplify(InRe("aaaa", re)))
11668 False
11669 >>> print(simplify(InRe("", re)))
11670 False
11671 """
11672 if z3_debug():
11673 _z3_assert(is_expr(re), "expression expected")
11674 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11675
11676
11677def Range(lo, hi, ctx=None):
11678 """Create the range regular expression over two sequences of length 1
11679 >>> range = Range("a","z")
11680 >>> print(simplify(InRe("b", range)))
11681 True
11682 >>> print(simplify(InRe("bb", range)))
11683 False
11684 """
11685 lo = _coerce_seq(lo, ctx)
11686 hi = _coerce_seq(hi, ctx)
11687 if z3_debug():
11688 _z3_assert(is_expr(lo), "expression expected")
11689 _z3_assert(is_expr(hi), "expression expected")
11690 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11691
11692def Diff(a, b, ctx=None):
11693 """Create the difference regular expression
11694 """
11695 if z3_debug():
11696 _z3_assert(is_expr(a), "expression expected")
11697 _z3_assert(is_expr(b), "expression expected")
11698 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11699
11700def AllChar(regex_sort, ctx=None):
11701 """Create a regular expression that accepts all single character strings
11702 """
11703 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11704
11705# Special Relations
11706
11707
11708def PartialOrder(a, index):
11709 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11710
11711
11712def LinearOrder(a, index):
11713 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11714
11715
11716def TreeOrder(a, index):
11717 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11718
11719
11720def PiecewiseLinearOrder(a, index):
11721 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11722
11723
11724def TransitiveClosure(f):
11725 """Given a binary relation R, such that the two arguments have the same sort
11726 create the transitive closure relation R+.
11727 The transitive closure R+ is a new relation.
11728 """
11729 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11730
11731def to_Ast(ptr,):
11732 ast = Ast(ptr)
11733 super(ctypes.c_void_p, ast).__init__(ptr)
11734 return ast
11735
11736def to_ContextObj(ptr,):
11737 ctx = ContextObj(ptr)
11738 super(ctypes.c_void_p, ctx).__init__(ptr)
11739 return ctx
11740
11741def to_AstVectorObj(ptr,):
11742 v = AstVectorObj(ptr)
11743 super(ctypes.c_void_p, v).__init__(ptr)
11744 return v
11745
11746# NB. my-hacky-class only works for a single instance of OnClause
11747# it should be replaced with a proper correlation between OnClause
11748# and object references that can be passed over the FFI.
11749# for UserPropagator we use a global dictionary, which isn't great code.
11750
11751_my_hacky_class = None
11752def on_clause_eh(ctx, p, n, dep, clause):
11753 onc = _my_hacky_class
11754 p = _to_expr_ref(to_Ast(p), onc.ctx)
11755 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11756 deps = [dep[i] for i in range(n)]
11757 onc.on_clause(p, deps, clause)
11758
11759_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11760
11761class OnClause:
11762 def __init__(self, s, on_clause):
11763 self.s = s
11764 self.ctx = s.ctx
11765 self.on_clause = on_clause
11766 self.idx = 22
11767 global _my_hacky_class
11768 _my_hacky_class = self
11769 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11770
11771
11772class PropClosures:
11773 def __init__(self):
11774 self.bases = {}
11775 self.lock = None
11776
11777 def set_threaded(self):
11778 if self.lock is None:
11779 import threading
11780 self.lock = threading.Lock()
11781
11782 def get(self, ctx):
11783 if self.lock:
11784 with self.lock:
11785 r = self.bases[ctx]
11786 else:
11787 r = self.bases[ctx]
11788 return r
11789
11790 def set(self, ctx, r):
11791 if self.lock:
11792 with self.lock:
11793 self.bases[ctx] = r
11794 else:
11795 self.bases[ctx] = r
11796
11797 def insert(self, r):
11798 if self.lock:
11799 with self.lock:
11800 id = len(self.bases) + 3
11801 self.bases[id] = r
11802 else:
11803 id = len(self.bases) + 3
11804 self.bases[id] = r
11805 return id
11806
11807
11808_prop_closures = None
11809
11810
11811def ensure_prop_closures():
11812 global _prop_closures
11813 if _prop_closures is None:
11814 _prop_closures = PropClosures()
11815
11816
11817def user_prop_push(ctx, cb):
11818 prop = _prop_closures.get(ctx)
11819 prop.cb = cb
11820 prop.push()
11821
11822
11823def user_prop_pop(ctx, cb, num_scopes):
11824 prop = _prop_closures.get(ctx)
11825 prop.cb = cb
11826 prop.pop(num_scopes)
11827
11828
11829def user_prop_fresh(ctx, _new_ctx):
11830 _prop_closures.set_threaded()
11831 prop = _prop_closures.get(ctx)
11832 nctx = Context()
11833 Z3_del_context(nctx.ctx)
11834 new_ctx = to_ContextObj(_new_ctx)
11835 nctx.ctx = new_ctx
11836 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11837 nctx.owner = False
11838 new_prop = prop.fresh(nctx)
11839 _prop_closures.set(new_prop.id, new_prop)
11840 return new_prop.id
11841
11842
11843def user_prop_fixed(ctx, cb, id, value):
11844 prop = _prop_closures.get(ctx)
11845 old_cb = prop.cb
11846 prop.cb = cb
11847 id = _to_expr_ref(to_Ast(id), prop.ctx())
11848 value = _to_expr_ref(to_Ast(value), prop.ctx())
11849 prop.fixed(id, value)
11850 prop.cb = old_cb
11851
11852def user_prop_created(ctx, cb, id):
11853 prop = _prop_closures.get(ctx)
11854 old_cb = prop.cb
11855 prop.cb = cb
11856 id = _to_expr_ref(to_Ast(id), prop.ctx())
11857 prop.created(id)
11858 prop.cb = old_cb
11859
11860
11861def user_prop_final(ctx, cb):
11862 prop = _prop_closures.get(ctx)
11863 old_cb = prop.cb
11864 prop.cb = cb
11865 prop.final()
11866 prop.cb = old_cb
11867
11868def user_prop_eq(ctx, cb, x, y):
11869 prop = _prop_closures.get(ctx)
11870 old_cb = prop.cb
11871 prop.cb = cb
11872 x = _to_expr_ref(to_Ast(x), prop.ctx())
11873 y = _to_expr_ref(to_Ast(y), prop.ctx())
11874 prop.eq(x, y)
11875 prop.cb = old_cb
11876
11877def user_prop_diseq(ctx, cb, x, y):
11878 prop = _prop_closures.get(ctx)
11879 old_cb = prop.cb
11880 prop.cb = cb
11881 x = _to_expr_ref(to_Ast(x), prop.ctx())
11882 y = _to_expr_ref(to_Ast(y), prop.ctx())
11883 prop.diseq(x, y)
11884 prop.cb = old_cb
11885
11886def user_prop_decide(ctx, cb, t_ref, idx, phase):
11887 prop = _prop_closures.get(ctx)
11888 old_cb = prop.cb
11889 prop.cb = cb
11890 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11891 prop.decide(t, idx, phase)
11892 prop.cb = old_cb
11893
11894def user_prop_binding(ctx, cb, q_ref, inst_ref):
11895 prop = _prop_closures.get(ctx)
11896 old_cb = prop.cb
11897 prop.cb = cb
11898 q = _to_expr_ref(to_Ast(q_ref), prop.ctx())
11899 inst = _to_expr_ref(to_Ast(inst_ref), prop.ctx())
11900 r = prop.binding(q, inst)
11901 prop.cb = old_cb
11902 return r
11903
11904
11905_user_prop_push = Z3_push_eh(user_prop_push)
11906_user_prop_pop = Z3_pop_eh(user_prop_pop)
11907_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11908_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11909_user_prop_created = Z3_created_eh(user_prop_created)
11910_user_prop_final = Z3_final_eh(user_prop_final)
11911_user_prop_eq = Z3_eq_eh(user_prop_eq)
11912_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11913_user_prop_decide = Z3_decide_eh(user_prop_decide)
11914_user_prop_binding = Z3_on_binding_eh(user_prop_binding)
11915
11916
11917def PropagateFunction(name, *sig):
11918 """Create a function that gets tracked by user propagator.
11919 Every term headed by this function symbol is tracked.
11920 If a term is fixed and the fixed callback is registered a
11921 callback is invoked that the term headed by this function is fixed.
11922 """
11923 sig = _get_args(sig)
11924 if z3_debug():
11925 _z3_assert(len(sig) > 0, "At least two arguments expected")
11926 arity = len(sig) - 1
11927 rng = sig[arity]
11928 if z3_debug():
11929 _z3_assert(is_sort(rng), "Z3 sort expected")
11930 dom = (Sort * arity)()
11931 for i in range(arity):
11932 if z3_debug():
11933 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11934 dom[i] = sig[i].ast
11935 ctx = rng.ctx
11936 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11937
11938
11939
11940class UserPropagateBase:
11941
11942 #
11943 # Either solver is set or ctx is set.
11944 # Propagators that are created through callbacks
11945 # to "fresh" inherit the context of that is supplied
11946 # as argument to the callback.
11947 # This context should not be deleted. It is owned by the solver.
11948 #
11949 def __init__(self, s, ctx=None):
11950 assert s is None or ctx is None
11951 ensure_prop_closures()
11952 self.solver = s
11953 self._ctx = None
11954 self.fresh_ctx = None
11955 self.cb = None
11956 self.id = _prop_closures.insert(self)
11957 self.fixed = None
11958 self.final = None
11959 self.eq = None
11960 self.diseq = None
11961 self.decide = None
11962 self.created = None
11963 self.binding = None
11964 if ctx:
11965 self.fresh_ctx = ctx
11966 if s:
11967 Z3_solver_propagate_init(self.ctx_ref(),
11968 s.solver,
11969 ctypes.c_void_p(self.id),
11970 _user_prop_push,
11971 _user_prop_pop,
11972 _user_prop_fresh)
11973
11974 def __del__(self):
11975 if self._ctx:
11976 self._ctx.ctx = None
11977
11978 def ctx(self):
11979 if self.fresh_ctx:
11980 return self.fresh_ctx
11981 else:
11982 return self.solver.ctx
11983
11984 def ctx_ref(self):
11985 return self.ctx().ref()
11986
11987 def add_fixed(self, fixed):
11988 assert not self.fixed
11989 assert not self._ctx
11990 if self.solver:
11991 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11992 self.fixed = fixed
11993
11994 def add_created(self, created):
11995 assert not self.created
11996 assert not self._ctx
11997 if self.solver:
11998 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
11999 self.created = created
12000
12001 def add_final(self, final):
12002 assert not self.final
12003 assert not self._ctx
12004 if self.solver:
12005 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
12006 self.final = final
12007
12008 def add_eq(self, eq):
12009 assert not self.eq
12010 assert not self._ctx
12011 if self.solver:
12012 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
12013 self.eq = eq
12014
12015 def add_diseq(self, diseq):
12016 assert not self.diseq
12017 assert not self._ctx
12018 if self.solver:
12019 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
12020 self.diseq = diseq
12021
12022 def add_decide(self, decide):
12023 assert not self.decide
12024 assert not self._ctx
12025 if self.solver:
12026 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
12027 self.decide = decide
12028
12029 def add_on_binding(self, binding):
12030 assert not self.binding
12031 assert not self._ctx
12032 if self.solver:
12033 Z3_solver_propagate_on_binding(self.ctx_ref(), self.solver.solver, _user_prop_binding)
12034 self.binding = binding
12035
12036 def push(self):
12037 raise Z3Exception("push needs to be overwritten")
12038
12039 def pop(self, num_scopes):
12040 raise Z3Exception("pop needs to be overwritten")
12041
12042 def fresh(self, new_ctx):
12043 raise Z3Exception("fresh needs to be overwritten")
12044
12045 def add(self, e):
12046 assert not self._ctx
12047 if self.solver:
12048 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
12049 else:
12050 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
12051
12052 #
12053 # Tell the solver to perform the next split on a given term
12054 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
12055 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
12056 #
12057 def next_split(self, t, idx, phase):
12058 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
12059
12060 #
12061 # Propagation can only be invoked as during a fixed or final callback.
12062 #
12063 def propagate(self, e, ids, eqs=[]):
12064 _ids, num_fixed = _to_ast_array(ids)
12065 num_eqs = len(eqs)
12066 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
12067 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
12068 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
12069 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
12070
12071 def conflict(self, deps = [], eqs = []):
12072 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3244
as_decimal(self, prec)
Definition z3py.py:3256
__rmod__(self, other)
Definition z3py.py:2726
__mod__(self, other)
Definition z3py.py:2711
__pow__(self, other)
Definition z3py.py:2635
__gt__(self, other)
Definition z3py.py:2784
__lt__(self, other)
Definition z3py.py:2771
__rtruediv__(self, other)
Definition z3py.py:2707
__rmul__(self, other)
Definition z3py.py:2602
__rsub__(self, other)
Definition z3py.py:2625
__add__(self, other)
Definition z3py.py:2564
__sub__(self, other)
Definition z3py.py:2612
is_real(self)
Definition z3py.py:2553
is_int(self)
Definition z3py.py:2539
__radd__(self, other)
Definition z3py.py:2577
__truediv__(self, other)
Definition z3py.py:2686
__le__(self, other)
Definition z3py.py:2758
__rpow__(self, other)
Definition z3py.py:2649
__pos__(self)
Definition z3py.py:2749
sort(self)
Definition z3py.py:2529
__mul__(self, other)
Definition z3py.py:2587
__rdiv__(self, other)
Definition z3py.py:2690
__ge__(self, other)
Definition z3py.py:2797
__neg__(self)
Definition z3py.py:2738
__div__(self, other)
Definition z3py.py:2663
Arithmetic.
Definition z3py.py:2434
subsort(self, other)
Definition z3py.py:2468
cast(self, val)
Definition z3py.py:2472
domain(self)
Definition z3py.py:4738
domain_n(self, i)
Definition z3py.py:4747
__getitem__(self, arg)
Definition z3py.py:4760
range(self)
Definition z3py.py:4751
sort(self)
Definition z3py.py:4729
default(self)
Definition z3py.py:4772
domain_n(self, i)
Definition z3py.py:4711
erase(self, k)
Definition z3py.py:6283
__deepcopy__(self, memo={})
Definition z3py.py:6220
__init__(self, m=None, ctx=None)
Definition z3py.py:6209
__repr__(self)
Definition z3py.py:6280
__len__(self)
Definition z3py.py:6227
keys(self)
Definition z3py.py:6312
__setitem__(self, k, v)
Definition z3py.py:6264
__contains__(self, key)
Definition z3py.py:6240
__del__(self)
Definition z3py.py:6223
__getitem__(self, key)
Definition z3py.py:6253
reset(self)
Definition z3py.py:6297
__deepcopy__(self, memo={})
Definition z3py.py:385
__nonzero__(self)
Definition z3py.py:400
as_ast(self)
Definition z3py.py:422
translate(self, target)
Definition z3py.py:451
__hash__(self)
Definition z3py.py:397
__init__(self, ast, ctx=None)
Definition z3py.py:375
__str__(self)
Definition z3py.py:388
ctx_ref(self)
Definition z3py.py:430
py_value(self)
Definition z3py.py:480
__repr__(self)
Definition z3py.py:391
get_id(self)
Definition z3py.py:426
hash(self)
Definition z3py.py:470
__eq__(self, other)
Definition z3py.py:394
eq(self, other)
Definition z3py.py:434
sexpr(self)
Definition z3py.py:413
__del__(self)
Definition z3py.py:380
__bool__(self)
Definition z3py.py:403
__copy__(self)
Definition z3py.py:467
__deepcopy__(self, memo={})
Definition z3py.py:6189
translate(self, other_ctx)
Definition z3py.py:6170
__repr__(self)
Definition z3py.py:6192
__len__(self)
Definition z3py.py:6064
__init__(self, v=None, ctx=None)
Definition z3py.py:6049
push(self, v)
Definition z3py.py:6122
__getitem__(self, i)
Definition z3py.py:6077
sexpr(self)
Definition z3py.py:6195
__del__(self)
Definition z3py.py:6060
__setitem__(self, i, v)
Definition z3py.py:6106
__contains__(self, item)
Definition z3py.py:6147
__copy__(self)
Definition z3py.py:6186
resize(self, sz)
Definition z3py.py:6134
as_binary_string(self)
Definition z3py.py:4090
as_signed_long(self)
Definition z3py.py:4064
as_string(self)
Definition z3py.py:4087
__and__(self, other)
Definition z3py.py:3754
__rmod__(self, other)
Definition z3py.py:3895
__rrshift__(self, other)
Definition z3py.py:4021
__mod__(self, other)
Definition z3py.py:3874
__or__(self, other)
Definition z3py.py:3731
__rlshift__(self, other)
Definition z3py.py:4035
__gt__(self, other)
Definition z3py.py:3945
__lt__(self, other)
Definition z3py.py:3929
__invert__(self)
Definition z3py.py:3820
__rtruediv__(self, other)
Definition z3py.py:3870
__rmul__(self, other)
Definition z3py.py:3698
__rxor__(self, other)
Definition z3py.py:3790
__ror__(self, other)
Definition z3py.py:3744
__rsub__(self, other)
Definition z3py.py:3721
__add__(self, other)
Definition z3py.py:3662
__sub__(self, other)
Definition z3py.py:3708
__radd__(self, other)
Definition z3py.py:3675
size(self)
Definition z3py.py:3651
__rand__(self, other)
Definition z3py.py:3767
__truediv__(self, other)
Definition z3py.py:3850
__le__(self, other)
Definition z3py.py:3913
__xor__(self, other)
Definition z3py.py:3777
__lshift__(self, other)
Definition z3py.py:4007
__pos__(self)
Definition z3py.py:3800
sort(self)
Definition z3py.py:3640
__mul__(self, other)
Definition z3py.py:3685
__rdiv__(self, other)
Definition z3py.py:3854
__ge__(self, other)
Definition z3py.py:3961
__neg__(self)
Definition z3py.py:3809
__rshift__(self, other)
Definition z3py.py:3977
__div__(self, other)
Definition z3py.py:3831
Bit-Vectors.
Definition z3py.py:3593
subsort(self, other)
Definition z3py.py:3605
cast(self, val)
Definition z3py.py:3608
__and__(self, other)
Definition z3py.py:1685
__or__(self, other)
Definition z3py.py:1688
__invert__(self)
Definition z3py.py:1694
__rmul__(self, other)
Definition z3py.py:1671
__add__(self, other)
Definition z3py.py:1663
py_value(self)
Definition z3py.py:1697
__radd__(self, other)
Definition z3py.py:1668
__xor__(self, other)
Definition z3py.py:1691
sort(self)
Definition z3py.py:1660
__mul__(self, other)
Definition z3py.py:1674
Booleans.
Definition z3py.py:1621
subsort(self, other)
Definition z3py.py:1647
is_bool(self)
Definition z3py.py:1653
cast(self, val)
Definition z3py.py:1624
__deepcopy__(self, memo={})
Definition z3py.py:7077
__eq__(self, other)
Definition z3py.py:7080
__ne__(self, other)
Definition z3py.py:7083
__init__(self, r)
Definition z3py.py:7074
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
__deepcopy__(self, memo={})
Definition z3py.py:5249
create(self)
Definition z3py.py:5288
__init__(self, name, ctx=None)
Definition z3py.py:5244
__repr__(self)
Definition z3py.py:5285
declare(self, name, *args)
Definition z3py.py:5264
declare_core(self, name, rec_name, *args)
Definition z3py.py:5254
constructor(self, idx)
Definition z3py.py:5441
accessor(self, i, j)
Definition z3py.py:5488
num_constructors(self)
Definition z3py.py:5428
recognizer(self, idx)
Definition z3py.py:5460
Expressions.
Definition z3py.py:1021
update(self, *args)
Definition z3py.py:1177
as_ast(self)
Definition z3py.py:1032
__hash__(self)
Definition z3py.py:1078
kind(self)
Definition z3py.py:1118
children(self)
Definition z3py.py:1162
serialize(self)
Definition z3py.py:1204
get_id(self)
Definition z3py.py:1035
num_args(self)
Definition z3py.py:1125
__eq__(self, other)
Definition z3py.py:1061
__ne__(self, other)
Definition z3py.py:1082
from_string(self, s)
Definition z3py.py:1201
sort_kind(self)
Definition z3py.py:1050
arg(self, idx)
Definition z3py.py:1141
sort(self)
Definition z3py.py:1038
params(self)
Definition z3py.py:1100
decl(self)
Definition z3py.py:1103
Function Declarations.
Definition z3py.py:778
as_func_decl(self)
Definition z3py.py:792
domain(self, i)
Definition z3py.py:816
as_ast(self)
Definition z3py.py:786
__call__(self, *args)
Definition z3py.py:879
arity(self)
Definition z3py.py:806
get_id(self)
Definition z3py.py:789
range(self)
Definition z3py.py:828
params(self)
Definition z3py.py:851
Definition z3py.py:6331
__deepcopy__(self, memo={})
Definition z3py.py:6339
ctx
Definition z3py.py:6336
__repr__(self)
Definition z3py.py:6436
num_args(self)
Definition z3py.py:6346
entry
Definition z3py.py:6335
value(self)
Definition z3py.py:6395
__init__(self, entry, ctx)
Definition z3py.py:6334
__del__(self)
Definition z3py.py:6342
as_list(self)
Definition z3py.py:6417
arg_value(self, idx)
Definition z3py.py:6364
__deepcopy__(self, memo={})
Definition z3py.py:6534
translate(self, other_ctx)
Definition z3py.py:6526
arity(self)
Definition z3py.py:6492
__repr__(self)
Definition z3py.py:6554
num_entries(self)
Definition z3py.py:6476
__init__(self, f, ctx)
Definition z3py.py:6443
__del__(self)
Definition z3py.py:6449
as_list(self)
Definition z3py.py:6537
else_value(self)
Definition z3py.py:6453
entry(self, idx)
Definition z3py.py:6506
__copy__(self)
Definition z3py.py:6531
__deepcopy__(self, memo={})
Definition z3py.py:5994
get(self, i)
Definition z3py.py:5852
prec(self)
Definition z3py.py:5796
translate(self, target)
Definition z3py.py:5968
append(self, *args)
Definition z3py.py:5895
as_expr(self)
Definition z3py.py:6017
assert_exprs(self, *args)
Definition z3py.py:5880
__repr__(self)
Definition z3py.py:5957
__len__(self)
Definition z3py.py:5839
inconsistent(self)
Definition z3py.py:5778
dimacs(self, include_names=True)
Definition z3py.py:5964
__getitem__(self, arg)
Definition z3py.py:5865
size(self)
Definition z3py.py:5826
precision(self)
Definition z3py.py:5817
simplify(self, *arguments, **keywords)
Definition z3py.py:5997
sexpr(self)
Definition z3py.py:5960
add(self, *args)
Definition z3py.py:5917
__del__(self)
Definition z3py.py:5756
convert_model(self, model)
Definition z3py.py:5928
insert(self, *args)
Definition z3py.py:5906
depth(self)
Definition z3py.py:5760
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5746
__copy__(self)
Definition z3py.py:5991
as_binary_string(self)
Definition z3py.py:3129
py_value(self)
Definition z3py.py:3137
as_long(self)
Definition z3py.py:3108
as_string(self)
Definition z3py.py:3121
__deepcopy__(self, memo={})
Definition z3py.py:6900
eval(self, t, model_completion=False)
Definition z3py.py:6578
translate(self, target)
Definition z3py.py:6865
__getitem__(self, idx)
Definition z3py.py:6779
num_sorts(self)
Definition z3py.py:6704
get_universe(self, s)
Definition z3py.py:6759
get_sort(self, idx)
Definition z3py.py:6719
project(self, vars, fml)
Definition z3py.py:6873
__repr__(self)
Definition z3py.py:6571
__len__(self)
Definition z3py.py:6635
get_interp(self, decl)
Definition z3py.py:6652
__init__(self, m, ctx)
Definition z3py.py:6561
sexpr(self)
Definition z3py.py:6574
sorts(self)
Definition z3py.py:6742
__del__(self)
Definition z3py.py:6567
decls(self)
Definition z3py.py:6824
project_with_witness(self, vars, fml)
Definition z3py.py:6885
update_value(self, x, value)
Definition z3py.py:6843
evaluate(self, t, model_completion=False)
Definition z3py.py:6609
__copy__(self)
Definition z3py.py:6897
__deepcopy__(self, memo={})
Definition z3py.py:5690
__init__(self, descr, ctx=None)
Definition z3py.py:5684
get_kind(self, n)
Definition z3py.py:5712
get_documentation(self, n)
Definition z3py.py:5717
__getitem__(self, arg)
Definition z3py.py:5722
get_name(self, i)
Definition z3py.py:5707
Parameter Sets.
Definition z3py.py:5611
__deepcopy__(self, memo={})
Definition z3py.py:5625
validate(self, ds)
Definition z3py.py:5652
__repr__(self)
Definition z3py.py:5649
__init__(self, ctx=None, params=None)
Definition z3py.py:5617
set(self, name, val)
Definition z3py.py:5632
__del__(self)
Definition z3py.py:5628
Patterns.
Definition z3py.py:2057
as_ast(self)
Definition z3py.py:2062
get_id(self)
Definition z3py.py:2065
Quantifiers.
Definition z3py.py:2124
num_no_patterns(self)
Definition z3py.py:2242
no_pattern(self, idx)
Definition z3py.py:2246
num_patterns(self)
Definition z3py.py:2212
var_name(self, idx)
Definition z3py.py:2275
__getitem__(self, arg)
Definition z3py.py:2181
var_sort(self, idx)
Definition z3py.py:2291
pattern(self, idx)
Definition z3py.py:2224
numerator_as_long(self)
Definition z3py.py:3170
is_int_value(self)
Definition z3py.py:3200
as_fraction(self)
Definition z3py.py:3228
py_value(self)
Definition z3py.py:3237
numerator(self)
Definition z3py.py:3144
is_real(self)
Definition z3py.py:3197
as_long(self)
Definition z3py.py:3203
is_int(self)
Definition z3py.py:3194
denominator_as_long(self)
Definition z3py.py:3183
as_string(self)
Definition z3py.py:3219
denominator(self)
Definition z3py.py:3159
as_decimal(self, prec)
Definition z3py.py:3207
__init__(self, c, ctx)
Definition z3py.py:5308
__init__(self, c, ctx)
Definition z3py.py:5320
Strings, Sequences and Regular expressions.
Definition z3py.py:11066
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7121
assert_and_track(self, a, p)
Definition z3py.py:7290
num_scopes(self)
Definition z3py.py:7202
append(self, *args)
Definition z3py.py:7268
__iadd__(self, fml)
Definition z3py.py:7264
backtrack_level
Definition z3py.py:7124
pop(self, num=1)
Definition z3py.py:7180
import_model_converter(self, other)
Definition z3py.py:7368
assert_exprs(self, *args)
Definition z3py.py:7234
model(self)
Definition z3py.py:7349
set(self, *args, **keys)
Definition z3py.py:7145
__enter__(self)
Definition z3py.py:7138
add(self, *args)
Definition z3py.py:7253
__del__(self)
Definition z3py.py:7134
insert(self, *args)
Definition z3py.py:7279
check(self, *assumptions)
Definition z3py.py:7320
push(self)
Definition z3py.py:7158
__exit__(self, *exc_info)
Definition z3py.py:7142
reset(self)
Definition z3py.py:7220
subsort(self, other)
Definition z3py.py:619
as_ast(self)
Definition z3py.py:596
__hash__(self)
Definition z3py.py:680
kind(self)
Definition z3py.py:602
__gt__(self, other)
Definition z3py.py:676
get_id(self)
Definition z3py.py:599
__eq__(self, other)
Definition z3py.py:652
__ne__(self, other)
Definition z3py.py:665
cast(self, val)
Definition z3py.py:627
name(self)
Definition z3py.py:642
Statistics.
Definition z3py.py:6930
__deepcopy__(self, memo={})
Definition z3py.py:6938
__getattr__(self, name)
Definition z3py.py:7033
__getitem__(self, idx)
Definition z3py.py:6977
__init__(self, stats, ctx)
Definition z3py.py:6933
__repr__(self)
Definition z3py.py:6945
__len__(self)
Definition z3py.py:6963
__del__(self)
Definition z3py.py:6941
get_key_value(self, key)
Definition z3py.py:7013
subsort(self, other)
Definition z3py.py:754
cast(self, val)
Definition z3py.py:757
ASTs base class.
Definition z3py.py:358
_repr_html_(self)
Definition z3py.py:364
use_pp(self)
Definition z3py.py:361
Z3_ast Z3_API Z3_model_get_const_interp(Z3_context c, Z3_model m, Z3_func_decl a)
Return the interpretation (i.e., assignment) of constant a in the model m. Return NULL,...
Z3_sort Z3_API Z3_mk_int_sort(Z3_context c)
Create the integer type.
Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const *domain, Z3_sort range)
Create an array type with N arguments.
bool Z3_API Z3_open_log(Z3_string filename)
Log interaction to a file.
Z3_parameter_kind Z3_API Z3_get_decl_parameter_kind(Z3_context c, Z3_func_decl d, unsigned idx)
Return the parameter type associated with a declaration.
Z3_ast Z3_API Z3_get_denominator(Z3_context c, Z3_ast a)
Return the denominator (as a numeral AST) of a numeral AST of sort Real.
Z3_probe Z3_API Z3_probe_not(Z3_context x, Z3_probe p)
Return a probe that evaluates to "true" when p does not evaluate to true.
Z3_decl_kind Z3_API Z3_get_decl_kind(Z3_context c, Z3_func_decl d)
Return declaration kind corresponding to declaration.
void Z3_API Z3_solver_assert_and_track(Z3_context c, Z3_solver s, Z3_ast a, Z3_ast p)
Assert a constraint a into the solver, and track it (in the unsat) core using the Boolean constant p.
Z3_ast Z3_API Z3_func_interp_get_else(Z3_context c, Z3_func_interp f)
Return the 'else' value of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsge(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than or equal to.
void Z3_API Z3_ast_map_inc_ref(Z3_context c, Z3_ast_map m)
Increment the reference counter of the given AST map.
Z3_ast Z3_API Z3_mk_const_array(Z3_context c, Z3_sort domain, Z3_ast v)
Create the constant array.
Z3_ast Z3_API Z3_mk_bvsle(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than or equal to.
Z3_func_decl Z3_API Z3_get_app_decl(Z3_context c, Z3_app a)
Return the declaration of a constant or function application.
void Z3_API Z3_del_context(Z3_context c)
Delete the given logical context.
Z3_func_decl Z3_API Z3_get_decl_func_decl_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_ast Z3_API Z3_ast_map_find(Z3_context c, Z3_ast_map m, Z3_ast k)
Return the value associated with the key k.
Z3_string Z3_API Z3_ast_map_to_string(Z3_context c, Z3_ast_map m)
Convert the given map into a string.
Z3_string Z3_API Z3_param_descrs_to_string(Z3_context c, Z3_param_descrs p)
Convert a parameter description set into a string. This function is mainly used for printing the cont...
Z3_ast Z3_API Z3_mk_zero_ext(Z3_context c, unsigned i, Z3_ast t1)
Extend the given bit-vector with zeros to the (unsigned) equivalent bit-vector of size m+i,...
void Z3_API Z3_solver_set_params(Z3_context c, Z3_solver s, Z3_params p)
Set the given solver using the given parameters.
Z3_ast Z3_API Z3_mk_set_intersect(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the intersection of a list of sets.
Z3_params Z3_API Z3_mk_params(Z3_context c)
Create a Z3 (empty) parameter set. Starting at Z3 4.0, parameter sets are used to configure many comp...
unsigned Z3_API Z3_get_decl_num_parameters(Z3_context c, Z3_func_decl d)
Return the number of parameters associated with a declaration.
Z3_ast Z3_API Z3_mk_set_subset(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Check for subsetness of sets.
Z3_ast Z3_API Z3_mk_bvule(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than or equal to.
Z3_ast Z3_API Z3_mk_full_set(Z3_context c, Z3_sort domain)
Create the full set.
Z3_param_kind Z3_API Z3_param_descrs_get_kind(Z3_context c, Z3_param_descrs p, Z3_symbol n)
Return the kind associated with the given parameter name n.
void Z3_API Z3_add_rec_def(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast args[], Z3_ast body)
Define the body of a recursive function.
Z3_ast Z3_API Z3_mk_true(Z3_context c)
Create an AST node representing true.
Z3_ast Z3_API Z3_mk_set_union(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the union of a list of sets.
Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast default_value)
Create a fresh func_interp object, add it to a model for a specified function. It has reference count...
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed division of t1 and t2 does not overflow.
unsigned Z3_API Z3_get_arity(Z3_context c, Z3_func_decl d)
Alias for Z3_get_domain_size.
void Z3_API Z3_ast_vector_set(Z3_context c, Z3_ast_vector v, unsigned i, Z3_ast a)
Update position i of the AST vector v with the AST a.
Z3_ast Z3_API Z3_mk_bvxor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise exclusive-or.
Z3_string Z3_API Z3_stats_to_string(Z3_context c, Z3_stats s)
Convert a statistics into a string.
Z3_sort Z3_API Z3_mk_real_sort(Z3_context c)
Create the real type.
Z3_ast Z3_API Z3_mk_le(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than or equal to.
bool Z3_API Z3_global_param_get(Z3_string param_id, Z3_string_ptr param_value)
Get a global (or module) parameter.
bool Z3_API Z3_goal_inconsistent(Z3_context c, Z3_goal g)
Return true if the given goal contains the formula false.
Z3_ast Z3_API Z3_mk_lambda_const(Z3_context c, unsigned num_bound, Z3_app const bound[], Z3_ast body)
Create a lambda expression using a list of constants that form the set of bound variables.
void Z3_API Z3_solver_dec_ref(Z3_context c, Z3_solver s)
Decrement the reference counter of the given solver.
Z3_ast Z3_API Z3_mk_bvslt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than.
Z3_func_decl Z3_API Z3_model_get_func_decl(Z3_context c, Z3_model m, unsigned i)
Return the declaration of the i-th function in the given model.
bool Z3_API Z3_ast_map_contains(Z3_context c, Z3_ast_map m, Z3_ast k)
Return true if the map m contains the AST key k.
Z3_ast Z3_API Z3_mk_numeral(Z3_context c, Z3_string numeral, Z3_sort ty)
Create a numeral of a given sort.
unsigned Z3_API Z3_func_entry_get_num_args(Z3_context c, Z3_func_entry e)
Return the number of arguments in a Z3_func_entry object.
Z3_symbol Z3_API Z3_get_decl_symbol_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the double value associated with an double parameter.
Z3_symbol Z3_API Z3_get_quantifier_skolem_id(Z3_context c, Z3_ast a)
Obtain skolem id of quantifier.
Z3_ast Z3_API Z3_get_numerator(Z3_context c, Z3_ast a)
Return the numerator (as a numeral AST) of a numeral AST of sort Real.
Z3_ast Z3_API Z3_mk_unary_minus(Z3_context c, Z3_ast arg)
Create an AST node representing - arg.
Z3_ast Z3_API Z3_mk_and(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] and ... and args[num_args-1].
void Z3_API Z3_interrupt(Z3_context c)
Interrupt the execution of a Z3 procedure. This procedure can be used to interrupt: solvers,...
void Z3_API Z3_goal_assert(Z3_context c, Z3_goal g, Z3_ast a)
Add a new formula a to the given goal. The formula is split according to the following procedure that...
Z3_symbol Z3_API Z3_param_descrs_get_name(Z3_context c, Z3_param_descrs p, unsigned i)
Return the name of the parameter at given index i.
Z3_ast Z3_API Z3_func_entry_get_value(Z3_context c, Z3_func_entry e)
Return the value of this point.
bool Z3_API Z3_is_quantifier_exists(Z3_context c, Z3_ast a)
Determine if ast is an existential quantifier.
Z3_sort Z3_API Z3_mk_uninterpreted_sort(Z3_context c, Z3_symbol s)
Create a free (uninterpreted) type using the given name (symbol).
Z3_ast Z3_API Z3_mk_false(Z3_context c)
Create an AST node representing false.
Z3_ast_vector Z3_API Z3_ast_map_keys(Z3_context c, Z3_ast_map m)
Return the keys stored in the given map.
Z3_ast Z3_API Z3_mk_bvmul(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement multiplication.
Z3_model Z3_API Z3_goal_convert_model(Z3_context c, Z3_goal g, Z3_model m)
Convert a model of the formulas of a goal to a model of an original goal. The model may be null,...
void Z3_API Z3_del_constructor(Z3_context c, Z3_constructor constr)
Reclaim memory allocated to constructor.
Z3_ast Z3_API Z3_mk_bvsgt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than.
Z3_string Z3_API Z3_ast_to_string(Z3_context c, Z3_ast a)
Convert the given AST node into a string.
Z3_context Z3_API Z3_mk_context_rc(Z3_config c)
Create a context using the given configuration. This function is similar to Z3_mk_context....
Z3_string Z3_API Z3_get_full_version(void)
Return a string that fully describes the version of Z3 in use.
void Z3_API Z3_enable_trace(Z3_string tag)
Enable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_mk_set_complement(Z3_context c, Z3_ast arg)
Take the complement of a set.
unsigned Z3_API Z3_get_quantifier_num_patterns(Z3_context c, Z3_ast a)
Return number of patterns used in quantifier.
Z3_symbol Z3_API Z3_get_quantifier_bound_name(Z3_context c, Z3_ast a, unsigned i)
Return symbol of the i'th bound variable.
bool Z3_API Z3_stats_is_uint(Z3_context c, Z3_stats s, unsigned idx)
Return true if the given statistical data is a unsigned integer.
unsigned Z3_API Z3_model_get_num_consts(Z3_context c, Z3_model m)
Return the number of constants assigned by the given model.
Z3_ast Z3_API Z3_mk_extract(Z3_context c, unsigned high, unsigned low, Z3_ast t1)
Extract the bits high down to low from a bit-vector of size m to yield a new bit-vector of size n,...
Z3_ast Z3_API Z3_mk_mod(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 mod arg2.
Z3_ast Z3_API Z3_mk_bvredand(Z3_context c, Z3_ast t1)
Take conjunction of bits in vector, return vector of length 1.
Z3_ast Z3_API Z3_mk_set_add(Z3_context c, Z3_ast set, Z3_ast elem)
Add an element to a set.
Z3_ast Z3_API Z3_mk_ge(Z3_context c, Z3_ast t1, Z3_ast t2)
Create greater than or equal to.
Z3_ast Z3_API Z3_mk_bvadd_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed addition of t1 and t2 does not underflow.
Z3_ast Z3_API Z3_mk_bvadd_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise addition of t1 and t2 does not overflow.
void Z3_API Z3_set_ast_print_mode(Z3_context c, Z3_ast_print_mode mode)
Select mode for the format used for pretty-printing AST nodes.
Z3_ast Z3_API Z3_mk_array_default(Z3_context c, Z3_ast array)
Access the array default value. Produces the default range value, for arrays that can be represented ...
unsigned Z3_API Z3_model_get_num_sorts(Z3_context c, Z3_model m)
Return the number of uninterpreted sorts that m assigns an interpretation to.
Z3_ast_vector Z3_API Z3_ast_vector_translate(Z3_context s, Z3_ast_vector v, Z3_context t)
Translate the AST vector v from context s into an AST vector in context t.
void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e)
Increment the reference counter of the given Z3_func_entry object.
Z3_ast Z3_API Z3_mk_fresh_const(Z3_context c, Z3_string prefix, Z3_sort ty)
Declare and create a fresh constant.
Z3_ast Z3_API Z3_mk_bvsub_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed subtraction of t1 and t2 does not overflow.
void Z3_API Z3_solver_push(Z3_context c, Z3_solver s)
Create a backtracking point.
Z3_ast Z3_API Z3_mk_bvsub_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise subtraction of t1 and t2 does not underflow.
Z3_goal Z3_API Z3_goal_translate(Z3_context source, Z3_goal g, Z3_context target)
Copy a goal g from the context source to the context target.
Z3_ast Z3_API Z3_mk_bvudiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned division.
Z3_string Z3_API Z3_ast_vector_to_string(Z3_context c, Z3_ast_vector v)
Convert AST vector into a string.
Z3_ast Z3_API Z3_mk_bvshl(Z3_context c, Z3_ast t1, Z3_ast t2)
Shift left.
bool Z3_API Z3_is_numeral_ast(Z3_context c, Z3_ast a)
Z3_ast Z3_API Z3_mk_bvsrem(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed remainder (sign follows dividend).
bool Z3_API Z3_is_as_array(Z3_context c, Z3_ast a)
The (_ as-array f) AST node is a construct for assigning interpretations for arrays in Z3....
Z3_func_decl Z3_API Z3_mk_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a constant or function.
Z3_ast Z3_API Z3_mk_is_int(Z3_context c, Z3_ast t1)
Check if a real number is an integer.
void Z3_API Z3_params_set_bool(Z3_context c, Z3_params p, Z3_symbol k, bool v)
Add a Boolean parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_mk_ite(Z3_context c, Z3_ast t1, Z3_ast t2, Z3_ast t3)
Create an AST node representing an if-then-else: ite(t1, t2, t3).
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i)
Array read. The argument a is the array and i is the index of the array that gets read.
Z3_ast Z3_API Z3_mk_sign_ext(Z3_context c, unsigned i, Z3_ast t1)
Sign-extend of the given bit-vector to the (signed) equivalent bit-vector of size m+i,...
unsigned Z3_API Z3_goal_size(Z3_context c, Z3_goal g)
Return the number of formulas in the given goal.
void Z3_API Z3_stats_inc_ref(Z3_context c, Z3_stats s)
Increment the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs)
n-ary Array read. The argument a is the array and idxs are the indices of the array that gets read.
Z3_ast_vector Z3_API Z3_algebraic_get_poly(Z3_context c, Z3_ast a)
Return the coefficients of the defining polynomial.
Z3_ast Z3_API Z3_mk_div(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 div arg2.
void Z3_API Z3_model_dec_ref(Z3_context c, Z3_model m)
Decrement the reference counter of the given model.
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_solver Z3_API Z3_mk_solver(Z3_context c)
Create a new solver. This solver is a "combined solver" (see combined_solver module) that internally ...
Z3_model Z3_API Z3_solver_get_model(Z3_context c, Z3_solver s)
Retrieve the model for the last Z3_solver_check or Z3_solver_check_assumptions.
int Z3_API Z3_get_symbol_int(Z3_context c, Z3_symbol s)
Return the symbol int value.
Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a)
Return the function declaration f associated with a (_ as_array f) node.
Z3_ast Z3_API Z3_mk_ext_rotate_left(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the left t2 times.
void Z3_API Z3_goal_inc_ref(Z3_context c, Z3_goal g)
Increment the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_implies(Z3_context c, Z3_ast t1, Z3_ast t2)
Create an AST node representing t1 implies t2.
unsigned Z3_API Z3_get_datatype_sort_num_constructors(Z3_context c, Z3_sort t)
Return number of constructors for datatype.
void Z3_API Z3_params_set_uint(Z3_context c, Z3_params p, Z3_symbol k, unsigned v)
Add a unsigned parameter k with value v to the parameter set p.
Z3_lbool Z3_API Z3_solver_check_assumptions(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[])
Check whether the assertions in the given solver and optional assumptions are consistent or not.
Z3_sort Z3_API Z3_model_get_sort(Z3_context c, Z3_model m, unsigned i)
Return a uninterpreted sort that m assigns an interpretation.
Z3_ast Z3_API Z3_mk_bvashr(Z3_context c, Z3_ast t1, Z3_ast t2)
Arithmetic shift right.
Z3_ast Z3_API Z3_mk_bv2int(Z3_context c, Z3_ast t1, bool is_signed)
Create an integer from the bit-vector argument t1. If is_signed is false, then the bit-vector t1 is t...
Z3_sort Z3_API Z3_get_array_sort_domain_n(Z3_context c, Z3_sort t, unsigned idx)
Return the i'th domain sort of an n-dimensional array.
Z3_ast Z3_API Z3_mk_set_del(Z3_context c, Z3_ast set, Z3_ast elem)
Remove an element to a set.
Z3_ast Z3_API Z3_mk_bvmul_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise multiplication of t1 and t2 does not overflow.
Z3_ast Z3_API Z3_mk_bvor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise or.
int Z3_API Z3_get_decl_int_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the integer value associated with an integer parameter.
unsigned Z3_API Z3_get_quantifier_num_no_patterns(Z3_context c, Z3_ast a)
Return number of no_patterns used in quantifier.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor(Z3_context c, Z3_sort t, unsigned idx)
Return idx'th constructor.
void Z3_API Z3_ast_vector_resize(Z3_context c, Z3_ast_vector v, unsigned n)
Resize the AST vector v.
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c, bool is_forall, unsigned weight, Z3_symbol quantifier_id, Z3_symbol skolem_id, unsigned num_bound, Z3_app const bound[], unsigned num_patterns, Z3_pattern const patterns[], unsigned num_no_patterns, Z3_ast const no_patterns[], Z3_ast body)
Create a universal or existential quantifier using a list of constants that will form the set of boun...
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[])
Create a pattern for quantifier instantiation.
Z3_symbol_kind Z3_API Z3_get_symbol_kind(Z3_context c, Z3_symbol s)
Return Z3_INT_SYMBOL if the symbol was constructed using Z3_mk_int_symbol, and Z3_STRING_SYMBOL if th...
bool Z3_API Z3_is_lambda(Z3_context c, Z3_ast a)
Determine if ast is a lambda expression.
unsigned Z3_API Z3_stats_get_uint_value(Z3_context c, Z3_stats s, unsigned idx)
Return the unsigned value of the given statistical data.
Z3_sort Z3_API Z3_get_array_sort_domain(Z3_context c, Z3_sort t)
Return the domain of the given array sort. In the case of a multi-dimensional array,...
Z3_ast Z3_API Z3_mk_bvmul_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed multiplication of t1 and t2 does not underflo...
Z3_ast Z3_API Z3_func_decl_to_ast(Z3_context c, Z3_func_decl f)
Convert a Z3_func_decl into Z3_ast. This is just type casting.
void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a)
Add a constant interpretation.
Z3_ast Z3_API Z3_mk_bvadd(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement addition.
unsigned Z3_API Z3_algebraic_get_i(Z3_context c, Z3_ast a)
Return which root of the polynomial the algebraic number represents.
void Z3_API Z3_params_dec_ref(Z3_context c, Z3_params p)
Decrement the reference counter of the given parameter set.
Z3_ast Z3_API Z3_get_app_arg(Z3_context c, Z3_app a, unsigned i)
Return the i-th argument of the given application.
Z3_string Z3_API Z3_model_to_string(Z3_context c, Z3_model m)
Convert the given model into a string.
Z3_func_decl Z3_API Z3_mk_fresh_func_decl(Z3_context c, Z3_string prefix, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a fresh constant or function.
unsigned Z3_API Z3_ast_map_size(Z3_context c, Z3_ast_map m)
Return the size of the given map.
unsigned Z3_API Z3_param_descrs_size(Z3_context c, Z3_param_descrs p)
Return the number of parameters in the given parameter description set.
Z3_string Z3_API Z3_goal_to_dimacs_string(Z3_context c, Z3_goal g, bool include_names)
Convert a goal into a DIMACS formatted string. The goal must be in CNF. You can convert a goal to CNF...
Z3_ast Z3_API Z3_mk_lt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than.
Z3_ast Z3_API Z3_get_quantifier_no_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th no_pattern.
double Z3_API Z3_stats_get_double_value(Z3_context c, Z3_stats s, unsigned idx)
Return the double value of the given statistical data.
Z3_ast Z3_API Z3_mk_bvugt(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than.
unsigned Z3_API Z3_goal_depth(Z3_context c, Z3_goal g)
Return the depth of the given goal. It tracks how many transformations were applied to it.
Z3_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_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_const(Z3_context c, Z3_symbol s, Z3_sort ty)
Declare and create a constant.
Z3_symbol Z3_API Z3_mk_string_symbol(Z3_context c, Z3_string s)
Create a Z3 symbol using a C string.
void Z3_API Z3_param_descrs_inc_ref(Z3_context c, Z3_param_descrs p)
Increment the reference counter of the given parameter description set.
void Z3_API Z3_stats_dec_ref(Z3_context c, Z3_stats s)
Decrement the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_array_ext(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create array extensionality index given two arrays with the same sort. The meaning is given by the ax...
Z3_ast Z3_API Z3_mk_re_concat(Z3_context c, unsigned n, Z3_ast const args[])
Create the concatenation of the regular languages.
Z3_ast Z3_API Z3_sort_to_ast(Z3_context c, Z3_sort s)
Convert a Z3_sort into Z3_ast. This is just type casting.
Z3_func_entry Z3_API Z3_func_interp_get_entry(Z3_context c, Z3_func_interp f, unsigned i)
Return a "point" of the given function interpretation. It represents the value of f in a particular p...
Z3_func_decl Z3_API Z3_mk_rec_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a recursive function.
unsigned Z3_API Z3_get_ast_id(Z3_context c, Z3_ast t)
Return a unique identifier for t. The identifier is unique up to structural equality....
Z3_ast Z3_API Z3_mk_concat(Z3_context c, Z3_ast t1, Z3_ast t2)
Concatenate the given bit-vectors.
unsigned Z3_API Z3_get_quantifier_num_bound(Z3_context c, Z3_ast a)
Return number of bound variables of quantifier.
Z3_sort Z3_API Z3_get_decl_sort_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the sort value associated with a sort parameter.
Z3_constructor_list Z3_API Z3_mk_constructor_list(Z3_context c, unsigned num_constructors, Z3_constructor const constructors[])
Create list of constructors.
Z3_ast Z3_API Z3_mk_app(Z3_context c, Z3_func_decl d, unsigned num_args, Z3_ast const args[])
Create a constant or function application.
Z3_sort_kind Z3_API Z3_get_sort_kind(Z3_context c, Z3_sort t)
Return the sort kind (e.g., array, tuple, int, bool, etc).
Z3_ast Z3_API Z3_mk_bvneg(Z3_context c, Z3_ast t1)
Standard two's complement unary minus.
Z3_ast Z3_API Z3_mk_store_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs, Z3_ast v)
n-ary Array update.
Z3_sort Z3_API Z3_get_domain(Z3_context c, Z3_func_decl d, unsigned i)
Return the sort of the i-th parameter of the given function declaration.
Z3_sort Z3_API Z3_mk_bool_sort(Z3_context c)
Create the Boolean type.
void Z3_API Z3_params_set_symbol(Z3_context c, Z3_params p, Z3_symbol k, Z3_symbol v)
Add a symbol parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_ast_vector_get(Z3_context c, Z3_ast_vector v, unsigned i)
Return the AST at position i in the AST vector v.
Z3_func_decl Z3_API Z3_to_func_decl(Z3_context c, Z3_ast a)
Convert an AST into a FUNC_DECL_AST. This is just type casting.
Z3_ast Z3_API Z3_mk_set_difference(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Take the set difference between two sets.
Z3_ast Z3_API Z3_mk_bvsdiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed division.
Z3_ast Z3_API Z3_mk_bvlshr(Z3_context c, Z3_ast t1, Z3_ast t2)
Logical shift right.
Z3_ast Z3_API Z3_get_decl_ast_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_pattern Z3_API Z3_get_quantifier_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th pattern.
void Z3_API Z3_goal_dec_ref(Z3_context c, Z3_goal g)
Decrement the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_not(Z3_context c, Z3_ast a)
Create an AST node representing not(a).
Z3_ast Z3_API Z3_mk_or(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] or ... or args[num_args-1].
Z3_sort Z3_API Z3_mk_array_sort(Z3_context c, Z3_sort domain, Z3_sort range)
Create an array type.
void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m)
Increment the reference counter of the given model.
Z3_ast Z3_API Z3_mk_seq_extract(Z3_context c, Z3_ast s, Z3_ast offset, Z3_ast length)
Extract subsequence starting at offset of length.
Z3_sort Z3_API Z3_mk_type_variable(Z3_context c, Z3_symbol s)
Create a type variable.
Z3_string Z3_API Z3_get_numeral_string(Z3_context c, Z3_ast a)
Return numeral value, as a decimal string of a numeric constant term.
void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value)
add a function entry to a function interpretation.
Z3_ast Z3_API Z3_mk_bvuge(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than or equal to.
Z3_string Z3_API Z3_get_numeral_binary_string(Z3_context c, Z3_ast a)
Return numeral value, as a binary string of a numeric constant term.
Z3_sort Z3_API Z3_get_quantifier_bound_sort(Z3_context c, Z3_ast a, unsigned i)
Return sort of the i'th bound variable.
void Z3_API Z3_disable_trace(Z3_string tag)
Disable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_goal_formula(Z3_context c, Z3_goal g, unsigned idx)
Return a formula from the given goal.
Z3_symbol Z3_API Z3_mk_int_symbol(Z3_context c, int i)
Create a Z3 symbol using an integer.
unsigned Z3_API Z3_func_interp_get_num_entries(Z3_context c, Z3_func_interp f)
Return the number of entries in the given function interpretation.
void Z3_API Z3_ast_map_insert(Z3_context c, Z3_ast_map m, Z3_ast k, Z3_ast v)
Store/Replace a new key, value pair in the given map.
Z3_constructor Z3_API Z3_mk_constructor(Z3_context c, Z3_symbol name, Z3_symbol recognizer, unsigned num_fields, Z3_symbol const field_names[], Z3_sort const sorts[], unsigned sort_refs[])
Create a constructor.
Z3_string Z3_API Z3_goal_to_string(Z3_context c, Z3_goal g)
Convert a goal into a string.
bool Z3_API Z3_is_eq_sort(Z3_context c, Z3_sort s1, Z3_sort s2)
compare sorts.
void Z3_API Z3_del_config(Z3_config c)
Delete the given configuration object.
double Z3_API Z3_get_numeral_double(Z3_context c, Z3_ast a)
Return numeral as a double.
void Z3_API Z3_inc_ref(Z3_context c, Z3_ast a)
Increment the reference counter of the given AST. The context c should have been created using Z3_mk_...
Z3_ast Z3_API Z3_mk_real2int(Z3_context c, Z3_ast t1)
Coerce a real to an integer.
Z3_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f)
Return the interpretation of the function f in the model m. Return NULL, if the model does not assign...
void Z3_API Z3_solver_inc_ref(Z3_context c, Z3_solver s)
Increment the reference counter of the given solver.
Z3_symbol Z3_API Z3_get_quantifier_id(Z3_context c, Z3_ast a)
Obtain id of quantifier.
Z3_ast Z3_API Z3_mk_ext_rotate_right(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the right t2 times.
Z3_string Z3_API Z3_get_numeral_decimal_string(Z3_context c, Z3_ast a, unsigned precision)
Return numeral as a string in decimal notation. The result has at most precision decimal places.
Z3_sort Z3_API Z3_get_sort(Z3_context c, Z3_ast a)
Return the sort of an AST node.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(Z3_context c, Z3_sort t, unsigned idx_c, unsigned idx_a)
Return idx_a'th accessor for the idx_c'th constructor.
Z3_ast Z3_API Z3_mk_bvredor(Z3_context c, Z3_ast t1)
Take disjunction of bits in vector, return vector of length 1.
void Z3_API Z3_ast_map_reset(Z3_context c, Z3_ast_map m)
Remove all keys from the given map.
void Z3_API Z3_solver_reset(Z3_context c, Z3_solver s)
Remove all assertions from the solver.
bool Z3_API Z3_is_algebraic_number(Z3_context c, Z3_ast a)
Return true if the given AST is a real algebraic number.
_py2expr(a, ctx=None)
Definition z3py.py:3275
RotateRight(a, b)
Definition z3py.py:4525
_symbol2py(ctx, s)
Definition z3py.py:140
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4175
BVSNegNoOverflow(a)
Definition z3py.py:4672
SetAdd(s, e)
Definition z3py.py:5137
SetSort(s)
Sets.
Definition z3py.py:5088
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1305
UGT(a, b)
Definition z3py.py:4396
is_probe(p)
Definition z3py.py:8968
SetDel(s, e)
Definition z3py.py:5148
bool is_le(Any a)
Definition z3py.py:3015
BoolSort(ctx=None)
Definition z3py.py:1827
is_bv_sort(s)
Definition z3py.py:3626
_ctx_from_ast_args(*args)
Definition z3py.py:545
RatVal(a, b, ctx=None)
Definition z3py.py:3367
_to_func_decl_ref(a, ctx)
Definition z3py.py:965
SetUnion(*args)
Definition z3py.py:5111
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5208
BitVec(name, bv, ctx=None)
Definition z3py.py:4192
EmptySet(s)
Definition z3py.py:5093
BVMulNoUnderflow(a, b)
Definition z3py.py:4686
CreateDatatypes(*ds)
Definition z3py.py:5329
is_func_decl(a)
Definition z3py.py:910
get_as_array_func(n)
Definition z3py.py:6917
Distinct(*args)
Definition z3py.py:1510
RecAddDefinition(f, args, body)
Definition z3py.py:987
ToInt(a)
Definition z3py.py:3526
Implies(a, b, ctx=None)
Definition z3py.py:1921
UGE(a, b)
Definition z3py.py:4378
Ext(a, b)
Definition z3py.py:5046
_to_ast_array(args)
Definition z3py.py:557
bool is_sort(Any s)
Definition z3py.py:685
_check_bv_args(a, b)
Definition z3py.py:4337
RealSort(ctx=None)
Definition z3py.py:3307
IsSubset(a, b)
Definition z3py.py:5191
DeclareTypeVar(name, ctx=None)
Definition z3py.py:761
_get_args_ast_list(args)
Definition z3py.py:168
bool is_to_real(Any a)
Definition z3py.py:3075
_to_ref_array(ref, args)
Definition z3py.py:565
get_map_func(a)
Definition z3py.py:4854
_z3_check_cint_overflow(n, name)
Definition z3py.py:118
bool is_and(Any a)
Definition z3py.py:1757
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5554
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1336
is_select(a)
Definition z3py.py:5057
SignExt(n, a)
Definition z3py.py:4541
Int(name, ctx=None)
Definition z3py.py:3396
Bools(names, ctx=None)
Definition z3py.py:1876
_probe_and(args, ctx)
Definition z3py.py:9035
Int2BV(a, num_bits)
Definition z3py.py:4151
Lambda(vs, body)
Definition z3py.py:2407
_to_param_value(val)
Definition z3py.py:178
FreshFunction(*sig)
Definition z3py.py:946
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3477
BVRedOr(a)
Definition z3py.py:4630
SRem(a, b)
Definition z3py.py:4456
SortRef _sort(Context ctx, Any a)
Definition z3py.py:729
set_option(*args, **kws)
Definition z3py.py:331
ExprRef RealVar(int idx, ctx=None)
Definition z3py.py:1593
bool is_sub(Any a)
Definition z3py.py:2962
is_bv(a)
Definition z3py.py:4099
SetDifference(a, b)
Definition z3py.py:5169
bool is_arith_sort(Any s)
Definition z3py.py:2510
BitVecs(names, bv, ctx=None)
Definition z3py.py:4216
_check_same_sort(a, b, ctx=None)
Definition z3py.py:1292
bool is_mod(Any a)
Definition z3py.py:3003
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1892
_has_probe(args)
Definition z3py.py:1977
IsMember(e, s)
Definition z3py.py:5180
get_param(name)
Definition z3py.py:337
BVAddNoUnderflow(a, b)
Definition z3py.py:4644
deserialize(st)
Definition z3py.py:1210
bool is_not(Any a)
Definition z3py.py:1793
Extract(high, low, a)
Definition z3py.py:4283
Function(name, *sig)
Definition z3py.py:923
get_version()
Definition z3py.py:100
FreshConst(sort, prefix="c")
Definition z3py.py:1570
ULT(a, b)
Definition z3py.py:4360
EnumSort(name, values, ctx=None)
Definition z3py.py:5578
bool is_is_int(Any a)
Definition z3py.py:3063
_to_int_str(val)
Definition z3py.py:3324
is_algebraic_value(a)
Definition z3py.py:2924
is_bv_value(a)
Definition z3py.py:4113
BVSDivNoOverflow(a, b)
Definition z3py.py:4665
bool is_eq(Any a)
Definition z3py.py:1805
Context main_ctx()
Definition z3py.py:269
SetIntersect(*args)
Definition z3py.py:5124
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9102
BV2Int(a, is_signed=False)
Definition z3py.py:4128
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3435
_to_ast_ref(a, ctx)
Definition z3py.py:573
_to_func_decl_array(args)
Definition z3py.py:549
disable_trace(msg)
Definition z3py.py:87
bool is_to_int(Any a)
Definition z3py.py:3090
is_map(a)
Definition z3py.py:4829
Context _get_ctx(ctx)
Definition z3py.py:290
Or(*args)
Definition z3py.py:2018
is_re(s)
Definition z3py.py:11556
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5657
bool is_idiv(Any a)
Definition z3py.py:2991
Consts(names, sort)
Definition z3py.py:1555
Cond(p, t1, t2, ctx=None)
Definition z3py.py:9085
_to_pattern(arg)
Definition z3py.py:2111
RealVarVector(int n, ctx=None)
Definition z3py.py:1603
is_arith(a)
Definition z3py.py:2811
bool is_true(Any a)
Definition z3py.py:1725
bool is_false(Any a)
Definition z3py.py:1743
bool is_int(a)
Definition z3py.py:2832
If(a, b, c, ctx=None)
Definition z3py.py:1487
bool eq(AstRef a, AstRef b)
Definition z3py.py:506
is_app_of(a, k)
Definition z3py.py:1474
is_app(a)
Definition z3py.py:1371
bool is_add(Any a)
Definition z3py.py:2938
z3_error_handler(c, e)
Definition z3py.py:184
None reset_params()
Definition z3py.py:325
Reals(names, ctx=None)
Definition z3py.py:3462
is_int_value(a)
Definition z3py.py:2878
set_param(*args, **kws)
Definition z3py.py:301
is_pattern(a)
Definition z3py.py:2069
_coerce_seq(s, ctx=None)
Definition z3py.py:11217
bool is_distinct(Any a)
Definition z3py.py:1815
bool is_lt(Any a)
Definition z3py.py:3027
ULE(a, b)
Definition z3py.py:4342
is_real(a)
Definition z3py.py:2851
FullSet(s)
Definition z3py.py:5102
to_symbol(s, ctx=None)
Definition z3py.py:132
bool is_mul(Any a)
Definition z3py.py:2950
bool is_ast(Any a)
Definition z3py.py:485
_get_args(args)
Definition z3py.py:152
And(*args)
Definition z3py.py:1985
RepeatBitVec(n, a)
Definition z3py.py:4599
get_version_string()
Definition z3py.py:91
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3492
Array(name, *sorts)
Definition z3py.py:4911
Concat(*args)
Definition z3py.py:4237
_reduce(func, sequence, initial)
Definition z3py.py:1329
_is_algebraic(ctx, a)
Definition z3py.py:2874
Ints(names, ctx=None)
Definition z3py.py:3409
Select(a, *args)
Definition z3py.py:4985
Const(name, sort)
Definition z3py.py:1543
is_array_sort(a)
Definition z3py.py:4785
bool is_div(Any a)
Definition z3py.py:2974
ExprRef Var(int idx, SortRef s)
Definition z3py.py:1578
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4637
Real(name, ctx=None)
Definition z3py.py:3449
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1907
BitVecSort(sz, ctx=None)
Definition z3py.py:4160
open_log(fname)
Definition z3py.py:122
RecFunction(name, *sig)
Definition z3py.py:969
bool is_ge(Any a)
Definition z3py.py:3039
Model(ctx=None, eval={})
Definition z3py.py:6904
BVSubNoOverflow(a, b)
Definition z3py.py:4651
bool is_gt(Any a)
Definition z3py.py:3051
is_default(a)
Definition z3py.py:4845
is_K(a)
Definition z3py.py:4816
Bool(name, ctx=None)
Definition z3py.py:1864
_is_int(v)
Definition z3py.py:76
is_const_array(a)
Definition z3py.py:4803
Sqrt(a, ctx=None)
Definition z3py.py:3561
Default(a)
Definition z3py.py:4957
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:531
SetComplement(s)
Definition z3py.py:5159
is_as_array(n)
Definition z3py.py:6912
is_store(a)
Definition z3py.py:5070
bool is_or(Any a)
Definition z3py.py:1769
is_quantifier(a)
Definition z3py.py:2319
_mk_bin(f, a, b)
Definition z3py.py:1534
K(dom, v)
Definition z3py.py:5024
Xor(a, b, ctx=None)
Definition z3py.py:1935
Store(a, *args)
Definition z3py.py:4968
bool is_array(Any a)
Definition z3py.py:4789
mk_not(a)
Definition z3py.py:1970
is_expr(a)
Definition z3py.py:1348
_array_select(ar, arg)
Definition z3py.py:4776
is_const(a)
Definition z3py.py:1397
BoolVal(val, ctx=None)
Definition z3py.py:1845
RealVal(val, ctx=None)
Definition z3py.py:3348
bool is_implies(Any a)
Definition z3py.py:1781
z3_debug()
Definition z3py.py:70
get_full_version()
Definition z3py.py:109
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3422
_coerce_expr_merge(s, a)
Definition z3py.py:1274
Context get_ctx(ctx)
Definition z3py.py:297
LShR(a, b)
Definition z3py.py:4477
ArraySort(*sig)
Definition z3py.py:4878
Map(f, *args)
Definition z3py.py:5001
is_rational_value(a)
Definition z3py.py:2902
_probe_or(args, ctx)
Definition z3py.py:9039
BVRedAnd(a)
Definition z3py.py:4623
Cbrt(a, ctx=None)
Definition z3py.py:3574
_to_expr_ref(a, ctx)
Definition z3py.py:1224
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5566
IntSort(ctx=None)
Definition z3py.py:3290
is_seq(a)
Definition z3py.py:11238
Not(a, ctx=None)
Definition z3py.py:1951
_to_sort_ref(s, ctx)
Definition z3py.py:698
enable_trace(msg)
Definition z3py.py:83
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2386
ToReal(a)
Definition z3py.py:3506
URem(a, b)
Definition z3py.py:4435
bool is_bool(Any a)
Definition z3py.py:1707
StringVal(s, ctx=None)
Definition z3py.py:11265
IsInt(a)
Definition z3py.py:3544
_is_numeral(ctx, a)
Definition z3py.py:2870
MultiPattern(*args)
Definition z3py.py:2087
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2368
ZeroExt(n, a)
Definition z3py.py:4571
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:589
int _ast_kind(Context ctx, Any a)
Definition z3py.py:525
DatatypeSort(name, params=None, ctx=None)
Definition z3py.py:5529
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4658
UDiv(a, b)
Definition z3py.py:4414
Q(a, b, ctx=None)
Definition z3py.py:3383
Update(a, *args)
Definition z3py.py:4925
get_var_index(a)
Definition z3py.py:1441
append_log(s)
Definition z3py.py:127
is_var(a)
Definition z3py.py:1416
SortRef DeclareSort(name, ctx=None)
Definition z3py.py:733
IntVal(val, ctx=None)
Definition z3py.py:3336
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4679
RotateLeft(a, b)
Definition z3py.py:4509
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2333
_z3_assert(cond, msg)
Definition z3py.py:113