Z3
 
Loading...
Searching...
No Matches
z3py.py
Go to the documentation of this file.
8
9"""Z3 is a high performance theorem prover developed at Microsoft Research.
10
11Z3 is used in many applications such as: software/hardware verification and testing,
12constraint solving, analysis of hybrid systems, security, biology (in silico analysis),
13and geometrical problems.
14
15
16Please send feedback, comments and/or corrections on the Issue tracker for
17https://github.com/Z3prover/z3.git. Your comments are very valuable.
18
19Small example:
20
21>>> x = Int('x')
22>>> y = Int('y')
23>>> s = Solver()
24>>> s.add(x > 0)
25>>> s.add(x < 2)
26>>> s.add(y == x + 1)
27>>> s.check()
28sat
29>>> m = s.model()
30>>> m[x]
311
32>>> m[y]
332
34
35Z3 exceptions:
36
37>>> try:
38... x = BitVec('x', 32)
39... y = Bool('y')
40... # the expression x + y is type incorrect
41... n = x + y
42... except Z3Exception as ex:
43... print("failed: %s" % ex)
44failed: sort mismatch
45"""
46from . import z3core
47from .z3core import *
48from .z3types import *
49from .z3consts import *
50from .z3printer import *
51from fractions import Fraction
52import sys
53import io
54import math
55import copy
56if sys.version_info.major >= 3:
57 from typing import Iterable, Iterator
58
59from collections.abc import Callable
60from typing import (
61 Any,
62 Iterable,
63 Sequence
64)
65
66
67Z3_DEBUG = __debug__
68
69
71 global Z3_DEBUG
72 return Z3_DEBUG
73
74
75if sys.version_info.major < 3:
76 def _is_int(v):
77 return isinstance(v, (int, long))
78else:
79 def _is_int(v):
80 return isinstance(v, int)
81
82
83def enable_trace(msg):
85
86
89
90
92 major = ctypes.c_uint(0)
93 minor = ctypes.c_uint(0)
94 build = ctypes.c_uint(0)
95 rev = ctypes.c_uint(0)
96 Z3_get_version(major, minor, build, rev)
97 return "%s.%s.%s" % (major.value, minor.value, build.value)
98
99
101 major = ctypes.c_uint(0)
102 minor = ctypes.c_uint(0)
103 build = ctypes.c_uint(0)
104 rev = ctypes.c_uint(0)
105 Z3_get_version(major, minor, build, rev)
106 return (major.value, minor.value, build.value, rev.value)
107
108
110 return Z3_get_full_version()
111
112
113def _z3_assert(cond, msg):
114 if not cond:
115 raise Z3Exception(msg)
116
117
119 _z3_assert(ctypes.c_int(n).value == n, name + " is too large")
120
121
122def open_log(fname):
123 """Log interaction to a file. This function must be invoked immediately after init(). """
124 Z3_open_log(fname)
125
126
128 """Append user-defined string to interaction log. """
130
131
132def to_symbol(s, ctx = None):
133 """Convert an integer or string into a Z3 symbol."""
134 if _is_int(s):
135 return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
136 else:
137 return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
138
139
140def _symbol2py(ctx, s):
141 """Convert a Z3 symbol back into a Python object. """
142 if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
143 return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
144 else:
145 return Z3_get_symbol_string(ctx.ref(), s)
146
147# Hack for having nary functions that can receive one argument that is the
148# list of arguments.
149# Use this when function takes a single list of arguments
150
151
152def _get_args(args):
153 try:
154 if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
155 return args[0]
156 elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)):
157 return [arg for arg in args[0]]
158 elif len(args) == 1 and isinstance(args[0], Iterator):
159 return list(args[0])
160 else:
161 return args
162 except TypeError: # len is not necessarily defined when args is not a sequence (use reflection?)
163 return args
164
165# Use this when function takes multiple arguments
166
167
169 try:
170 if isinstance(args, (set, AstVector, tuple)):
171 return [arg for arg in args]
172 else:
173 return args
174 except Exception:
175 return args
176
177
179 if isinstance(val, bool):
180 return "true" if val else "false"
181 return str(val)
182
183
185 # Do nothing error handler, just avoid exit(0)
186 # The wrappers in z3core.py will raise a Z3Exception if an error is detected
187 return
188
189
190class Context:
191 """A Context manages all other Z3 objects, global configuration options, etc.
192
193 Z3Py uses a default global context. For most applications this is sufficient.
194 An application may use multiple Z3 contexts. Objects created in one context
195 cannot be used in another one. However, several objects may be "translated" from
196 one context to another. It is not safe to access Z3 objects from multiple threads.
197 The only exception is the method `interrupt()` that can be used to interrupt() a long
198 computation.
199 The initialization method receives global configuration options for the new context.
200 """
201
202 def __init__(self, *args, **kws):
203 if z3_debug():
204 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
205 conf = Z3_mk_config()
206 for key in kws:
207 value = kws[key]
208 Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
209 prev = None
210 for a in args:
211 if prev is None:
212 prev = a
213 else:
214 Z3_set_param_value(conf, str(prev), _to_param_value(a))
215 prev = None
217 self.owner = True
218 self.eh = Z3_set_error_handler(self.ctx, z3_error_handler)
219 Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
220 Z3_del_config(conf)
221
222 def __del__(self):
223 if Z3_del_context is not None and self.owner:
224 Z3_del_context(self.ctx)
225 self.ctx = None
226 self.eh = None
227
228 def ref(self):
229 """Return a reference to the actual C pointer to the Z3 context."""
230 return self.ctx
231
232 def interrupt(self):
233 """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
234
235 This method can be invoked from a thread different from the one executing the
236 interruptible procedure.
237 """
238 Z3_interrupt(self.ref())
239
240 def param_descrs(self):
241 """Return the global parameter description set."""
242 return ParamDescrsRef(Z3_get_global_param_descrs(self.ref()), self)
243
244 def set_ast_print_mode(self, mode):
245 """Set the pretty printing mode for ASTs.
246
247 The following modes are available:
248 - Z3_PRINT_SMTLIB_FULL (0): Print AST nodes in SMTLIB verbose format.
249 - Z3_PRINT_LOW_LEVEL (1): Print AST nodes using a low-level format.
250 - Z3_PRINT_SMTLIB2_COMPLIANT (2): Print AST nodes in SMTLIB 2.x compliant format.
251
252 Example:
253 >>> c = Context()
254 >>> x = Int('x', c)
255 >>> c.set_ast_print_mode(Z3_PRINT_SMTLIB2_COMPLIANT)
256 >>> print(x)
257 x
258 """
259 Z3_set_ast_print_mode(self.ref(), mode)
260
261
262# Global Z3 context
263_main_ctx = None
264
265
266def main_ctx() -> Context:
267 """Return a reference to the global Z3 context.
268
269 >>> x = Real('x')
270 >>> x.ctx == main_ctx()
271 True
272 >>> c = Context()
273 >>> c == main_ctx()
274 False
275 >>> x2 = Real('x', c)
276 >>> x2.ctx == c
277 True
278 >>> eq(x, x2)
279 False
280 """
281 global _main_ctx
282 if _main_ctx is None:
283 _main_ctx = Context()
284 return _main_ctx
285
286
287def _get_ctx(ctx) -> Context:
288 if ctx is None:
289 return main_ctx()
290 else:
291 return ctx
292
293
294def get_ctx(ctx) -> Context:
295 return _get_ctx(ctx)
296
297
298def set_param(*args, **kws):
299 """Set Z3 global (or module) parameters.
300
301 >>> set_param(precision=10)
302 """
303 if z3_debug():
304 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
305 new_kws = {}
306 for k in kws:
307 v = kws[k]
308 if not set_pp_option(k, v):
309 new_kws[k] = v
310 for key in new_kws:
311 value = new_kws[key]
312 Z3_global_param_set(str(key).upper(), _to_param_value(value))
313 prev = None
314 for a in args:
315 if prev is None:
316 prev = a
317 else:
319 prev = None
320
321
322def reset_params() -> None:
323 """Reset all global (or module) parameters.
324 """
326
327
328def set_option(*args, **kws):
329 """Alias for 'set_param' for backward compatibility.
330 """
331 return set_param(*args, **kws)
332
333
334def get_param(name):
335 """Return the value of a Z3 global (or module) parameter
336
337 >>> get_param('nlsat.reorder')
338 'true'
339 """
340 ptr = (ctypes.c_char_p * 1)()
341 if Z3_global_param_get(str(name), ptr):
342 r = z3core._to_pystr(ptr[0])
343 return r
344 raise Z3Exception("failed to retrieve value for '%s'" % name)
345
346
351
352# Mark objects that use pretty printer
353
354
356 """Superclass for all Z3 objects that have support for pretty printing."""
357
358 def use_pp(self):
359 return True
360
361 def _repr_html_(self):
362 in_html = in_html_mode()
363 set_html_mode(True)
364 res = repr(self)
365 set_html_mode(in_html)
366 return res
367
368
370 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
371
372 def __init__(self, ast, ctx=None):
373 self.ast = ast
374 self.ctx = _get_ctx(ctx)
375 Z3_inc_ref(self.ctx.ref(), self.as_ast())
376
377 def __del__(self):
378 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
379 Z3_dec_ref(self.ctx.ref(), self.as_ast())
380 self.ast = None
381
382 def __deepcopy__(self, memo={}):
383 return _to_ast_ref(self.ast, self.ctx)
384
385 def __str__(self):
386 return obj_to_string(self)
387
388 def __repr__(self):
389 return obj_to_string(self)
390
391 def __eq__(self, other):
392 return self.eq(other)
393
394 def __hash__(self):
395 return self.hash()
396
397 def __nonzero__(self):
398 return self.__bool__()
399
400 def __bool__(self):
401 if is_true(self):
402 return True
403 elif is_false(self):
404 return False
405 elif is_eq(self) and self.num_args() == 2:
406 return self.arg(0).eq(self.arg(1))
407 else:
408 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
409
410 def sexpr(self):
411 """Return a string representing the AST node in s-expression notation.
412
413 >>> x = Int('x')
414 >>> ((x + 1)*x).sexpr()
415 '(* (+ x 1) x)'
416 """
417 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
418
419 def as_ast(self):
420 """Return a pointer to the corresponding C Z3_ast object."""
421 return self.ast
422
423 def get_id(self):
424 """Return unique identifier for object. It can be used for hash-tables and maps."""
425 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
426
427 def ctx_ref(self):
428 """Return a reference to the C context where this AST node is stored."""
429 return self.ctx.ref()
430
431 def eq(self, other):
432 """Return `True` if `self` and `other` are structurally identical.
433
434 >>> x = Int('x')
435 >>> n1 = x + 1
436 >>> n2 = 1 + x
437 >>> n1.eq(n2)
438 False
439 >>> n1 = simplify(n1)
440 >>> n2 = simplify(n2)
441 >>> n1.eq(n2)
442 True
443 """
444 if z3_debug():
445 _z3_assert(is_ast(other), "Z3 AST expected")
446 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
447
448 def translate(self, target):
449 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
450
451 >>> c1 = Context()
452 >>> c2 = Context()
453 >>> x = Int('x', c1)
454 >>> y = Int('y', c2)
455 >>> # Nodes in different contexts can't be mixed.
456 >>> # However, we can translate nodes from one context to another.
457 >>> x.translate(c2) + y
458 x + y
459 """
460 if z3_debug():
461 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
462 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
463
464 def __copy__(self):
465 return self.translate(self.ctx)
466
467 def hash(self):
468 """Return a hashcode for the `self`.
469
470 >>> n1 = simplify(Int('x') + 1)
471 >>> n2 = simplify(2 + Int('x') - 1)
472 >>> n1.hash() == n2.hash()
473 True
474 """
475 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
476
477 def py_value(self):
478 """Return a Python value that is equivalent to `self`."""
479 return None
480
481
482def is_ast(a : Any) -> bool:
483 """Return `True` if `a` is an AST node.
484
485 >>> is_ast(10)
486 False
487 >>> is_ast(IntVal(10))
488 True
489 >>> is_ast(Int('x'))
490 True
491 >>> is_ast(BoolSort())
492 True
493 >>> is_ast(Function('f', IntSort(), IntSort()))
494 True
495 >>> is_ast("x")
496 False
497 >>> is_ast(Solver())
498 False
499 """
500 return isinstance(a, AstRef)
501
502
503def eq(a : AstRef, b : AstRef) -> bool:
504 """Return `True` if `a` and `b` are structurally identical AST nodes.
505
506 >>> x = Int('x')
507 >>> y = Int('y')
508 >>> eq(x, y)
509 False
510 >>> eq(x + 1, x + 1)
511 True
512 >>> eq(x + 1, 1 + x)
513 False
514 >>> eq(simplify(x + 1), simplify(1 + x))
515 True
516 """
517 if z3_debug():
518 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
519 return a.eq(b)
520
521
522def _ast_kind(ctx : Context, a : Any) -> int:
523 if is_ast(a):
524 a = a.as_ast()
525 return Z3_get_ast_kind(ctx.ref(), a)
526
527
528def _ctx_from_ast_arg_list(args, default_ctx=None):
529 ctx = None
530 for a in args:
531 if is_ast(a) or is_probe(a):
532 if ctx is None:
533 ctx = a.ctx
534 else:
535 if z3_debug():
536 _z3_assert(ctx == a.ctx, "Context mismatch")
537 if ctx is None:
538 ctx = default_ctx
539 return ctx
540
541
543 return _ctx_from_ast_arg_list(args)
544
545
547 sz = len(args)
548 _args = (FuncDecl * sz)()
549 for i in range(sz):
550 _args[i] = args[i].as_func_decl()
551 return _args, sz
552
553
555 sz = len(args)
556 _args = (Ast * sz)()
557 for i in range(sz):
558 _args[i] = args[i].as_ast()
559 return _args, sz
560
561
562def _to_ref_array(ref, args):
563 sz = len(args)
564 _args = (ref * sz)()
565 for i in range(sz):
566 _args[i] = args[i].as_ast()
567 return _args, sz
568
569
570def _to_ast_ref(a, ctx):
571 k = _ast_kind(ctx, a)
572 if k == Z3_SORT_AST:
573 return _to_sort_ref(a, ctx)
574 elif k == Z3_FUNC_DECL_AST:
575 return _to_func_decl_ref(a, ctx)
576 else:
577 return _to_expr_ref(a, ctx)
578
579
580
585
586def _sort_kind(ctx, s):
587 return Z3_get_sort_kind(ctx.ref(), s)
588
589
591 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
592
593 def as_ast(self):
594 return Z3_sort_to_ast(self.ctx_ref(), self.astast)
595
596 def get_id(self):
597 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
598
599 def kind(self):
600 """Return the Z3 internal kind of a sort.
601 This method can be used to test if `self` is one of the Z3 builtin sorts.
602
603 >>> b = BoolSort()
604 >>> b.kind() == Z3_BOOL_SORT
605 True
606 >>> b.kind() == Z3_INT_SORT
607 False
608 >>> A = ArraySort(IntSort(), IntSort())
609 >>> A.kind() == Z3_ARRAY_SORT
610 True
611 >>> A.kind() == Z3_INT_SORT
612 False
613 """
614 return _sort_kind(self.ctxctx, self.astast)
615
616 def subsort(self, other):
617 """Return `True` if `self` is a subsort of `other`.
618
619 >>> IntSort().subsort(RealSort())
620 True
621 """
622 return False
623
624 def cast(self, val):
625 """Try to cast `val` as an element of sort `self`.
626
627 This method is used in Z3Py to convert Python objects such as integers,
628 floats, longs and strings into Z3 expressions.
629
630 >>> x = Int('x')
631 >>> RealSort().cast(x)
632 ToReal(x)
633 """
634 if z3_debug():
635 _z3_assert(is_expr(val), "Z3 expression expected")
636 _z3_assert(self.eq(val.sort()), "Sort mismatch")
637 return val
638
639 def name(self):
640 """Return the name (string) of sort `self`.
641
642 >>> BoolSort().name()
643 'Bool'
644 >>> ArraySort(IntSort(), IntSort()).name()
645 'Array'
646 """
647 return _symbol2py(self.ctxctx, Z3_get_sort_name(self.ctx_ref(), self.astast))
648
649 def __eq__(self, other):
650 """Return `True` if `self` and `other` are the same Z3 sort.
651
652 >>> p = Bool('p')
653 >>> p.sort() == BoolSort()
654 True
655 >>> p.sort() == IntSort()
656 False
657 """
658 if other is None:
659 return False
660 return Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
661
662 def __ne__(self, other):
663 """Return `True` if `self` and `other` are not the same Z3 sort.
664
665 >>> p = Bool('p')
666 >>> p.sort() != BoolSort()
667 False
668 >>> p.sort() != IntSort()
669 True
670 """
671 return not Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
672
673 def __gt__(self, other):
674 """Create the function space Array(self, other)"""
675 return ArraySort(self, other)
676
677 def __hash__(self):
678 """ Hash code. """
679 return AstRef.__hash__(self)
680
681
682def is_sort(s : Any) -> bool:
683 """Return `True` if `s` is a Z3 sort.
684
685 >>> is_sort(IntSort())
686 True
687 >>> is_sort(Int('x'))
688 False
689 >>> is_expr(Int('x'))
690 True
691 """
692 return isinstance(s, SortRef)
693
694
695def _to_sort_ref(s, ctx):
696 if z3_debug():
697 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
698 k = _sort_kind(ctx, s)
699 if k == Z3_BOOL_SORT:
700 return BoolSortRef(s, ctx)
701 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
702 return ArithSortRef(s, ctx)
703 elif k == Z3_BV_SORT:
704 return BitVecSortRef(s, ctx)
705 elif k == Z3_ARRAY_SORT:
706 return ArraySortRef(s, ctx)
707 elif k == Z3_DATATYPE_SORT:
708 return DatatypeSortRef(s, ctx)
709 elif k == Z3_FINITE_DOMAIN_SORT:
710 return FiniteDomainSortRef(s, ctx)
711 elif k == Z3_FLOATING_POINT_SORT:
712 return FPSortRef(s, ctx)
713 elif k == Z3_ROUNDING_MODE_SORT:
714 return FPRMSortRef(s, ctx)
715 elif k == Z3_RE_SORT:
716 return ReSortRef(s, ctx)
717 elif k == Z3_SEQ_SORT:
718 return SeqSortRef(s, ctx)
719 elif k == Z3_CHAR_SORT:
720 return CharSortRef(s, ctx)
721 elif k == Z3_TYPE_VAR:
722 return TypeVarRef(s, ctx)
723 return SortRef(s, ctx)
724
725
726def _sort(ctx : Context, a : Any) -> SortRef:
727 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
728
729
730def DeclareSort(name, ctx= None) -> SortRef:
731 """Create a new uninterpreted sort named `name`.
732
733 If `ctx=None`, then the new sort is declared in the global Z3Py context.
734
735 >>> A = DeclareSort('A')
736 >>> a = Const('a', A)
737 >>> b = Const('b', A)
738 >>> a.sort() == A
739 True
740 >>> b.sort() == A
741 True
742 >>> a == b
743 a == b
744 """
745 ctx = _get_ctx(ctx)
746 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
747
749 """Type variable reference"""
750
751 def subsort(self, other):
752 return True
753
754 def cast(self, val):
755 return val
756
757
758def DeclareTypeVar(name, ctx=None):
759 """Create a new type variable named `name`.
760
761 If `ctx=None`, then the new sort is declared in the global Z3Py context.
762
763 """
764 ctx = _get_ctx(ctx)
765 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
766
767
768
773
774
776 """Function declaration. Every constant and function have an associated declaration.
777
778 The declaration assigns a name, a sort (i.e., type), and for function
779 the sort (i.e., type) of each of its arguments. Note that, in Z3,
780 a constant is a function with 0 arguments.
781 """
782
783 def as_ast(self):
784 return Z3_func_decl_to_ast(self.ctx_ref(), self.astast)
785
786 def get_id(self):
787 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
788
789 def as_func_decl(self):
790 return self.astast
791
792 def name(self):
793 """Return the name of the function declaration `self`.
794
795 >>> f = Function('f', IntSort(), IntSort())
796 >>> f.name()
797 'f'
798 >>> isinstance(f.name(), str)
799 True
800 """
801 return _symbol2py(self.ctxctx, Z3_get_decl_name(self.ctx_ref(), self.astast))
802
803 def arity(self):
804 """Return the number of arguments of a function declaration.
805 If `self` is a constant, then `self.arity()` is 0.
806
807 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
808 >>> f.arity()
809 2
810 """
811 return int(Z3_get_arity(self.ctx_ref(), self.astast))
812
813 def domain(self, i):
814 """Return the sort of the argument `i` of a function declaration.
815 This method assumes that `0 <= i < self.arity()`.
816
817 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
818 >>> f.domain(0)
819 Int
820 >>> f.domain(1)
821 Real
822 """
823 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.astast, i), self.ctxctx)
824
825 def range(self):
826 """Return the sort of the range of a function declaration.
827 For constants, this is the sort of the constant.
828
829 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
830 >>> f.range()
831 Bool
832 """
833 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.astast), self.ctxctx)
834
835 def kind(self):
836 """Return the internal kind of a function declaration.
837 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
838
839 >>> x = Int('x')
840 >>> d = (x + 1).decl()
841 >>> d.kind() == Z3_OP_ADD
842 True
843 >>> d.kind() == Z3_OP_MUL
844 False
845 """
846 return Z3_get_decl_kind(self.ctx_ref(), self.astast)
847
848 def params(self):
849 ctx = self.ctxctx
851 result = [None for i in range(n)]
852 for i in range(n):
853 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.astast, i)
854 if k == Z3_PARAMETER_INT:
855 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.astast, i)
856 elif k == Z3_PARAMETER_DOUBLE:
857 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.astast, i)
858 elif k == Z3_PARAMETER_RATIONAL:
859 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.astast, i)
860 elif k == Z3_PARAMETER_SYMBOL:
861 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.astast, i)
862 elif k == Z3_PARAMETER_SORT:
863 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.astast, i), ctx)
864 elif k == Z3_PARAMETER_AST:
865 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.astast, i), ctx)
866 elif k == Z3_PARAMETER_FUNC_DECL:
867 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.astast, i), ctx)
868 elif k == Z3_PARAMETER_INTERNAL:
869 result[i] = "internal parameter"
870 elif k == Z3_PARAMETER_ZSTRING:
871 result[i] = "internal string"
872 else:
873 raise Z3Exception("Unexpected parameter kind")
874 return result
875
876 def __call__(self, *args):
877 """Create a Z3 application expression using the function `self`, and the given arguments.
878
879 The arguments must be Z3 expressions. This method assumes that
880 the sorts of the elements in `args` match the sorts of the
881 domain. Limited coercion is supported. For example, if
882 args[0] is a Python integer, and the function expects a Z3
883 integer, then the argument is automatically converted into a
884 Z3 integer.
885
886 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
887 >>> x = Int('x')
888 >>> y = Real('y')
889 >>> f(x, y)
890 f(x, y)
891 >>> f(x, x)
892 f(x, ToReal(x))
893 """
894 args = _get_args(args)
895 num = len(args)
896 _args = (Ast * num)()
897 saved = []
898 for i in range(num):
899 # self.domain(i).cast(args[i]) may create a new Z3 expression,
900 # then we must save in 'saved' to prevent it from being garbage collected.
901 tmp = self.domain(i).cast(args[i])
902 saved.append(tmp)
903 _args[i] = tmp.as_ast()
904 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.astast, len(args), _args), self.ctxctx)
905
906
908 """Return `True` if `a` is a Z3 function declaration.
909
910 >>> f = Function('f', IntSort(), IntSort())
911 >>> is_func_decl(f)
912 True
913 >>> x = Real('x')
914 >>> is_func_decl(x)
915 False
916 """
917 return isinstance(a, FuncDeclRef)
918
919
920def Function(name, *sig):
921 """Create a new Z3 uninterpreted function with the given sorts.
922
923 >>> f = Function('f', IntSort(), IntSort())
924 >>> f(f(0))
925 f(f(0))
926 """
927 sig = _get_args(sig)
928 if z3_debug():
929 _z3_assert(len(sig) > 0, "At least two arguments expected")
930 arity = len(sig) - 1
931 rng = sig[arity]
932 if z3_debug():
933 _z3_assert(is_sort(rng), "Z3 sort expected")
934 dom = (Sort * arity)()
935 for i in range(arity):
936 if z3_debug():
937 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
938 dom[i] = sig[i].ast
939 ctx = rng.ctx
940 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
941
942
944 """Create a new fresh Z3 uninterpreted function with the given sorts.
945 """
946 sig = _get_args(sig)
947 if z3_debug():
948 _z3_assert(len(sig) > 0, "At least two arguments expected")
949 arity = len(sig) - 1
950 rng = sig[arity]
951 if z3_debug():
952 _z3_assert(is_sort(rng), "Z3 sort expected")
953 dom = (z3.Sort * arity)()
954 for i in range(arity):
955 if z3_debug():
956 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
957 dom[i] = sig[i].ast
958 ctx = rng.ctx
959 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
960
961
963 return FuncDeclRef(a, ctx)
964
965
966def RecFunction(name, *sig):
967 """Create a new Z3 recursive with the given sorts."""
968 sig = _get_args(sig)
969 if z3_debug():
970 _z3_assert(len(sig) > 0, "At least two arguments expected")
971 arity = len(sig) - 1
972 rng = sig[arity]
973 if z3_debug():
974 _z3_assert(is_sort(rng), "Z3 sort expected")
975 dom = (Sort * arity)()
976 for i in range(arity):
977 if z3_debug():
978 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
979 dom[i] = sig[i].ast
980 ctx = rng.ctx
981 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
982
983
984def RecAddDefinition(f, args, body):
985 """Set the body of a recursive function.
986 Recursive definitions can be simplified if they are applied to ground
987 arguments.
988 >>> ctx = Context()
989 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
990 >>> n = Int('n', ctx)
991 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
992 >>> simplify(fac(5))
993 120
994 >>> s = Solver(ctx=ctx)
995 >>> s.add(fac(n) < 3)
996 >>> s.check()
997 sat
998 >>> s.model().eval(fac(5))
999 120
1000 """
1001 if is_app(args):
1002 args = [args]
1003 ctx = body.ctx
1004 args = _get_args(args)
1005 n = len(args)
1006 _args = (Ast * n)()
1007 for i in range(n):
1008 _args[i] = args[i].ast
1009 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
1010
1011
1016
1017
1019 """Constraints, formulas and terms are expressions in Z3.
1020
1021 Expressions are ASTs. Every expression has a sort.
1022 There are three main kinds of expressions:
1023 function applications, quantifiers and bounded variables.
1024 A constant is a function application with 0 arguments.
1025 For quantifier free problems, all expressions are
1026 function applications.
1027 """
1028
1029 def as_ast(self):
1030 return self.astast
1031
1032 def get_id(self):
1033 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
1034
1035 def sort(self):
1036 """Return the sort of expression `self`.
1037
1038 >>> x = Int('x')
1039 >>> (x + 1).sort()
1040 Int
1041 >>> y = Real('y')
1042 >>> (x + y).sort()
1043 Real
1044 """
1045 return _sort(self.ctxctx, self.as_astas_ast())
1046
1047 def sort_kind(self):
1048 """Shorthand for `self.sort().kind()`.
1049
1050 >>> a = Array('a', IntSort(), IntSort())
1051 >>> a.sort_kind() == Z3_ARRAY_SORT
1052 True
1053 >>> a.sort_kind() == Z3_INT_SORT
1054 False
1055 """
1056 return self.sort().kind()
1057
1058 def __eq__(self, other):
1059 """Return a Z3 expression that represents the constraint `self == other`.
1060
1061 If `other` is `None`, then this method simply returns `False`.
1062
1063 >>> a = Int('a')
1064 >>> b = Int('b')
1065 >>> a == b
1066 a == b
1067 >>> a is None
1068 False
1069 """
1070 if other is None:
1071 return False
1072 a, b = _coerce_exprs(self, other)
1073 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctx)
1074
1075 def __hash__(self):
1076 """ Hash code. """
1077 return AstRef.__hash__(self)
1078
1079 def __ne__(self, other):
1080 """Return a Z3 expression that represents the constraint `self != other`.
1081
1082 If `other` is `None`, then this method simply returns `True`.
1083
1084 >>> a = Int('a')
1085 >>> b = Int('b')
1086 >>> a != b
1087 a != b
1088 >>> a is not None
1089 True
1090 """
1091 if other is None:
1092 return True
1093 a, b = _coerce_exprs(self, other)
1094 _args, sz = _to_ast_array((a, b))
1095 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctxctx)
1096
1097 def params(self):
1098 return self.decl().params()
1099
1100 def decl(self):
1101 """Return the Z3 function declaration associated with a Z3 application.
1102
1103 >>> f = Function('f', IntSort(), IntSort())
1104 >>> a = Int('a')
1105 >>> t = f(a)
1106 >>> eq(t.decl(), f)
1107 True
1108 >>> (a + 1).decl()
1109 +
1110 """
1111 if z3_debug():
1112 _z3_assert(is_app(self), "Z3 application expected")
1113 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_astas_ast()), self.ctxctx)
1114
1115 def kind(self):
1116 """Return the Z3 internal kind of a function application."""
1117 if z3_debug():
1118 _z3_assert(is_app(self), "Z3 application expected")
1120
1121
1122 def num_args(self):
1123 """Return the number of arguments of a Z3 application.
1124
1125 >>> a = Int('a')
1126 >>> b = Int('b')
1127 >>> (a + b).num_args()
1128 2
1129 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1130 >>> t = f(a, b, 0)
1131 >>> t.num_args()
1132 3
1133 """
1134 if z3_debug():
1135 _z3_assert(is_app(self), "Z3 application expected")
1136 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_astas_ast()))
1137
1138 def arg(self, idx):
1139 """Return argument `idx` of the application `self`.
1140
1141 This method assumes that `self` is a function application with at least `idx+1` arguments.
1142
1143 >>> a = Int('a')
1144 >>> b = Int('b')
1145 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1146 >>> t = f(a, b, 0)
1147 >>> t.arg(0)
1148 a
1149 >>> t.arg(1)
1150 b
1151 >>> t.arg(2)
1152 0
1153 """
1154 if z3_debug():
1155 _z3_assert(is_app(self), "Z3 application expected")
1156 _z3_assert(idx < self.num_args(), "Invalid argument index")
1157 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_astas_ast(), idx), self.ctxctx)
1158
1159 def children(self):
1160 """Return a list containing the children of the given expression
1161
1162 >>> a = Int('a')
1163 >>> b = Int('b')
1164 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1165 >>> t = f(a, b, 0)
1166 >>> t.children()
1167 [a, b, 0]
1168 """
1169 if is_app(self):
1170 return [self.arg(i) for i in range(self.num_args())]
1171 else:
1172 return []
1173
1174 def update(self, *args):
1175 """Update the arguments of the expression.
1176
1177 Return a new expression with the same function declaration and updated arguments.
1178 The number of new arguments must match the current number of arguments.
1179
1180 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1181 >>> a = Int('a')
1182 >>> b = Int('b')
1183 >>> c = Int('c')
1184 >>> t = f(a, b)
1185 >>> t.update(c, c)
1186 f(c, c)
1187 """
1188 if z3_debug():
1189 _z3_assert(is_app(self), "Z3 application expected")
1190 _z3_assert(len(args) == self.num_args(), "Number of arguments does not match")
1191 _z3_assert(all([is_expr(arg) for arg in args]), "Z3 expressions expected")
1192 num = len(args)
1193 _args = (Ast * num)()
1194 for i in range(num):
1195 _args[i] = args[i].as_ast()
1196 return _to_expr_ref(Z3_update_term(self.ctx_ref(), self.as_astas_ast(), num, _args), self.ctxctx)
1197
1198 def from_string(self, s):
1199 pass
1200
1201 def serialize(self):
1202 s = Solver()
1203 f = Function('F', self.sort(), BoolSort(self.ctx))
1204 s.add(f(self))
1205 return s.sexpr()
1206
1208 """inverse function to the serialize method on ExprRef.
1209 It is made available to make it easier for users to serialize expressions back and forth between
1210 strings. Solvers can be serialized using the 'sexpr()' method.
1211 """
1212 s = Solver()
1213 s.from_string(st)
1214 if len(s.assertions()) != 1:
1215 raise Z3Exception("single assertion expected")
1216 fml = s.assertions()[0]
1217 if fml.num_args() != 1:
1218 raise Z3Exception("dummy function 'F' expected")
1219 return fml.arg(0)
1220
1221def _to_expr_ref(a, ctx):
1222 if isinstance(a, Pattern):
1223 return PatternRef(a, ctx)
1224 ctx_ref = ctx.ref()
1225 k = Z3_get_ast_kind(ctx_ref, a)
1226 if k == Z3_QUANTIFIER_AST:
1227 return QuantifierRef(a, ctx)
1228 sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1229 if sk == Z3_BOOL_SORT:
1230 return BoolRef(a, ctx)
1231 if sk == Z3_INT_SORT:
1232 if k == Z3_NUMERAL_AST:
1233 return IntNumRef(a, ctx)
1234 return ArithRef(a, ctx)
1235 if sk == Z3_REAL_SORT:
1236 if k == Z3_NUMERAL_AST:
1237 return RatNumRef(a, ctx)
1238 if _is_algebraic(ctx, a):
1239 return AlgebraicNumRef(a, ctx)
1240 return ArithRef(a, ctx)
1241 if sk == Z3_BV_SORT:
1242 if k == Z3_NUMERAL_AST:
1243 return BitVecNumRef(a, ctx)
1244 else:
1245 return BitVecRef(a, ctx)
1246 if sk == Z3_ARRAY_SORT:
1247 return ArrayRef(a, ctx)
1248 if sk == Z3_DATATYPE_SORT:
1249 return DatatypeRef(a, ctx)
1250 if sk == Z3_FLOATING_POINT_SORT:
1251 if k == Z3_APP_AST and _is_numeral(ctx, a):
1252 return FPNumRef(a, ctx)
1253 else:
1254 return FPRef(a, ctx)
1255 if sk == Z3_FINITE_DOMAIN_SORT:
1256 if k == Z3_NUMERAL_AST:
1257 return FiniteDomainNumRef(a, ctx)
1258 else:
1259 return FiniteDomainRef(a, ctx)
1260 if sk == Z3_ROUNDING_MODE_SORT:
1261 return FPRMRef(a, ctx)
1262 if sk == Z3_SEQ_SORT:
1263 return SeqRef(a, ctx)
1264 if sk == Z3_CHAR_SORT:
1265 return CharRef(a, ctx)
1266 if sk == Z3_RE_SORT:
1267 return ReRef(a, ctx)
1268 return ExprRef(a, ctx)
1269
1270
1272 if is_expr(a):
1273 s1 = a.sort()
1274 if s is None:
1275 return s1
1276 if s1.eq(s):
1277 return s
1278 elif s.subsort(s1):
1279 return s1
1280 elif s1.subsort(s):
1281 return s
1282 else:
1283 if z3_debug():
1284 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1285 _z3_assert(False, "sort mismatch")
1286 else:
1287 return s
1288
1289def _check_same_sort(a, b, ctx=None):
1290 if not isinstance(a, ExprRef):
1291 return False
1292 if not isinstance(b, ExprRef):
1293 return False
1294 if ctx is None:
1295 ctx = a.ctx
1296
1297 a_sort = Z3_get_sort(ctx.ctx, a.ast)
1298 b_sort = Z3_get_sort(ctx.ctx, b.ast)
1299 return Z3_is_eq_sort(ctx.ctx, a_sort, b_sort)
1300
1301
1302def _coerce_exprs(a, b, ctx=None):
1303 if not is_expr(a) and not is_expr(b):
1304 a = _py2expr(a, ctx)
1305 b = _py2expr(b, ctx)
1306 if isinstance(a, str) and isinstance(b, SeqRef):
1307 a = StringVal(a, b.ctx)
1308 if isinstance(b, str) and isinstance(a, SeqRef):
1309 b = StringVal(b, a.ctx)
1310 if isinstance(a, float) and isinstance(b, ArithRef):
1311 a = RealVal(a, b.ctx)
1312 if isinstance(b, float) and isinstance(a, ArithRef):
1313 b = RealVal(b, a.ctx)
1314
1315 if _check_same_sort(a, b, ctx):
1316 return (a, b)
1317
1318 s = None
1319 s = _coerce_expr_merge(s, a)
1320 s = _coerce_expr_merge(s, b)
1321 a = s.cast(a)
1322 b = s.cast(b)
1323 return (a, b)
1324
1325
1326def _reduce(func, sequence, initial):
1327 result = initial
1328 for element in sequence:
1329 result = func(result, element)
1330 return result
1331
1332
1333def _coerce_expr_list(alist, ctx=None):
1334 has_expr = False
1335 for a in alist:
1336 if is_expr(a):
1337 has_expr = True
1338 break
1339 if not has_expr:
1340 alist = [_py2expr(a, ctx) for a in alist]
1341 s = _reduce(_coerce_expr_merge, alist, None)
1342 return [s.cast(a) for a in alist]
1343
1344
1345def is_expr(a):
1346 """Return `True` if `a` is a Z3 expression.
1347
1348 >>> a = Int('a')
1349 >>> is_expr(a)
1350 True
1351 >>> is_expr(a + 1)
1352 True
1353 >>> is_expr(IntSort())
1354 False
1355 >>> is_expr(1)
1356 False
1357 >>> is_expr(IntVal(1))
1358 True
1359 >>> x = Int('x')
1360 >>> is_expr(ForAll(x, x >= 0))
1361 True
1362 >>> is_expr(FPVal(1.0))
1363 True
1364 """
1365 return isinstance(a, ExprRef)
1366
1367
1368def is_app(a):
1369 """Return `True` if `a` is a Z3 function application.
1370
1371 Note that, constants are function applications with 0 arguments.
1372
1373 >>> a = Int('a')
1374 >>> is_app(a)
1375 True
1376 >>> is_app(a + 1)
1377 True
1378 >>> is_app(IntSort())
1379 False
1380 >>> is_app(1)
1381 False
1382 >>> is_app(IntVal(1))
1383 True
1384 >>> x = Int('x')
1385 >>> is_app(ForAll(x, x >= 0))
1386 False
1387 """
1388 if not isinstance(a, ExprRef):
1389 return False
1390 k = _ast_kind(a.ctx, a)
1391 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1392
1393
1395 """Return `True` if `a` is Z3 constant/variable expression.
1396
1397 >>> a = Int('a')
1398 >>> is_const(a)
1399 True
1400 >>> is_const(a + 1)
1401 False
1402 >>> is_const(1)
1403 False
1404 >>> is_const(IntVal(1))
1405 True
1406 >>> x = Int('x')
1407 >>> is_const(ForAll(x, x >= 0))
1408 False
1409 """
1410 return is_app(a) and a.num_args() == 0
1411
1412
1413def is_var(a):
1414 """Return `True` if `a` is variable.
1415
1416 Z3 uses de-Bruijn indices for representing bound variables in
1417 quantifiers.
1418
1419 >>> x = Int('x')
1420 >>> is_var(x)
1421 False
1422 >>> is_const(x)
1423 True
1424 >>> f = Function('f', IntSort(), IntSort())
1425 >>> # Z3 replaces x with bound variables when ForAll is executed.
1426 >>> q = ForAll(x, f(x) == x)
1427 >>> b = q.body()
1428 >>> b
1429 f(Var(0)) == Var(0)
1430 >>> b.arg(1)
1431 Var(0)
1432 >>> is_var(b.arg(1))
1433 True
1434 """
1435 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1436
1437
1439 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1440
1441 >>> x = Int('x')
1442 >>> y = Int('y')
1443 >>> is_var(x)
1444 False
1445 >>> is_const(x)
1446 True
1447 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1448 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1449 >>> q = ForAll([x, y], f(x, y) == x + y)
1450 >>> q.body()
1451 f(Var(1), Var(0)) == Var(1) + Var(0)
1452 >>> b = q.body()
1453 >>> b.arg(0)
1454 f(Var(1), Var(0))
1455 >>> v1 = b.arg(0).arg(0)
1456 >>> v2 = b.arg(0).arg(1)
1457 >>> v1
1458 Var(1)
1459 >>> v2
1460 Var(0)
1461 >>> get_var_index(v1)
1462 1
1463 >>> get_var_index(v2)
1464 0
1465 """
1466 if z3_debug():
1467 _z3_assert(is_var(a), "Z3 bound variable expected")
1468 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1469
1470
1471def is_app_of(a, k):
1472 """Return `True` if `a` is an application of the given kind `k`.
1473
1474 >>> x = Int('x')
1475 >>> n = x + 1
1476 >>> is_app_of(n, Z3_OP_ADD)
1477 True
1478 >>> is_app_of(n, Z3_OP_MUL)
1479 False
1480 """
1481 return is_app(a) and a.kind() == k
1482
1483
1484def If(a, b, c, ctx=None):
1485 """Create a Z3 if-then-else expression.
1486
1487 >>> x = Int('x')
1488 >>> y = Int('y')
1489 >>> max = If(x > y, x, y)
1490 >>> max
1491 If(x > y, x, y)
1492 >>> simplify(max)
1493 If(x <= y, y, x)
1494 """
1495 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1496 return Cond(a, b, c, ctx)
1497 else:
1498 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1499 s = BoolSort(ctx)
1500 a = s.cast(a)
1501 b, c = _coerce_exprs(b, c, ctx)
1502 if z3_debug():
1503 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1504 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1505
1506
1507def Distinct(*args):
1508 """Create a Z3 distinct expression.
1509
1510 >>> x = Int('x')
1511 >>> y = Int('y')
1512 >>> Distinct(x, y)
1513 x != y
1514 >>> z = Int('z')
1515 >>> Distinct(x, y, z)
1516 Distinct(x, y, z)
1517 >>> simplify(Distinct(x, y, z))
1518 Distinct(x, y, z)
1519 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1520 And(Not(x == y), Not(x == z), Not(y == z))
1521 """
1522 args = _get_args(args)
1523 ctx = _ctx_from_ast_arg_list(args)
1524 if z3_debug():
1525 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1526 args = _coerce_expr_list(args, ctx)
1527 _args, sz = _to_ast_array(args)
1528 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1529
1530
1531def _mk_bin(f, a, b):
1532 args = (Ast * 2)()
1533 if z3_debug():
1534 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1535 args[0] = a.as_ast()
1536 args[1] = b.as_ast()
1537 return f(a.ctx.ref(), 2, args)
1538
1539
1540def Const(name, sort):
1541 """Create a constant of the given sort.
1542
1543 >>> Const('x', IntSort())
1544 x
1545 """
1546 if z3_debug():
1547 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1548 ctx = sort.ctx
1549 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1550
1551
1552def Consts(names, sort):
1553 """Create several constants of the given sort.
1554
1555 `names` is a string containing the names of all constants to be created.
1556 Blank spaces separate the names of different constants.
1557
1558 >>> x, y, z = Consts('x y z', IntSort())
1559 >>> x + y + z
1560 x + y + z
1561 """
1562 if isinstance(names, str):
1563 names = names.split(" ")
1564 return [Const(name, sort) for name in names]
1565
1566
1567def FreshConst(sort, prefix="c"):
1568 """Create a fresh constant of a specified sort"""
1569 if z3_debug():
1570 _z3_assert(is_sort(sort), f"Z3 sort expected, got {type(sort)}")
1571 ctx = _get_ctx(sort.ctx)
1572 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1573
1574
1575def Var(idx : int, s : SortRef) -> ExprRef:
1576 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1577 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1578 declarations.
1579
1580 >>> Var(0, IntSort())
1581 Var(0)
1582 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1583 False
1584 """
1585 if z3_debug():
1586 _z3_assert(is_sort(s), "Z3 sort expected")
1587 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1588
1589
1590def RealVar(idx: int, ctx=None) -> ExprRef:
1591 """
1592 Create a real free variable. Free variables are used to create quantified formulas.
1593 They are also used to create polynomials.
1594
1595 >>> RealVar(0)
1596 Var(0)
1597 """
1598 return Var(idx, RealSort(ctx))
1599
1600def RealVarVector(n: int, ctx= None):
1601 """
1602 Create a list of Real free variables.
1603 The variables have ids: 0, 1, ..., n-1
1604
1605 >>> x0, x1, x2, x3 = RealVarVector(4)
1606 >>> x2
1607 Var(2)
1608 """
1609 return [RealVar(i, ctx) for i in range(n)]
1610
1611
1616
1617
1619 """Boolean sort."""
1620
1621 def cast(self, val):
1622 """Try to cast `val` as a Boolean.
1623
1624 >>> x = BoolSort().cast(True)
1625 >>> x
1626 True
1627 >>> is_expr(x)
1628 True
1629 >>> is_expr(True)
1630 False
1631 >>> x.sort()
1632 Bool
1633 """
1634 if isinstance(val, bool):
1635 return BoolVal(val, self.ctxctxctx)
1636 if z3_debug():
1637 if not is_expr(val):
1638 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1639 _z3_assert(is_expr(val), msg % (val, type(val)))
1640 if not self.eq(val.sort()):
1641 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1642 return val
1643
1644 def subsort(self, other):
1645 return isinstance(other, ArithSortRef)
1646
1647 def is_int(self):
1648 return True
1649
1650 def is_bool(self):
1651 return True
1652
1653
1655 """All Boolean expressions are instances of this class."""
1656
1657 def sort(self):
1659
1660 def __add__(self, other):
1661 if isinstance(other, BoolRef):
1662 other = If(other, 1, 0)
1663 return If(self, 1, 0) + other
1664
1665 def __radd__(self, other):
1666 return self + other
1667
1668 def __rmul__(self, other):
1669 return self * other
1670
1671 def __mul__(self, other):
1672 """Create the Z3 expression `self * other`.
1673 """
1674 if isinstance(other, int) and other == 1:
1675 return If(self, 1, 0)
1676 if isinstance(other, int) and other == 0:
1677 return IntVal(0, self.ctxctxctx)
1678 if isinstance(other, BoolRef):
1679 other = If(other, 1, 0)
1680 return If(self, other, 0)
1681
1682 def __and__(self, other):
1683 return And(self, other)
1684
1685 def __or__(self, other):
1686 return Or(self, other)
1687
1688 def __xor__(self, other):
1689 return Xor(self, other)
1690
1691 def __invert__(self):
1692 return Not(self)
1693
1694 def py_value(self):
1695 if is_true(self):
1696 return True
1697 if is_false(self):
1698 return False
1699 return None
1700
1701
1702
1703
1704def is_bool(a : Any) -> bool:
1705 """Return `True` if `a` is a Z3 Boolean expression.
1706
1707 >>> p = Bool('p')
1708 >>> is_bool(p)
1709 True
1710 >>> q = Bool('q')
1711 >>> is_bool(And(p, q))
1712 True
1713 >>> x = Real('x')
1714 >>> is_bool(x)
1715 False
1716 >>> is_bool(x == 0)
1717 True
1718 """
1719 return isinstance(a, BoolRef)
1720
1721
1722def is_true(a : Any) -> bool:
1723 """Return `True` if `a` is the Z3 true expression.
1724
1725 >>> p = Bool('p')
1726 >>> is_true(p)
1727 False
1728 >>> is_true(simplify(p == p))
1729 True
1730 >>> x = Real('x')
1731 >>> is_true(x == 0)
1732 False
1733 >>> # True is a Python Boolean expression
1734 >>> is_true(True)
1735 False
1736 """
1737 return is_app_of(a, Z3_OP_TRUE)
1738
1739
1740def is_false(a : Any) -> bool:
1741 """Return `True` if `a` is the Z3 false expression.
1742
1743 >>> p = Bool('p')
1744 >>> is_false(p)
1745 False
1746 >>> is_false(False)
1747 False
1748 >>> is_false(BoolVal(False))
1749 True
1750 """
1751 return is_app_of(a, Z3_OP_FALSE)
1752
1753
1754def is_and(a : Any) -> bool:
1755 """Return `True` if `a` is a Z3 and expression.
1756
1757 >>> p, q = Bools('p q')
1758 >>> is_and(And(p, q))
1759 True
1760 >>> is_and(Or(p, q))
1761 False
1762 """
1763 return is_app_of(a, Z3_OP_AND)
1764
1765
1766def is_or(a : Any) -> bool:
1767 """Return `True` if `a` is a Z3 or expression.
1768
1769 >>> p, q = Bools('p q')
1770 >>> is_or(Or(p, q))
1771 True
1772 >>> is_or(And(p, q))
1773 False
1774 """
1775 return is_app_of(a, Z3_OP_OR)
1776
1777
1778def is_implies(a : Any) -> bool:
1779 """Return `True` if `a` is a Z3 implication expression.
1780
1781 >>> p, q = Bools('p q')
1782 >>> is_implies(Implies(p, q))
1783 True
1784 >>> is_implies(And(p, q))
1785 False
1786 """
1787 return is_app_of(a, Z3_OP_IMPLIES)
1788
1789
1790def is_not(a : Any) -> bool:
1791 """Return `True` if `a` is a Z3 not expression.
1792
1793 >>> p = Bool('p')
1794 >>> is_not(p)
1795 False
1796 >>> is_not(Not(p))
1797 True
1798 """
1799 return is_app_of(a, Z3_OP_NOT)
1800
1801
1802def is_eq(a : Any) -> bool:
1803 """Return `True` if `a` is a Z3 equality expression.
1804
1805 >>> x, y = Ints('x y')
1806 >>> is_eq(x == y)
1807 True
1808 """
1809 return is_app_of(a, Z3_OP_EQ)
1810
1811
1812def is_distinct(a : Any) -> bool:
1813 """Return `True` if `a` is a Z3 distinct expression.
1814
1815 >>> x, y, z = Ints('x y z')
1816 >>> is_distinct(x == y)
1817 False
1818 >>> is_distinct(Distinct(x, y, z))
1819 True
1820 """
1821 return is_app_of(a, Z3_OP_DISTINCT)
1822
1823
1824def BoolSort(ctx=None):
1825 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1826
1827 >>> BoolSort()
1828 Bool
1829 >>> p = Const('p', BoolSort())
1830 >>> is_bool(p)
1831 True
1832 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1833 >>> r(0, 1)
1834 r(0, 1)
1835 >>> is_bool(r(0, 1))
1836 True
1837 """
1838 ctx = _get_ctx(ctx)
1839 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1840
1841
1842def BoolVal(val, ctx=None):
1843 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1844
1845 >>> BoolVal(True)
1846 True
1847 >>> is_true(BoolVal(True))
1848 True
1849 >>> is_true(True)
1850 False
1851 >>> is_false(BoolVal(False))
1852 True
1853 """
1854 ctx = _get_ctx(ctx)
1855 if val:
1856 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1857 else:
1858 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1859
1860
1861def Bool(name, ctx=None):
1862 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1863
1864 >>> p = Bool('p')
1865 >>> q = Bool('q')
1866 >>> And(p, q)
1867 And(p, q)
1868 """
1869 ctx = _get_ctx(ctx)
1870 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1871
1872
1873def Bools(names, ctx=None):
1874 """Return a tuple of Boolean constants.
1875
1876 `names` is a single string containing all names separated by blank spaces.
1877 If `ctx=None`, then the global context is used.
1878
1879 >>> p, q, r = Bools('p q r')
1880 >>> And(p, Or(q, r))
1881 And(p, Or(q, r))
1882 """
1883 ctx = _get_ctx(ctx)
1884 if isinstance(names, str):
1885 names = names.split(" ")
1886 return [Bool(name, ctx) for name in names]
1887
1888
1889def BoolVector(prefix, sz, ctx=None):
1890 """Return a list of Boolean constants of size `sz`.
1891
1892 The constants are named using the given prefix.
1893 If `ctx=None`, then the global context is used.
1894
1895 >>> P = BoolVector('p', 3)
1896 >>> P
1897 [p__0, p__1, p__2]
1898 >>> And(P)
1899 And(p__0, p__1, p__2)
1900 """
1901 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1902
1903
1904def FreshBool(prefix="b", ctx=None):
1905 """Return a fresh Boolean constant in the given context using the given prefix.
1906
1907 If `ctx=None`, then the global context is used.
1908
1909 >>> b1 = FreshBool()
1910 >>> b2 = FreshBool()
1911 >>> eq(b1, b2)
1912 False
1913 """
1914 ctx = _get_ctx(ctx)
1915 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1916
1917
1918def Implies(a, b, ctx=None):
1919 """Create a Z3 implies expression.
1920
1921 >>> p, q = Bools('p q')
1922 >>> Implies(p, q)
1923 Implies(p, q)
1924 """
1925 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1926 s = BoolSort(ctx)
1927 a = s.cast(a)
1928 b = s.cast(b)
1929 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1930
1931
1932def Xor(a, b, ctx=None):
1933 """Create a Z3 Xor expression.
1934
1935 >>> p, q = Bools('p q')
1936 >>> Xor(p, q)
1937 Xor(p, q)
1938 >>> simplify(Xor(p, q))
1939 Not(p == q)
1940 """
1941 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1942 s = BoolSort(ctx)
1943 a = s.cast(a)
1944 b = s.cast(b)
1945 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1946
1947
1948def Not(a, ctx=None):
1949 """Create a Z3 not expression or probe.
1950
1951 >>> p = Bool('p')
1952 >>> Not(Not(p))
1953 Not(Not(p))
1954 >>> simplify(Not(Not(p)))
1955 p
1956 """
1957 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1958 if is_probe(a):
1959 # Not is also used to build probes
1960 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1961 else:
1962 s = BoolSort(ctx)
1963 a = s.cast(a)
1964 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1965
1966
1967def mk_not(a):
1968 if is_not(a):
1969 return a.arg(0)
1970 else:
1971 return Not(a)
1972
1973
1974def _has_probe(args):
1975 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1976 for arg in args:
1977 if is_probe(arg):
1978 return True
1979 return False
1980
1981
1982def And(*args):
1983 """Create a Z3 and-expression or and-probe.
1984
1985 >>> p, q, r = Bools('p q r')
1986 >>> And(p, q, r)
1987 And(p, q, r)
1988 >>> P = BoolVector('p', 5)
1989 >>> And(P)
1990 And(p__0, p__1, p__2, p__3, p__4)
1991 """
1992 last_arg = None
1993 if len(args) > 0:
1994 last_arg = args[len(args) - 1]
1995 if isinstance(last_arg, Context):
1996 ctx = args[len(args) - 1]
1997 args = args[:len(args) - 1]
1998 elif len(args) == 1 and isinstance(args[0], AstVector):
1999 ctx = args[0].ctx
2000 args = [a for a in args[0]]
2001 else:
2002 ctx = None
2003 args = _get_args(args)
2004 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2005 if z3_debug():
2006 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2007 if _has_probe(args):
2008 return _probe_and(args, ctx)
2009 else:
2010 args = _coerce_expr_list(args, ctx)
2011 _args, sz = _to_ast_array(args)
2012 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
2013
2014
2015def Or(*args):
2016 """Create a Z3 or-expression or or-probe.
2017
2018 >>> p, q, r = Bools('p q r')
2019 >>> Or(p, q, r)
2020 Or(p, q, r)
2021 >>> P = BoolVector('p', 5)
2022 >>> Or(P)
2023 Or(p__0, p__1, p__2, p__3, p__4)
2024 """
2025 last_arg = None
2026 if len(args) > 0:
2027 last_arg = args[len(args) - 1]
2028 if isinstance(last_arg, Context):
2029 ctx = args[len(args) - 1]
2030 args = args[:len(args) - 1]
2031 elif len(args) == 1 and isinstance(args[0], AstVector):
2032 ctx = args[0].ctx
2033 args = [a for a in args[0]]
2034 else:
2035 ctx = None
2036 args = _get_args(args)
2037 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2038 if z3_debug():
2039 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2040 if _has_probe(args):
2041 return _probe_or(args, ctx)
2042 else:
2043 args = _coerce_expr_list(args, ctx)
2044 _args, sz = _to_ast_array(args)
2045 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
2046
2047
2052
2053
2055 """Patterns are hints for quantifier instantiation.
2056
2057 """
2058
2059 def as_ast(self):
2061
2062 def get_id(self):
2063 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2064
2065
2067 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
2068
2069 >>> f = Function('f', IntSort(), IntSort())
2070 >>> x = Int('x')
2071 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
2072 >>> q
2073 ForAll(x, f(x) == 0)
2074 >>> q.num_patterns()
2075 1
2076 >>> is_pattern(q.pattern(0))
2077 True
2078 >>> q.pattern(0)
2079 f(Var(0))
2080 """
2081 return isinstance(a, PatternRef)
2082
2083
2084def MultiPattern(*args):
2085 """Create a Z3 multi-pattern using the given expressions `*args`
2086
2087 >>> f = Function('f', IntSort(), IntSort())
2088 >>> g = Function('g', IntSort(), IntSort())
2089 >>> x = Int('x')
2090 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2091 >>> q
2092 ForAll(x, f(x) != g(x))
2093 >>> q.num_patterns()
2094 1
2095 >>> is_pattern(q.pattern(0))
2096 True
2097 >>> q.pattern(0)
2098 MultiPattern(f(Var(0)), g(Var(0)))
2099 """
2100 if z3_debug():
2101 _z3_assert(len(args) > 0, "At least one argument expected")
2102 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2103 ctx = args[0].ctx
2104 args, sz = _to_ast_array(args)
2105 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2106
2107
2109 if is_pattern(arg):
2110 return arg
2111 else:
2112 return MultiPattern(arg)
2113
2114
2119
2120
2122 """Universally and Existentially quantified formulas."""
2123
2124 def as_ast(self):
2125 return self.astastast
2126
2127 def get_id(self):
2128 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2129
2130 def sort(self):
2131 """Return the Boolean sort or sort of Lambda."""
2132 if self.is_lambda():
2134 return BoolSort(self.ctxctxctxctx)
2135
2136 def is_forall(self):
2137 """Return `True` if `self` is a universal quantifier.
2138
2139 >>> f = Function('f', IntSort(), IntSort())
2140 >>> x = Int('x')
2141 >>> q = ForAll(x, f(x) == 0)
2142 >>> q.is_forall()
2143 True
2144 >>> q = Exists(x, f(x) != 0)
2145 >>> q.is_forall()
2146 False
2147 """
2149
2150 def is_exists(self):
2151 """Return `True` if `self` is an existential quantifier.
2152
2153 >>> f = Function('f', IntSort(), IntSort())
2154 >>> x = Int('x')
2155 >>> q = ForAll(x, f(x) == 0)
2156 >>> q.is_exists()
2157 False
2158 >>> q = Exists(x, f(x) != 0)
2159 >>> q.is_exists()
2160 True
2161 """
2162 return Z3_is_quantifier_exists(self.ctx_ref(), self.astastast)
2163
2164 def is_lambda(self):
2165 """Return `True` if `self` is a lambda expression.
2166
2167 >>> f = Function('f', IntSort(), IntSort())
2168 >>> x = Int('x')
2169 >>> q = Lambda(x, f(x))
2170 >>> q.is_lambda()
2171 True
2172 >>> q = Exists(x, f(x) != 0)
2173 >>> q.is_lambda()
2174 False
2175 """
2176 return Z3_is_lambda(self.ctx_ref(), self.astastast)
2177
2178 def __getitem__(self, arg):
2179 """Return the Z3 expression `self[arg]`.
2180 """
2181 if z3_debug():
2182 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2183 return _array_select(self, arg)
2184
2185 def weight(self):
2186 """Return the weight annotation of `self`.
2187
2188 >>> f = Function('f', IntSort(), IntSort())
2189 >>> x = Int('x')
2190 >>> q = ForAll(x, f(x) == 0)
2191 >>> q.weight()
2192 1
2193 >>> q = ForAll(x, f(x) == 0, weight=10)
2194 >>> q.weight()
2195 10
2196 """
2197 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.astastast))
2198
2199 def skolem_id(self):
2200 """Return the skolem id of `self`.
2201 """
2203
2204 def qid(self):
2205 """Return the quantifier id of `self`.
2206 """
2208
2209 def num_patterns(self):
2210 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2211
2212 >>> f = Function('f', IntSort(), IntSort())
2213 >>> g = Function('g', IntSort(), IntSort())
2214 >>> x = Int('x')
2215 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2216 >>> q.num_patterns()
2217 2
2218 """
2219 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.astastast))
2220
2221 def pattern(self, idx):
2222 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2223
2224 >>> f = Function('f', IntSort(), IntSort())
2225 >>> g = Function('g', IntSort(), IntSort())
2226 >>> x = Int('x')
2227 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2228 >>> q.num_patterns()
2229 2
2230 >>> q.pattern(0)
2231 f(Var(0))
2232 >>> q.pattern(1)
2233 g(Var(0))
2234 """
2235 if z3_debug():
2236 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2238
2240 """Return the number of no-patterns."""
2242
2243 def no_pattern(self, idx):
2244 """Return a no-pattern."""
2245 if z3_debug():
2246 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2248
2249 def body(self):
2250 """Return the expression being quantified.
2251
2252 >>> f = Function('f', IntSort(), IntSort())
2253 >>> x = Int('x')
2254 >>> q = ForAll(x, f(x) == 0)
2255 >>> q.body()
2256 f(Var(0)) == 0
2257 """
2259
2260 def num_vars(self):
2261 """Return the number of variables bounded by this quantifier.
2262
2263 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2264 >>> x = Int('x')
2265 >>> y = Int('y')
2266 >>> q = ForAll([x, y], f(x, y) >= x)
2267 >>> q.num_vars()
2268 2
2269 """
2270 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.astastast))
2271
2272 def var_name(self, idx):
2273 """Return a string representing a name used when displaying the quantifier.
2274
2275 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2276 >>> x = Int('x')
2277 >>> y = Int('y')
2278 >>> q = ForAll([x, y], f(x, y) >= x)
2279 >>> q.var_name(0)
2280 'x'
2281 >>> q.var_name(1)
2282 'y'
2283 """
2284 if z3_debug():
2285 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2287
2288 def var_sort(self, idx):
2289 """Return the sort of a bound variable.
2290
2291 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2292 >>> x = Int('x')
2293 >>> y = Real('y')
2294 >>> q = ForAll([x, y], f(x, y) >= x)
2295 >>> q.var_sort(0)
2296 Int
2297 >>> q.var_sort(1)
2298 Real
2299 """
2300 if z3_debug():
2301 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2303
2304 def children(self):
2305 """Return a list containing a single element self.body()
2306
2307 >>> f = Function('f', IntSort(), IntSort())
2308 >>> x = Int('x')
2309 >>> q = ForAll(x, f(x) == 0)
2310 >>> q.children()
2311 [f(Var(0)) == 0]
2312 """
2313 return [self.body()]
2314
2315
2317 """Return `True` if `a` is a Z3 quantifier.
2318
2319 >>> f = Function('f', IntSort(), IntSort())
2320 >>> x = Int('x')
2321 >>> q = ForAll(x, f(x) == 0)
2322 >>> is_quantifier(q)
2323 True
2324 >>> is_quantifier(f(x))
2325 False
2326 """
2327 return isinstance(a, QuantifierRef)
2328
2329
2330def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2331 if z3_debug():
2332 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2333 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2334 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2335 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2336 if is_app(vs):
2337 ctx = vs.ctx
2338 vs = [vs]
2339 else:
2340 ctx = vs[0].ctx
2341 if not is_expr(body):
2342 body = BoolVal(body, ctx)
2343 num_vars = len(vs)
2344 if num_vars == 0:
2345 return body
2346 _vs = (Ast * num_vars)()
2347 for i in range(num_vars):
2348 # TODO: Check if is constant
2349 _vs[i] = vs[i].as_ast()
2350 patterns = [_to_pattern(p) for p in patterns]
2351 num_pats = len(patterns)
2352 _pats = (Pattern * num_pats)()
2353 for i in range(num_pats):
2354 _pats[i] = patterns[i].ast
2355 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2356 qid = to_symbol(qid, ctx)
2357 skid = to_symbol(skid, ctx)
2358 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2359 num_vars, _vs,
2360 num_pats, _pats,
2361 num_no_pats, _no_pats,
2362 body.as_ast()), ctx)
2363
2364
2365def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2366 """Create a Z3 forall formula.
2367
2368 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2369
2370 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2371 >>> x = Int('x')
2372 >>> y = Int('y')
2373 >>> ForAll([x, y], f(x, y) >= x)
2374 ForAll([x, y], f(x, y) >= x)
2375 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2376 ForAll([x, y], f(x, y) >= x)
2377 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2378 ForAll([x, y], f(x, y) >= x)
2379 """
2380 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2381
2382
2383def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2384 """Create a Z3 exists formula.
2385
2386 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2387
2388
2389 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2390 >>> x = Int('x')
2391 >>> y = Int('y')
2392 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2393 >>> q
2394 Exists([x, y], f(x, y) >= x)
2395 >>> is_quantifier(q)
2396 True
2397 >>> r = Tactic('nnf')(q).as_expr()
2398 >>> is_quantifier(r)
2399 False
2400 """
2401 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2402
2403
2404def Lambda(vs, body):
2405 """Create a Z3 lambda expression.
2406
2407 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2408 >>> mem0 = Array('mem0', IntSort(), IntSort())
2409 >>> lo, hi, e, i = Ints('lo hi e i')
2410 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2411 >>> mem1
2412 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2413 """
2414 ctx = body.ctx
2415 if is_app(vs):
2416 vs = [vs]
2417 num_vars = len(vs)
2418 _vs = (Ast * num_vars)()
2419 for i in range(num_vars):
2420 # TODO: Check if is constant
2421 _vs[i] = vs[i].as_ast()
2422 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2423
2424
2429
2430
2432 """Real and Integer sorts."""
2433
2434 def is_real(self):
2435 """Return `True` if `self` is of the sort Real.
2436
2437 >>> x = Real('x')
2438 >>> x.is_real()
2439 True
2440 >>> (x + 1).is_real()
2441 True
2442 >>> x = Int('x')
2443 >>> x.is_real()
2444 False
2445 """
2446 return self.kind() == Z3_REAL_SORT
2447
2448 def is_int(self):
2449 """Return `True` if `self` is of the sort Integer.
2450
2451 >>> x = Int('x')
2452 >>> x.is_int()
2453 True
2454 >>> (x + 1).is_int()
2455 True
2456 >>> x = Real('x')
2457 >>> x.is_int()
2458 False
2459 """
2460 return self.kind() == Z3_INT_SORT
2461
2462 def is_bool(self):
2463 return False
2464
2465 def subsort(self, other):
2466 """Return `True` if `self` is a subsort of `other`."""
2467 return self.is_int() and is_arith_sort(other) and other.is_real()
2468
2469 def cast(self, val):
2470 """Try to cast `val` as an Integer or Real.
2471
2472 >>> IntSort().cast(10)
2473 10
2474 >>> is_int(IntSort().cast(10))
2475 True
2476 >>> is_int(10)
2477 False
2478 >>> RealSort().cast(10)
2479 10
2480 >>> is_real(RealSort().cast(10))
2481 True
2482 """
2483 if is_expr(val):
2484 if z3_debug():
2485 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
2486 val_s = val.sort()
2487 if self.eq(val_s):
2488 return val
2489 if val_s.is_int() and self.is_real():
2490 return ToReal(val)
2491 if val_s.is_bool() and self.is_int():
2492 return If(val, 1, 0)
2493 if val_s.is_bool() and self.is_real():
2494 return ToReal(If(val, 1, 0))
2495 if z3_debug():
2496 _z3_assert(False, "Z3 Integer/Real expression expected")
2497 else:
2498 if self.is_int():
2499 return IntVal(val, self.ctxctxctx)
2500 if self.is_real():
2501 return RealVal(val, self.ctxctxctx)
2502 if z3_debug():
2503 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2504 _z3_assert(False, msg % self)
2505
2506
2507def is_arith_sort(s : Any) -> bool:
2508 """Return `True` if s is an arithmetical sort (type).
2509
2510 >>> is_arith_sort(IntSort())
2511 True
2512 >>> is_arith_sort(RealSort())
2513 True
2514 >>> is_arith_sort(BoolSort())
2515 False
2516 >>> n = Int('x') + 1
2517 >>> is_arith_sort(n.sort())
2518 True
2519 """
2520 return isinstance(s, ArithSortRef)
2521
2522
2524 """Integer and Real expressions."""
2525
2526 def sort(self):
2527 """Return the sort (type) of the arithmetical expression `self`.
2528
2529 >>> Int('x').sort()
2530 Int
2531 >>> (Real('x') + 1).sort()
2532 Real
2533 """
2535
2536 def is_int(self):
2537 """Return `True` if `self` is an integer expression.
2538
2539 >>> x = Int('x')
2540 >>> x.is_int()
2541 True
2542 >>> (x + 1).is_int()
2543 True
2544 >>> y = Real('y')
2545 >>> (x + y).is_int()
2546 False
2547 """
2548 return self.sortsort().is_int()
2549
2550 def is_real(self):
2551 """Return `True` if `self` is an real expression.
2552
2553 >>> x = Real('x')
2554 >>> x.is_real()
2555 True
2556 >>> (x + 1).is_real()
2557 True
2558 """
2559 return self.sortsort().is_real()
2560
2561 def __add__(self, other):
2562 """Create the Z3 expression `self + other`.
2563
2564 >>> x = Int('x')
2565 >>> y = Int('y')
2566 >>> x + y
2567 x + y
2568 >>> (x + y).sort()
2569 Int
2570 """
2571 a, b = _coerce_exprs(self, other)
2572 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctxctxctx)
2573
2574 def __radd__(self, other):
2575 """Create the Z3 expression `other + self`.
2576
2577 >>> x = Int('x')
2578 >>> 10 + x
2579 10 + x
2580 """
2581 a, b = _coerce_exprs(self, other)
2582 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctxctxctx)
2583
2584 def __mul__(self, other):
2585 """Create the Z3 expression `self * other`.
2586
2587 >>> x = Real('x')
2588 >>> y = Real('y')
2589 >>> x * y
2590 x*y
2591 >>> (x * y).sort()
2592 Real
2593 """
2594 if isinstance(other, BoolRef):
2595 return If(other, self, 0)
2596 a, b = _coerce_exprs(self, other)
2597 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctxctxctx)
2598
2599 def __rmul__(self, other):
2600 """Create the Z3 expression `other * self`.
2601
2602 >>> x = Real('x')
2603 >>> 10 * x
2604 10*x
2605 """
2606 a, b = _coerce_exprs(self, other)
2607 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctxctxctx)
2608
2609 def __sub__(self, other):
2610 """Create the Z3 expression `self - other`.
2611
2612 >>> x = Int('x')
2613 >>> y = Int('y')
2614 >>> x - y
2615 x - y
2616 >>> (x - y).sort()
2617 Int
2618 """
2619 a, b = _coerce_exprs(self, other)
2620 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctxctxctx)
2621
2622 def __rsub__(self, other):
2623 """Create the Z3 expression `other - self`.
2624
2625 >>> x = Int('x')
2626 >>> 10 - x
2627 10 - x
2628 """
2629 a, b = _coerce_exprs(self, other)
2630 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctxctxctx)
2631
2632 def __pow__(self, other):
2633 """Create the Z3 expression `self**other` (** is the power operator).
2634
2635 >>> x = Real('x')
2636 >>> x**3
2637 x**3
2638 >>> (x**3).sort()
2639 Real
2640 >>> simplify(IntVal(2)**8)
2641 256
2642 """
2643 a, b = _coerce_exprs(self, other)
2644 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2645
2646 def __rpow__(self, other):
2647 """Create the Z3 expression `other**self` (** is the power operator).
2648
2649 >>> x = Real('x')
2650 >>> 2**x
2651 2**x
2652 >>> (2**x).sort()
2653 Real
2654 >>> simplify(2**IntVal(8))
2655 256
2656 """
2657 a, b = _coerce_exprs(self, other)
2658 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2659
2660 def __div__(self, other):
2661 """Create the Z3 expression `other/self`.
2662
2663 >>> x = Int('x')
2664 >>> y = Int('y')
2665 >>> x/y
2666 x/y
2667 >>> (x/y).sort()
2668 Int
2669 >>> (x/y).sexpr()
2670 '(div x y)'
2671 >>> x = Real('x')
2672 >>> y = Real('y')
2673 >>> x/y
2674 x/y
2675 >>> (x/y).sort()
2676 Real
2677 >>> (x/y).sexpr()
2678 '(/ x y)'
2679 """
2680 a, b = _coerce_exprs(self, other)
2681 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2682
2683 def __truediv__(self, other):
2684 """Create the Z3 expression `other/self`."""
2685 return self.__div__(other)
2686
2687 def __rdiv__(self, other):
2688 """Create the Z3 expression `other/self`.
2689
2690 >>> x = Int('x')
2691 >>> 10/x
2692 10/x
2693 >>> (10/x).sexpr()
2694 '(div 10 x)'
2695 >>> x = Real('x')
2696 >>> 10/x
2697 10/x
2698 >>> (10/x).sexpr()
2699 '(/ 10.0 x)'
2700 """
2701 a, b = _coerce_exprs(self, other)
2702 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2703
2704 def __rtruediv__(self, other):
2705 """Create the Z3 expression `other/self`."""
2706 return self.__rdiv__(other)
2707
2708 def __mod__(self, other):
2709 """Create the Z3 expression `other%self`.
2710
2711 >>> x = Int('x')
2712 >>> y = Int('y')
2713 >>> x % y
2714 x%y
2715 >>> simplify(IntVal(10) % IntVal(3))
2716 1
2717 """
2718 a, b = _coerce_exprs(self, other)
2719 if z3_debug():
2720 _z3_assert(a.is_int(), "Z3 integer expression expected")
2721 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2722
2723 def __rmod__(self, other):
2724 """Create the Z3 expression `other%self`.
2725
2726 >>> x = Int('x')
2727 >>> 10 % x
2728 10%x
2729 """
2730 a, b = _coerce_exprs(self, other)
2731 if z3_debug():
2732 _z3_assert(a.is_int(), "Z3 integer expression expected")
2733 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2734
2735 def __neg__(self):
2736 """Return an expression representing `-self`.
2737
2738 >>> x = Int('x')
2739 >>> -x
2740 -x
2741 >>> simplify(-(-x))
2742 x
2743 """
2744 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
2745
2746 def __pos__(self):
2747 """Return `self`.
2748
2749 >>> x = Int('x')
2750 >>> +x
2751 x
2752 """
2753 return self
2754
2755 def __le__(self, other):
2756 """Create the Z3 expression `other <= self`.
2757
2758 >>> x, y = Ints('x y')
2759 >>> x <= y
2760 x <= y
2761 >>> y = Real('y')
2762 >>> x <= y
2763 ToReal(x) <= y
2764 """
2765 a, b = _coerce_exprs(self, other)
2766 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2767
2768 def __lt__(self, other):
2769 """Create the Z3 expression `other < self`.
2770
2771 >>> x, y = Ints('x y')
2772 >>> x < y
2773 x < y
2774 >>> y = Real('y')
2775 >>> x < y
2776 ToReal(x) < y
2777 """
2778 a, b = _coerce_exprs(self, other)
2779 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2780
2781 def __gt__(self, other):
2782 """Create the Z3 expression `other > self`.
2783
2784 >>> x, y = Ints('x y')
2785 >>> x > y
2786 x > y
2787 >>> y = Real('y')
2788 >>> x > y
2789 ToReal(x) > y
2790 """
2791 a, b = _coerce_exprs(self, other)
2792 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2793
2794 def __ge__(self, other):
2795 """Create the Z3 expression `other >= self`.
2796
2797 >>> x, y = Ints('x y')
2798 >>> x >= y
2799 x >= y
2800 >>> y = Real('y')
2801 >>> x >= y
2802 ToReal(x) >= y
2803 """
2804 a, b = _coerce_exprs(self, other)
2805 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2806
2807 def __abs__(self):
2808 """Return an expression representing `abs(self)`.
2809
2810 >>> x = Int('x')
2811 >>> abs(x)
2812 If(x > 0, x, -x)
2813 >>> eq(abs(x), Abs(x))
2814 True
2815 """
2816 return Abs(self)
2817
2818
2820 """Return `True` if `a` is an arithmetical expression.
2821
2822 >>> x = Int('x')
2823 >>> is_arith(x)
2824 True
2825 >>> is_arith(x + 1)
2826 True
2827 >>> is_arith(1)
2828 False
2829 >>> is_arith(IntVal(1))
2830 True
2831 >>> y = Real('y')
2832 >>> is_arith(y)
2833 True
2834 >>> is_arith(y + 1)
2835 True
2836 """
2837 return isinstance(a, ArithRef)
2838
2839
2840def is_int(a) -> bool:
2841 """Return `True` if `a` is an integer expression.
2842
2843 >>> x = Int('x')
2844 >>> is_int(x + 1)
2845 True
2846 >>> is_int(1)
2847 False
2848 >>> is_int(IntVal(1))
2849 True
2850 >>> y = Real('y')
2851 >>> is_int(y)
2852 False
2853 >>> is_int(y + 1)
2854 False
2855 """
2856 return is_arith(a) and a.is_int()
2857
2858
2859def is_real(a):
2860 """Return `True` if `a` is a real expression.
2861
2862 >>> x = Int('x')
2863 >>> is_real(x + 1)
2864 False
2865 >>> y = Real('y')
2866 >>> is_real(y)
2867 True
2868 >>> is_real(y + 1)
2869 True
2870 >>> is_real(1)
2871 False
2872 >>> is_real(RealVal(1))
2873 True
2874 """
2875 return is_arith(a) and a.is_real()
2876
2877
2878def _is_numeral(ctx, a):
2879 return Z3_is_numeral_ast(ctx.ref(), a)
2880
2881
2882def _is_algebraic(ctx, a):
2883 return Z3_is_algebraic_number(ctx.ref(), a)
2884
2885
2887 """Return `True` if `a` is an integer value of sort Int.
2888
2889 >>> is_int_value(IntVal(1))
2890 True
2891 >>> is_int_value(1)
2892 False
2893 >>> is_int_value(Int('x'))
2894 False
2895 >>> n = Int('x') + 1
2896 >>> n
2897 x + 1
2898 >>> n.arg(1)
2899 1
2900 >>> is_int_value(n.arg(1))
2901 True
2902 >>> is_int_value(RealVal("1/3"))
2903 False
2904 >>> is_int_value(RealVal(1))
2905 False
2906 """
2907 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2908
2909
2911 """Return `True` if `a` is rational value of sort Real.
2912
2913 >>> is_rational_value(RealVal(1))
2914 True
2915 >>> is_rational_value(RealVal("3/5"))
2916 True
2917 >>> is_rational_value(IntVal(1))
2918 False
2919 >>> is_rational_value(1)
2920 False
2921 >>> n = Real('x') + 1
2922 >>> n.arg(1)
2923 1
2924 >>> is_rational_value(n.arg(1))
2925 True
2926 >>> is_rational_value(Real('x'))
2927 False
2928 """
2929 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2930
2931
2933 """Return `True` if `a` is an algebraic value of sort Real.
2934
2935 >>> is_algebraic_value(RealVal("3/5"))
2936 False
2937 >>> n = simplify(Sqrt(2))
2938 >>> n
2939 1.4142135623?
2940 >>> is_algebraic_value(n)
2941 True
2942 """
2943 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2944
2945
2946def is_add(a : Any) -> bool:
2947 """Return `True` if `a` is an expression of the form b + c.
2948
2949 >>> x, y = Ints('x y')
2950 >>> is_add(x + y)
2951 True
2952 >>> is_add(x - y)
2953 False
2954 """
2955 return is_app_of(a, Z3_OP_ADD)
2956
2957
2958def is_mul(a : Any) -> bool:
2959 """Return `True` if `a` is an expression of the form b * c.
2960
2961 >>> x, y = Ints('x y')
2962 >>> is_mul(x * y)
2963 True
2964 >>> is_mul(x - y)
2965 False
2966 """
2967 return is_app_of(a, Z3_OP_MUL)
2968
2969
2970def is_sub(a : Any) -> bool:
2971 """Return `True` if `a` is an expression of the form b - c.
2972
2973 >>> x, y = Ints('x y')
2974 >>> is_sub(x - y)
2975 True
2976 >>> is_sub(x + y)
2977 False
2978 """
2979 return is_app_of(a, Z3_OP_SUB)
2980
2981
2982def is_div(a : Any) -> bool:
2983 """Return `True` if `a` is an expression of the form b / c.
2984
2985 >>> x, y = Reals('x y')
2986 >>> is_div(x / y)
2987 True
2988 >>> is_div(x + y)
2989 False
2990 >>> x, y = Ints('x y')
2991 >>> is_div(x / y)
2992 False
2993 >>> is_idiv(x / y)
2994 True
2995 """
2996 return is_app_of(a, Z3_OP_DIV)
2997
2998
2999def is_idiv(a : Any) -> bool:
3000 """Return `True` if `a` is an expression of the form b div c.
3001
3002 >>> x, y = Ints('x y')
3003 >>> is_idiv(x / y)
3004 True
3005 >>> is_idiv(x + y)
3006 False
3007 """
3008 return is_app_of(a, Z3_OP_IDIV)
3009
3010
3011def is_mod(a : Any) -> bool:
3012 """Return `True` if `a` is an expression of the form b % c.
3013
3014 >>> x, y = Ints('x y')
3015 >>> is_mod(x % y)
3016 True
3017 >>> is_mod(x + y)
3018 False
3019 """
3020 return is_app_of(a, Z3_OP_MOD)
3021
3022
3023def is_le(a : Any) -> bool:
3024 """Return `True` if `a` is an expression of the form b <= c.
3025
3026 >>> x, y = Ints('x y')
3027 >>> is_le(x <= y)
3028 True
3029 >>> is_le(x < y)
3030 False
3031 """
3032 return is_app_of(a, Z3_OP_LE)
3033
3034
3035def is_lt(a : Any) -> bool:
3036 """Return `True` if `a` is an expression of the form b < c.
3037
3038 >>> x, y = Ints('x y')
3039 >>> is_lt(x < y)
3040 True
3041 >>> is_lt(x == y)
3042 False
3043 """
3044 return is_app_of(a, Z3_OP_LT)
3045
3046
3047def is_ge(a : Any) -> bool:
3048 """Return `True` if `a` is an expression of the form b >= c.
3049
3050 >>> x, y = Ints('x y')
3051 >>> is_ge(x >= y)
3052 True
3053 >>> is_ge(x == y)
3054 False
3055 """
3056 return is_app_of(a, Z3_OP_GE)
3057
3058
3059def is_gt(a : Any) -> bool:
3060 """Return `True` if `a` is an expression of the form b > c.
3061
3062 >>> x, y = Ints('x y')
3063 >>> is_gt(x > y)
3064 True
3065 >>> is_gt(x == y)
3066 False
3067 """
3068 return is_app_of(a, Z3_OP_GT)
3069
3070
3071def is_is_int(a : Any) -> bool:
3072 """Return `True` if `a` is an expression of the form IsInt(b).
3073
3074 >>> x = Real('x')
3075 >>> is_is_int(IsInt(x))
3076 True
3077 >>> is_is_int(x)
3078 False
3079 """
3080 return is_app_of(a, Z3_OP_IS_INT)
3081
3082
3083def is_to_real(a : Any) -> bool:
3084 """Return `True` if `a` is an expression of the form ToReal(b).
3085
3086 >>> x = Int('x')
3087 >>> n = ToReal(x)
3088 >>> n
3089 ToReal(x)
3090 >>> is_to_real(n)
3091 True
3092 >>> is_to_real(x)
3093 False
3094 """
3095 return is_app_of(a, Z3_OP_TO_REAL)
3096
3097
3098def is_to_int(a : Any) -> bool:
3099 """Return `True` if `a` is an expression of the form ToInt(b).
3100
3101 >>> x = Real('x')
3102 >>> n = ToInt(x)
3103 >>> n
3104 ToInt(x)
3105 >>> is_to_int(n)
3106 True
3107 >>> is_to_int(x)
3108 False
3109 """
3110 return is_app_of(a, Z3_OP_TO_INT)
3111
3112
3114 """Integer values."""
3115
3116 def as_long(self):
3117 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3118
3119 >>> v = IntVal(1)
3120 >>> v + 1
3121 1 + 1
3122 >>> v.as_long() + 1
3123 2
3124 """
3125 if z3_debug():
3126 _z3_assert(self.is_int(), "Integer value expected")
3127 return int(self.as_string())
3128
3129 def as_string(self):
3130 """Return a Z3 integer numeral as a Python string.
3131 >>> v = IntVal(100)
3132 >>> v.as_string()
3133 '100'
3134 """
3135 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3136
3138 """Return a Z3 integer numeral as a Python binary string.
3139 >>> v = IntVal(10)
3140 >>> v.as_binary_string()
3141 '1010'
3142 """
3144
3145 def py_value(self):
3146 return self.as_long()
3147
3148
3150 """Rational values."""
3151
3152 def numerator(self):
3153 """ Return the numerator of a Z3 rational numeral.
3154
3155 >>> is_rational_value(RealVal("3/5"))
3156 True
3157 >>> n = RealVal("3/5")
3158 >>> n.numerator()
3159 3
3160 >>> is_rational_value(Q(3,5))
3161 True
3162 >>> Q(3,5).numerator()
3163 3
3164 """
3166
3167 def denominator(self):
3168 """ Return the denominator of a Z3 rational numeral.
3169
3170 >>> is_rational_value(Q(3,5))
3171 True
3172 >>> n = Q(3,5)
3173 >>> n.denominator()
3174 5
3175 """
3176 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctxctx)
3177
3179 """ Return the numerator as a Python long.
3180
3181 >>> v = RealVal(10000000000)
3182 >>> v
3183 10000000000
3184 >>> v + 1
3185 10000000000 + 1
3186 >>> v.numerator_as_long() + 1 == 10000000001
3187 True
3188 """
3189 return self.numerator().as_long()
3190
3192 """ Return the denominator as a Python long.
3193
3194 >>> v = RealVal("1/3")
3195 >>> v
3196 1/3
3197 >>> v.denominator_as_long()
3198 3
3199 """
3200 return self.denominator().as_long()
3201
3202 def is_int(self):
3203 return False
3204
3205 def is_real(self):
3206 return True
3207
3208 def is_int_value(self):
3209 return self.denominator().is_int() and self.denominator_as_long() == 1
3210
3211 def as_long(self):
3212 _z3_assert(self.is_int_value(), "Expected integer fraction")
3213 return self.numerator_as_long()
3214
3215 def as_decimal(self, prec):
3216 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3217
3218 >>> v = RealVal("1/5")
3219 >>> v.as_decimal(3)
3220 '0.2'
3221 >>> v = RealVal("1/3")
3222 >>> v.as_decimal(3)
3223 '0.333?'
3224 """
3225 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3226
3227 def as_string(self):
3228 """Return a Z3 rational numeral as a Python string.
3229
3230 >>> v = Q(3,6)
3231 >>> v.as_string()
3232 '1/2'
3233 """
3234 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3235
3236 def as_fraction(self):
3237 """Return a Z3 rational as a Python Fraction object.
3238
3239 >>> v = RealVal("1/5")
3240 >>> v.as_fraction()
3241 Fraction(1, 5)
3242 """
3243 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3244
3245 def py_value(self):
3246 return Z3_get_numeral_double(self.ctx_ref(), self.as_astas_ast())
3247
3248
3250 """Algebraic irrational values."""
3251
3252 def approx(self, precision=10):
3253 """Return a Z3 rational number that approximates the algebraic number `self`.
3254 The result `r` is such that |r - self| <= 1/10^precision
3255
3256 >>> x = simplify(Sqrt(2))
3257 >>> x.approx(20)
3258 6838717160008073720548335/4835703278458516698824704
3259 >>> x.approx(5)
3260 2965821/2097152
3261 """
3263
3264 def as_decimal(self, prec):
3265 """Return a string representation of the algebraic number `self` in decimal notation
3266 using `prec` decimal places.
3267
3268 >>> x = simplify(Sqrt(2))
3269 >>> x.as_decimal(10)
3270 '1.4142135623?'
3271 >>> x.as_decimal(20)
3272 '1.41421356237309504880?'
3273 """
3274 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3275
3276 def poly(self):
3278
3279 def index(self):
3280 return Z3_algebraic_get_i(self.ctx_ref(), self.as_astas_ast())
3281
3282
3283def _py2expr(a, ctx=None):
3284 if isinstance(a, bool):
3285 return BoolVal(a, ctx)
3286 if _is_int(a):
3287 return IntVal(a, ctx)
3288 if isinstance(a, float):
3289 return RealVal(a, ctx)
3290 if isinstance(a, str):
3291 return StringVal(a, ctx)
3292 if is_expr(a):
3293 return a
3294 if z3_debug():
3295 _z3_assert(False, "Python bool, int, long or float expected")
3296
3297
3298def IntSort(ctx=None):
3299 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3300
3301 >>> IntSort()
3302 Int
3303 >>> x = Const('x', IntSort())
3304 >>> is_int(x)
3305 True
3306 >>> x.sort() == IntSort()
3307 True
3308 >>> x.sort() == BoolSort()
3309 False
3310 """
3311 ctx = _get_ctx(ctx)
3312 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3313
3314
3315def RealSort(ctx=None):
3316 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3317
3318 >>> RealSort()
3319 Real
3320 >>> x = Const('x', RealSort())
3321 >>> is_real(x)
3322 True
3323 >>> is_int(x)
3324 False
3325 >>> x.sort() == RealSort()
3326 True
3327 """
3328 ctx = _get_ctx(ctx)
3329 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3330
3331
3333 if isinstance(val, float):
3334 return str(int(val))
3335 elif isinstance(val, bool):
3336 if val:
3337 return "1"
3338 else:
3339 return "0"
3340 else:
3341 return str(val)
3342
3343
3344def IntVal(val, ctx=None):
3345 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3346
3347 >>> IntVal(1)
3348 1
3349 >>> IntVal("100")
3350 100
3351 """
3352 ctx = _get_ctx(ctx)
3353 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3354
3355
3356def RealVal(val, ctx=None):
3357 """Return a Z3 real value.
3358
3359 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3360 If `ctx=None`, then the global context is used.
3361
3362 >>> RealVal(1)
3363 1
3364 >>> RealVal(1).sort()
3365 Real
3366 >>> RealVal("3/5")
3367 3/5
3368 >>> RealVal("1.5")
3369 3/2
3370 """
3371 ctx = _get_ctx(ctx)
3372 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3373
3374
3375def RatVal(a, b, ctx=None):
3376 """Return a Z3 rational a/b.
3377
3378 If `ctx=None`, then the global context is used.
3379
3380 Note: Division by zero (b == 0) is allowed in Z3 symbolic expressions.
3381 Z3 can reason about such expressions symbolically.
3382
3383 >>> RatVal(3,5)
3384 3/5
3385 >>> RatVal(3,5).sort()
3386 Real
3387 """
3388 if z3_debug():
3389 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3390 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3391 # Division by 0 is intentionally allowed - Z3 handles it symbolically
3392 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3393
3394
3395def Q(a, b, ctx=None):
3396 """Return a Z3 rational a/b.
3397
3398 If `ctx=None`, then the global context is used.
3399
3400 >>> Q(3,5)
3401 3/5
3402 >>> Q(3,5).sort()
3403 Real
3404 """
3405 return simplify(RatVal(a, b, ctx=ctx))
3406
3407
3408def Int(name, ctx=None):
3409 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3410
3411 >>> x = Int('x')
3412 >>> is_int(x)
3413 True
3414 >>> is_int(x + 1)
3415 True
3416 """
3417 ctx = _get_ctx(ctx)
3418 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3419
3420
3421def Ints(names, ctx=None):
3422 """Return a tuple of Integer constants.
3423
3424 >>> x, y, z = Ints('x y z')
3425 >>> Sum(x, y, z)
3426 x + y + z
3427 """
3428 ctx = _get_ctx(ctx)
3429 if isinstance(names, str):
3430 names = names.split(" ")
3431 return [Int(name, ctx) for name in names]
3432
3433
3434def IntVector(prefix, sz, ctx=None):
3435 """Return a list of integer constants of size `sz`.
3436
3437 >>> X = IntVector('x', 3)
3438 >>> X
3439 [x__0, x__1, x__2]
3440 >>> Sum(X)
3441 x__0 + x__1 + x__2
3442 """
3443 ctx = _get_ctx(ctx)
3444 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3445
3446
3447def FreshInt(prefix="x", ctx=None):
3448 """Return a fresh integer constant in the given context using the given prefix.
3449
3450 >>> x = FreshInt()
3451 >>> y = FreshInt()
3452 >>> eq(x, y)
3453 False
3454 >>> x.sort()
3455 Int
3456 """
3457 ctx = _get_ctx(ctx)
3458 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3459
3460
3461def Real(name, ctx=None):
3462 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3463
3464 >>> x = Real('x')
3465 >>> is_real(x)
3466 True
3467 >>> is_real(x + 1)
3468 True
3469 """
3470 ctx = _get_ctx(ctx)
3471 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3472
3473
3474def Reals(names, ctx=None):
3475 """Return a tuple of real constants.
3476
3477 >>> x, y, z = Reals('x y z')
3478 >>> Sum(x, y, z)
3479 x + y + z
3480 >>> Sum(x, y, z).sort()
3481 Real
3482 """
3483 ctx = _get_ctx(ctx)
3484 if isinstance(names, str):
3485 names = names.split(" ")
3486 return [Real(name, ctx) for name in names]
3487
3488
3489def RealVector(prefix, sz, ctx=None):
3490 """Return a list of real constants of size `sz`.
3491
3492 >>> X = RealVector('x', 3)
3493 >>> X
3494 [x__0, x__1, x__2]
3495 >>> Sum(X)
3496 x__0 + x__1 + x__2
3497 >>> Sum(X).sort()
3498 Real
3499 """
3500 ctx = _get_ctx(ctx)
3501 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3502
3503
3504def FreshReal(prefix="b", ctx=None):
3505 """Return a fresh real constant in the given context using the given prefix.
3506
3507 >>> x = FreshReal()
3508 >>> y = FreshReal()
3509 >>> eq(x, y)
3510 False
3511 >>> x.sort()
3512 Real
3513 """
3514 ctx = _get_ctx(ctx)
3515 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3516
3517
3518def ToReal(a):
3519 """ Return the Z3 expression ToReal(a).
3520
3521 >>> x = Int('x')
3522 >>> x.sort()
3523 Int
3524 >>> n = ToReal(x)
3525 >>> n
3526 ToReal(x)
3527 >>> n.sort()
3528 Real
3529 """
3530 ctx = a.ctx
3531 if isinstance(a, BoolRef):
3532 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3533 if z3_debug():
3534 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3535 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3536
3537
3538def ToInt(a):
3539 """ Return the Z3 expression ToInt(a).
3540
3541 >>> x = Real('x')
3542 >>> x.sort()
3543 Real
3544 >>> n = ToInt(x)
3545 >>> n
3546 ToInt(x)
3547 >>> n.sort()
3548 Int
3549 """
3550 if z3_debug():
3551 _z3_assert(a.is_real(), "Z3 real expression expected.")
3552 ctx = a.ctx
3553 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3554
3555
3556def IsInt(a):
3557 """ Return the Z3 predicate IsInt(a).
3558
3559 >>> x = Real('x')
3560 >>> IsInt(x + "1/2")
3561 IsInt(x + 1/2)
3562 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3563 [x = 1/2]
3564 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3565 no solution
3566 """
3567 if z3_debug():
3568 _z3_assert(a.is_real(), "Z3 real expression expected.")
3569 ctx = a.ctx
3570 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3571
3572
3573def Sqrt(a, ctx=None):
3574 """ Return a Z3 expression which represents the square root of a.
3575
3576 >>> x = Real('x')
3577 >>> Sqrt(x)
3578 x**(1/2)
3579 """
3580 if not is_expr(a):
3581 ctx = _get_ctx(ctx)
3582 a = RealVal(a, ctx)
3583 return a ** "1/2"
3584
3585
3586def Cbrt(a, ctx=None):
3587 """ Return a Z3 expression which represents the cubic root of a.
3588
3589 >>> x = Real('x')
3590 >>> Cbrt(x)
3591 x**(1/3)
3592 """
3593 if not is_expr(a):
3594 ctx = _get_ctx(ctx)
3595 a = RealVal(a, ctx)
3596 return a ** "1/3"
3597
3598
3603
3604
3606 """Bit-vector sort."""
3607
3608 def size(self):
3609 """Return the size (number of bits) of the bit-vector sort `self`.
3610
3611 >>> b = BitVecSort(32)
3612 >>> b.size()
3613 32
3614 """
3615 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.astastast))
3616
3617 def subsort(self, other):
3618 return is_bv_sort(other) and self.size() < other.size()
3619
3620 def cast(self, val):
3621 """Try to cast `val` as a Bit-Vector.
3622
3623 >>> b = BitVecSort(32)
3624 >>> b.cast(10)
3625 10
3626 >>> b.cast(10).sexpr()
3627 '#x0000000a'
3628 """
3629 if is_expr(val):
3630 if z3_debug():
3631 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
3632 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3633 return val
3634 else:
3635 return BitVecVal(val, self)
3636
3637
3639 """Return True if `s` is a Z3 bit-vector sort.
3640
3641 >>> is_bv_sort(BitVecSort(32))
3642 True
3643 >>> is_bv_sort(IntSort())
3644 False
3645 """
3646 return isinstance(s, BitVecSortRef)
3647
3648
3650 """Bit-vector expressions."""
3651
3652 def sort(self):
3653 """Return the sort of the bit-vector expression `self`.
3654
3655 >>> x = BitVec('x', 32)
3656 >>> x.sort()
3657 BitVec(32)
3658 >>> x.sort() == BitVecSort(32)
3659 True
3660 """
3662
3663 def size(self):
3664 """Return the number of bits of the bit-vector expression `self`.
3665
3666 >>> x = BitVec('x', 32)
3667 >>> (x + 1).size()
3668 32
3669 >>> Concat(x, x).size()
3670 64
3671 """
3672 return self.sortsort().size()
3673
3674 def __add__(self, other):
3675 """Create the Z3 expression `self + other`.
3676
3677 >>> x = BitVec('x', 32)
3678 >>> y = BitVec('y', 32)
3679 >>> x + y
3680 x + y
3681 >>> (x + y).sort()
3682 BitVec(32)
3683 """
3684 a, b = _coerce_exprs(self, other)
3685 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3686
3687 def __radd__(self, other):
3688 """Create the Z3 expression `other + self`.
3689
3690 >>> x = BitVec('x', 32)
3691 >>> 10 + x
3692 10 + x
3693 """
3694 a, b = _coerce_exprs(self, other)
3695 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3696
3697 def __mul__(self, other):
3698 """Create the Z3 expression `self * other`.
3699
3700 >>> x = BitVec('x', 32)
3701 >>> y = BitVec('y', 32)
3702 >>> x * y
3703 x*y
3704 >>> (x * y).sort()
3705 BitVec(32)
3706 """
3707 a, b = _coerce_exprs(self, other)
3708 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3709
3710 def __rmul__(self, other):
3711 """Create the Z3 expression `other * self`.
3712
3713 >>> x = BitVec('x', 32)
3714 >>> 10 * x
3715 10*x
3716 """
3717 a, b = _coerce_exprs(self, other)
3718 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3719
3720 def __sub__(self, other):
3721 """Create the Z3 expression `self - other`.
3722
3723 >>> x = BitVec('x', 32)
3724 >>> y = BitVec('y', 32)
3725 >>> x - y
3726 x - y
3727 >>> (x - y).sort()
3728 BitVec(32)
3729 """
3730 a, b = _coerce_exprs(self, other)
3731 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3732
3733 def __rsub__(self, other):
3734 """Create the Z3 expression `other - self`.
3735
3736 >>> x = BitVec('x', 32)
3737 >>> 10 - x
3738 10 - x
3739 """
3740 a, b = _coerce_exprs(self, other)
3741 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3742
3743 def __or__(self, other):
3744 """Create the Z3 expression bitwise-or `self | other`.
3745
3746 >>> x = BitVec('x', 32)
3747 >>> y = BitVec('y', 32)
3748 >>> x | y
3749 x | y
3750 >>> (x | y).sort()
3751 BitVec(32)
3752 """
3753 a, b = _coerce_exprs(self, other)
3754 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3755
3756 def __ror__(self, other):
3757 """Create the Z3 expression bitwise-or `other | self`.
3758
3759 >>> x = BitVec('x', 32)
3760 >>> 10 | x
3761 10 | x
3762 """
3763 a, b = _coerce_exprs(self, other)
3764 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3765
3766 def __and__(self, other):
3767 """Create the Z3 expression bitwise-and `self & other`.
3768
3769 >>> x = BitVec('x', 32)
3770 >>> y = BitVec('y', 32)
3771 >>> x & y
3772 x & y
3773 >>> (x & y).sort()
3774 BitVec(32)
3775 """
3776 a, b = _coerce_exprs(self, other)
3777 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3778
3779 def __rand__(self, other):
3780 """Create the Z3 expression bitwise-or `other & self`.
3781
3782 >>> x = BitVec('x', 32)
3783 >>> 10 & x
3784 10 & x
3785 """
3786 a, b = _coerce_exprs(self, other)
3787 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3788
3789 def __xor__(self, other):
3790 """Create the Z3 expression bitwise-xor `self ^ other`.
3791
3792 >>> x = BitVec('x', 32)
3793 >>> y = BitVec('y', 32)
3794 >>> x ^ y
3795 x ^ y
3796 >>> (x ^ y).sort()
3797 BitVec(32)
3798 """
3799 a, b = _coerce_exprs(self, other)
3800 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3801
3802 def __rxor__(self, other):
3803 """Create the Z3 expression bitwise-xor `other ^ self`.
3804
3805 >>> x = BitVec('x', 32)
3806 >>> 10 ^ x
3807 10 ^ x
3808 """
3809 a, b = _coerce_exprs(self, other)
3810 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3811
3812 def __pos__(self):
3813 """Return `self`.
3814
3815 >>> x = BitVec('x', 32)
3816 >>> +x
3817 x
3818 """
3819 return self
3820
3821 def __neg__(self):
3822 """Return an expression representing `-self`.
3823
3824 >>> x = BitVec('x', 32)
3825 >>> -x
3826 -x
3827 >>> simplify(-(-x))
3828 x
3829 """
3830 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3831
3832 def __invert__(self):
3833 """Create the Z3 expression bitwise-not `~self`.
3834
3835 >>> x = BitVec('x', 32)
3836 >>> ~x
3837 ~x
3838 >>> simplify(~(~x))
3839 x
3840 """
3841 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3842
3843 def __div__(self, other):
3844 """Create the Z3 expression (signed) division `self / other`.
3845
3846 Use the function UDiv() for unsigned division.
3847
3848 >>> x = BitVec('x', 32)
3849 >>> y = BitVec('y', 32)
3850 >>> x / y
3851 x/y
3852 >>> (x / y).sort()
3853 BitVec(32)
3854 >>> (x / y).sexpr()
3855 '(bvsdiv x y)'
3856 >>> UDiv(x, y).sexpr()
3857 '(bvudiv x y)'
3858 """
3859 a, b = _coerce_exprs(self, other)
3860 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3861
3862 def __truediv__(self, other):
3863 """Create the Z3 expression (signed) division `self / other`."""
3864 return self.__div__(other)
3865
3866 def __rdiv__(self, other):
3867 """Create the Z3 expression (signed) division `other / self`.
3868
3869 Use the function UDiv() for unsigned division.
3870
3871 >>> x = BitVec('x', 32)
3872 >>> 10 / x
3873 10/x
3874 >>> (10 / x).sexpr()
3875 '(bvsdiv #x0000000a x)'
3876 >>> UDiv(10, x).sexpr()
3877 '(bvudiv #x0000000a x)'
3878 """
3879 a, b = _coerce_exprs(self, other)
3880 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3881
3882 def __rtruediv__(self, other):
3883 """Create the Z3 expression (signed) division `other / self`."""
3884 return self.__rdiv__(other)
3885
3886 def __mod__(self, other):
3887 """Create the Z3 expression (signed) mod `self % other`.
3888
3889 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3890
3891 >>> x = BitVec('x', 32)
3892 >>> y = BitVec('y', 32)
3893 >>> x % y
3894 x%y
3895 >>> (x % y).sort()
3896 BitVec(32)
3897 >>> (x % y).sexpr()
3898 '(bvsmod x y)'
3899 >>> URem(x, y).sexpr()
3900 '(bvurem x y)'
3901 >>> SRem(x, y).sexpr()
3902 '(bvsrem x y)'
3903 """
3904 a, b = _coerce_exprs(self, other)
3905 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3906
3907 def __rmod__(self, other):
3908 """Create the Z3 expression (signed) mod `other % self`.
3909
3910 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3911
3912 >>> x = BitVec('x', 32)
3913 >>> 10 % x
3914 10%x
3915 >>> (10 % x).sexpr()
3916 '(bvsmod #x0000000a x)'
3917 >>> URem(10, x).sexpr()
3918 '(bvurem #x0000000a x)'
3919 >>> SRem(10, x).sexpr()
3920 '(bvsrem #x0000000a x)'
3921 """
3922 a, b = _coerce_exprs(self, other)
3923 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3924
3925 def __le__(self, other):
3926 """Create the Z3 expression (signed) `other <= self`.
3927
3928 Use the function ULE() for unsigned less than or equal to.
3929
3930 >>> x, y = BitVecs('x y', 32)
3931 >>> x <= y
3932 x <= y
3933 >>> (x <= y).sexpr()
3934 '(bvsle x y)'
3935 >>> ULE(x, y).sexpr()
3936 '(bvule x y)'
3937 """
3938 a, b = _coerce_exprs(self, other)
3939 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3940
3941 def __lt__(self, other):
3942 """Create the Z3 expression (signed) `other < self`.
3943
3944 Use the function ULT() for unsigned less than.
3945
3946 >>> x, y = BitVecs('x y', 32)
3947 >>> x < y
3948 x < y
3949 >>> (x < y).sexpr()
3950 '(bvslt x y)'
3951 >>> ULT(x, y).sexpr()
3952 '(bvult x y)'
3953 """
3954 a, b = _coerce_exprs(self, other)
3955 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3956
3957 def __gt__(self, other):
3958 """Create the Z3 expression (signed) `other > self`.
3959
3960 Use the function UGT() for unsigned greater than.
3961
3962 >>> x, y = BitVecs('x y', 32)
3963 >>> x > y
3964 x > y
3965 >>> (x > y).sexpr()
3966 '(bvsgt x y)'
3967 >>> UGT(x, y).sexpr()
3968 '(bvugt x y)'
3969 """
3970 a, b = _coerce_exprs(self, other)
3971 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3972
3973 def __ge__(self, other):
3974 """Create the Z3 expression (signed) `other >= self`.
3975
3976 Use the function UGE() for unsigned greater than or equal to.
3977
3978 >>> x, y = BitVecs('x y', 32)
3979 >>> x >= y
3980 x >= y
3981 >>> (x >= y).sexpr()
3982 '(bvsge x y)'
3983 >>> UGE(x, y).sexpr()
3984 '(bvuge x y)'
3985 """
3986 a, b = _coerce_exprs(self, other)
3987 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3988
3989 def __rshift__(self, other):
3990 """Create the Z3 expression (arithmetical) right shift `self >> other`
3991
3992 Use the function LShR() for the right logical shift
3993
3994 >>> x, y = BitVecs('x y', 32)
3995 >>> x >> y
3996 x >> y
3997 >>> (x >> y).sexpr()
3998 '(bvashr x y)'
3999 >>> LShR(x, y).sexpr()
4000 '(bvlshr x y)'
4001 >>> BitVecVal(4, 3)
4002 4
4003 >>> BitVecVal(4, 3).as_signed_long()
4004 -4
4005 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4006 -2
4007 >>> simplify(BitVecVal(4, 3) >> 1)
4008 6
4009 >>> simplify(LShR(BitVecVal(4, 3), 1))
4010 2
4011 >>> simplify(BitVecVal(2, 3) >> 1)
4012 1
4013 >>> simplify(LShR(BitVecVal(2, 3), 1))
4014 1
4015 """
4016 a, b = _coerce_exprs(self, other)
4017 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
4018
4019 def __lshift__(self, other):
4020 """Create the Z3 expression left shift `self << other`
4021
4022 >>> x, y = BitVecs('x y', 32)
4023 >>> x << y
4024 x << y
4025 >>> (x << y).sexpr()
4026 '(bvshl x y)'
4027 >>> simplify(BitVecVal(2, 3) << 1)
4028 4
4029 """
4030 a, b = _coerce_exprs(self, other)
4031 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
4032
4033 def __rrshift__(self, other):
4034 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
4035
4036 Use the function LShR() for the right logical shift
4037
4038 >>> x = BitVec('x', 32)
4039 >>> 10 >> x
4040 10 >> x
4041 >>> (10 >> x).sexpr()
4042 '(bvashr #x0000000a x)'
4043 """
4044 a, b = _coerce_exprs(self, other)
4045 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
4046
4047 def __rlshift__(self, other):
4048 """Create the Z3 expression left shift `other << self`.
4049
4050 Use the function LShR() for the right logical shift
4051
4052 >>> x = BitVec('x', 32)
4053 >>> 10 << x
4054 10 << x
4055 >>> (10 << x).sexpr()
4056 '(bvshl #x0000000a x)'
4057 """
4058 a, b = _coerce_exprs(self, other)
4059 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
4060
4061
4063 """Bit-vector values."""
4064
4065 def as_long(self):
4066 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4067
4068 >>> v = BitVecVal(0xbadc0de, 32)
4069 >>> v
4070 195936478
4071 >>> print("0x%.8x" % v.as_long())
4072 0x0badc0de
4073 """
4074 return int(self.as_string())
4075
4077 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4078 The most significant bit is assumed to be the sign.
4079
4080 >>> BitVecVal(4, 3).as_signed_long()
4081 -4
4082 >>> BitVecVal(7, 3).as_signed_long()
4083 -1
4084 >>> BitVecVal(3, 3).as_signed_long()
4085 3
4086 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4087 -1
4088 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4089 -1
4090 """
4091 sz = self.size()
4092 val = self.as_long()
4093 if val >= 2**(sz - 1):
4094 val = val - 2**sz
4095 if val < -2**(sz - 1):
4096 val = val + 2**sz
4097 return int(val)
4098
4099 def as_string(self):
4100 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
4101
4104
4105 def py_value(self):
4106 """Return the Python value of a Z3 bit-vector numeral."""
4107 return self.as_long()
4108
4109
4110
4111def is_bv(a):
4112 """Return `True` if `a` is a Z3 bit-vector expression.
4113
4114 >>> b = BitVec('b', 32)
4115 >>> is_bv(b)
4116 True
4117 >>> is_bv(b + 10)
4118 True
4119 >>> is_bv(Int('x'))
4120 False
4121 """
4122 return isinstance(a, BitVecRef)
4123
4124
4126 """Return `True` if `a` is a Z3 bit-vector numeral value.
4127
4128 >>> b = BitVec('b', 32)
4129 >>> is_bv_value(b)
4130 False
4131 >>> b = BitVecVal(10, 32)
4132 >>> b
4133 10
4134 >>> is_bv_value(b)
4135 True
4136 """
4137 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4138
4139
4140def BV2Int(a, is_signed=False):
4141 """Return the Z3 expression BV2Int(a).
4142
4143 >>> b = BitVec('b', 3)
4144 >>> BV2Int(b).sort()
4145 Int
4146 >>> x = Int('x')
4147 >>> x > BV2Int(b)
4148 x > BV2Int(b)
4149 >>> x > BV2Int(b, is_signed=False)
4150 x > BV2Int(b)
4151 >>> x > BV2Int(b, is_signed=True)
4152 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4153 >>> solve(x > BV2Int(b), b == 1, x < 3)
4154 [x = 2, b = 1]
4155 """
4156 if z3_debug():
4157 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4158 ctx = a.ctx
4159 # investigate problem with bv2int
4160 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4161
4162
4163def Int2BV(a, num_bits):
4164 """Return the z3 expression Int2BV(a, num_bits).
4165 It is a bit-vector of width num_bits and represents the
4166 modulo of a by 2^num_bits
4167 """
4168 ctx = a.ctx
4169 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4170
4171
4172def BitVecSort(sz, ctx=None):
4173 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4174
4175 >>> Byte = BitVecSort(8)
4176 >>> Word = BitVecSort(16)
4177 >>> Byte
4178 BitVec(8)
4179 >>> x = Const('x', Byte)
4180 >>> eq(x, BitVec('x', 8))
4181 True
4182 """
4183 ctx = _get_ctx(ctx)
4184 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4185
4186
4187def BitVecVal(val, bv, ctx=None):
4188 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4189
4190 >>> v = BitVecVal(10, 32)
4191 >>> v
4192 10
4193 >>> print("0x%.8x" % v.as_long())
4194 0x0000000a
4195 """
4196 if is_bv_sort(bv):
4197 ctx = bv.ctx
4198 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4199 else:
4200 ctx = _get_ctx(ctx)
4201 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4202
4203
4204def BitVec(name, bv, ctx=None):
4205 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4206 If `ctx=None`, then the global context is used.
4207
4208 >>> x = BitVec('x', 16)
4209 >>> is_bv(x)
4210 True
4211 >>> x.size()
4212 16
4213 >>> x.sort()
4214 BitVec(16)
4215 >>> word = BitVecSort(16)
4216 >>> x2 = BitVec('x', word)
4217 >>> eq(x, x2)
4218 True
4219 """
4220 if isinstance(bv, BitVecSortRef):
4221 ctx = bv.ctx
4222 else:
4223 ctx = _get_ctx(ctx)
4224 bv = BitVecSort(bv, ctx)
4225 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4226
4227
4228def BitVecs(names, bv, ctx=None):
4229 """Return a tuple of bit-vector constants of size bv.
4230
4231 >>> x, y, z = BitVecs('x y z', 16)
4232 >>> x.size()
4233 16
4234 >>> x.sort()
4235 BitVec(16)
4236 >>> Sum(x, y, z)
4237 0 + x + y + z
4238 >>> Product(x, y, z)
4239 1*x*y*z
4240 >>> simplify(Product(x, y, z))
4241 x*y*z
4242 """
4243 ctx = _get_ctx(ctx)
4244 if isinstance(names, str):
4245 names = names.split(" ")
4246 return [BitVec(name, bv, ctx) for name in names]
4247
4248
4249def Concat(*args):
4250 """Create a Z3 bit-vector concatenation expression.
4251
4252 >>> v = BitVecVal(1, 4)
4253 >>> Concat(v, v+1, v)
4254 Concat(Concat(1, 1 + 1), 1)
4255 >>> simplify(Concat(v, v+1, v))
4256 289
4257 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4258 121
4259 """
4260 args = _get_args(args)
4261 sz = len(args)
4262 if z3_debug():
4263 _z3_assert(sz >= 2, "At least two arguments expected.")
4264
4265 ctx = None
4266 for a in args:
4267 if is_expr(a):
4268 ctx = a.ctx
4269 break
4270 if is_seq(args[0]) or isinstance(args[0], str):
4271 args = [_coerce_seq(s, ctx) for s in args]
4272 if z3_debug():
4273 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4274 v = (Ast * sz)()
4275 for i in range(sz):
4276 v[i] = args[i].as_ast()
4277 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4278
4279 if is_re(args[0]):
4280 if z3_debug():
4281 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4282 v = (Ast * sz)()
4283 for i in range(sz):
4284 v[i] = args[i].as_ast()
4285 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4286
4287 if z3_debug():
4288 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4289 r = args[0]
4290 for i in range(sz - 1):
4291 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4292 return r
4293
4294
4295def Extract(high, low, a):
4296 """Create a Z3 bit-vector extraction expression or sequence extraction expression.
4297
4298 Extract is overloaded to work with both bit-vectors and sequences:
4299
4300 **Bit-vector extraction**: Extract(high, low, bitvector)
4301 Extracts bits from position `high` down to position `low` (both inclusive).
4302 - high: int - the highest bit position to extract (0-indexed from right)
4303 - low: int - the lowest bit position to extract (0-indexed from right)
4304 - bitvector: BitVecRef - the bit-vector to extract from
4305 Returns a new bit-vector containing bits [high:low]
4306
4307 **Sequence extraction**: Extract(sequence, offset, length)
4308 Extracts a subsequence starting at the given offset with the specified length.
4309 The functions SubString and SubSeq are redirected to this form of Extract.
4310 - sequence: SeqRef or str - the sequence to extract from
4311 - offset: int - the starting position (0-indexed)
4312 - length: int - the number of elements to extract
4313 Returns a new sequence containing the extracted subsequence
4314
4315 >>> # Bit-vector extraction examples
4316 >>> x = BitVec('x', 8)
4317 >>> Extract(6, 2, x) # Extract bits 6 down to 2 (5 bits total)
4318 Extract(6, 2, x)
4319 >>> Extract(6, 2, x).sort() # Result is a 5-bit vector
4320 BitVec(5)
4321 >>> Extract(7, 0, x) # Extract all 8 bits
4322 Extract(7, 0, x)
4323 >>> Extract(3, 3, x) # Extract single bit at position 3
4324 Extract(3, 3, x)
4325
4326 >>> # Sequence extraction examples
4327 >>> s = StringVal("hello")
4328 >>> Extract(s, 1, 3) # Extract 3 characters starting at position 1
4329 str.substr("hello", 1, 3)
4330 >>> simplify(Extract(StringVal("abcd"), 2, 1)) # Extract 1 character at position 2
4331 "c"
4332 >>> simplify(Extract(StringVal("abcd"), 0, 2)) # Extract first 2 characters
4333 "ab"
4334 """
4335 if isinstance(high, str):
4336 high = StringVal(high)
4337 if is_seq(high):
4338 s = high
4339 offset, length = _coerce_exprs(low, a, s.ctx)
4340 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4341 if z3_debug():
4342 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4343 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4344 "First and second arguments must be non negative integers")
4345 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4346 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4347
4348
4350 if z3_debug():
4351 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4352
4353
4354def ULE(a, b):
4355 """Create the Z3 expression (unsigned) `other <= self`.
4356
4357 Use the operator <= for signed less than or equal to.
4358
4359 >>> x, y = BitVecs('x y', 32)
4360 >>> ULE(x, y)
4361 ULE(x, y)
4362 >>> (x <= y).sexpr()
4363 '(bvsle x y)'
4364 >>> ULE(x, y).sexpr()
4365 '(bvule x y)'
4366 """
4367 _check_bv_args(a, b)
4368 a, b = _coerce_exprs(a, b)
4369 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4370
4371
4372def ULT(a, b):
4373 """Create the Z3 expression (unsigned) `other < self`.
4374
4375 Use the operator < for signed less than.
4376
4377 >>> x, y = BitVecs('x y', 32)
4378 >>> ULT(x, y)
4379 ULT(x, y)
4380 >>> (x < y).sexpr()
4381 '(bvslt x y)'
4382 >>> ULT(x, y).sexpr()
4383 '(bvult x y)'
4384 """
4385 _check_bv_args(a, b)
4386 a, b = _coerce_exprs(a, b)
4387 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4388
4389
4390def UGE(a, b):
4391 """Create the Z3 expression (unsigned) `other >= self`.
4392
4393 Use the operator >= for signed greater than or equal to.
4394
4395 >>> x, y = BitVecs('x y', 32)
4396 >>> UGE(x, y)
4397 UGE(x, y)
4398 >>> (x >= y).sexpr()
4399 '(bvsge x y)'
4400 >>> UGE(x, y).sexpr()
4401 '(bvuge x y)'
4402 """
4403 _check_bv_args(a, b)
4404 a, b = _coerce_exprs(a, b)
4405 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4406
4407
4408def UGT(a, b):
4409 """Create the Z3 expression (unsigned) `other > self`.
4410
4411 Use the operator > for signed greater than.
4412
4413 >>> x, y = BitVecs('x y', 32)
4414 >>> UGT(x, y)
4415 UGT(x, y)
4416 >>> (x > y).sexpr()
4417 '(bvsgt x y)'
4418 >>> UGT(x, y).sexpr()
4419 '(bvugt x y)'
4420 """
4421 _check_bv_args(a, b)
4422 a, b = _coerce_exprs(a, b)
4423 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4424
4425
4426def UDiv(a, b):
4427 """Create the Z3 expression (unsigned) division `self / other`.
4428
4429 Use the operator / for signed division.
4430
4431 >>> x = BitVec('x', 32)
4432 >>> y = BitVec('y', 32)
4433 >>> UDiv(x, y)
4434 UDiv(x, y)
4435 >>> UDiv(x, y).sort()
4436 BitVec(32)
4437 >>> (x / y).sexpr()
4438 '(bvsdiv x y)'
4439 >>> UDiv(x, y).sexpr()
4440 '(bvudiv x y)'
4441 """
4442 _check_bv_args(a, b)
4443 a, b = _coerce_exprs(a, b)
4444 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4445
4446
4447def URem(a, b):
4448 """Create the Z3 expression (unsigned) remainder `self % other`.
4449
4450 Use the operator % for signed modulus, and SRem() for signed remainder.
4451
4452 >>> x = BitVec('x', 32)
4453 >>> y = BitVec('y', 32)
4454 >>> URem(x, y)
4455 URem(x, y)
4456 >>> URem(x, y).sort()
4457 BitVec(32)
4458 >>> (x % y).sexpr()
4459 '(bvsmod x y)'
4460 >>> URem(x, y).sexpr()
4461 '(bvurem x y)'
4462 """
4463 _check_bv_args(a, b)
4464 a, b = _coerce_exprs(a, b)
4465 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4466
4467
4468def SRem(a, b):
4469 """Create the Z3 expression signed remainder.
4470
4471 Use the operator % for signed modulus, and URem() for unsigned remainder.
4472
4473 >>> x = BitVec('x', 32)
4474 >>> y = BitVec('y', 32)
4475 >>> SRem(x, y)
4476 SRem(x, y)
4477 >>> SRem(x, y).sort()
4478 BitVec(32)
4479 >>> (x % y).sexpr()
4480 '(bvsmod x y)'
4481 >>> SRem(x, y).sexpr()
4482 '(bvsrem x y)'
4483 """
4484 _check_bv_args(a, b)
4485 a, b = _coerce_exprs(a, b)
4486 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4487
4488
4489def LShR(a, b):
4490 """Create the Z3 expression logical right shift.
4491
4492 Use the operator >> for the arithmetical right shift.
4493
4494 >>> x, y = BitVecs('x y', 32)
4495 >>> LShR(x, y)
4496 LShR(x, y)
4497 >>> (x >> y).sexpr()
4498 '(bvashr x y)'
4499 >>> LShR(x, y).sexpr()
4500 '(bvlshr x y)'
4501 >>> BitVecVal(4, 3)
4502 4
4503 >>> BitVecVal(4, 3).as_signed_long()
4504 -4
4505 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4506 -2
4507 >>> simplify(BitVecVal(4, 3) >> 1)
4508 6
4509 >>> simplify(LShR(BitVecVal(4, 3), 1))
4510 2
4511 >>> simplify(BitVecVal(2, 3) >> 1)
4512 1
4513 >>> simplify(LShR(BitVecVal(2, 3), 1))
4514 1
4515 """
4516 _check_bv_args(a, b)
4517 a, b = _coerce_exprs(a, b)
4518 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4519
4520
4521def RotateLeft(a, b):
4522 """Return an expression representing `a` rotated to the left `b` times.
4523
4524 >>> a, b = BitVecs('a b', 16)
4525 >>> RotateLeft(a, b)
4526 RotateLeft(a, b)
4527 >>> simplify(RotateLeft(a, 0))
4528 a
4529 >>> simplify(RotateLeft(a, 16))
4530 a
4531 """
4532 _check_bv_args(a, b)
4533 a, b = _coerce_exprs(a, b)
4534 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4535
4536
4537def RotateRight(a, b):
4538 """Return an expression representing `a` rotated to the right `b` times.
4539
4540 >>> a, b = BitVecs('a b', 16)
4541 >>> RotateRight(a, b)
4542 RotateRight(a, b)
4543 >>> simplify(RotateRight(a, 0))
4544 a
4545 >>> simplify(RotateRight(a, 16))
4546 a
4547 """
4548 _check_bv_args(a, b)
4549 a, b = _coerce_exprs(a, b)
4550 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4551
4552
4553def SignExt(n, a):
4554 """Return a bit-vector expression with `n` extra sign-bits.
4555
4556 >>> x = BitVec('x', 16)
4557 >>> n = SignExt(8, x)
4558 >>> n.size()
4559 24
4560 >>> n
4561 SignExt(8, x)
4562 >>> n.sort()
4563 BitVec(24)
4564 >>> v0 = BitVecVal(2, 2)
4565 >>> v0
4566 2
4567 >>> v0.size()
4568 2
4569 >>> v = simplify(SignExt(6, v0))
4570 >>> v
4571 254
4572 >>> v.size()
4573 8
4574 >>> print("%.x" % v.as_long())
4575 fe
4576 """
4577 if z3_debug():
4578 _z3_assert(_is_int(n), "First argument must be an integer")
4579 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4580 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4581
4582
4583def ZeroExt(n, a):
4584 """Return a bit-vector expression with `n` extra zero-bits.
4585
4586 >>> x = BitVec('x', 16)
4587 >>> n = ZeroExt(8, x)
4588 >>> n.size()
4589 24
4590 >>> n
4591 ZeroExt(8, x)
4592 >>> n.sort()
4593 BitVec(24)
4594 >>> v0 = BitVecVal(2, 2)
4595 >>> v0
4596 2
4597 >>> v0.size()
4598 2
4599 >>> v = simplify(ZeroExt(6, v0))
4600 >>> v
4601 2
4602 >>> v.size()
4603 8
4604 """
4605 if z3_debug():
4606 _z3_assert(_is_int(n), "First argument must be an integer")
4607 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4608 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4609
4610
4612 """Return an expression representing `n` copies of `a`.
4613
4614 >>> x = BitVec('x', 8)
4615 >>> n = RepeatBitVec(4, x)
4616 >>> n
4617 RepeatBitVec(4, x)
4618 >>> n.size()
4619 32
4620 >>> v0 = BitVecVal(10, 4)
4621 >>> print("%.x" % v0.as_long())
4622 a
4623 >>> v = simplify(RepeatBitVec(4, v0))
4624 >>> v.size()
4625 16
4626 >>> print("%.x" % v.as_long())
4627 aaaa
4628 """
4629 if z3_debug():
4630 _z3_assert(_is_int(n), "First argument must be an integer")
4631 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4632 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4633
4634
4636 """Return the reduction-and expression of `a`."""
4637 if z3_debug():
4638 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4639 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4640
4641
4642def BVRedOr(a):
4643 """Return the reduction-or expression of `a`."""
4644 if z3_debug():
4645 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4646 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4647
4648
4649def BVAddNoOverflow(a, b, signed):
4650 """A predicate the determines that bit-vector addition does not overflow"""
4651 _check_bv_args(a, b)
4652 a, b = _coerce_exprs(a, b)
4653 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4654
4655
4657 """A predicate the determines that signed bit-vector addition does not underflow"""
4658 _check_bv_args(a, b)
4659 a, b = _coerce_exprs(a, b)
4660 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4661
4662
4664 """A predicate the determines that bit-vector subtraction does not overflow"""
4665 _check_bv_args(a, b)
4666 a, b = _coerce_exprs(a, b)
4667 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4668
4669
4670def BVSubNoUnderflow(a, b, signed):
4671 """A predicate the determines that bit-vector subtraction does not underflow"""
4672 _check_bv_args(a, b)
4673 a, b = _coerce_exprs(a, b)
4674 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4675
4676
4678 """A predicate the determines that bit-vector signed division does not overflow"""
4679 _check_bv_args(a, b)
4680 a, b = _coerce_exprs(a, b)
4681 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4682
4683
4685 """A predicate the determines that bit-vector unary negation does not overflow"""
4686 if z3_debug():
4687 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4688 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4689
4690
4691def BVMulNoOverflow(a, b, signed):
4692 """A predicate the determines that bit-vector multiplication does not overflow"""
4693 _check_bv_args(a, b)
4694 a, b = _coerce_exprs(a, b)
4695 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4696
4697
4699 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4700 _check_bv_args(a, b)
4701 a, b = _coerce_exprs(a, b)
4702 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4703
4704
4705
4710
4712 """Array sorts."""
4713
4714 def domain(self):
4715 """Return the domain of the array sort `self`.
4716
4717 >>> A = ArraySort(IntSort(), BoolSort())
4718 >>> A.domain()
4719 Int
4720 """
4722
4723 def domain_n(self, i):
4724 """Return the domain of the array sort `self`.
4725 """
4727
4728 def range(self):
4729 """Return the range of the array sort `self`.
4730
4731 >>> A = ArraySort(IntSort(), BoolSort())
4732 >>> A.range()
4733 Bool
4734 """
4736
4737
4739 """Array expressions. """
4740
4741 def sort(self):
4742 """Return the array sort of the array expression `self`.
4743
4744 >>> a = Array('a', IntSort(), BoolSort())
4745 >>> a.sort()
4746 Array(Int, Bool)
4747 """
4749
4750 def domain(self):
4751 """Shorthand for `self.sort().domain()`.
4752
4753 >>> a = Array('a', IntSort(), BoolSort())
4754 >>> a.domain()
4755 Int
4756 """
4757 return self.sortsort().domain()
4758
4759 def domain_n(self, i):
4760 """Shorthand for self.sort().domain_n(i)`."""
4761 return self.sortsort().domain_n(i)
4762
4763 def range(self):
4764 """Shorthand for `self.sort().range()`.
4765
4766 >>> a = Array('a', IntSort(), BoolSort())
4767 >>> a.range()
4768 Bool
4769 """
4770 return self.sortsort().range()
4771
4772 def __getitem__(self, arg):
4773 """Return the Z3 expression `self[arg]`.
4774
4775 >>> a = Array('a', IntSort(), BoolSort())
4776 >>> i = Int('i')
4777 >>> a[i]
4778 a[i]
4779 >>> a[i].sexpr()
4780 '(select a i)'
4781 """
4782 return _array_select(self, arg)
4783
4784 def default(self):
4785 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
4786
4787
4788def _array_select(ar, arg):
4789 if isinstance(arg, tuple):
4790 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4791 _args, sz = _to_ast_array(args)
4792 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4793 arg = ar.sort().domain().cast(arg)
4794 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4795
4796
4798 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4799
4800
4801def is_array(a : Any) -> bool:
4802 """Return `True` if `a` is a Z3 array expression.
4803
4804 >>> a = Array('a', IntSort(), IntSort())
4805 >>> is_array(a)
4806 True
4807 >>> is_array(Store(a, 0, 1))
4808 True
4809 >>> is_array(a[0])
4810 False
4811 """
4812 return isinstance(a, ArrayRef)
4813
4814
4816 """Return `True` if `a` is a Z3 constant array.
4817
4818 >>> a = K(IntSort(), 10)
4819 >>> is_const_array(a)
4820 True
4821 >>> a = Array('a', IntSort(), IntSort())
4822 >>> is_const_array(a)
4823 False
4824 """
4825 return is_app_of(a, Z3_OP_CONST_ARRAY)
4826
4827
4828def is_K(a):
4829 """Return `True` if `a` is a Z3 constant array.
4830
4831 >>> a = K(IntSort(), 10)
4832 >>> is_K(a)
4833 True
4834 >>> a = Array('a', IntSort(), IntSort())
4835 >>> is_K(a)
4836 False
4837 """
4838 return is_app_of(a, Z3_OP_CONST_ARRAY)
4839
4840
4841def is_map(a):
4842 """Return `True` if `a` is a Z3 map array expression.
4843
4844 >>> f = Function('f', IntSort(), IntSort())
4845 >>> b = Array('b', IntSort(), IntSort())
4846 >>> a = Map(f, b)
4847 >>> a
4848 Map(f, b)
4849 >>> is_map(a)
4850 True
4851 >>> is_map(b)
4852 False
4853 """
4854 return is_app_of(a, Z3_OP_ARRAY_MAP)
4855
4856
4858 """Return `True` if `a` is a Z3 default array expression.
4859 >>> d = Default(K(IntSort(), 10))
4860 >>> is_default(d)
4861 True
4862 """
4863 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4864
4865
4867 """Return the function declaration associated with a Z3 map array expression.
4868
4869 >>> f = Function('f', IntSort(), IntSort())
4870 >>> b = Array('b', IntSort(), IntSort())
4871 >>> a = Map(f, b)
4872 >>> eq(f, get_map_func(a))
4873 True
4874 >>> get_map_func(a)
4875 f
4876 >>> get_map_func(a)(0)
4877 f(0)
4878 """
4879 if z3_debug():
4880 _z3_assert(is_map(a), "Z3 array map expression expected.")
4881 return FuncDeclRef(
4883 a.ctx_ref(),
4884 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4885 ),
4886 ctx=a.ctx,
4887 )
4888
4889
4890def ArraySort(*sig):
4891 """Return the Z3 array sort with the given domain and range sorts.
4892
4893 >>> A = ArraySort(IntSort(), BoolSort())
4894 >>> A
4895 Array(Int, Bool)
4896 >>> A.domain()
4897 Int
4898 >>> A.range()
4899 Bool
4900 >>> AA = ArraySort(IntSort(), A)
4901 >>> AA
4902 Array(Int, Array(Int, Bool))
4903 """
4904 sig = _get_args(sig)
4905 if z3_debug():
4906 _z3_assert(len(sig) > 1, "At least two arguments expected")
4907 arity = len(sig) - 1
4908 r = sig[arity]
4909 d = sig[0]
4910 if z3_debug():
4911 for s in sig:
4912 _z3_assert(is_sort(s), "Z3 sort expected")
4913 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4914 ctx = d.ctx
4915 if len(sig) == 2:
4916 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4917 dom = (Sort * arity)()
4918 for i in range(arity):
4919 dom[i] = sig[i].ast
4920 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4921
4922
4923def Array(name, *sorts):
4924 """Return an array constant named `name` with the given domain and range sorts.
4925
4926 >>> a = Array('a', IntSort(), IntSort())
4927 >>> a.sort()
4928 Array(Int, Int)
4929 >>> a[0]
4930 a[0]
4931 """
4932 s = ArraySort(sorts)
4933 ctx = s.ctx
4934 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4935
4936
4937def Update(a, *args):
4938 """Return a Z3 store array expression.
4939
4940 >>> a = Array('a', IntSort(), IntSort())
4941 >>> i, v = Ints('i v')
4942 >>> s = Update(a, i, v)
4943 >>> s.sort()
4944 Array(Int, Int)
4945 >>> prove(s[i] == v)
4946 proved
4947 >>> j = Int('j')
4948 >>> prove(Implies(i != j, s[j] == a[j]))
4949 proved
4950 """
4951 if z3_debug():
4952 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4953 args = _get_args(args)
4954 ctx = a.ctx
4955 if len(args) <= 1:
4956 raise Z3Exception("array update requires index and value arguments")
4957 if len(args) == 2:
4958 i = args[0]
4959 v = args[1]
4960 i = a.sort().domain().cast(i)
4961 v = a.sort().range().cast(v)
4962 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4963 v = a.sort().range().cast(args[-1])
4964 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4965 _args, sz = _to_ast_array(idxs)
4966 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4967
4968
4969def Default(a):
4970 """ Return a default value for array expression.
4971 >>> b = K(IntSort(), 1)
4972 >>> prove(Default(b) == 1)
4973 proved
4974 """
4975 if z3_debug():
4976 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4977 return a.default()
4978
4979
4980def Store(a, *args):
4981 """Return a Z3 store array expression.
4982
4983 >>> a = Array('a', IntSort(), IntSort())
4984 >>> i, v = Ints('i v')
4985 >>> s = Store(a, i, v)
4986 >>> s.sort()
4987 Array(Int, Int)
4988 >>> prove(s[i] == v)
4989 proved
4990 >>> j = Int('j')
4991 >>> prove(Implies(i != j, s[j] == a[j]))
4992 proved
4993 """
4994 return Update(a, args)
4995
4996
4997def Select(a, *args):
4998 """Return a Z3 select array expression.
4999
5000 >>> a = Array('a', IntSort(), IntSort())
5001 >>> i = Int('i')
5002 >>> Select(a, i)
5003 a[i]
5004 >>> eq(Select(a, i), a[i])
5005 True
5006 """
5007 args = _get_args(args)
5008 if z3_debug():
5009 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
5010 return a[args]
5011
5012
5013def Map(f, *args):
5014 """Return a Z3 map array expression.
5015
5016 >>> f = Function('f', IntSort(), IntSort(), IntSort())
5017 >>> a1 = Array('a1', IntSort(), IntSort())
5018 >>> a2 = Array('a2', IntSort(), IntSort())
5019 >>> b = Map(f, a1, a2)
5020 >>> b
5021 Map(f, a1, a2)
5022 >>> prove(b[0] == f(a1[0], a2[0]))
5023 proved
5024 """
5025 args = _get_args(args)
5026 if z3_debug():
5027 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
5028 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
5029 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
5030 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
5031 _args, sz = _to_ast_array(args)
5032 ctx = f.ctx
5033 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
5034
5035
5036def K(dom, v):
5037 """Return a Z3 constant array expression.
5038
5039 >>> a = K(IntSort(), 10)
5040 >>> a
5041 K(Int, 10)
5042 >>> a.sort()
5043 Array(Int, Int)
5044 >>> i = Int('i')
5045 >>> a[i]
5046 K(Int, 10)[i]
5047 >>> simplify(a[i])
5048 10
5049 """
5050 if z3_debug():
5051 _z3_assert(is_sort(dom), "Z3 sort expected")
5052 ctx = dom.ctx
5053 if not is_expr(v):
5054 v = _py2expr(v, ctx)
5055 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
5056
5057
5058def Ext(a, b):
5059 """Return extensionality index for one-dimensional arrays.
5060 >> a, b = Consts('a b', SetSort(IntSort()))
5061 >> Ext(a, b)
5062 Ext(a, b)
5063 """
5064 ctx = a.ctx
5065 if z3_debug():
5066 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
5067 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5068
5070 """Return `True` if `a` is a Z3 array select application.
5071
5072 >>> a = Array('a', IntSort(), IntSort())
5073 >>> is_select(a)
5074 False
5075 >>> i = Int('i')
5076 >>> is_select(a[i])
5077 True
5078 """
5079 return is_app_of(a, Z3_OP_SELECT)
5080
5081
5083 """Return `True` if `a` is a Z3 array store application.
5084
5085 >>> a = Array('a', IntSort(), IntSort())
5086 >>> is_store(a)
5087 False
5088 >>> is_store(Store(a, 0, 1))
5089 True
5090 """
5091 return is_app_of(a, Z3_OP_STORE)
5092
5093
5098
5099
5100def SetSort(s):
5101 """ Create a set sort over element sort s"""
5102 return ArraySort(s, BoolSort())
5103
5104
5106 """Create the empty set
5107 >>> EmptySet(IntSort())
5108 K(Int, False)
5109 """
5110 ctx = s.ctx
5111 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5112
5113
5114def FullSet(s):
5115 """Create the full set
5116 >>> FullSet(IntSort())
5117 K(Int, True)
5118 """
5119 ctx = s.ctx
5120 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5121
5122
5123def SetUnion(*args):
5124 """ Take the union of sets
5125 >>> a = Const('a', SetSort(IntSort()))
5126 >>> b = Const('b', SetSort(IntSort()))
5127 >>> SetUnion(a, b)
5128 union(a, b)
5129 """
5130 args = _get_args(args)
5131 ctx = _ctx_from_ast_arg_list(args)
5132 _args, sz = _to_ast_array(args)
5133 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5134
5135
5136def SetIntersect(*args):
5137 """ Take the union of sets
5138 >>> a = Const('a', SetSort(IntSort()))
5139 >>> b = Const('b', SetSort(IntSort()))
5140 >>> SetIntersect(a, b)
5141 intersection(a, b)
5142 """
5143 args = _get_args(args)
5144 ctx = _ctx_from_ast_arg_list(args)
5145 _args, sz = _to_ast_array(args)
5146 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5147
5148
5149def SetAdd(s, e):
5150 """ Add element e to set s
5151 >>> a = Const('a', SetSort(IntSort()))
5152 >>> SetAdd(a, 1)
5153 Store(a, 1, True)
5154 """
5155 ctx = _ctx_from_ast_arg_list([s, e])
5156 e = _py2expr(e, ctx)
5157 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5158
5159
5160def SetDel(s, e):
5161 """ Remove element e to set s
5162 >>> a = Const('a', SetSort(IntSort()))
5163 >>> SetDel(a, 1)
5164 Store(a, 1, False)
5165 """
5166 ctx = _ctx_from_ast_arg_list([s, e])
5167 e = _py2expr(e, ctx)
5168 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5169
5170
5172 """ The complement of set s
5173 >>> a = Const('a', SetSort(IntSort()))
5174 >>> SetComplement(a)
5175 complement(a)
5176 """
5177 ctx = s.ctx
5178 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5179
5180
5182 """ The set difference of a and b
5183 >>> a = Const('a', SetSort(IntSort()))
5184 >>> b = Const('b', SetSort(IntSort()))
5185 >>> SetDifference(a, b)
5186 setminus(a, b)
5187 """
5188 ctx = _ctx_from_ast_arg_list([a, b])
5189 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5190
5191
5192def IsMember(e, s):
5193 """ Check if e is a member of set s
5194 >>> a = Const('a', SetSort(IntSort()))
5195 >>> IsMember(1, a)
5196 a[1]
5197 """
5198 ctx = _ctx_from_ast_arg_list([s, e])
5199 e = _py2expr(e, ctx)
5200 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5201
5202
5203def IsSubset(a, b):
5204 """ Check if a is a subset of b
5205 >>> a = Const('a', SetSort(IntSort()))
5206 >>> b = Const('b', SetSort(IntSort()))
5207 >>> IsSubset(a, b)
5208 subset(a, b)
5209 """
5210 ctx = _ctx_from_ast_arg_list([a, b])
5211 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5212
5213
5214
5219
5221 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5222 if not isinstance(acc, tuple):
5223 return False
5224 if len(acc) != 2:
5225 return False
5226 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5227
5228
5230 """Helper class for declaring Z3 datatypes.
5231
5232 >>> List = Datatype('List')
5233 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5234 >>> List.declare('nil')
5235 >>> List = List.create()
5236 >>> # List is now a Z3 declaration
5237 >>> List.nil
5238 nil
5239 >>> List.cons(10, List.nil)
5240 cons(10, nil)
5241 >>> List.cons(10, List.nil).sort()
5242 List
5243 >>> cons = List.cons
5244 >>> nil = List.nil
5245 >>> car = List.car
5246 >>> cdr = List.cdr
5247 >>> n = cons(1, cons(0, nil))
5248 >>> n
5249 cons(1, cons(0, nil))
5250 >>> simplify(cdr(n))
5251 cons(0, nil)
5252 >>> simplify(car(n))
5253 1
5254 """
5255
5256 def __init__(self, name, ctx=None):
5257 self.ctx = _get_ctx(ctx)
5258 self.name = name
5260
5261 def __deepcopy__(self, memo={}):
5262 r = Datatype(self.name, self.ctx)
5263 r.constructors = copy.deepcopy(self.constructors)
5264 return r
5265
5266 def declare_core(self, name, rec_name, *args):
5267 if z3_debug():
5268 _z3_assert(isinstance(name, str), "String expected")
5269 _z3_assert(isinstance(rec_name, str), "String expected")
5270 _z3_assert(
5271 all([_valid_accessor(a) for a in args]),
5272 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5273 )
5274 self.constructors.append((name, rec_name, args))
5275
5276 def declare(self, name, *args):
5277 """Declare constructor named `name` with the given accessors `args`.
5278 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5279 or a reference to the datatypes being declared.
5280
5281 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5282 declares the constructor named `cons` that builds a new List using an integer and a List.
5283 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5284 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5285 we use the method create() to create the actual datatype in Z3.
5286
5287 >>> List = Datatype('List')
5288 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5289 >>> List.declare('nil')
5290 >>> List = List.create()
5291 """
5292 if z3_debug():
5293 _z3_assert(isinstance(name, str), "String expected")
5294 _z3_assert(name != "", "Constructor name cannot be empty")
5295 return self.declare_core(name, "is-" + name, *args)
5296
5297 def __repr__(self):
5298 return "Datatype(%s, %s)" % (self.name, self.constructors)
5299
5300 def create(self):
5301 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5302
5303 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5304
5305 >>> List = Datatype('List')
5306 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5307 >>> List.declare('nil')
5308 >>> List = List.create()
5309 >>> List.nil
5310 nil
5311 >>> List.cons(10, List.nil)
5312 cons(10, nil)
5313 """
5314 return CreateDatatypes([self])[0]
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 is not None:
5326 Z3_del_constructor(self.ctx.ref(), self.c)
5327
5328
5330 """Auxiliary object used to create Z3 datatypes."""
5331
5332 def __init__(self, c, ctx):
5333 self.c = c
5334 self.ctx = ctx
5335
5336 def __del__(self):
5337 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5338 Z3_del_constructor_list(self.ctx.ref(), self.c)
5339
5340
5342 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5343
5344 In the following example we define a Tree-List using two mutually recursive datatypes.
5345
5346 >>> TreeList = Datatype('TreeList')
5347 >>> Tree = Datatype('Tree')
5348 >>> # Tree has two constructors: leaf and node
5349 >>> Tree.declare('leaf', ('val', IntSort()))
5350 >>> # a node contains a list of trees
5351 >>> Tree.declare('node', ('children', TreeList))
5352 >>> TreeList.declare('nil')
5353 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5354 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5355 >>> Tree.val(Tree.leaf(10))
5356 val(leaf(10))
5357 >>> simplify(Tree.val(Tree.leaf(10)))
5358 10
5359 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5360 >>> n1
5361 node(cons(leaf(10), cons(leaf(20), nil)))
5362 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5363 >>> simplify(n2 == n1)
5364 False
5365 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5366 True
5367 """
5368 ds = _get_args(ds)
5369 if z3_debug():
5370 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5371 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5372 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5373 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5374 ctx = ds[0].ctx
5375 num = len(ds)
5376 names = (Symbol * num)()
5377 out = (Sort * num)()
5378 clists = (ConstructorList * num)()
5379 to_delete = []
5380 for i in range(num):
5381 d = ds[i]
5382 names[i] = to_symbol(d.name, ctx)
5383 num_cs = len(d.constructors)
5384 cs = (Constructor * num_cs)()
5385 for j in range(num_cs):
5386 c = d.constructors[j]
5387 cname = to_symbol(c[0], ctx)
5388 rname = to_symbol(c[1], ctx)
5389 fs = c[2]
5390 num_fs = len(fs)
5391 fnames = (Symbol * num_fs)()
5392 sorts = (Sort * num_fs)()
5393 refs = (ctypes.c_uint * num_fs)()
5394 for k in range(num_fs):
5395 fname = fs[k][0]
5396 ftype = fs[k][1]
5397 fnames[k] = to_symbol(fname, ctx)
5398 if isinstance(ftype, Datatype):
5399 if z3_debug():
5400 _z3_assert(
5401 ds.count(ftype) == 1,
5402 "One and only one occurrence of each datatype is expected",
5403 )
5404 sorts[k] = None
5405 refs[k] = ds.index(ftype)
5406 else:
5407 if z3_debug():
5408 _z3_assert(is_sort(ftype), "Z3 sort expected")
5409 sorts[k] = ftype.ast
5410 refs[k] = 0
5411 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5412 to_delete.append(ScopedConstructor(cs[j], ctx))
5413 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5414 to_delete.append(ScopedConstructorList(clists[i], ctx))
5415 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5416 result = []
5417 # Create a field for every constructor, recognizer and accessor
5418 for i in range(num):
5419 dref = DatatypeSortRef(out[i], ctx)
5420 num_cs = dref.num_constructors()
5421 for j in range(num_cs):
5422 cref = dref.constructor(j)
5423 cref_name = cref.name()
5424 cref_arity = cref.arity()
5425 if cref.arity() == 0:
5426 cref = cref()
5427 setattr(dref, cref_name, cref)
5428 rref = dref.recognizer(j)
5429 setattr(dref, "is_" + cref_name, rref)
5430 for k in range(cref_arity):
5431 aref = dref.accessor(j, k)
5432 setattr(dref, aref.name(), aref)
5433 result.append(dref)
5434 return tuple(result)
5435
5436
5438 """Datatype sorts."""
5439
5441 """Return the number of constructors in the given Z3 datatype.
5442
5443 >>> List = Datatype('List')
5444 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5445 >>> List.declare('nil')
5446 >>> List = List.create()
5447 >>> # List is now a Z3 declaration
5448 >>> List.num_constructors()
5449 2
5450 """
5452
5453 def constructor(self, idx):
5454 """Return a constructor of the datatype `self`.
5455
5456 >>> List = Datatype('List')
5457 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5458 >>> List.declare('nil')
5459 >>> List = List.create()
5460 >>> # List is now a Z3 declaration
5461 >>> List.num_constructors()
5462 2
5463 >>> List.constructor(0)
5464 cons
5465 >>> List.constructor(1)
5466 nil
5467 """
5468 if z3_debug():
5469 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5471
5472 def recognizer(self, idx):
5473 """In Z3, each constructor has an associated recognizer predicate.
5474
5475 If the constructor is named `name`, then the recognizer `is_name`.
5476
5477 >>> List = Datatype('List')
5478 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5479 >>> List.declare('nil')
5480 >>> List = List.create()
5481 >>> # List is now a Z3 declaration
5482 >>> List.num_constructors()
5483 2
5484 >>> List.recognizer(0)
5485 is(cons)
5486 >>> List.recognizer(1)
5487 is(nil)
5488 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5489 False
5490 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5491 True
5492 >>> l = Const('l', List)
5493 >>> simplify(List.is_cons(l))
5494 is(cons, l)
5495 """
5496 if z3_debug():
5497 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5499
5500 def accessor(self, i, j):
5501 """In Z3, each constructor has 0 or more accessor.
5502 The number of accessors is equal to the arity of the constructor.
5503
5504 >>> List = Datatype('List')
5505 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5506 >>> List.declare('nil')
5507 >>> List = List.create()
5508 >>> List.num_constructors()
5509 2
5510 >>> List.constructor(0)
5511 cons
5512 >>> num_accs = List.constructor(0).arity()
5513 >>> num_accs
5514 2
5515 >>> List.accessor(0, 0)
5516 car
5517 >>> List.accessor(0, 1)
5518 cdr
5519 >>> List.constructor(1)
5520 nil
5521 >>> num_accs = List.constructor(1).arity()
5522 >>> num_accs
5523 0
5524 """
5525 if z3_debug():
5526 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5527 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5528 return FuncDeclRef(
5530 ctx=self.ctxctxctx,
5531 )
5532
5533
5535 """Datatype expressions."""
5536
5537 def sort(self):
5538 """Return the datatype sort of the datatype expression `self`."""
5540
5541 def update_field(self, field_accessor, new_value):
5542 """Return a new datatype expression with the specified field updated.
5543
5544 Args:
5545 field_accessor: The accessor function declaration for the field to update
5546 new_value: The new value for the field
5547
5548 Returns:
5549 A new datatype expression with the field updated, other fields unchanged
5550
5551 Example:
5552 >>> Person = Datatype('Person')
5553 >>> Person.declare('person', ('name', StringSort()), ('age', IntSort()))
5554 >>> Person = Person.create()
5555 >>> person_age = Person.accessor(0, 1) # age accessor
5556 >>> p = Const('p', Person)
5557 >>> p2 = p.update_field(person_age, IntVal(30))
5558 """
5559 if z3_debug():
5560 _z3_assert(is_func_decl(field_accessor), "Z3 function declaration expected")
5561 _z3_assert(is_expr(new_value), "Z3 expression expected")
5562 return _to_expr_ref(
5563 Z3_datatype_update_field(self.ctx_ref(), field_accessor.ast, self.as_astas_ast(), new_value.as_ast()),
5564 self.ctxctxctx
5565 )
5566
5567def DatatypeSort(name, params=None, ctx=None):
5568 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype.
5569
5570 Args:
5571 name: name of the datatype sort
5572 params: optional list/tuple of sort parameters for parametric datatypes
5573 ctx: Z3 context (optional)
5574
5575 Example:
5576 >>> # Non-parametric datatype
5577 >>> TreeRef = DatatypeSort('Tree')
5578 >>> # Parametric datatype with one parameter
5579 >>> ListIntRef = DatatypeSort('List', [IntSort()])
5580 >>> # Parametric datatype with multiple parameters
5581 >>> PairRef = DatatypeSort('Pair', [IntSort(), BoolSort()])
5582 """
5583 ctx = _get_ctx(ctx)
5584 if params is None or len(params) == 0:
5585 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), 0, (Sort * 0)()), ctx)
5586 else:
5587 _params = (Sort * len(params))()
5588 for i in range(len(params)):
5589 _params[i] = params[i].ast
5590 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), len(params), _params), ctx)
5591
5592def TupleSort(name, sorts, ctx=None):
5593 """Create a named tuple sort base on a set of underlying sorts
5594 Example:
5595 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5596 """
5597 tuple = Datatype(name, ctx)
5598 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5599 tuple.declare(name, *projects)
5600 tuple = tuple.create()
5601 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5602
5603
5604def DisjointSum(name, sorts, ctx=None):
5605 """Create a named tagged union sort base on a set of underlying sorts
5606 Example:
5607 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5608 """
5609 sum = Datatype(name, ctx)
5610 for i in range(len(sorts)):
5611 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5612 sum = sum.create()
5613 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5614
5615
5616def EnumSort(name, values, ctx=None):
5617 """Return a new enumeration sort named `name` containing the given values.
5618
5619 The result is a pair (sort, list of constants).
5620 Example:
5621 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5622 """
5623 if z3_debug():
5624 _z3_assert(isinstance(name, str), "Name must be a string")
5625 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5626 _z3_assert(len(values) > 0, "At least one value expected")
5627 ctx = _get_ctx(ctx)
5628 num = len(values)
5629 _val_names = (Symbol * num)()
5630 for i in range(num):
5631 _val_names[i] = to_symbol(values[i], ctx)
5632 _values = (FuncDecl * num)()
5633 _testers = (FuncDecl * num)()
5634 name = to_symbol(name, ctx)
5635 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5636 V = []
5637 for i in range(num):
5638 V.append(FuncDeclRef(_values[i], ctx))
5639 V = [a() for a in V]
5640 return S, V
5641
5642
5647
5648
5650 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5651
5652 Consider using the function `args2params` to create instances of this object.
5653 """
5654
5655 def __init__(self, ctx=None, params=None):
5656 self.ctx = _get_ctx(ctx)
5657 if params is None:
5658 self.params = Z3_mk_params(self.ctx.ref())
5659 else:
5660 self.params = params
5661 Z3_params_inc_ref(self.ctx.ref(), self.params)
5662
5663 def __deepcopy__(self, memo={}):
5664 return ParamsRef(self.ctx, self.params)
5665
5666 def __del__(self):
5667 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5668 Z3_params_dec_ref(self.ctx.ref(), self.params)
5669
5670 def set(self, name, val):
5671 """Set parameter name with value val."""
5672 if z3_debug():
5673 _z3_assert(isinstance(name, str), "parameter name must be a string")
5674 name_sym = to_symbol(name, self.ctx)
5675 if isinstance(val, bool):
5676 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5677 elif _is_int(val):
5678 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5679 elif isinstance(val, float):
5680 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5681 elif isinstance(val, str):
5682 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5683 else:
5684 if z3_debug():
5685 _z3_assert(False, "invalid parameter value")
5686
5687 def __repr__(self):
5688 return Z3_params_to_string(self.ctx.ref(), self.params)
5689
5690 def validate(self, ds):
5691 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5692 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5693
5694
5695def args2params(arguments, keywords, ctx=None):
5696 """Convert python arguments into a Z3_params object.
5697 A ':' is added to the keywords, and '_' is replaced with '-'
5698
5699 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5700 (params model true relevancy 2 elim_and true)
5701 """
5702 if z3_debug():
5703 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5704 prev = None
5705 r = ParamsRef(ctx)
5706 for a in arguments:
5707 if prev is None:
5708 prev = a
5709 else:
5710 r.set(prev, a)
5711 prev = None
5712 for k in keywords:
5713 v = keywords[k]
5714 r.set(k, v)
5715 return r
5716
5717
5719 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5720 """
5721
5722 def __init__(self, descr, ctx=None):
5723 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5724 self.ctx = _get_ctx(ctx)
5725 self.descr = descr
5726 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5727
5728 def __deepcopy__(self, memo={}):
5729 return ParamsDescrsRef(self.descr, self.ctx)
5730
5731 def __del__(self):
5732 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5733 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5734
5735 def size(self):
5736 """Return the size of in the parameter description `self`.
5737 """
5738 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5739
5740 def __len__(self):
5741 """Return the size of in the parameter description `self`.
5742 """
5743 return self.size()
5744
5745 def get_name(self, i):
5746 """Return the i-th parameter name in the parameter description `self`.
5747 """
5748 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5749
5750 def get_kind(self, n):
5751 """Return the kind of the parameter named `n`.
5752 """
5753 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5754
5755 def get_documentation(self, n):
5756 """Return the documentation string of the parameter named `n`.
5757 """
5758 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5759
5760 def __getitem__(self, arg):
5761 if _is_int(arg):
5762 return self.get_name(arg)
5763 else:
5764 return self.get_kind(arg)
5765
5766 def __repr__(self):
5767 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5768
5769
5774
5775
5777 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5778
5779 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5780 A goal has a solution if one of its subgoals has a solution.
5781 A goal is unsatisfiable if all subgoals are unsatisfiable.
5782 """
5783
5784 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5785 if z3_debug():
5786 _z3_assert(goal is None or ctx is not None,
5787 "If goal is different from None, then ctx must be also different from None")
5788 self.ctx = _get_ctx(ctx)
5789 self.goal = goal
5790 if self.goal is None:
5791 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5792 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5793
5794 def __del__(self):
5795 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5796 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5797
5798 def depth(self):
5799 """Return the depth of the goal `self`.
5800 The depth corresponds to the number of tactics applied to `self`.
5801
5802 >>> x, y = Ints('x y')
5803 >>> g = Goal()
5804 >>> g.add(x == 0, y >= x + 1)
5805 >>> g.depth()
5806 0
5807 >>> r = Then('simplify', 'solve-eqs')(g)
5808 >>> # r has 1 subgoal
5809 >>> len(r)
5810 1
5811 >>> r[0].depth()
5812 2
5813 """
5814 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5815
5816 def inconsistent(self):
5817 """Return `True` if `self` contains the `False` constraints.
5818
5819 >>> x, y = Ints('x y')
5820 >>> g = Goal()
5821 >>> g.inconsistent()
5822 False
5823 >>> g.add(x == 0, x == 1)
5824 >>> g
5825 [x == 0, x == 1]
5826 >>> g.inconsistent()
5827 False
5828 >>> g2 = Tactic('propagate-values')(g)[0]
5829 >>> g2.inconsistent()
5830 True
5831 """
5832 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5833
5834 def prec(self):
5835 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5836
5837 >>> g = Goal()
5838 >>> g.prec() == Z3_GOAL_PRECISE
5839 True
5840 >>> x, y = Ints('x y')
5841 >>> g.add(x == y + 1)
5842 >>> g.prec() == Z3_GOAL_PRECISE
5843 True
5844 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5845 >>> g2 = t(g)[0]
5846 >>> g2
5847 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5848 >>> g2.prec() == Z3_GOAL_PRECISE
5849 False
5850 >>> g2.prec() == Z3_GOAL_UNDER
5851 True
5852 """
5853 return Z3_goal_precision(self.ctx.ref(), self.goal)
5854
5855 def precision(self):
5856 """Alias for `prec()`.
5857
5858 >>> g = Goal()
5859 >>> g.precision() == Z3_GOAL_PRECISE
5860 True
5861 """
5862 return self.prec()
5863
5864 def size(self):
5865 """Return the number of constraints in the goal `self`.
5866
5867 >>> g = Goal()
5868 >>> g.size()
5869 0
5870 >>> x, y = Ints('x y')
5871 >>> g.add(x == 0, y > x)
5872 >>> g.size()
5873 2
5874 """
5875 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5876
5877 def __len__(self):
5878 """Return the number of constraints in the goal `self`.
5879
5880 >>> g = Goal()
5881 >>> len(g)
5882 0
5883 >>> x, y = Ints('x y')
5884 >>> g.add(x == 0, y > x)
5885 >>> len(g)
5886 2
5887 """
5888 return self.size()
5889
5890 def get(self, i):
5891 """Return a constraint in the goal `self`.
5892
5893 >>> g = Goal()
5894 >>> x, y = Ints('x y')
5895 >>> g.add(x == 0, y > x)
5896 >>> g.get(0)
5897 x == 0
5898 >>> g.get(1)
5899 y > x
5900 """
5901 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5902
5903 def __getitem__(self, arg):
5904 """Return a constraint in the goal `self`.
5905
5906 >>> g = Goal()
5907 >>> x, y = Ints('x y')
5908 >>> g.add(x == 0, y > x)
5909 >>> g[0]
5910 x == 0
5911 >>> g[1]
5912 y > x
5913 """
5914 if arg < 0:
5915 arg += len(self)
5916 if arg < 0 or arg >= len(self):
5917 raise IndexError
5918 return self.get(arg)
5919
5920 def assert_exprs(self, *args):
5921 """Assert constraints into the goal.
5922
5923 >>> x = Int('x')
5924 >>> g = Goal()
5925 >>> g.assert_exprs(x > 0, x < 2)
5926 >>> g
5927 [x > 0, x < 2]
5928 """
5929 args = _get_args(args)
5930 s = BoolSort(self.ctx)
5931 for arg in args:
5932 arg = s.cast(arg)
5933 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5934
5935 def append(self, *args):
5936 """Add constraints.
5937
5938 >>> x = Int('x')
5939 >>> g = Goal()
5940 >>> g.append(x > 0, x < 2)
5941 >>> g
5942 [x > 0, x < 2]
5943 """
5944 self.assert_exprs(*args)
5945
5946 def insert(self, *args):
5947 """Add constraints.
5948
5949 >>> x = Int('x')
5950 >>> g = Goal()
5951 >>> g.insert(x > 0, x < 2)
5952 >>> g
5953 [x > 0, x < 2]
5954 """
5955 self.assert_exprs(*args)
5956
5957 def add(self, *args):
5958 """Add constraints.
5959
5960 >>> x = Int('x')
5961 >>> g = Goal()
5962 >>> g.add(x > 0, x < 2)
5963 >>> g
5964 [x > 0, x < 2]
5965 """
5966 self.assert_exprs(*args)
5967
5968 def convert_model(self, model):
5969 """Retrieve model from a satisfiable goal
5970 >>> a, b = Ints('a b')
5971 >>> g = Goal()
5972 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5973 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5974 >>> r = t(g)
5975 >>> r[0]
5976 [Or(b == 0, b == 1), Not(0 <= b)]
5977 >>> r[1]
5978 [Or(b == 0, b == 1), Not(1 <= b)]
5979 >>> # Remark: the subgoal r[0] is unsatisfiable
5980 >>> # Creating a solver for solving the second subgoal
5981 >>> s = Solver()
5982 >>> s.add(r[1])
5983 >>> s.check()
5984 sat
5985 >>> s.model()
5986 [b = 0]
5987 >>> # Model s.model() does not assign a value to `a`
5988 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5989 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5990 >>> r[1].convert_model(s.model())
5991 [b = 0, a = 1]
5992 """
5993 if z3_debug():
5994 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5995 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5996
5997 def __repr__(self):
5998 return obj_to_string(self)
5999
6000 def sexpr(self):
6001 """Return a textual representation of the s-expression representing the goal."""
6002 return Z3_goal_to_string(self.ctx.ref(), self.goal)
6003
6004 def dimacs(self, include_names=True):
6005 """Return a textual representation of the goal in DIMACS format."""
6006 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
6007
6008 def translate(self, target):
6009 """Copy goal `self` to context `target`.
6010
6011 >>> x = Int('x')
6012 >>> g = Goal()
6013 >>> g.add(x > 10)
6014 >>> g
6015 [x > 10]
6016 >>> c2 = Context()
6017 >>> g2 = g.translate(c2)
6018 >>> g2
6019 [x > 10]
6020 >>> g.ctx == main_ctx()
6021 True
6022 >>> g2.ctx == c2
6023 True
6024 >>> g2.ctx == main_ctx()
6025 False
6026 """
6027 if z3_debug():
6028 _z3_assert(isinstance(target, Context), "target must be a context")
6029 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
6030
6031 def __copy__(self):
6032 return self.translate(self.ctx)
6033
6034 def __deepcopy__(self, memo={}):
6035 return self.translate(self.ctx)
6036
6037 def simplify(self, *arguments, **keywords):
6038 """Return a new simplified goal.
6039
6040 This method is essentially invoking the simplify tactic.
6041
6042 >>> g = Goal()
6043 >>> x = Int('x')
6044 >>> g.add(x + 1 >= 2)
6045 >>> g
6046 [x + 1 >= 2]
6047 >>> g2 = g.simplify()
6048 >>> g2
6049 [x >= 1]
6050 >>> # g was not modified
6051 >>> g
6052 [x + 1 >= 2]
6053 """
6054 t = Tactic("simplify")
6055 return t.apply(self, *arguments, **keywords)[0]
6056
6057 def as_expr(self):
6058 """Return goal `self` as a single Z3 expression.
6059
6060 >>> x = Int('x')
6061 >>> g = Goal()
6062 >>> g.as_expr()
6063 True
6064 >>> g.add(x > 1)
6065 >>> g.as_expr()
6066 x > 1
6067 >>> g.add(x < 10)
6068 >>> g.as_expr()
6069 And(x > 1, x < 10)
6070 """
6071 sz = len(self)
6072 if sz == 0:
6073 return BoolVal(True, self.ctx)
6074 elif sz == 1:
6075 return self.get(0)
6076 else:
6077 return And([self.get(i) for i in range(len(self))], self.ctx)
6078
6079
6084
6085
6087 """A collection (vector) of ASTs."""
6088
6089 def __init__(self, v=None, ctx=None):
6090 self.vector = None
6091 if v is None:
6092 self.ctx = _get_ctx(ctx)
6093 self.vector = Z3_mk_ast_vector(self.ctx.ref())
6094 else:
6095 self.vector = v
6096 assert ctx is not None
6097 self.ctx = ctx
6098 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
6099
6100 def __del__(self):
6101 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
6102 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
6103
6104 def __len__(self):
6105 """Return the size of the vector `self`.
6106
6107 >>> A = AstVector()
6108 >>> len(A)
6109 0
6110 >>> A.push(Int('x'))
6111 >>> A.push(Int('x'))
6112 >>> len(A)
6113 2
6114 """
6115 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
6116
6117 def __getitem__(self, i):
6118 """Return the AST at position `i`.
6119
6120 >>> A = AstVector()
6121 >>> A.push(Int('x') + 1)
6122 >>> A.push(Int('y'))
6123 >>> A[0]
6124 x + 1
6125 >>> A[1]
6126 y
6127 """
6128
6129 if isinstance(i, int):
6130 if i < 0:
6131 i += self.__len__()
6132
6133 if i >= self.__len__():
6134 raise IndexError
6135 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
6136
6137 elif isinstance(i, slice):
6138 result = []
6139 for ii in range(*i.indices(self.__len__())):
6140 result.append(_to_ast_ref(
6141 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6142 self.ctx,
6143 ))
6144 return result
6145
6146 def __setitem__(self, i, v):
6147 """Update AST at position `i`.
6148
6149 >>> A = AstVector()
6150 >>> A.push(Int('x') + 1)
6151 >>> A.push(Int('y'))
6152 >>> A[0]
6153 x + 1
6154 >>> A[0] = Int('x')
6155 >>> A[0]
6156 x
6157 """
6158 if i < 0:
6159 i += self.__len__()
6160 if i < 0 or i >= self.__len__():
6161 raise IndexError
6162 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6163
6164 def push(self, v):
6165 """Add `v` in the end of the vector.
6166
6167 >>> A = AstVector()
6168 >>> len(A)
6169 0
6170 >>> A.push(Int('x'))
6171 >>> len(A)
6172 1
6173 """
6174 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6175
6176 def resize(self, sz):
6177 """Resize the vector to `sz` elements.
6178
6179 >>> A = AstVector()
6180 >>> A.resize(10)
6181 >>> len(A)
6182 10
6183 >>> for i in range(10): A[i] = Int('x')
6184 >>> A[5]
6185 x
6186 """
6187 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6188
6189 def __contains__(self, item):
6190 """Return `True` if the vector contains `item`.
6191
6192 >>> x = Int('x')
6193 >>> A = AstVector()
6194 >>> x in A
6195 False
6196 >>> A.push(x)
6197 >>> x in A
6198 True
6199 >>> (x+1) in A
6200 False
6201 >>> A.push(x+1)
6202 >>> (x+1) in A
6203 True
6204 >>> A
6205 [x, x + 1]
6206 """
6207 for elem in self:
6208 if elem.eq(item):
6209 return True
6210 return False
6211
6212 def translate(self, other_ctx):
6213 """Copy vector `self` to context `other_ctx`.
6214
6215 >>> x = Int('x')
6216 >>> A = AstVector()
6217 >>> A.push(x)
6218 >>> c2 = Context()
6219 >>> B = A.translate(c2)
6220 >>> B
6221 [x]
6222 """
6223 return AstVector(
6224 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6225 ctx=other_ctx,
6226 )
6227
6228 def __copy__(self):
6229 return self.translate(self.ctx)
6230
6231 def __deepcopy__(self, memo={}):
6232 return self.translate(self.ctx)
6233
6234 def __repr__(self):
6235 return obj_to_string(self)
6236
6237 def sexpr(self):
6238 """Return a textual representation of the s-expression representing the vector."""
6239 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6240
6241
6246
6247
6249 """A mapping from ASTs to ASTs."""
6250
6251 def __init__(self, m=None, ctx=None):
6252 self.map = None
6253 if m is None:
6254 self.ctx = _get_ctx(ctx)
6255 self.map = Z3_mk_ast_map(self.ctx.ref())
6256 else:
6257 self.map = m
6258 assert ctx is not None
6259 self.ctx = ctx
6260 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6261
6262 def __deepcopy__(self, memo={}):
6263 return AstMap(self.map, self.ctx)
6264
6265 def __del__(self):
6266 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6267 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6268
6269 def __len__(self):
6270 """Return the size of the map.
6271
6272 >>> M = AstMap()
6273 >>> len(M)
6274 0
6275 >>> x = Int('x')
6276 >>> M[x] = IntVal(1)
6277 >>> len(M)
6278 1
6279 """
6280 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6281
6282 def __contains__(self, key):
6283 """Return `True` if the map contains key `key`.
6284
6285 >>> M = AstMap()
6286 >>> x = Int('x')
6287 >>> M[x] = x + 1
6288 >>> x in M
6289 True
6290 >>> x+1 in M
6291 False
6292 """
6293 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6294
6295 def __getitem__(self, key):
6296 """Retrieve the value associated with key `key`.
6297
6298 >>> M = AstMap()
6299 >>> x = Int('x')
6300 >>> M[x] = x + 1
6301 >>> M[x]
6302 x + 1
6303 """
6304 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6305
6306 def __setitem__(self, k, v):
6307 """Add/Update key `k` with value `v`.
6308
6309 >>> M = AstMap()
6310 >>> x = Int('x')
6311 >>> M[x] = x + 1
6312 >>> len(M)
6313 1
6314 >>> M[x]
6315 x + 1
6316 >>> M[x] = IntVal(1)
6317 >>> M[x]
6318 1
6319 """
6320 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6321
6322 def __repr__(self):
6323 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6324
6325 def erase(self, k):
6326 """Remove the entry associated with key `k`.
6327
6328 >>> M = AstMap()
6329 >>> x = Int('x')
6330 >>> M[x] = x + 1
6331 >>> len(M)
6332 1
6333 >>> M.erase(x)
6334 >>> len(M)
6335 0
6336 """
6337 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6338
6339 def reset(self):
6340 """Remove all entries from the map.
6341
6342 >>> M = AstMap()
6343 >>> x = Int('x')
6344 >>> M[x] = x + 1
6345 >>> M[x+x] = IntVal(1)
6346 >>> len(M)
6347 2
6348 >>> M.reset()
6349 >>> len(M)
6350 0
6351 """
6352 Z3_ast_map_reset(self.ctx.ref(), self.map)
6353
6354 def keys(self):
6355 """Return an AstVector containing all keys in the map.
6356
6357 >>> M = AstMap()
6358 >>> x = Int('x')
6359 >>> M[x] = x + 1
6360 >>> M[x+x] = IntVal(1)
6361 >>> M.keys()
6362 [x, x + x]
6363 """
6364 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6365
6366
6371
6372
6374 """Store the value of the interpretation of a function in a particular point."""
6375
6376 def __init__(self, entry, ctx):
6377 self.entry = entry
6378 self.ctx = ctx
6379 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6380
6381 def __deepcopy__(self, memo={}):
6382 return FuncEntry(self.entry, self.ctx)
6383
6384 def __del__(self):
6385 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6386 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6387
6388 def num_args(self):
6389 """Return the number of arguments in the given entry.
6390
6391 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6392 >>> s = Solver()
6393 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6394 >>> s.check()
6395 sat
6396 >>> m = s.model()
6397 >>> f_i = m[f]
6398 >>> f_i.num_entries()
6399 1
6400 >>> e = f_i.entry(0)
6401 >>> e.num_args()
6402 2
6403 """
6404 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6405
6406 def arg_value(self, idx):
6407 """Return the value of argument `idx`.
6408
6409 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6410 >>> s = Solver()
6411 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6412 >>> s.check()
6413 sat
6414 >>> m = s.model()
6415 >>> f_i = m[f]
6416 >>> f_i.num_entries()
6417 1
6418 >>> e = f_i.entry(0)
6419 >>> e
6420 [1, 2, 20]
6421 >>> e.num_args()
6422 2
6423 >>> e.arg_value(0)
6424 1
6425 >>> e.arg_value(1)
6426 2
6427 >>> try:
6428 ... e.arg_value(2)
6429 ... except IndexError:
6430 ... print("index error")
6431 index error
6432 """
6433 if idx >= self.num_args():
6434 raise IndexError
6435 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6436
6437 def value(self):
6438 """Return the value of the function at point `self`.
6439
6440 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6441 >>> s = Solver()
6442 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6443 >>> s.check()
6444 sat
6445 >>> m = s.model()
6446 >>> f_i = m[f]
6447 >>> f_i.num_entries()
6448 1
6449 >>> e = f_i.entry(0)
6450 >>> e
6451 [1, 2, 20]
6452 >>> e.num_args()
6453 2
6454 >>> e.value()
6455 20
6456 """
6457 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6458
6459 def as_list(self):
6460 """Return entry `self` as a Python list.
6461 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6462 >>> s = Solver()
6463 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6464 >>> s.check()
6465 sat
6466 >>> m = s.model()
6467 >>> f_i = m[f]
6468 >>> f_i.num_entries()
6469 1
6470 >>> e = f_i.entry(0)
6471 >>> e.as_list()
6472 [1, 2, 20]
6473 """
6474 args = [self.arg_value(i) for i in range(self.num_args())]
6475 args.append(self.value())
6476 return args
6477
6478 def __repr__(self):
6479 return repr(self.as_list())
6480
6481
6483 """Stores the interpretation of a function in a Z3 model."""
6484
6485 def __init__(self, f, ctx):
6486 self.f = f
6487 self.ctx = ctx
6488 if self.f is not None:
6489 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6490
6491 def __del__(self):
6492 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6493 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6494
6495 def else_value(self):
6496 """
6497 Return the `else` value for a function interpretation.
6498 Return None if Z3 did not specify the `else` value for
6499 this object.
6500
6501 >>> f = Function('f', IntSort(), IntSort())
6502 >>> s = Solver()
6503 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6504 >>> s.check()
6505 sat
6506 >>> m = s.model()
6507 >>> m[f]
6508 [2 -> 0, else -> 1]
6509 >>> m[f].else_value()
6510 1
6511 """
6512 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6513 if r:
6514 return _to_expr_ref(r, self.ctx)
6515 else:
6516 return None
6517
6518 def num_entries(self):
6519 """Return the number of entries/points in the function interpretation `self`.
6520
6521 >>> f = Function('f', IntSort(), IntSort())
6522 >>> s = Solver()
6523 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6524 >>> s.check()
6525 sat
6526 >>> m = s.model()
6527 >>> m[f]
6528 [2 -> 0, else -> 1]
6529 >>> m[f].num_entries()
6530 1
6531 """
6532 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6533
6534 def arity(self):
6535 """Return the number of arguments for each entry in the function interpretation `self`.
6536
6537 >>> f = Function('f', IntSort(), IntSort())
6538 >>> s = Solver()
6539 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6540 >>> s.check()
6541 sat
6542 >>> m = s.model()
6543 >>> m[f].arity()
6544 1
6545 """
6546 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6547
6548 def entry(self, idx):
6549 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6550
6551 >>> f = Function('f', IntSort(), IntSort())
6552 >>> s = Solver()
6553 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6554 >>> s.check()
6555 sat
6556 >>> m = s.model()
6557 >>> m[f]
6558 [2 -> 0, else -> 1]
6559 >>> m[f].num_entries()
6560 1
6561 >>> m[f].entry(0)
6562 [2, 0]
6563 """
6564 if idx >= self.num_entries():
6565 raise IndexError
6566 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6567
6568 def translate(self, other_ctx):
6569 """Copy model 'self' to context 'other_ctx'.
6570 """
6571 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6572
6573 def __copy__(self):
6574 return self.translate(self.ctx)
6575
6576 def __deepcopy__(self, memo={}):
6577 return self.translate(self.ctx)
6578
6579 def as_list(self):
6580 """Return the function interpretation as a Python list.
6581 >>> f = Function('f', IntSort(), IntSort())
6582 >>> s = Solver()
6583 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6584 >>> s.check()
6585 sat
6586 >>> m = s.model()
6587 >>> m[f]
6588 [2 -> 0, else -> 1]
6589 >>> m[f].as_list()
6590 [[2, 0], 1]
6591 """
6592 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6593 r.append(self.else_value())
6594 return r
6595
6596 def __repr__(self):
6597 return obj_to_string(self)
6598
6599
6601 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6602
6603 def __init__(self, m, ctx):
6604 assert ctx is not None
6605 self.model = m
6606 self.ctx = ctx
6607 Z3_model_inc_ref(self.ctx.ref(), self.model)
6608
6609 def __del__(self):
6610 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6611 Z3_model_dec_ref(self.ctx.ref(), self.model)
6612
6613 def __repr__(self):
6614 return obj_to_string(self)
6615
6616 def sexpr(self):
6617 """Return a textual representation of the s-expression representing the model."""
6618 return Z3_model_to_string(self.ctx.ref(), self.model)
6619
6620 def eval(self, t, model_completion=False):
6621 """Evaluate the expression `t` in the model `self`.
6622 If `model_completion` is enabled, then a default interpretation is automatically added
6623 for symbols that do not have an interpretation in the model `self`.
6624
6625 >>> x = Int('x')
6626 >>> s = Solver()
6627 >>> s.add(x > 0, x < 2)
6628 >>> s.check()
6629 sat
6630 >>> m = s.model()
6631 >>> m.eval(x + 1)
6632 2
6633 >>> m.eval(x == 1)
6634 True
6635 >>> y = Int('y')
6636 >>> m.eval(y + x)
6637 1 + y
6638 >>> m.eval(y)
6639 y
6640 >>> m.eval(y, model_completion=True)
6641 0
6642 >>> # Now, m contains an interpretation for y
6643 >>> m.eval(y + x)
6644 1
6645 """
6646 r = (Ast * 1)()
6647 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6648 return _to_expr_ref(r[0], self.ctx)
6649 raise Z3Exception("failed to evaluate expression in the model")
6650
6651 def evaluate(self, t, model_completion=False):
6652 """Alias for `eval`.
6653
6654 >>> x = Int('x')
6655 >>> s = Solver()
6656 >>> s.add(x > 0, x < 2)
6657 >>> s.check()
6658 sat
6659 >>> m = s.model()
6660 >>> m.evaluate(x + 1)
6661 2
6662 >>> m.evaluate(x == 1)
6663 True
6664 >>> y = Int('y')
6665 >>> m.evaluate(y + x)
6666 1 + y
6667 >>> m.evaluate(y)
6668 y
6669 >>> m.evaluate(y, model_completion=True)
6670 0
6671 >>> # Now, m contains an interpretation for y
6672 >>> m.evaluate(y + x)
6673 1
6674 """
6675 return self.eval(t, model_completion)
6676
6677 def __len__(self):
6678 """Return the number of constant and function declarations in the model `self`.
6679
6680 >>> f = Function('f', IntSort(), IntSort())
6681 >>> x = Int('x')
6682 >>> s = Solver()
6683 >>> s.add(x > 0, f(x) != x)
6684 >>> s.check()
6685 sat
6686 >>> m = s.model()
6687 >>> len(m)
6688 2
6689 """
6690 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6691 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6692 return num_consts + num_funcs
6693
6694 def get_interp(self, decl):
6695 """Return the interpretation for a given declaration or constant.
6696
6697 >>> f = Function('f', IntSort(), IntSort())
6698 >>> x = Int('x')
6699 >>> s = Solver()
6700 >>> s.add(x > 0, x < 2, f(x) == 0)
6701 >>> s.check()
6702 sat
6703 >>> m = s.model()
6704 >>> m[x]
6705 1
6706 >>> m[f]
6707 [else -> 0]
6708 """
6709 if z3_debug():
6710 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6711 if is_const(decl):
6712 decl = decl.decl()
6713 try:
6714 if decl.arity() == 0:
6715 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6716 if _r.value is None:
6717 return None
6718 r = _to_expr_ref(_r, self.ctx)
6719 if is_as_array(r):
6720 fi = self.get_interp(get_as_array_func(r))
6721 if fi is None:
6722 return fi
6723 e = fi.else_value()
6724 if e is None:
6725 return fi
6726 if fi.arity() != 1:
6727 return fi
6728 srt = decl.range()
6729 dom = srt.domain()
6730 e = K(dom, e)
6731 i = 0
6732 sz = fi.num_entries()
6733 n = fi.arity()
6734 while i < sz:
6735 fe = fi.entry(i)
6736 e = Store(e, fe.arg_value(0), fe.value())
6737 i += 1
6738 return e
6739 else:
6740 return r
6741 else:
6742 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6743 except Z3Exception:
6744 return None
6745
6746 def num_sorts(self):
6747 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6748
6749 >>> A = DeclareSort('A')
6750 >>> a, b = Consts('a b', A)
6751 >>> s = Solver()
6752 >>> s.add(a != b)
6753 >>> s.check()
6754 sat
6755 >>> m = s.model()
6756 >>> m.num_sorts()
6757 1
6758 """
6759 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6760
6761 def get_sort(self, idx):
6762 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6763
6764 >>> A = DeclareSort('A')
6765 >>> B = DeclareSort('B')
6766 >>> a1, a2 = Consts('a1 a2', A)
6767 >>> b1, b2 = Consts('b1 b2', B)
6768 >>> s = Solver()
6769 >>> s.add(a1 != a2, b1 != b2)
6770 >>> s.check()
6771 sat
6772 >>> m = s.model()
6773 >>> m.num_sorts()
6774 2
6775 >>> m.get_sort(0)
6776 A
6777 >>> m.get_sort(1)
6778 B
6779 """
6780 if idx >= self.num_sorts():
6781 raise IndexError
6782 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6783
6784 def sorts(self):
6785 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6786
6787 >>> A = DeclareSort('A')
6788 >>> B = DeclareSort('B')
6789 >>> a1, a2 = Consts('a1 a2', A)
6790 >>> b1, b2 = Consts('b1 b2', B)
6791 >>> s = Solver()
6792 >>> s.add(a1 != a2, b1 != b2)
6793 >>> s.check()
6794 sat
6795 >>> m = s.model()
6796 >>> m.sorts()
6797 [A, B]
6798 """
6799 return [self.get_sort(i) for i in range(self.num_sorts())]
6800
6801 def get_universe(self, s):
6802 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6803
6804 >>> A = DeclareSort('A')
6805 >>> a, b = Consts('a b', A)
6806 >>> s = Solver()
6807 >>> s.add(a != b)
6808 >>> s.check()
6809 sat
6810 >>> m = s.model()
6811 >>> m.get_universe(A)
6812 [A!val!1, A!val!0]
6813 """
6814 if z3_debug():
6815 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6816 try:
6817 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6818 except Z3Exception:
6819 return None
6820
6821 def __getitem__(self, idx):
6822 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6823 If `idx` is a declaration, then the actual interpretation is returned.
6824
6825 The elements can be retrieved using position or the actual declaration.
6826
6827 >>> f = Function('f', IntSort(), IntSort())
6828 >>> x = Int('x')
6829 >>> s = Solver()
6830 >>> s.add(x > 0, x < 2, f(x) == 0)
6831 >>> s.check()
6832 sat
6833 >>> m = s.model()
6834 >>> len(m)
6835 2
6836 >>> m[0]
6837 x
6838 >>> m[1]
6839 f
6840 >>> m[x]
6841 1
6842 >>> m[f]
6843 [else -> 0]
6844 >>> for d in m: print("%s -> %s" % (d, m[d]))
6845 x -> 1
6846 f -> [else -> 0]
6847 """
6848 if _is_int(idx):
6849 if idx < 0:
6850 idx += len(self)
6851 if idx < 0 or idx >= len(self):
6852 raise IndexError
6853 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6854 if (idx < num_consts):
6855 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6856 else:
6857 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6858 if isinstance(idx, FuncDeclRef):
6859 return self.get_interp(idx)
6860 if is_const(idx):
6861 return self.get_interp(idx.decl())
6862 if isinstance(idx, SortRef):
6863 return self.get_universe(idx)
6864 if z3_debug():
6865 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected. Use model.eval instead for complicated expressions")
6866 return None
6867
6868 def decls(self):
6869 """Return a list with all symbols that have an interpretation in the model `self`.
6870 >>> f = Function('f', IntSort(), IntSort())
6871 >>> x = Int('x')
6872 >>> s = Solver()
6873 >>> s.add(x > 0, x < 2, f(x) == 0)
6874 >>> s.check()
6875 sat
6876 >>> m = s.model()
6877 >>> m.decls()
6878 [x, f]
6879 """
6880 r = []
6881 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6882 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6883 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6884 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6885 return r
6886
6887 def update_value(self, x, value):
6888 """Update the interpretation of a constant"""
6889 if is_expr(x):
6890 x = x.decl()
6891 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6892 fi1 = value.f
6893 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6894 fi2 = FuncInterp(fi2, x.ctx)
6895 for i in range(value.num_entries()):
6896 e = value.entry(i)
6897 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6898 v = AstVector()
6899 for j in range(n):
6900 v.push(e.arg_value(j))
6901 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6902 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6903 return
6904 if not is_func_decl(x) or x.arity() != 0:
6905 raise Z3Exception("Expecting 0-ary function or constant expression")
6906 value = _py2expr(value)
6907 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6908
6909 def translate(self, target):
6910 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6911 """
6912 if z3_debug():
6913 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6914 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6915 return ModelRef(model, target)
6916
6917 def project(self, vars, fml):
6918 """Perform model-based projection on fml with respect to vars.
6919 Assume that the model satisfies fml. Then compute a projection fml_p, such
6920 that vars do not occur free in fml_p, fml_p is true in the model and
6921 fml_p => exists vars . fml
6922 """
6923 ctx = self.ctx.ref()
6924 _vars = (Ast * len(vars))()
6925 for i in range(len(vars)):
6926 _vars[i] = vars[i].as_ast()
6927 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6928
6929 def project_with_witness(self, vars, fml):
6930 """Perform model-based projection, but also include realizer terms for the projected variables"""
6931 ctx = self.ctx.ref()
6932 _vars = (Ast * len(vars))()
6933 for i in range(len(vars)):
6934 _vars[i] = vars[i].as_ast()
6935 defs = AstMap()
6936 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6937 result = _to_expr_ref(result, self.ctx)
6938 return result, defs
6939
6940
6941 def __copy__(self):
6942 return self.translate(self.ctx)
6943
6944 def __deepcopy__(self, memo={}):
6945 return self.translate(self.ctx)
6946
6947
6948def Model(ctx=None, eval = {}):
6949 ctx = _get_ctx(ctx)
6950 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6951 for k, v in eval.items():
6952 mdl.update_value(k, v)
6953 return mdl
6954
6955
6957 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6958 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6959
6960
6962 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6963 if z3_debug():
6964 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6965 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6966
6967
6972
6973
6975 """Statistics for `Solver.check()`."""
6976
6977 def __init__(self, stats, ctx):
6978 self.stats = stats
6979 self.ctx = ctx
6980 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6981
6982 def __deepcopy__(self, memo={}):
6983 return Statistics(self.stats, self.ctx)
6984
6985 def __del__(self):
6986 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6987 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6988
6989 def __repr__(self):
6990 if in_html_mode():
6991 out = io.StringIO()
6992 even = True
6993 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6994 for k, v in self:
6995 if even:
6996 out.write(u('<tr style="background-color:#CFCFCF">'))
6997 even = False
6998 else:
6999 out.write(u("<tr>"))
7000 even = True
7001 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
7002 out.write(u("</table>"))
7003 return out.getvalue()
7004 else:
7005 return Z3_stats_to_string(self.ctx.ref(), self.stats)
7006
7007 def __len__(self):
7008 """Return the number of statistical counters.
7009
7010 >>> x = Int('x')
7011 >>> s = Then('simplify', 'nlsat').solver()
7012 >>> s.add(x > 0)
7013 >>> s.check()
7014 sat
7015 >>> st = s.statistics()
7016 >>> len(st)
7017 7
7018 """
7019 return int(Z3_stats_size(self.ctx.ref(), self.stats))
7020
7021 def __getitem__(self, idx):
7022 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
7023
7024 >>> x = Int('x')
7025 >>> s = Then('simplify', 'nlsat').solver()
7026 >>> s.add(x > 0)
7027 >>> s.check()
7028 sat
7029 >>> st = s.statistics()
7030 >>> len(st)
7031 7
7032 >>> st[0]
7033 ('nlsat propagations', 2)
7034 >>> st[1]
7035 ('nlsat restarts', 1)
7036 """
7037 if idx >= len(self):
7038 raise IndexError
7039 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7040 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7041 else:
7042 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7043 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
7044
7045 def keys(self):
7046 """Return the list of statistical counters.
7047
7048 >>> x = Int('x')
7049 >>> s = Then('simplify', 'nlsat').solver()
7050 >>> s.add(x > 0)
7051 >>> s.check()
7052 sat
7053 >>> st = s.statistics()
7054 """
7055 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
7056
7057 def get_key_value(self, key):
7058 """Return the value of a particular statistical counter.
7059
7060 >>> x = Int('x')
7061 >>> s = Then('simplify', 'nlsat').solver()
7062 >>> s.add(x > 0)
7063 >>> s.check()
7064 sat
7065 >>> st = s.statistics()
7066 >>> st.get_key_value('nlsat propagations')
7067 2
7068 """
7069 for idx in range(len(self)):
7070 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
7071 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7072 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7073 else:
7074 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7075 raise Z3Exception("unknown key")
7076
7077 def __getattr__(self, name):
7078 """Access the value of statistical using attributes.
7079
7080 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
7081 we should use '_' (e.g., 'nlsat_propagations').
7082
7083 >>> x = Int('x')
7084 >>> s = Then('simplify', 'nlsat').solver()
7085 >>> s.add(x > 0)
7086 >>> s.check()
7087 sat
7088 >>> st = s.statistics()
7089 >>> st.nlsat_propagations
7090 2
7091 >>> st.nlsat_stages
7092 2
7093 """
7094 key = name.replace("_", " ")
7095 try:
7096 return self.get_key_value(key)
7097 except Z3Exception:
7098 raise AttributeError
7099
7100
7105
7106
7108 """Represents the result of a satisfiability check: sat, unsat, unknown.
7109
7110 >>> s = Solver()
7111 >>> s.check()
7112 sat
7113 >>> r = s.check()
7114 >>> isinstance(r, CheckSatResult)
7115 True
7116 """
7117
7118 def __init__(self, r):
7119 self.r = r
7120
7121 def __deepcopy__(self, memo={}):
7122 return CheckSatResult(self.r)
7123
7124 def __eq__(self, other):
7125 return isinstance(other, CheckSatResult) and self.r == other.r
7126
7127 def __ne__(self, other):
7128 return not self.__eq__(other)
7129
7130 def __repr__(self):
7131 if in_html_mode():
7132 if self.r == Z3_L_TRUE:
7133 return "<b>sat</b>"
7134 elif self.r == Z3_L_FALSE:
7135 return "<b>unsat</b>"
7136 else:
7137 return "<b>unknown</b>"
7138 else:
7139 if self.r == Z3_L_TRUE:
7140 return "sat"
7141 elif self.r == Z3_L_FALSE:
7142 return "unsat"
7143 else:
7144 return "unknown"
7145
7146 def _repr_html_(self):
7147 in_html = in_html_mode()
7148 set_html_mode(True)
7149 res = repr(self)
7150 set_html_mode(in_html)
7151 return res
7152
7153
7154sat = CheckSatResult(Z3_L_TRUE)
7155unsat = CheckSatResult(Z3_L_FALSE)
7156unknown = CheckSatResult(Z3_L_UNDEF)
7157
7158
7160 """
7161 Solver API provides methods for implementing the main SMT 2.0 commands:
7162 push, pop, check, get-model, etc.
7163 """
7164
7165 def __init__(self, solver=None, ctx=None, logFile=None):
7166 assert solver is None or ctx is not None
7167 self.ctx = _get_ctx(ctx)
7168 self.backtrack_level = 4000000000
7169 self.solver = None
7170 if solver is None:
7171 self.solver = Z3_mk_solver(self.ctx.ref())
7172 else:
7173 self.solver = solver
7174 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7175 if logFile is not None:
7176 self.set("smtlib2_log", logFile)
7177
7178 def __del__(self):
7179 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7180 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7181
7182 def __enter__(self):
7183 self.push()
7184 return self
7185
7186 def __exit__(self, *exc_info):
7187 self.pop()
7188
7189 def set(self, *args, **keys):
7190 """Set a configuration option.
7191 The method `help()` return a string containing all available options.
7192
7193 >>> s = Solver()
7194 >>> # The option MBQI can be set using three different approaches.
7195 >>> s.set(mbqi=True)
7196 >>> s.set('MBQI', True)
7197 >>> s.set(':mbqi', True)
7198 """
7199 p = args2params(args, keys, self.ctx)
7200 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7201
7202 def push(self):
7203 """Create a backtracking point.
7204
7205 >>> x = Int('x')
7206 >>> s = Solver()
7207 >>> s.add(x > 0)
7208 >>> s
7209 [x > 0]
7210 >>> s.push()
7211 >>> s.add(x < 1)
7212 >>> s
7213 [x > 0, x < 1]
7214 >>> s.check()
7215 unsat
7216 >>> s.pop()
7217 >>> s.check()
7218 sat
7219 >>> s
7220 [x > 0]
7221 """
7222 Z3_solver_push(self.ctx.ref(), self.solver)
7223
7224 def pop(self, num=1):
7225 """Backtrack \\c num backtracking points.
7226
7227 >>> x = Int('x')
7228 >>> s = Solver()
7229 >>> s.add(x > 0)
7230 >>> s
7231 [x > 0]
7232 >>> s.push()
7233 >>> s.add(x < 1)
7234 >>> s
7235 [x > 0, x < 1]
7236 >>> s.check()
7237 unsat
7238 >>> s.pop()
7239 >>> s.check()
7240 sat
7241 >>> s
7242 [x > 0]
7243 """
7244 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7245
7246 def num_scopes(self):
7247 """Return the current number of backtracking points.
7248
7249 >>> s = Solver()
7250 >>> s.num_scopes()
7251 0
7252 >>> s.push()
7253 >>> s.num_scopes()
7254 1
7255 >>> s.push()
7256 >>> s.num_scopes()
7257 2
7258 >>> s.pop()
7259 >>> s.num_scopes()
7260 1
7261 """
7262 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7263
7264 def reset(self):
7265 """Remove all asserted constraints and backtracking points created using `push()`.
7266
7267 >>> x = Int('x')
7268 >>> s = Solver()
7269 >>> s.add(x > 0)
7270 >>> s
7271 [x > 0]
7272 >>> s.reset()
7273 >>> s
7274 []
7275 """
7276 Z3_solver_reset(self.ctx.ref(), self.solver)
7277
7278 def assert_exprs(self, *args):
7279 """Assert constraints into the solver.
7280
7281 >>> x = Int('x')
7282 >>> s = Solver()
7283 >>> s.assert_exprs(x > 0, x < 2)
7284 >>> s
7285 [x > 0, x < 2]
7286 """
7287 args = _get_args(args)
7288 s = BoolSort(self.ctx)
7289 for arg in args:
7290 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7291 for f in arg:
7292 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7293 else:
7294 arg = s.cast(arg)
7295 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7296
7297 def add(self, *args):
7298 """Assert constraints into the solver.
7299
7300 >>> x = Int('x')
7301 >>> s = Solver()
7302 >>> s.add(x > 0, x < 2)
7303 >>> s
7304 [x > 0, x < 2]
7305 """
7306 self.assert_exprs(*args)
7307
7308 def __iadd__(self, fml):
7309 self.add(fml)
7310 return self
7311
7312 def append(self, *args):
7313 """Assert constraints into the solver.
7314
7315 >>> x = Int('x')
7316 >>> s = Solver()
7317 >>> s.append(x > 0, x < 2)
7318 >>> s
7319 [x > 0, x < 2]
7320 """
7321 self.assert_exprs(*args)
7322
7323 def insert(self, *args):
7324 """Assert constraints into the solver.
7325
7326 >>> x = Int('x')
7327 >>> s = Solver()
7328 >>> s.insert(x > 0, x < 2)
7329 >>> s
7330 [x > 0, x < 2]
7331 """
7332 self.assert_exprs(*args)
7333
7334 def assert_and_track(self, a, p):
7335 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7336
7337 If `p` is a string, it will be automatically converted into a Boolean constant.
7338
7339 >>> x = Int('x')
7340 >>> p3 = Bool('p3')
7341 >>> s = Solver()
7342 >>> s.set(unsat_core=True)
7343 >>> s.assert_and_track(x > 0, 'p1')
7344 >>> s.assert_and_track(x != 1, 'p2')
7345 >>> s.assert_and_track(x < 0, p3)
7346 >>> print(s.check())
7347 unsat
7348 >>> c = s.unsat_core()
7349 >>> len(c)
7350 2
7351 >>> Bool('p1') in c
7352 True
7353 >>> Bool('p2') in c
7354 False
7355 >>> p3 in c
7356 True
7357 """
7358 if isinstance(p, str):
7359 p = Bool(p, self.ctx)
7360 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7361 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7362 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7363
7364 def check(self, *assumptions):
7365 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7366
7367 >>> x = Int('x')
7368 >>> s = Solver()
7369 >>> s.check()
7370 sat
7371 >>> s.add(x > 0, x < 2)
7372 >>> s.check()
7373 sat
7374 >>> s.model().eval(x)
7375 1
7376 >>> s.add(x < 1)
7377 >>> s.check()
7378 unsat
7379 >>> s.reset()
7380 >>> s.add(2**x == 4)
7381 >>> s.check()
7382 sat
7383 """
7384 s = BoolSort(self.ctx)
7385 assumptions = _get_args(assumptions)
7386 num = len(assumptions)
7387 _assumptions = (Ast * num)()
7388 for i in range(num):
7389 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7390 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7391 return CheckSatResult(r)
7392
7393 def model(self):
7394 """Return a model for the last `check()`.
7395
7396 This function raises an exception if
7397 a model is not available (e.g., last `check()` returned unsat).
7398
7399 >>> s = Solver()
7400 >>> a = Int('a')
7401 >>> s.add(a + 2 == 0)
7402 >>> s.check()
7403 sat
7404 >>> s.model()
7405 [a = -2]
7406 """
7407 try:
7408 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7409 except Z3Exception:
7410 raise Z3Exception("model is not available")
7411
7412 def import_model_converter(self, other):
7413 """Import model converter from other into the current solver"""
7414 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7415
7416 def interrupt(self):
7417 """Interrupt the execution of the solver object.
7418 Remarks: This ensures that the interrupt applies only
7419 to the given solver object and it applies only if it is running.
7420 """
7421 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7422
7423 def unsat_core(self):
7424 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7425
7426 These are the assumptions Z3 used in the unsatisfiability proof.
7427 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7428 They may be also used to "retract" assumptions. Note that, assumptions are not really
7429 "soft constraints", but they can be used to implement them.
7430
7431 >>> p1, p2, p3 = Bools('p1 p2 p3')
7432 >>> x, y = Ints('x y')
7433 >>> s = Solver()
7434 >>> s.add(Implies(p1, x > 0))
7435 >>> s.add(Implies(p2, y > x))
7436 >>> s.add(Implies(p2, y < 1))
7437 >>> s.add(Implies(p3, y > -3))
7438 >>> s.check(p1, p2, p3)
7439 unsat
7440 >>> core = s.unsat_core()
7441 >>> len(core)
7442 2
7443 >>> p1 in core
7444 True
7445 >>> p2 in core
7446 True
7447 >>> p3 in core
7448 False
7449 >>> # "Retracting" p2
7450 >>> s.check(p1, p3)
7451 sat
7452 """
7453 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7454
7455 def consequences(self, assumptions, variables):
7456 """Determine fixed values for the variables based on the solver state and assumptions.
7457 >>> s = Solver()
7458 >>> a, b, c, d = Bools('a b c d')
7459 >>> s.add(Implies(a,b), Implies(b, c))
7460 >>> s.consequences([a],[b,c,d])
7461 (sat, [Implies(a, b), Implies(a, c)])
7462 >>> s.consequences([Not(c),d],[a,b,c,d])
7463 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7464 """
7465 if isinstance(assumptions, list):
7466 _asms = AstVector(None, self.ctx)
7467 for a in assumptions:
7468 _asms.push(a)
7469 assumptions = _asms
7470 if isinstance(variables, list):
7471 _vars = AstVector(None, self.ctx)
7472 for a in variables:
7473 _vars.push(a)
7474 variables = _vars
7475 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7476 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7477 consequences = AstVector(None, self.ctx)
7478 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7479 variables.vector, consequences.vector)
7480 sz = len(consequences)
7481 consequences = [consequences[i] for i in range(sz)]
7482 return CheckSatResult(r), consequences
7483
7484 def from_file(self, filename):
7485 """Parse assertions from a file"""
7486 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7487
7488 def from_string(self, s):
7489 """Parse assertions from a string"""
7490 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7491
7492 def cube(self, vars=None):
7493 """Get set of cubes
7494 The method takes an optional set of variables that restrict which
7495 variables may be used as a starting point for cubing.
7496 If vars is not None, then the first case split is based on a variable in
7497 this set.
7498 """
7499 self.cube_vs = AstVector(None, self.ctx)
7500 if vars is not None:
7501 for v in vars:
7502 self.cube_vs.push(v)
7503 while True:
7504 lvl = self.backtrack_level
7505 self.backtrack_level = 4000000000
7506 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7507 if (len(r) == 1 and is_false(r[0])):
7508 return
7509 yield r
7510 if (len(r) == 0):
7511 return
7512
7513 def cube_vars(self):
7514 """Access the set of variables that were touched by the most recently generated cube.
7515 This set of variables can be used as a starting point for additional cubes.
7516 The idea is that variables that appear in clauses that are reduced by the most recent
7517 cube are likely more useful to cube on."""
7518 return self.cube_vs
7519
7520 def root(self, t):
7521 """Retrieve congruence closure root of the term t relative to the current search state
7522 The function primarily works for SimpleSolver. Terms and variables that are
7523 eliminated during pre-processing are not visible to the congruence closure.
7524 """
7525 t = _py2expr(t, self.ctx)
7526 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7527
7528 def next(self, t):
7529 """Retrieve congruence closure sibling of the term t relative to the current search state
7530 The function primarily works for SimpleSolver. Terms and variables that are
7531 eliminated during pre-processing are not visible to the congruence closure.
7532 """
7533 t = _py2expr(t, self.ctx)
7534 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7535
7536 def explain_congruent(self, a, b):
7537 """Explain congruence of a and b relative to the current search state"""
7538 a = _py2expr(a, self.ctx)
7539 b = _py2expr(b, self.ctx)
7540 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7541
7542
7543 def solve_for(self, ts):
7544 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7545 vars = AstVector(ctx=self.ctx);
7546 terms = AstVector(ctx=self.ctx);
7547 guards = AstVector(ctx=self.ctx);
7548 for t in ts:
7549 t = _py2expr(t, self.ctx)
7550 vars.push(t)
7551 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7552 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7553
7554
7555 def proof(self):
7556 """Return a proof for the last `check()`. Proof construction must be enabled."""
7557 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7558
7559 def assertions(self):
7560 """Return an AST vector containing all added constraints.
7561
7562 >>> s = Solver()
7563 >>> s.assertions()
7564 []
7565 >>> a = Int('a')
7566 >>> s.add(a > 0)
7567 >>> s.add(a < 10)
7568 >>> s.assertions()
7569 [a > 0, a < 10]
7570 """
7571 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7572
7573 def units(self):
7574 """Return an AST vector containing all currently inferred units.
7575 """
7576 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7577
7578 def non_units(self):
7579 """Return an AST vector containing all atomic formulas in solver state that are not units.
7580 """
7581 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7582
7583 def trail_levels(self):
7584 """Return trail and decision levels of the solver state after a check() call.
7585 """
7586 trail = self.trail()
7587 levels = (ctypes.c_uint * len(trail))()
7588 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7589 return trail, levels
7590
7591 def set_initial_value(self, var, value):
7592 """initialize the solver's state by setting the initial value of var to value
7593 """
7594 s = var.sort()
7595 value = s.cast(value)
7596 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7597
7598 def trail(self):
7599 """Return trail of the solver state after a check() call.
7600 """
7601 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7602
7603 def statistics(self):
7604 """Return statistics for the last `check()`.
7605
7606 >>> s = SimpleSolver()
7607 >>> x = Int('x')
7608 >>> s.add(x > 0)
7609 >>> s.check()
7610 sat
7611 >>> st = s.statistics()
7612 >>> st.get_key_value('final checks')
7613 1
7614 >>> len(st) > 0
7615 True
7616 >>> st[0] != 0
7617 True
7618 """
7619 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7620
7621 def reason_unknown(self):
7622 """Return a string describing why the last `check()` returned `unknown`.
7623
7624 >>> x = Int('x')
7625 >>> s = SimpleSolver()
7626 >>> s.add(x == 2**x)
7627 >>> s.check()
7628 unknown
7629 >>> s.reason_unknown()
7630 '(incomplete (theory arithmetic))'
7631 """
7632 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7633
7634 def help(self):
7635 """Display a string describing all available options."""
7636 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7637
7638 def param_descrs(self):
7639 """Return the parameter description set."""
7640 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7641
7642 def __repr__(self):
7643 """Return a formatted string with all added constraints."""
7644 return obj_to_string(self)
7645
7646 def translate(self, target):
7647 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7648
7649 >>> c1 = Context()
7650 >>> c2 = Context()
7651 >>> s1 = Solver(ctx=c1)
7652 >>> s2 = s1.translate(c2)
7653 """
7654 if z3_debug():
7655 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7656 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7657 return Solver(solver, target)
7658
7659 def __copy__(self):
7660 return self.translate(self.ctx)
7661
7662 def __deepcopy__(self, memo={}):
7663 return self.translate(self.ctx)
7664
7665 def sexpr(self):
7666 """Return a formatted string (in Lisp-like format) with all added constraints.
7667 """
7668 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7669
7670 def dimacs(self, include_names=True):
7671 """Return a textual representation of the solver in DIMACS format."""
7672 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7673
7674 def to_smt2(self):
7675 """return SMTLIB2 formatted benchmark for solver's assertions"""
7676 es = self.assertions()
7677 sz = len(es)
7678 sz1 = sz
7679 if sz1 > 0:
7680 sz1 -= 1
7681 v = (Ast * sz1)()
7682 for i in range(sz1):
7683 v[i] = es[i].as_ast()
7684 if sz > 0:
7685 e = es[sz1].as_ast()
7686 else:
7687 e = BoolVal(True, self.ctx).as_ast()
7688 return Z3_benchmark_to_smtlib_string(
7689 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7690 )
7691
7692 def solutions(self, t):
7693 """Returns an iterator over solutions that satisfy the constraints.
7694
7695 The parameter `t` is an expression whose values should be returned.
7696
7697 >>> s = Solver()
7698 >>> x, y, z = Ints("x y z")
7699 >>> s.add(x * x == 4)
7700 >>> print(list(s.solutions(x)))
7701 [-2, 2]
7702 >>> s.reset()
7703 >>> s.add(x >= 0, x < 10)
7704 >>> print(list(s.solutions(x)))
7705 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7706 >>> s.reset()
7707 >>> s.add(x >= 0, y < 10, y == 2*x)
7708 >>> print(list(s.solutions([x, y])))
7709 [[0, 0], [1, 2], [2, 4], [3, 6], [4, 8]]
7710 """
7711 s = Solver()
7712 s.add(self.assertions())
7713 t = _get_args(t)
7714 if isinstance(t, (list, tuple)):
7715 while s.check() == sat:
7716 result = [s.model().eval(t_, model_completion=True) for t_ in t]
7717 yield result
7718 s.add(*(t_ != result_ for t_, result_ in zip(t, result)))
7719 else:
7720 while s.check() == sat:
7721 result = s.model().eval(t, model_completion=True)
7722 yield result
7723 s.add(t != result)
7724
7725
7726def SolverFor(logic, ctx=None, logFile=None):
7727 """Create a solver customized for the given logic.
7728
7729 The parameter `logic` is a string. It should be contains
7730 the name of a SMT-LIB logic.
7731 See http://www.smtlib.org/ for the name of all available logics.
7732
7733 >>> s = SolverFor("QF_LIA")
7734 >>> x = Int('x')
7735 >>> s.add(x > 0)
7736 >>> s.add(x < 2)
7737 >>> s.check()
7738 sat
7739 >>> s.model()
7740 [x = 1]
7741 """
7742 ctx = _get_ctx(ctx)
7743 logic = to_symbol(logic)
7744 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7745
7746
7747def SimpleSolver(ctx=None, logFile=None):
7748 """Return a simple general purpose solver with limited amount of preprocessing.
7749
7750 >>> s = SimpleSolver()
7751 >>> x = Int('x')
7752 >>> s.add(x > 0)
7753 >>> s.check()
7754 sat
7755 """
7756 ctx = _get_ctx(ctx)
7757 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7758
7759#########################################
7760#
7761# Fixedpoint
7762#
7763#########################################
7764
7765
7766class Fixedpoint(Z3PPObject):
7767 """Fixedpoint API provides methods for solving with recursive predicates"""
7768
7769 def __init__(self, fixedpoint=None, ctx=None):
7770 assert fixedpoint is None or ctx is not None
7771 self.ctx = _get_ctx(ctx)
7772 self.fixedpoint = None
7773 if fixedpoint is None:
7774 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7775 else:
7776 self.fixedpoint = fixedpoint
7777 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7778 self.vars = []
7779
7780 def __deepcopy__(self, memo={}):
7781 return FixedPoint(self.fixedpoint, self.ctx)
7782
7783 def __del__(self):
7784 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7785 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7786
7787 def set(self, *args, **keys):
7788 """Set a configuration option. The method `help()` return a string containing all available options.
7789 """
7790 p = args2params(args, keys, self.ctx)
7791 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7792
7793 def help(self):
7794 """Display a string describing all available options."""
7795 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7796
7797 def param_descrs(self):
7798 """Return the parameter description set."""
7799 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7800
7801 def assert_exprs(self, *args):
7802 """Assert constraints as background axioms for the fixedpoint solver."""
7803 args = _get_args(args)
7804 s = BoolSort(self.ctx)
7805 for arg in args:
7806 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7807 for f in arg:
7808 f = self.abstract(f)
7809 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7810 else:
7811 arg = s.cast(arg)
7812 arg = self.abstract(arg)
7813 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7814
7815 def add(self, *args):
7816 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7817 self.assert_exprs(*args)
7818
7819 def __iadd__(self, fml):
7820 self.add(fml)
7821 return self
7822
7823 def append(self, *args):
7824 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7825 self.assert_exprs(*args)
7826
7827 def insert(self, *args):
7828 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7829 self.assert_exprs(*args)
7830
7831 def add_rule(self, head, body=None, name=None):
7832 """Assert rules defining recursive predicates to the fixedpoint solver.
7833 >>> a = Bool('a')
7834 >>> b = Bool('b')
7835 >>> s = Fixedpoint()
7836 >>> s.register_relation(a.decl())
7837 >>> s.register_relation(b.decl())
7838 >>> s.fact(a)
7839 >>> s.rule(b, a)
7840 >>> s.query(b)
7841 sat
7842 """
7843 if name is None:
7844 name = ""
7845 name = to_symbol(name, self.ctx)
7846 if body is None:
7847 head = self.abstract(head)
7848 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7849 else:
7850 body = _get_args(body)
7851 f = self.abstract(Implies(And(body, self.ctx), head))
7852 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7853
7854 def rule(self, head, body=None, name=None):
7855 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7856 self.add_rule(head, body, name)
7857
7858 def fact(self, head, name=None):
7859 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7860 self.add_rule(head, None, name)
7861
7862 def query(self, *query):
7863 """Query the fixedpoint engine whether formula is derivable.
7864 You can also pass an tuple or list of recursive predicates.
7865 """
7866 query = _get_args(query)
7867 sz = len(query)
7868 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7869 _decls = (FuncDecl * sz)()
7870 i = 0
7871 for q in query:
7872 _decls[i] = q.ast
7873 i = i + 1
7874 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7875 else:
7876 if sz == 1:
7877 query = query[0]
7878 else:
7879 query = And(query, self.ctx)
7880 query = self.abstract(query, False)
7881 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7882 return CheckSatResult(r)
7883
7884 def query_from_lvl(self, lvl, *query):
7885 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7886 """
7887 query = _get_args(query)
7888 sz = len(query)
7889 if sz >= 1 and isinstance(query[0], FuncDecl):
7890 _z3_assert(False, "unsupported")
7891 else:
7892 if sz == 1:
7893 query = query[0]
7894 else:
7895 query = And(query)
7896 query = self.abstract(query, False)
7897 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7898 return CheckSatResult(r)
7899
7900 def update_rule(self, head, body, name):
7901 """update rule"""
7902 if name is None:
7903 name = ""
7904 name = to_symbol(name, self.ctx)
7905 body = _get_args(body)
7906 f = self.abstract(Implies(And(body, self.ctx), head))
7907 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7908
7909 def get_answer(self):
7910 """Retrieve answer from last query call."""
7911 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7912 return _to_expr_ref(r, self.ctx)
7913
7914 def get_ground_sat_answer(self):
7915 """Retrieve a ground cex from last query call."""
7916 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7917 return _to_expr_ref(r, self.ctx)
7918
7919 def get_rules_along_trace(self):
7920 """retrieve rules along the counterexample trace"""
7921 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7922
7923 def get_rule_names_along_trace(self):
7924 """retrieve rule names along the counterexample trace"""
7925 # this is a hack as I don't know how to return a list of symbols from C++;
7926 # obtain names as a single string separated by semicolons
7927 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7928 # split into individual names
7929 return names.split(";")
7930
7931 def get_num_levels(self, predicate):
7932 """Retrieve number of levels used for predicate in PDR engine"""
7933 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7934
7935 def get_cover_delta(self, level, predicate):
7936 """Retrieve properties known about predicate for the level'th unfolding.
7937 -1 is treated as the limit (infinity)
7938 """
7939 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7940 return _to_expr_ref(r, self.ctx)
7941
7942 def add_cover(self, level, predicate, property):
7943 """Add property to predicate for the level'th unfolding.
7944 -1 is treated as infinity (infinity)
7945 """
7946 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7947
7948 def register_relation(self, *relations):
7949 """Register relation as recursive"""
7950 relations = _get_args(relations)
7951 for f in relations:
7952 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7953
7954 def set_predicate_representation(self, f, *representations):
7955 """Control how relation is represented"""
7956 representations = _get_args(representations)
7957 representations = [to_symbol(s) for s in representations]
7958 sz = len(representations)
7959 args = (Symbol * sz)()
7960 for i in range(sz):
7961 args[i] = representations[i]
7962 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7963
7964 def parse_string(self, s):
7965 """Parse rules and queries from a string"""
7966 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7967
7968 def parse_file(self, f):
7969 """Parse rules and queries from a file"""
7970 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7971
7972 def get_rules(self):
7973 """retrieve rules that have been added to fixedpoint context"""
7974 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7975
7976 def get_assertions(self):
7977 """retrieve assertions that have been added to fixedpoint context"""
7978 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7979
7980 def __repr__(self):
7981 """Return a formatted string with all added rules and constraints."""
7982 return self.sexpr()
7983
7984 def sexpr(self):
7985 """Return a formatted string (in Lisp-like format) with all added constraints.
7986 We say the string is in s-expression format.
7987 """
7988 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7989
7990 def to_string(self, queries):
7991 """Return a formatted string (in Lisp-like format) with all added constraints.
7992 We say the string is in s-expression format.
7993 Include also queries.
7994 """
7995 args, len = _to_ast_array(queries)
7996 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7997
7998 def statistics(self):
7999 """Return statistics for the last `query()`.
8000 """
8001 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
8002
8003 def reason_unknown(self):
8004 """Return a string describing why the last `query()` returned `unknown`.
8005 """
8006 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
8007
8008 def declare_var(self, *vars):
8009 """Add variable or several variables.
8010 The added variable or variables will be bound in the rules
8011 and queries
8012 """
8013 vars = _get_args(vars)
8014 for v in vars:
8015 self.vars += [v]
8016
8017 def abstract(self, fml, is_forall=True):
8018 if self.vars == []:
8019 return fml
8020 if is_forall:
8021 return ForAll(self.vars, fml)
8022 else:
8023 return Exists(self.vars, fml)
8024
8025
8026#########################################
8027#
8028# Finite domains
8029#
8030#########################################
8031
8032class FiniteDomainSortRef(SortRef):
8033 """Finite domain sort."""
8034
8035 def size(self):
8036 """Return the size of the finite domain sort"""
8037 r = (ctypes.c_ulonglong * 1)()
8038 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
8039 return r[0]
8040 else:
8041 raise Z3Exception("Failed to retrieve finite domain sort size")
8042
8043
8044def FiniteDomainSort(name, sz, ctx=None):
8045 """Create a named finite domain sort of a given size sz"""
8046 if not isinstance(name, Symbol):
8047 name = to_symbol(name)
8048 ctx = _get_ctx(ctx)
8049 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
8050
8051
8052def is_finite_domain_sort(s):
8053 """Return True if `s` is a Z3 finite-domain sort.
8054
8055 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
8056 True
8057 >>> is_finite_domain_sort(IntSort())
8058 False
8059 """
8060 return isinstance(s, FiniteDomainSortRef)
8061
8062
8063class FiniteDomainRef(ExprRef):
8064 """Finite-domain expressions."""
8065
8066 def sort(self):
8067 """Return the sort of the finite-domain expression `self`."""
8068 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
8069
8070 def as_string(self):
8071 """Return a Z3 floating point expression as a Python string."""
8072 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
8073
8074
8075def is_finite_domain(a):
8076 """Return `True` if `a` is a Z3 finite-domain expression.
8077
8078 >>> s = FiniteDomainSort('S', 100)
8079 >>> b = Const('b', s)
8080 >>> is_finite_domain(b)
8081 True
8082 >>> is_finite_domain(Int('x'))
8083 False
8084 """
8085 return isinstance(a, FiniteDomainRef)
8086
8087
8088class FiniteDomainNumRef(FiniteDomainRef):
8089 """Integer values."""
8090
8091 def as_long(self):
8092 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
8093
8094 >>> s = FiniteDomainSort('S', 100)
8095 >>> v = FiniteDomainVal(3, s)
8096 >>> v
8097 3
8098 >>> v.as_long() + 1
8099 4
8100 """
8101 return int(self.as_string())
8102
8103 def as_string(self):
8104 """Return a Z3 finite-domain numeral as a Python string.
8105
8106 >>> s = FiniteDomainSort('S', 100)
8107 >>> v = FiniteDomainVal(42, s)
8108 >>> v.as_string()
8109 '42'
8110 """
8111 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
8112
8113
8114def FiniteDomainVal(val, sort, ctx=None):
8115 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
8116
8117 >>> s = FiniteDomainSort('S', 256)
8118 >>> FiniteDomainVal(255, s)
8119 255
8120 >>> FiniteDomainVal('100', s)
8121 100
8122 """
8123 if z3_debug():
8124 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
8125 ctx = sort.ctx
8126 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
8127
8128
8129def is_finite_domain_value(a):
8130 """Return `True` if `a` is a Z3 finite-domain value.
8131
8132 >>> s = FiniteDomainSort('S', 100)
8133 >>> b = Const('b', s)
8134 >>> is_finite_domain_value(b)
8135 False
8136 >>> b = FiniteDomainVal(10, s)
8137 >>> b
8138 10
8139 >>> is_finite_domain_value(b)
8140 True
8141 """
8142 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
8143
8144
8145#########################################
8146#
8147# Optimize
8148#
8149#########################################
8150
8151class OptimizeObjective:
8152 def __init__(self, opt, value, is_max):
8153 self._opt = opt
8154 self._value = value
8155 self._is_max = is_max
8156
8157 def lower(self):
8158 opt = self._opt
8159 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8160
8161 def upper(self):
8162 opt = self._opt
8163 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8164
8165 def lower_values(self):
8166 opt = self._opt
8167 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8168
8169 def upper_values(self):
8170 opt = self._opt
8171 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8172
8173 def value(self):
8174 if self._is_max:
8175 return self.upper()
8176 else:
8177 return self.lower()
8178
8179 def __str__(self):
8180 return "%s:%s" % (self._value, self._is_max)
8181
8182
8183_on_models = {}
8184
8185
8186def _global_on_model(ctx):
8187 (fn, mdl) = _on_models[ctx]
8188 fn(mdl)
8189
8190
8191_on_model_eh = on_model_eh_type(_global_on_model)
8192
8193
8194class Optimize(Z3PPObject):
8195 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8196
8197 def __init__(self, optimize=None, ctx=None):
8198 self.ctx = _get_ctx(ctx)
8199 if optimize is None:
8200 self.optimize = Z3_mk_optimize(self.ctx.ref())
8201 else:
8202 self.optimize = optimize
8203 self._on_models_id = None
8204 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8205
8206 def __deepcopy__(self, memo={}):
8207 return Optimize(self.optimize, self.ctx)
8208
8209 def __del__(self):
8210 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8211 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8212 if self._on_models_id is not None:
8213 del _on_models[self._on_models_id]
8214
8215 def __enter__(self):
8216 self.push()
8217 return self
8218
8219 def __exit__(self, *exc_info):
8220 self.pop()
8221
8222 def set(self, *args, **keys):
8223 """Set a configuration option.
8224 The method `help()` return a string containing all available options.
8225 """
8226 p = args2params(args, keys, self.ctx)
8227 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8228
8229 def help(self):
8230 """Display a string describing all available options."""
8231 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8232
8233 def param_descrs(self):
8234 """Return the parameter description set."""
8235 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8236
8237 def assert_exprs(self, *args):
8238 """Assert constraints as background axioms for the optimize solver."""
8239 args = _get_args(args)
8240 s = BoolSort(self.ctx)
8241 for arg in args:
8242 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8243 for f in arg:
8244 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8245 else:
8246 arg = s.cast(arg)
8247 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8248
8249 def add(self, *args):
8250 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8251 self.assert_exprs(*args)
8252
8253 def __iadd__(self, fml):
8254 self.add(fml)
8255 return self
8256
8257 def assert_and_track(self, a, p):
8258 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8259
8260 If `p` is a string, it will be automatically converted into a Boolean constant.
8261
8262 >>> x = Int('x')
8263 >>> p3 = Bool('p3')
8264 >>> s = Optimize()
8265 >>> s.assert_and_track(x > 0, 'p1')
8266 >>> s.assert_and_track(x != 1, 'p2')
8267 >>> s.assert_and_track(x < 0, p3)
8268 >>> print(s.check())
8269 unsat
8270 >>> c = s.unsat_core()
8271 >>> len(c)
8272 2
8273 >>> Bool('p1') in c
8274 True
8275 >>> Bool('p2') in c
8276 False
8277 >>> p3 in c
8278 True
8279 """
8280 if isinstance(p, str):
8281 p = Bool(p, self.ctx)
8282 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8283 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8284 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8285
8286 def add_soft(self, arg, weight="1", id=None):
8287 """Add soft constraint with optional weight and optional identifier.
8288 If no weight is supplied, then the penalty for violating the soft constraint
8289 is 1.
8290 Soft constraints are grouped by identifiers. Soft constraints that are
8291 added without identifiers are grouped by default.
8292 """
8293 if _is_int(weight):
8294 weight = "%d" % weight
8295 elif isinstance(weight, float):
8296 weight = "%f" % weight
8297 if not isinstance(weight, str):
8298 raise Z3Exception("weight should be a string or an integer")
8299 if id is None:
8300 id = ""
8301 id = to_symbol(id, self.ctx)
8302
8303 def asoft(a):
8304 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8305 return OptimizeObjective(self, v, False)
8306 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8307 return [asoft(a) for a in arg]
8308 return asoft(arg)
8309
8310 def set_initial_value(self, var, value):
8311 """initialize the solver's state by setting the initial value of var to value
8312 """
8313 s = var.sort()
8314 value = s.cast(value)
8315 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8316
8317 def maximize(self, arg):
8318 """Add objective function to maximize."""
8319 return OptimizeObjective(
8320 self,
8321 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8322 is_max=True,
8323 )
8324
8325 def minimize(self, arg):
8326 """Add objective function to minimize."""
8327 return OptimizeObjective(
8328 self,
8329 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8330 is_max=False,
8331 )
8332
8333 def push(self):
8334 """create a backtracking point for added rules, facts and assertions"""
8335 Z3_optimize_push(self.ctx.ref(), self.optimize)
8336
8337 def pop(self):
8338 """restore to previously created backtracking point"""
8339 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8340
8341 def check(self, *assumptions):
8342 """Check consistency and produce optimal values."""
8343 assumptions = _get_args(assumptions)
8344 num = len(assumptions)
8345 _assumptions = (Ast * num)()
8346 for i in range(num):
8347 _assumptions[i] = assumptions[i].as_ast()
8348 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8349
8350 def reason_unknown(self):
8351 """Return a string that describes why the last `check()` returned `unknown`."""
8352 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8353
8354 def model(self):
8355 """Return a model for the last check()."""
8356 try:
8357 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8358 except Z3Exception:
8359 raise Z3Exception("model is not available")
8360
8361 def unsat_core(self):
8362 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8363
8364 def lower(self, obj):
8365 if not isinstance(obj, OptimizeObjective):
8366 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8367 return obj.lower()
8368
8369 def upper(self, obj):
8370 if not isinstance(obj, OptimizeObjective):
8371 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8372 return obj.upper()
8373
8374 def lower_values(self, obj):
8375 if not isinstance(obj, OptimizeObjective):
8376 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8377 return obj.lower_values()
8378
8379 def upper_values(self, obj):
8380 if not isinstance(obj, OptimizeObjective):
8381 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8382 return obj.upper_values()
8383
8384 def from_file(self, filename):
8385 """Parse assertions and objectives from a file"""
8386 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8387
8388 def from_string(self, s):
8389 """Parse assertions and objectives from a string"""
8390 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8391
8392 def assertions(self):
8393 """Return an AST vector containing all added constraints."""
8394 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8395
8396 def objectives(self):
8397 """returns set of objective functions"""
8398 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8399
8400 def __repr__(self):
8401 """Return a formatted string with all added rules and constraints."""
8402 return self.sexpr()
8403
8404 def sexpr(self):
8405 """Return a formatted string (in Lisp-like format) with all added constraints.
8406 We say the string is in s-expression format.
8407 """
8408 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8409
8410 def statistics(self):
8411 """Return statistics for the last check`.
8412 """
8413 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8414
8415 def set_on_model(self, on_model):
8416 """Register a callback that is invoked with every incremental improvement to
8417 objective values. The callback takes a model as argument.
8418 The life-time of the model is limited to the callback so the
8419 model has to be (deep) copied if it is to be used after the callback
8420 """
8421 id = len(_on_models) + 41
8422 mdl = Model(self.ctx)
8423 _on_models[id] = (on_model, mdl)
8424 self._on_models_id = id
8425 Z3_optimize_register_model_eh(
8426 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8427 )
8428
8429
8430#########################################
8431#
8432# ApplyResult
8433#
8434#########################################
8435class ApplyResult(Z3PPObject):
8436 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8437 It also contains model and proof converters.
8438 """
8439
8440 def __init__(self, result, ctx):
8441 self.result = result
8442 self.ctx = ctx
8443 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8444
8445 def __deepcopy__(self, memo={}):
8446 return ApplyResult(self.result, self.ctx)
8447
8448 def __del__(self):
8449 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8450 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8451
8452 def __len__(self):
8453 """Return the number of subgoals in `self`.
8454
8455 >>> a, b = Ints('a b')
8456 >>> g = Goal()
8457 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8458 >>> t = Tactic('split-clause')
8459 >>> r = t(g)
8460 >>> len(r)
8461 2
8462 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8463 >>> len(t(g))
8464 4
8465 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8466 >>> len(t(g))
8467 1
8468 """
8469 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8470
8471 def __getitem__(self, idx):
8472 """Return one of the subgoals stored in ApplyResult object `self`.
8473
8474 >>> a, b = Ints('a b')
8475 >>> g = Goal()
8476 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8477 >>> t = Tactic('split-clause')
8478 >>> r = t(g)
8479 >>> r[0]
8480 [a == 0, Or(b == 0, b == 1), a > b]
8481 >>> r[1]
8482 [a == 1, Or(b == 0, b == 1), a > b]
8483 """
8484 if idx < 0:
8485 idx += len(self)
8486 if idx < 0 or idx >= len(self):
8487 raise IndexError
8488 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8489
8490 def __repr__(self):
8491 return obj_to_string(self)
8492
8493 def sexpr(self):
8494 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8495 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8496
8497 def as_expr(self):
8498 """Return a Z3 expression consisting of all subgoals.
8499
8500 >>> x = Int('x')
8501 >>> g = Goal()
8502 >>> g.add(x > 1)
8503 >>> g.add(Or(x == 2, x == 3))
8504 >>> r = Tactic('simplify')(g)
8505 >>> r
8506 [[Not(x <= 1), Or(x == 2, x == 3)]]
8507 >>> r.as_expr()
8508 And(Not(x <= 1), Or(x == 2, x == 3))
8509 >>> r = Tactic('split-clause')(g)
8510 >>> r
8511 [[x > 1, x == 2], [x > 1, x == 3]]
8512 >>> r.as_expr()
8513 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8514 """
8515 sz = len(self)
8516 if sz == 0:
8517 return BoolVal(False, self.ctx)
8518 elif sz == 1:
8519 return self[0].as_expr()
8520 else:
8521 return Or([self[i].as_expr() for i in range(len(self))])
8522
8523#########################################
8524#
8525# Simplifiers
8526#
8527#########################################
8528
8529class Simplifier:
8530 """Simplifiers act as pre-processing utilities for solvers.
8531 Build a custom simplifier and add it to a solver"""
8532
8533 def __init__(self, simplifier, ctx=None):
8534 self.ctx = _get_ctx(ctx)
8535 self.simplifier = None
8536 if isinstance(simplifier, SimplifierObj):
8537 self.simplifier = simplifier
8538 elif isinstance(simplifier, list):
8539 simps = [Simplifier(s, ctx) for s in simplifier]
8540 self.simplifier = simps[0].simplifier
8541 for i in range(1, len(simps)):
8542 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8543 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8544 return
8545 else:
8546 if z3_debug():
8547 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8548 try:
8549 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8550 except Z3Exception:
8551 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8552 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8553
8554 def __deepcopy__(self, memo={}):
8555 return Simplifier(self.simplifier, self.ctx)
8556
8557 def __del__(self):
8558 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8559 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8560
8561 def using_params(self, *args, **keys):
8562 """Return a simplifier that uses the given configuration options"""
8563 p = args2params(args, keys, self.ctx)
8564 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8565
8566 def add(self, solver):
8567 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8568 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8569
8570 def help(self):
8571 """Display a string containing a description of the available options for the `self` simplifier."""
8572 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8573
8574 def param_descrs(self):
8575 """Return the parameter description set."""
8576 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8577
8578
8579#########################################
8580#
8581# Tactics
8582#
8583#########################################
8584
8585
8586class Tactic:
8587 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8588 A Tactic can be converted into a Solver using the method solver().
8589
8590 Several combinators are available for creating new tactics using the built-in ones:
8591 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8592 """
8593
8594 def __init__(self, tactic, ctx=None):
8595 self.ctx = _get_ctx(ctx)
8596 self.tactic = None
8597 if isinstance(tactic, TacticObj):
8598 self.tactic = tactic
8599 else:
8600 if z3_debug():
8601 _z3_assert(isinstance(tactic, str), "tactic name expected")
8602 try:
8603 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8604 except Z3Exception:
8605 raise Z3Exception("unknown tactic '%s'" % tactic)
8606 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8607
8608 def __deepcopy__(self, memo={}):
8609 return Tactic(self.tactic, self.ctx)
8610
8611 def __del__(self):
8612 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8613 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8614
8615 def solver(self, logFile=None):
8616 """Create a solver using the tactic `self`.
8617
8618 The solver supports the methods `push()` and `pop()`, but it
8619 will always solve each `check()` from scratch.
8620
8621 >>> t = Then('simplify', 'nlsat')
8622 >>> s = t.solver()
8623 >>> x = Real('x')
8624 >>> s.add(x**2 == 2, x > 0)
8625 >>> s.check()
8626 sat
8627 >>> s.model()
8628 [x = 1.4142135623?]
8629 """
8630 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8631
8632 def apply(self, goal, *arguments, **keywords):
8633 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8634
8635 >>> x, y = Ints('x y')
8636 >>> t = Tactic('solve-eqs')
8637 >>> t.apply(And(x == 0, y >= x + 1))
8638 [[y >= 1]]
8639 """
8640 if z3_debug():
8641 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8642 goal = _to_goal(goal)
8643 if len(arguments) > 0 or len(keywords) > 0:
8644 p = args2params(arguments, keywords, self.ctx)
8645 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8646 else:
8647 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8648
8649 def __call__(self, goal, *arguments, **keywords):
8650 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8651
8652 >>> x, y = Ints('x y')
8653 >>> t = Tactic('solve-eqs')
8654 >>> t(And(x == 0, y >= x + 1))
8655 [[y >= 1]]
8656 """
8657 return self.apply(goal, *arguments, **keywords)
8658
8659 def help(self):
8660 """Display a string containing a description of the available options for the `self` tactic."""
8661 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8662
8663 def param_descrs(self):
8664 """Return the parameter description set."""
8665 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8666
8667
8668def _to_goal(a):
8669 if isinstance(a, BoolRef):
8670 goal = Goal(ctx=a.ctx)
8671 goal.add(a)
8672 return goal
8673 else:
8674 return a
8675
8676
8677def _to_tactic(t, ctx=None):
8678 if isinstance(t, Tactic):
8679 return t
8680 else:
8681 return Tactic(t, ctx)
8682
8683
8684def _and_then(t1, t2, ctx=None):
8685 t1 = _to_tactic(t1, ctx)
8686 t2 = _to_tactic(t2, ctx)
8687 if z3_debug():
8688 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8689 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8690
8691
8692def _or_else(t1, t2, ctx=None):
8693 t1 = _to_tactic(t1, ctx)
8694 t2 = _to_tactic(t2, ctx)
8695 if z3_debug():
8696 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8697 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8698
8699
8700def AndThen(*ts, **ks):
8701 """Return a tactic that applies the tactics in `*ts` in sequence.
8702
8703 >>> x, y = Ints('x y')
8704 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8705 >>> t(And(x == 0, y > x + 1))
8706 [[Not(y <= 1)]]
8707 >>> t(And(x == 0, y > x + 1)).as_expr()
8708 Not(y <= 1)
8709 """
8710 if z3_debug():
8711 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8712 ctx = ks.get("ctx", None)
8713 num = len(ts)
8714 r = ts[0]
8715 for i in range(num - 1):
8716 r = _and_then(r, ts[i + 1], ctx)
8717 return r
8718
8719
8720def Then(*ts, **ks):
8721 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8722
8723 >>> x, y = Ints('x y')
8724 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8725 >>> t(And(x == 0, y > x + 1))
8726 [[Not(y <= 1)]]
8727 >>> t(And(x == 0, y > x + 1)).as_expr()
8728 Not(y <= 1)
8729 """
8730 return AndThen(*ts, **ks)
8731
8732
8733def OrElse(*ts, **ks):
8734 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8735
8736 >>> x = Int('x')
8737 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8738 >>> # Tactic split-clause fails if there is no clause in the given goal.
8739 >>> t(x == 0)
8740 [[x == 0]]
8741 >>> t(Or(x == 0, x == 1))
8742 [[x == 0], [x == 1]]
8743 """
8744 if z3_debug():
8745 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8746 ctx = ks.get("ctx", None)
8747 num = len(ts)
8748 r = ts[0]
8749 for i in range(num - 1):
8750 r = _or_else(r, ts[i + 1], ctx)
8751 return r
8752
8753
8754def ParOr(*ts, **ks):
8755 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8756
8757 >>> x = Int('x')
8758 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8759 >>> t(x + 1 == 2)
8760 [[x == 1]]
8761 """
8762 if z3_debug():
8763 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8764 ctx = _get_ctx(ks.get("ctx", None))
8765 ts = [_to_tactic(t, ctx) for t in ts]
8766 sz = len(ts)
8767 _args = (TacticObj * sz)()
8768 for i in range(sz):
8769 _args[i] = ts[i].tactic
8770 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8771
8772
8773def ParThen(t1, t2, ctx=None):
8774 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8775 The subgoals are processed in parallel.
8776
8777 >>> x, y = Ints('x y')
8778 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8779 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8780 [[x == 1, y == 2], [x == 2, y == 3]]
8781 """
8782 t1 = _to_tactic(t1, ctx)
8783 t2 = _to_tactic(t2, ctx)
8784 if z3_debug():
8785 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8786 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8787
8788
8789def ParAndThen(t1, t2, ctx=None):
8790 """Alias for ParThen(t1, t2, ctx)."""
8791 return ParThen(t1, t2, ctx)
8792
8793
8794def With(t, *args, **keys):
8795 """Return a tactic that applies tactic `t` using the given configuration options.
8796
8797 >>> x, y = Ints('x y')
8798 >>> t = With(Tactic('simplify'), som=True)
8799 >>> t((x + 1)*(y + 2) == 0)
8800 [[2*x + y + x*y == -2]]
8801 """
8802 ctx = keys.pop("ctx", None)
8803 t = _to_tactic(t, ctx)
8804 p = args2params(args, keys, t.ctx)
8805 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8806
8807
8808def WithParams(t, p):
8809 """Return a tactic that applies tactic `t` using the given configuration options.
8810
8811 >>> x, y = Ints('x y')
8812 >>> p = ParamsRef()
8813 >>> p.set("som", True)
8814 >>> t = WithParams(Tactic('simplify'), p)
8815 >>> t((x + 1)*(y + 2) == 0)
8816 [[2*x + y + x*y == -2]]
8817 """
8818 t = _to_tactic(t, None)
8819 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8820
8821
8822def Repeat(t, max=4294967295, ctx=None):
8823 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8824 or the maximum number of iterations `max` is reached.
8825
8826 >>> x, y = Ints('x y')
8827 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8828 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8829 >>> r = t(c)
8830 >>> for subgoal in r: print(subgoal)
8831 [x == 0, y == 0, x > y]
8832 [x == 0, y == 1, x > y]
8833 [x == 1, y == 0, x > y]
8834 [x == 1, y == 1, x > y]
8835 >>> t = Then(t, Tactic('propagate-values'))
8836 >>> t(c)
8837 [[x == 1, y == 0]]
8838 """
8839 t = _to_tactic(t, ctx)
8840 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8841
8842
8843def TryFor(t, ms, ctx=None):
8844 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8845
8846 If `t` does not terminate in `ms` milliseconds, then it fails.
8847 """
8848 t = _to_tactic(t, ctx)
8849 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8850
8851
8852def tactics(ctx=None):
8853 """Return a list of all available tactics in Z3.
8854
8855 >>> l = tactics()
8856 >>> l.count('simplify') == 1
8857 True
8858 """
8859 ctx = _get_ctx(ctx)
8860 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8861
8862
8863def tactic_description(name, ctx=None):
8864 """Return a short description for the tactic named `name`.
8865
8866 >>> d = tactic_description('simplify')
8867 """
8868 ctx = _get_ctx(ctx)
8869 return Z3_tactic_get_descr(ctx.ref(), name)
8870
8871
8872def describe_tactics():
8873 """Display a (tabular) description of all available tactics in Z3."""
8874 if in_html_mode():
8875 even = True
8876 print('<table border="1" cellpadding="2" cellspacing="0">')
8877 for t in tactics():
8878 if even:
8879 print('<tr style="background-color:#CFCFCF">')
8880 even = False
8881 else:
8882 print("<tr>")
8883 even = True
8884 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8885 print("</table>")
8886 else:
8887 for t in tactics():
8888 print("%s : %s" % (t, tactic_description(t)))
8889
8890
8891class Probe:
8892 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8893 to decide which solver and/or preprocessing step will be used.
8894 """
8895
8896 def __init__(self, probe, ctx=None):
8897 self.ctx = _get_ctx(ctx)
8898 self.probe = None
8899 if isinstance(probe, ProbeObj):
8900 self.probe = probe
8901 elif isinstance(probe, float):
8902 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8903 elif _is_int(probe):
8904 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8905 elif isinstance(probe, bool):
8906 if probe:
8907 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8908 else:
8909 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8910 else:
8911 if z3_debug():
8912 _z3_assert(isinstance(probe, str), "probe name expected")
8913 try:
8914 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8915 except Z3Exception:
8916 raise Z3Exception("unknown probe '%s'" % probe)
8917 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8918
8919 def __deepcopy__(self, memo={}):
8920 return Probe(self.probe, self.ctx)
8921
8922 def __del__(self):
8923 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8924 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8925
8926 def __lt__(self, other):
8927 """Return a probe that evaluates to "true" when the value returned by `self`
8928 is less than the value returned by `other`.
8929
8930 >>> p = Probe('size') < 10
8931 >>> x = Int('x')
8932 >>> g = Goal()
8933 >>> g.add(x > 0)
8934 >>> g.add(x < 10)
8935 >>> p(g)
8936 1.0
8937 """
8938 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8939
8940 def __gt__(self, other):
8941 """Return a probe that evaluates to "true" when the value returned by `self`
8942 is greater than the value returned by `other`.
8943
8944 >>> p = Probe('size') > 10
8945 >>> x = Int('x')
8946 >>> g = Goal()
8947 >>> g.add(x > 0)
8948 >>> g.add(x < 10)
8949 >>> p(g)
8950 0.0
8951 """
8952 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8953
8954 def __le__(self, other):
8955 """Return a probe that evaluates to "true" when the value returned by `self`
8956 is less than or equal to the value returned by `other`.
8957
8958 >>> p = Probe('size') <= 2
8959 >>> x = Int('x')
8960 >>> g = Goal()
8961 >>> g.add(x > 0)
8962 >>> g.add(x < 10)
8963 >>> p(g)
8964 1.0
8965 """
8966 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8967
8968 def __ge__(self, other):
8969 """Return a probe that evaluates to "true" when the value returned by `self`
8970 is greater than or equal to the value returned by `other`.
8971
8972 >>> p = Probe('size') >= 2
8973 >>> x = Int('x')
8974 >>> g = Goal()
8975 >>> g.add(x > 0)
8976 >>> g.add(x < 10)
8977 >>> p(g)
8978 1.0
8979 """
8980 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8981
8982 def __eq__(self, other):
8983 """Return a probe that evaluates to "true" when the value returned by `self`
8984 is equal to the value returned by `other`.
8985
8986 >>> p = Probe('size') == 2
8987 >>> x = Int('x')
8988 >>> g = Goal()
8989 >>> g.add(x > 0)
8990 >>> g.add(x < 10)
8991 >>> p(g)
8992 1.0
8993 """
8994 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8995
8996 def __ne__(self, other):
8997 """Return a probe that evaluates to "true" when the value returned by `self`
8998 is not equal to the value returned by `other`.
8999
9000 >>> p = Probe('size') != 2
9001 >>> x = Int('x')
9002 >>> g = Goal()
9003 >>> g.add(x > 0)
9004 >>> g.add(x < 10)
9005 >>> p(g)
9006 0.0
9007 """
9008 p = self.__eq__(other)
9009 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
9010
9011 def __call__(self, goal):
9012 """Evaluate the probe `self` in the given goal.
9013
9014 >>> p = Probe('size')
9015 >>> x = Int('x')
9016 >>> g = Goal()
9017 >>> g.add(x > 0)
9018 >>> g.add(x < 10)
9019 >>> p(g)
9020 2.0
9021 >>> g.add(x < 20)
9022 >>> p(g)
9023 3.0
9024 >>> p = Probe('num-consts')
9025 >>> p(g)
9026 1.0
9027 >>> p = Probe('is-propositional')
9028 >>> p(g)
9029 0.0
9030 >>> p = Probe('is-qflia')
9031 >>> p(g)
9032 1.0
9033 """
9034 if z3_debug():
9035 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
9036 goal = _to_goal(goal)
9037 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
9038
9039
9040def is_probe(p):
9041 """Return `True` if `p` is a Z3 probe.
9042
9043 >>> is_probe(Int('x'))
9044 False
9045 >>> is_probe(Probe('memory'))
9046 True
9047 """
9048 return isinstance(p, Probe)
9049
9050
9051def _to_probe(p, ctx=None):
9052 if is_probe(p):
9053 return p
9054 else:
9055 return Probe(p, ctx)
9056
9057
9058def probes(ctx=None):
9059 """Return a list of all available probes in Z3.
9060
9061 >>> l = probes()
9062 >>> l.count('memory') == 1
9063 True
9064 """
9065 ctx = _get_ctx(ctx)
9066 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
9067
9068
9069def probe_description(name, ctx=None):
9070 """Return a short description for the probe named `name`.
9071
9072 >>> d = probe_description('memory')
9073 """
9074 ctx = _get_ctx(ctx)
9075 return Z3_probe_get_descr(ctx.ref(), name)
9076
9077
9078def describe_probes():
9079 """Display a (tabular) description of all available probes in Z3."""
9080 if in_html_mode():
9081 even = True
9082 print('<table border="1" cellpadding="2" cellspacing="0">')
9083 for p in probes():
9084 if even:
9085 print('<tr style="background-color:#CFCFCF">')
9086 even = False
9087 else:
9088 print("<tr>")
9089 even = True
9090 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
9091 print("</table>")
9092 else:
9093 for p in probes():
9094 print("%s : %s" % (p, probe_description(p)))
9095
9096
9097def _probe_nary(f, args, ctx):
9098 if z3_debug():
9099 _z3_assert(len(args) > 0, "At least one argument expected")
9100 num = len(args)
9101 r = _to_probe(args[0], ctx)
9102 for i in range(num - 1):
9103 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
9104 return r
9105
9106
9107def _probe_and(args, ctx):
9108 return _probe_nary(Z3_probe_and, args, ctx)
9109
9110
9111def _probe_or(args, ctx):
9112 return _probe_nary(Z3_probe_or, args, ctx)
9113
9114
9115def FailIf(p, ctx=None):
9116 """Return a tactic that fails if the probe `p` evaluates to true.
9117 Otherwise, it returns the input goal unmodified.
9118
9119 In the following example, the tactic applies 'simplify' if and only if there are
9120 more than 2 constraints in the goal.
9121
9122 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
9123 >>> x, y = Ints('x y')
9124 >>> g = Goal()
9125 >>> g.add(x > 0)
9126 >>> g.add(y > 0)
9127 >>> t(g)
9128 [[x > 0, y > 0]]
9129 >>> g.add(x == y + 1)
9130 >>> t(g)
9131 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9132 """
9133 p = _to_probe(p, ctx)
9134 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
9135
9136
9137def When(p, t, ctx=None):
9138 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
9139 Otherwise, it returns the input goal unmodified.
9140
9141 >>> t = When(Probe('size') > 2, Tactic('simplify'))
9142 >>> x, y = Ints('x y')
9143 >>> g = Goal()
9144 >>> g.add(x > 0)
9145 >>> g.add(y > 0)
9146 >>> t(g)
9147 [[x > 0, y > 0]]
9148 >>> g.add(x == y + 1)
9149 >>> t(g)
9150 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9151 """
9152 p = _to_probe(p, ctx)
9153 t = _to_tactic(t, ctx)
9154 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
9155
9156
9157def Cond(p, t1, t2, ctx=None):
9158 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
9159
9160 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
9161 """
9162 p = _to_probe(p, ctx)
9163 t1 = _to_tactic(t1, ctx)
9164 t2 = _to_tactic(t2, ctx)
9165 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
9166
9167#########################################
9168#
9169# Utils
9170#
9171#########################################
9172
9173
9174def simplify(a, *arguments, **keywords):
9175 """Simplify the expression `a` using the given options.
9176
9177 This function has many options. Use `help_simplify` to obtain the complete list.
9178
9179 >>> x = Int('x')
9180 >>> y = Int('y')
9181 >>> simplify(x + 1 + y + x + 1)
9182 2 + 2*x + y
9183 >>> simplify((x + 1)*(y + 1), som=True)
9184 1 + x + y + x*y
9185 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9186 And(Not(x == y), Not(x == 1), Not(y == 1))
9187 >>> simplify(And(x == 0, y == 1), elim_and=True)
9188 Not(Or(Not(x == 0), Not(y == 1)))
9189 """
9190 if z3_debug():
9191 _z3_assert(is_expr(a), "Z3 expression expected")
9192 if len(arguments) > 0 or len(keywords) > 0:
9193 p = args2params(arguments, keywords, a.ctx)
9194 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9195 else:
9196 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9197
9198
9199def help_simplify():
9200 """Return a string describing all options available for Z3 `simplify` procedure."""
9201 print(Z3_simplify_get_help(main_ctx().ref()))
9202
9203
9204def simplify_param_descrs():
9205 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9206 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9207
9208
9209def substitute(t, *m):
9210 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9211 Every occurrence in t of from is replaced with to.
9212
9213 >>> x = Int('x')
9214 >>> y = Int('y')
9215 >>> substitute(x + 1, (x, y + 1))
9216 y + 1 + 1
9217 >>> f = Function('f', IntSort(), IntSort())
9218 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9219 1 + 1
9220 """
9221 if isinstance(m, tuple):
9222 m1 = _get_args(m)
9223 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9224 m = m1
9225 if z3_debug():
9226 _z3_assert(is_expr(t), "Z3 expression expected")
9227 _z3_assert(
9228 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9229 "Z3 invalid substitution, expression pairs expected.")
9230 _z3_assert(
9231 all([p[0].sort().eq(p[1].sort()) for p in m]),
9232 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9233 num = len(m)
9234 _from = (Ast * num)()
9235 _to = (Ast * num)()
9236 for i in range(num):
9237 _from[i] = m[i][0].as_ast()
9238 _to[i] = m[i][1].as_ast()
9239 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9240
9241
9242def substitute_vars(t, *m):
9243 """Substitute the free variables in t with the expression in m.
9244
9245 >>> v0 = Var(0, IntSort())
9246 >>> v1 = Var(1, IntSort())
9247 >>> x = Int('x')
9248 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9249 >>> # replace v0 with x+1 and v1 with x
9250 >>> substitute_vars(f(v0, v1), x + 1, x)
9251 f(x + 1, x)
9252 """
9253 if z3_debug():
9254 _z3_assert(is_expr(t), "Z3 expression expected")
9255 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9256 num = len(m)
9257 _to = (Ast * num)()
9258 for i in range(num):
9259 _to[i] = m[i].as_ast()
9260 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9261
9262def substitute_funs(t, *m):
9263 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9264 Every occurrence in to of the function from is replaced with the expression to.
9265 The expression to can have free variables, that refer to the arguments of from.
9266 For examples, see
9267 """
9268 if isinstance(m, tuple):
9269 m1 = _get_args(m)
9270 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9271 m = m1
9272 if z3_debug():
9273 _z3_assert(is_expr(t), "Z3 expression expected")
9274 _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.")
9275 num = len(m)
9276 _from = (FuncDecl * num)()
9277 _to = (Ast * num)()
9278 for i in range(num):
9279 _from[i] = m[i][0].as_func_decl()
9280 _to[i] = m[i][1].as_ast()
9281 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9282
9283
9284def Sum(*args):
9285 """Create the sum of the Z3 expressions.
9286
9287 >>> a, b, c = Ints('a b c')
9288 >>> Sum(a, b, c)
9289 a + b + c
9290 >>> Sum([a, b, c])
9291 a + b + c
9292 >>> A = IntVector('a', 5)
9293 >>> Sum(A)
9294 a__0 + a__1 + a__2 + a__3 + a__4
9295 """
9296 args = _get_args(args)
9297 if len(args) == 0:
9298 return 0
9299 ctx = _ctx_from_ast_arg_list(args)
9300 if ctx is None:
9301 return _reduce(lambda a, b: a + b, args, 0)
9302 args = _coerce_expr_list(args, ctx)
9303 if is_bv(args[0]):
9304 return _reduce(lambda a, b: a + b, args, 0)
9305 else:
9306 _args, sz = _to_ast_array(args)
9307 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9308
9309
9310def Product(*args):
9311 """Create the product of the Z3 expressions.
9312
9313 >>> a, b, c = Ints('a b c')
9314 >>> Product(a, b, c)
9315 a*b*c
9316 >>> Product([a, b, c])
9317 a*b*c
9318 >>> A = IntVector('a', 5)
9319 >>> Product(A)
9320 a__0*a__1*a__2*a__3*a__4
9321 """
9322 args = _get_args(args)
9323 if len(args) == 0:
9324 return 1
9325 ctx = _ctx_from_ast_arg_list(args)
9326 if ctx is None:
9327 return _reduce(lambda a, b: a * b, args, 1)
9328 args = _coerce_expr_list(args, ctx)
9329 if is_bv(args[0]):
9330 return _reduce(lambda a, b: a * b, args, 1)
9331 else:
9332 _args, sz = _to_ast_array(args)
9333 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9334
9335def Abs(arg):
9336 """Create the absolute value of an arithmetic expression"""
9337 return If(arg > 0, arg, -arg)
9338
9339
9340def AtMost(*args):
9341 """Create an at-most Pseudo-Boolean k constraint.
9342
9343 >>> a, b, c = Bools('a b c')
9344 >>> f = AtMost(a, b, c, 2)
9345 """
9346 args = _get_args(args)
9347 if z3_debug():
9348 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9349 ctx = _ctx_from_ast_arg_list(args)
9350 if z3_debug():
9351 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9352 args1 = _coerce_expr_list(args[:-1], ctx)
9353 k = args[-1]
9354 _args, sz = _to_ast_array(args1)
9355 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9356
9357
9358def AtLeast(*args):
9359 """Create an at-least Pseudo-Boolean k constraint.
9360
9361 >>> a, b, c = Bools('a b c')
9362 >>> f = AtLeast(a, b, c, 2)
9363 """
9364 args = _get_args(args)
9365 if z3_debug():
9366 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9367 ctx = _ctx_from_ast_arg_list(args)
9368 if z3_debug():
9369 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9370 args1 = _coerce_expr_list(args[:-1], ctx)
9371 k = args[-1]
9372 _args, sz = _to_ast_array(args1)
9373 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9374
9375
9376def _reorder_pb_arg(arg):
9377 a, b = arg
9378 if not _is_int(b) and _is_int(a):
9379 return b, a
9380 return arg
9381
9382
9383def _pb_args_coeffs(args, default_ctx=None):
9384 args = _get_args_ast_list(args)
9385 if len(args) == 0:
9386 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9387 args = [_reorder_pb_arg(arg) for arg in args]
9388 args, coeffs = zip(*args)
9389 if z3_debug():
9390 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9391 ctx = _ctx_from_ast_arg_list(args)
9392 if z3_debug():
9393 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9394 args = _coerce_expr_list(args, ctx)
9395 _args, sz = _to_ast_array(args)
9396 _coeffs = (ctypes.c_int * len(coeffs))()
9397 for i in range(len(coeffs)):
9398 _z3_check_cint_overflow(coeffs[i], "coefficient")
9399 _coeffs[i] = coeffs[i]
9400 return ctx, sz, _args, _coeffs, args
9401
9402
9403def PbLe(args, k):
9404 """Create a Pseudo-Boolean inequality k constraint.
9405
9406 >>> a, b, c = Bools('a b c')
9407 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9408 """
9409 _z3_check_cint_overflow(k, "k")
9410 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9411 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9412
9413
9414def PbGe(args, k):
9415 """Create a Pseudo-Boolean inequality k constraint.
9416
9417 >>> a, b, c = Bools('a b c')
9418 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9419 """
9420 _z3_check_cint_overflow(k, "k")
9421 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9422 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9423
9424
9425def PbEq(args, k, ctx=None):
9426 """Create a Pseudo-Boolean equality k constraint.
9427
9428 >>> a, b, c = Bools('a b c')
9429 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9430 """
9431 _z3_check_cint_overflow(k, "k")
9432 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9433 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9434
9435
9436def solve(*args, **keywords):
9437 """Solve the constraints `*args`.
9438
9439 This is a simple function for creating demonstrations. It creates a solver,
9440 configure it using the options in `keywords`, adds the constraints
9441 in `args`, and invokes check.
9442
9443 >>> a = Int('a')
9444 >>> solve(a > 0, a < 2)
9445 [a = 1]
9446 """
9447 show = keywords.pop("show", False)
9448 s = Solver()
9449 s.set(**keywords)
9450 s.add(*args)
9451 if show:
9452 print(s)
9453 r = s.check()
9454 if r == unsat:
9455 print("no solution")
9456 elif r == unknown:
9457 print("failed to solve")
9458 try:
9459 print(s.model())
9460 except Z3Exception:
9461 return
9462 else:
9463 print(s.model())
9464
9465
9466def solve_using(s, *args, **keywords):
9467 """Solve the constraints `*args` using solver `s`.
9468
9469 This is a simple function for creating demonstrations. It is similar to `solve`,
9470 but it uses the given solver `s`.
9471 It configures solver `s` using the options in `keywords`, adds the constraints
9472 in `args`, and invokes check.
9473 """
9474 show = keywords.pop("show", False)
9475 if z3_debug():
9476 _z3_assert(isinstance(s, Solver), "Solver object expected")
9477 s.set(**keywords)
9478 s.add(*args)
9479 if show:
9480 print("Problem:")
9481 print(s)
9482 r = s.check()
9483 if r == unsat:
9484 print("no solution")
9485 elif r == unknown:
9486 print("failed to solve")
9487 try:
9488 print(s.model())
9489 except Z3Exception:
9490 return
9491 else:
9492 if show:
9493 print("Solution:")
9494 print(s.model())
9495
9496
9497def prove(claim, show=False, **keywords):
9498 """Try to prove the given claim.
9499
9500 This is a simple function for creating demonstrations. It tries to prove
9501 `claim` by showing the negation is unsatisfiable.
9502
9503 >>> p, q = Bools('p q')
9504 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9505 proved
9506 """
9507 if z3_debug():
9508 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9509 s = Solver()
9510 s.set(**keywords)
9511 s.add(Not(claim))
9512 if show:
9513 print(s)
9514 r = s.check()
9515 if r == unsat:
9516 print("proved")
9517 elif r == unknown:
9518 print("failed to prove")
9519 print(s.model())
9520 else:
9521 print("counterexample")
9522 print(s.model())
9523
9524
9525def _solve_html(*args, **keywords):
9526 """Version of function `solve` that renders HTML output."""
9527 show = keywords.pop("show", False)
9528 s = Solver()
9529 s.set(**keywords)
9530 s.add(*args)
9531 if show:
9532 print("<b>Problem:</b>")
9533 print(s)
9534 r = s.check()
9535 if r == unsat:
9536 print("<b>no solution</b>")
9537 elif r == unknown:
9538 print("<b>failed to solve</b>")
9539 try:
9540 print(s.model())
9541 except Z3Exception:
9542 return
9543 else:
9544 if show:
9545 print("<b>Solution:</b>")
9546 print(s.model())
9547
9548
9549def _solve_using_html(s, *args, **keywords):
9550 """Version of function `solve_using` that renders HTML."""
9551 show = keywords.pop("show", False)
9552 if z3_debug():
9553 _z3_assert(isinstance(s, Solver), "Solver object expected")
9554 s.set(**keywords)
9555 s.add(*args)
9556 if show:
9557 print("<b>Problem:</b>")
9558 print(s)
9559 r = s.check()
9560 if r == unsat:
9561 print("<b>no solution</b>")
9562 elif r == unknown:
9563 print("<b>failed to solve</b>")
9564 try:
9565 print(s.model())
9566 except Z3Exception:
9567 return
9568 else:
9569 if show:
9570 print("<b>Solution:</b>")
9571 print(s.model())
9572
9573
9574def _prove_html(claim, show=False, **keywords):
9575 """Version of function `prove` that renders HTML."""
9576 if z3_debug():
9577 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9578 s = Solver()
9579 s.set(**keywords)
9580 s.add(Not(claim))
9581 if show:
9582 print(s)
9583 r = s.check()
9584 if r == unsat:
9585 print("<b>proved</b>")
9586 elif r == unknown:
9587 print("<b>failed to prove</b>")
9588 print(s.model())
9589 else:
9590 print("<b>counterexample</b>")
9591 print(s.model())
9592
9593
9594def _dict2sarray(sorts, ctx):
9595 sz = len(sorts)
9596 _names = (Symbol * sz)()
9597 _sorts = (Sort * sz)()
9598 i = 0
9599 for k in sorts:
9600 v = sorts[k]
9601 if z3_debug():
9602 _z3_assert(isinstance(k, str), "String expected")
9603 _z3_assert(is_sort(v), "Z3 sort expected")
9604 _names[i] = to_symbol(k, ctx)
9605 _sorts[i] = v.ast
9606 i = i + 1
9607 return sz, _names, _sorts
9608
9609
9610def _dict2darray(decls, ctx):
9611 sz = len(decls)
9612 _names = (Symbol * sz)()
9613 _decls = (FuncDecl * sz)()
9614 i = 0
9615 for k in decls:
9616 v = decls[k]
9617 if z3_debug():
9618 _z3_assert(isinstance(k, str), "String expected")
9619 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9620 _names[i] = to_symbol(k, ctx)
9621 if is_const(v):
9622 _decls[i] = v.decl().ast
9623 else:
9624 _decls[i] = v.ast
9625 i = i + 1
9626 return sz, _names, _decls
9627
9628class ParserContext:
9629 def __init__(self, ctx= None):
9630 self.ctx = _get_ctx(ctx)
9631 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9632 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9633
9634 def __del__(self):
9635 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9636 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9637 self.pctx = None
9638
9639 def add_sort(self, sort):
9640 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9641
9642 def add_decl(self, decl):
9643 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9644
9645 def from_string(self, s):
9646 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9647
9648def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9649 """Parse a string in SMT 2.0 format using the given sorts and decls.
9650
9651 The arguments sorts and decls are Python dictionaries used to initialize
9652 the symbol table used for the SMT 2.0 parser.
9653
9654 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9655 [x > 0, x < 10]
9656 >>> x, y = Ints('x y')
9657 >>> f = Function('f', IntSort(), IntSort())
9658 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9659 [x + f(y) > 0]
9660 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9661 [a > 0]
9662 """
9663 ctx = _get_ctx(ctx)
9664 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9665 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9666 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9667
9668
9669def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9670 """Parse a file in SMT 2.0 format using the given sorts and decls.
9671
9672 This function is similar to parse_smt2_string().
9673 """
9674 ctx = _get_ctx(ctx)
9675 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9676 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9677 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9678
9679
9680#########################################
9681#
9682# Floating-Point Arithmetic
9683#
9684#########################################
9685
9686
9687# Global default rounding mode
9688_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9689_dflt_fpsort_ebits = 11
9690_dflt_fpsort_sbits = 53
9691
9692
9693def get_default_rounding_mode(ctx=None):
9694 """Retrieves the global default rounding mode."""
9695 global _dflt_rounding_mode
9696 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9697 return RTZ(ctx)
9698 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9699 return RTN(ctx)
9700 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9701 return RTP(ctx)
9702 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9703 return RNE(ctx)
9704 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9705 return RNA(ctx)
9706
9707
9708_ROUNDING_MODES = frozenset({
9709 Z3_OP_FPA_RM_TOWARD_ZERO,
9710 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9711 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9712 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9713 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9714})
9715
9716
9717def set_default_rounding_mode(rm, ctx=None):
9718 global _dflt_rounding_mode
9719 if is_fprm_value(rm):
9720 _dflt_rounding_mode = rm.kind()
9721 else:
9722 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9723 _dflt_rounding_mode = rm
9724
9725
9726def get_default_fp_sort(ctx=None):
9727 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9728
9729
9730def set_default_fp_sort(ebits, sbits, ctx=None):
9731 global _dflt_fpsort_ebits
9732 global _dflt_fpsort_sbits
9733 _dflt_fpsort_ebits = ebits
9734 _dflt_fpsort_sbits = sbits
9735
9736
9737def _dflt_rm(ctx=None):
9738 return get_default_rounding_mode(ctx)
9739
9740
9741def _dflt_fps(ctx=None):
9742 return get_default_fp_sort(ctx)
9743
9744
9745def _coerce_fp_expr_list(alist, ctx):
9746 first_fp_sort = None
9747 for a in alist:
9748 if is_fp(a):
9749 if first_fp_sort is None:
9750 first_fp_sort = a.sort()
9751 elif first_fp_sort == a.sort():
9752 pass # OK, same as before
9753 else:
9754 # we saw at least 2 different float sorts; something will
9755 # throw a sort mismatch later, for now assume None.
9756 first_fp_sort = None
9757 break
9758
9759 r = []
9760 for i in range(len(alist)):
9761 a = alist[i]
9762 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9763 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9764 r.append(FPVal(a, None, first_fp_sort, ctx))
9765 else:
9766 r.append(a)
9767 return _coerce_expr_list(r, ctx)
9768
9769
9770# FP Sorts
9771
9772class FPSortRef(SortRef):
9773 """Floating-point sort."""
9774
9775 def ebits(self):
9776 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9777 >>> b = FPSort(8, 24)
9778 >>> b.ebits()
9779 8
9780 """
9781 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9782
9783 def sbits(self):
9784 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9785 >>> b = FPSort(8, 24)
9786 >>> b.sbits()
9787 24
9788 """
9789 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9790
9791 def cast(self, val):
9792 """Try to cast `val` as a floating-point expression.
9793 >>> b = FPSort(8, 24)
9794 >>> b.cast(1.0)
9795 1
9796 >>> b.cast(1.0).sexpr()
9797 '(fp #b0 #x7f #b00000000000000000000000)'
9798 """
9799 if is_expr(val):
9800 if z3_debug():
9801 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9802 return val
9803 else:
9804 return FPVal(val, None, self, self.ctx)
9805
9806
9807def Float16(ctx=None):
9808 """Floating-point 16-bit (half) sort."""
9809 ctx = _get_ctx(ctx)
9810 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9811
9812
9813def FloatHalf(ctx=None):
9814 """Floating-point 16-bit (half) sort."""
9815 ctx = _get_ctx(ctx)
9816 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9817
9818
9819def Float32(ctx=None):
9820 """Floating-point 32-bit (single) sort."""
9821 ctx = _get_ctx(ctx)
9822 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9823
9824
9825def FloatSingle(ctx=None):
9826 """Floating-point 32-bit (single) sort."""
9827 ctx = _get_ctx(ctx)
9828 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9829
9830
9831def Float64(ctx=None):
9832 """Floating-point 64-bit (double) sort."""
9833 ctx = _get_ctx(ctx)
9834 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9835
9836
9837def FloatDouble(ctx=None):
9838 """Floating-point 64-bit (double) sort."""
9839 ctx = _get_ctx(ctx)
9840 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9841
9842
9843def Float128(ctx=None):
9844 """Floating-point 128-bit (quadruple) sort."""
9845 ctx = _get_ctx(ctx)
9846 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9847
9848
9849def FloatQuadruple(ctx=None):
9850 """Floating-point 128-bit (quadruple) sort."""
9851 ctx = _get_ctx(ctx)
9852 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9853
9854
9855class FPRMSortRef(SortRef):
9856 """"Floating-point rounding mode sort."""
9857
9858
9859def is_fp_sort(s):
9860 """Return True if `s` is a Z3 floating-point sort.
9861
9862 >>> is_fp_sort(FPSort(8, 24))
9863 True
9864 >>> is_fp_sort(IntSort())
9865 False
9866 """
9867 return isinstance(s, FPSortRef)
9868
9869
9870def is_fprm_sort(s):
9871 """Return True if `s` is a Z3 floating-point rounding mode sort.
9872
9873 >>> is_fprm_sort(FPSort(8, 24))
9874 False
9875 >>> is_fprm_sort(RNE().sort())
9876 True
9877 """
9878 return isinstance(s, FPRMSortRef)
9879
9880# FP Expressions
9881
9882
9883class FPRef(ExprRef):
9884 """Floating-point expressions."""
9885
9886 def sort(self):
9887 """Return the sort of the floating-point expression `self`.
9888
9889 >>> x = FP('1.0', FPSort(8, 24))
9890 >>> x.sort()
9891 FPSort(8, 24)
9892 >>> x.sort() == FPSort(8, 24)
9893 True
9894 """
9895 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9896
9897 def ebits(self):
9898 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9899 >>> b = FPSort(8, 24)
9900 >>> b.ebits()
9901 8
9902 """
9903 return self.sort().ebits()
9904
9905 def sbits(self):
9906 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9907 >>> b = FPSort(8, 24)
9908 >>> b.sbits()
9909 24
9910 """
9911 return self.sort().sbits()
9912
9913 def as_string(self):
9914 """Return a Z3 floating point expression as a Python string."""
9915 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9916
9917 def __le__(self, other):
9918 return fpLEQ(self, other, self.ctx)
9919
9920 def __lt__(self, other):
9921 return fpLT(self, other, self.ctx)
9922
9923 def __ge__(self, other):
9924 return fpGEQ(self, other, self.ctx)
9925
9926 def __gt__(self, other):
9927 return fpGT(self, other, self.ctx)
9928
9929 def __add__(self, other):
9930 """Create the Z3 expression `self + other`.
9931
9932 >>> x = FP('x', FPSort(8, 24))
9933 >>> y = FP('y', FPSort(8, 24))
9934 >>> x + y
9935 x + y
9936 >>> (x + y).sort()
9937 FPSort(8, 24)
9938 """
9939 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9940 return fpAdd(_dflt_rm(), a, b, self.ctx)
9941
9942 def __radd__(self, other):
9943 """Create the Z3 expression `other + self`.
9944
9945 >>> x = FP('x', FPSort(8, 24))
9946 >>> 10 + x
9947 1.25*(2**3) + x
9948 """
9949 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9950 return fpAdd(_dflt_rm(), a, b, self.ctx)
9951
9952 def __sub__(self, other):
9953 """Create the Z3 expression `self - other`.
9954
9955 >>> x = FP('x', FPSort(8, 24))
9956 >>> y = FP('y', FPSort(8, 24))
9957 >>> x - y
9958 x - y
9959 >>> (x - y).sort()
9960 FPSort(8, 24)
9961 """
9962 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9963 return fpSub(_dflt_rm(), a, b, self.ctx)
9964
9965 def __rsub__(self, other):
9966 """Create the Z3 expression `other - self`.
9967
9968 >>> x = FP('x', FPSort(8, 24))
9969 >>> 10 - x
9970 1.25*(2**3) - x
9971 """
9972 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9973 return fpSub(_dflt_rm(), a, b, self.ctx)
9974
9975 def __mul__(self, other):
9976 """Create the Z3 expression `self * other`.
9977
9978 >>> x = FP('x', FPSort(8, 24))
9979 >>> y = FP('y', FPSort(8, 24))
9980 >>> x * y
9981 x * y
9982 >>> (x * y).sort()
9983 FPSort(8, 24)
9984 >>> 10 * y
9985 1.25*(2**3) * y
9986 """
9987 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9988 return fpMul(_dflt_rm(), a, b, self.ctx)
9989
9990 def __rmul__(self, other):
9991 """Create the Z3 expression `other * self`.
9992
9993 >>> x = FP('x', FPSort(8, 24))
9994 >>> y = FP('y', FPSort(8, 24))
9995 >>> x * y
9996 x * y
9997 >>> x * 10
9998 x * 1.25*(2**3)
9999 """
10000 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10001 return fpMul(_dflt_rm(), a, b, self.ctx)
10002
10003 def __pos__(self):
10004 """Create the Z3 expression `+self`."""
10005 return self
10006
10007 def __neg__(self):
10008 """Create the Z3 expression `-self`.
10009
10010 >>> x = FP('x', Float32())
10011 >>> -x
10012 -x
10013 """
10014 return fpNeg(self)
10015
10016 def __div__(self, other):
10017 """Create the Z3 expression `self / other`.
10018
10019 >>> x = FP('x', FPSort(8, 24))
10020 >>> y = FP('y', FPSort(8, 24))
10021 >>> x / y
10022 x / y
10023 >>> (x / y).sort()
10024 FPSort(8, 24)
10025 >>> 10 / y
10026 1.25*(2**3) / y
10027 """
10028 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
10029 return fpDiv(_dflt_rm(), a, b, self.ctx)
10030
10031 def __rdiv__(self, other):
10032 """Create the Z3 expression `other / self`.
10033
10034 >>> x = FP('x', FPSort(8, 24))
10035 >>> y = FP('y', FPSort(8, 24))
10036 >>> x / y
10037 x / y
10038 >>> x / 10
10039 x / 1.25*(2**3)
10040 """
10041 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10042 return fpDiv(_dflt_rm(), a, b, self.ctx)
10043
10044 def __truediv__(self, other):
10045 """Create the Z3 expression division `self / other`."""
10046 return self.__div__(other)
10047
10048 def __rtruediv__(self, other):
10049 """Create the Z3 expression division `other / self`."""
10050 return self.__rdiv__(other)
10051
10052 def __mod__(self, other):
10053 """Create the Z3 expression mod `self % other`."""
10054 return fpRem(self, other)
10055
10056 def __rmod__(self, other):
10057 """Create the Z3 expression mod `other % self`."""
10058 return fpRem(other, self)
10059
10060
10061class FPRMRef(ExprRef):
10062 """Floating-point rounding mode expressions"""
10063
10064 def as_string(self):
10065 """Return a Z3 floating point expression as a Python string."""
10066 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10067
10068
10069def RoundNearestTiesToEven(ctx=None):
10070 ctx = _get_ctx(ctx)
10071 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10072
10073
10074def RNE(ctx=None):
10075 ctx = _get_ctx(ctx)
10076 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10077
10078
10079def RoundNearestTiesToAway(ctx=None):
10080 ctx = _get_ctx(ctx)
10081 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10082
10083
10084def RNA(ctx=None):
10085 ctx = _get_ctx(ctx)
10086 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10087
10088
10089def RoundTowardPositive(ctx=None):
10090 ctx = _get_ctx(ctx)
10091 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10092
10093
10094def RTP(ctx=None):
10095 ctx = _get_ctx(ctx)
10096 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10097
10098
10099def RoundTowardNegative(ctx=None):
10100 ctx = _get_ctx(ctx)
10101 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10102
10103
10104def RTN(ctx=None):
10105 ctx = _get_ctx(ctx)
10106 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10107
10108
10109def RoundTowardZero(ctx=None):
10110 ctx = _get_ctx(ctx)
10111 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10112
10113
10114def RTZ(ctx=None):
10115 ctx = _get_ctx(ctx)
10116 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10117
10118
10119def is_fprm(a):
10120 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
10121
10122 >>> rm = RNE()
10123 >>> is_fprm(rm)
10124 True
10125 >>> rm = 1.0
10126 >>> is_fprm(rm)
10127 False
10128 """
10129 return isinstance(a, FPRMRef)
10130
10131
10132def is_fprm_value(a):
10133 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
10134 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
10135
10136# FP Numerals
10137
10138
10139class FPNumRef(FPRef):
10140 """The sign of the numeral.
10141
10142 >>> x = FPVal(+1.0, FPSort(8, 24))
10143 >>> x.sign()
10144 False
10145 >>> x = FPVal(-1.0, FPSort(8, 24))
10146 >>> x.sign()
10147 True
10148 """
10149
10150 def sign(self):
10151 num = ctypes.c_bool()
10152 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
10153 if nsign is False:
10154 raise Z3Exception("error retrieving the sign of a numeral.")
10155 return num.value != 0
10156
10157 """The sign of a floating-point numeral as a bit-vector expression.
10158
10159 Remark: NaN's are invalid arguments.
10160 """
10161
10162 def sign_as_bv(self):
10163 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10164
10165 """The significand of the numeral.
10166
10167 >>> x = FPVal(2.5, FPSort(8, 24))
10168 >>> x.significand()
10169 1.25
10170 """
10171
10172 def significand(self):
10173 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10174
10175 """The significand of the numeral as a long.
10176
10177 >>> x = FPVal(2.5, FPSort(8, 24))
10178 >>> x.significand_as_long()
10179 1.25
10180 """
10181
10182 def significand_as_long(self):
10183 ptr = (ctypes.c_ulonglong * 1)()
10184 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10185 raise Z3Exception("error retrieving the significand of a numeral.")
10186 return ptr[0]
10187
10188 """The significand of the numeral as a bit-vector expression.
10189
10190 Remark: NaN are invalid arguments.
10191 """
10192
10193 def significand_as_bv(self):
10194 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10195
10196 """The exponent of the numeral.
10197
10198 >>> x = FPVal(2.5, FPSort(8, 24))
10199 >>> x.exponent()
10200 1
10201 """
10202
10203 def exponent(self, biased=True):
10204 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10205
10206 """The exponent of the numeral as a long.
10207
10208 >>> x = FPVal(2.5, FPSort(8, 24))
10209 >>> x.exponent_as_long()
10210 1
10211 """
10212
10213 def exponent_as_long(self, biased=True):
10214 ptr = (ctypes.c_longlong * 1)()
10215 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10216 raise Z3Exception("error retrieving the exponent of a numeral.")
10217 return ptr[0]
10218
10219 """The exponent of the numeral as a bit-vector expression.
10220
10221 Remark: NaNs are invalid arguments.
10222 """
10223
10224 def exponent_as_bv(self, biased=True):
10225 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10226
10227 """Indicates whether the numeral is a NaN."""
10228
10229 def isNaN(self):
10230 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10231
10232 """Indicates whether the numeral is +oo or -oo."""
10233
10234 def isInf(self):
10235 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10236
10237 """Indicates whether the numeral is +zero or -zero."""
10238
10239 def isZero(self):
10240 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10241
10242 """Indicates whether the numeral is normal."""
10243
10244 def isNormal(self):
10245 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10246
10247 """Indicates whether the numeral is subnormal."""
10248
10249 def isSubnormal(self):
10250 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10251
10252 """Indicates whether the numeral is positive."""
10253
10254 def isPositive(self):
10255 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10256
10257 """Indicates whether the numeral is negative."""
10258
10259 def isNegative(self):
10260 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10261
10262 """
10263 The string representation of the numeral.
10264
10265 >>> x = FPVal(20, FPSort(8, 24))
10266 >>> x.as_string()
10267 1.25*(2**4)
10268 """
10269
10270 def as_string(self):
10271 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10272 return ("FPVal(%s, %s)" % (s, self.sort()))
10273
10274 def py_value(self):
10275 bv = simplify(fpToIEEEBV(self))
10276 binary = bv.py_value()
10277 if not isinstance(binary, int):
10278 return None
10279 # Decode the IEEE 754 binary representation
10280 import struct
10281 bytes_rep = binary.to_bytes(8, byteorder='big')
10282 return struct.unpack('>d', bytes_rep)[0]
10283
10284
10285def is_fp(a):
10286 """Return `True` if `a` is a Z3 floating-point expression.
10287
10288 >>> b = FP('b', FPSort(8, 24))
10289 >>> is_fp(b)
10290 True
10291 >>> is_fp(b + 1.0)
10292 True
10293 >>> is_fp(Int('x'))
10294 False
10295 """
10296 return isinstance(a, FPRef)
10297
10298
10299def is_fp_value(a):
10300 """Return `True` if `a` is a Z3 floating-point numeral value.
10301
10302 >>> b = FP('b', FPSort(8, 24))
10303 >>> is_fp_value(b)
10304 False
10305 >>> b = FPVal(1.0, FPSort(8, 24))
10306 >>> b
10307 1
10308 >>> is_fp_value(b)
10309 True
10310 """
10311 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10312
10313
10314def FPSort(ebits, sbits, ctx=None):
10315 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10316
10317 >>> Single = FPSort(8, 24)
10318 >>> Double = FPSort(11, 53)
10319 >>> Single
10320 FPSort(8, 24)
10321 >>> x = Const('x', Single)
10322 >>> eq(x, FP('x', FPSort(8, 24)))
10323 True
10324 """
10325 ctx = _get_ctx(ctx)
10326 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10327
10328
10329def _to_float_str(val, exp=0):
10330 if isinstance(val, float):
10331 if math.isnan(val):
10332 res = "NaN"
10333 elif val == 0.0:
10334 sone = math.copysign(1.0, val)
10335 if sone < 0.0:
10336 return "-0.0"
10337 else:
10338 return "+0.0"
10339 elif val == float("+inf"):
10340 res = "+oo"
10341 elif val == float("-inf"):
10342 res = "-oo"
10343 else:
10344 v = val.as_integer_ratio()
10345 num = v[0]
10346 den = v[1]
10347 rvs = str(num) + "/" + str(den)
10348 res = rvs + "p" + _to_int_str(exp)
10349 elif isinstance(val, bool):
10350 if val:
10351 res = "1.0"
10352 else:
10353 res = "0.0"
10354 elif _is_int(val):
10355 res = str(val)
10356 elif isinstance(val, str):
10357 inx = val.find("*(2**")
10358 if inx == -1:
10359 res = val
10360 elif val[-1] == ")":
10361 res = val[0:inx]
10362 exp = str(int(val[inx + 5:-1]) + int(exp))
10363 else:
10364 _z3_assert(False, "String does not have floating-point numeral form.")
10365 elif z3_debug():
10366 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10367 if exp == 0:
10368 return res
10369 else:
10370 return res + "p" + exp
10371
10372
10373def fpNaN(s):
10374 """Create a Z3 floating-point NaN term.
10375
10376 >>> s = FPSort(8, 24)
10377 >>> set_fpa_pretty(True)
10378 >>> fpNaN(s)
10379 NaN
10380 >>> pb = get_fpa_pretty()
10381 >>> set_fpa_pretty(False)
10382 >>> fpNaN(s)
10383 fpNaN(FPSort(8, 24))
10384 >>> set_fpa_pretty(pb)
10385 """
10386 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10387 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10388
10389
10390def fpPlusInfinity(s):
10391 """Create a Z3 floating-point +oo term.
10392
10393 >>> s = FPSort(8, 24)
10394 >>> pb = get_fpa_pretty()
10395 >>> set_fpa_pretty(True)
10396 >>> fpPlusInfinity(s)
10397 +oo
10398 >>> set_fpa_pretty(False)
10399 >>> fpPlusInfinity(s)
10400 fpPlusInfinity(FPSort(8, 24))
10401 >>> set_fpa_pretty(pb)
10402 """
10403 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10404 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10405
10406
10407def fpMinusInfinity(s):
10408 """Create a Z3 floating-point -oo term."""
10409 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10410 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10411
10412
10413def fpInfinity(s, negative):
10414 """Create a Z3 floating-point +oo or -oo term."""
10415 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10416 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10417 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10418
10419
10420def fpPlusZero(s):
10421 """Create a Z3 floating-point +0.0 term."""
10422 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10423 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10424
10425
10426def fpMinusZero(s):
10427 """Create a Z3 floating-point -0.0 term."""
10428 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10429 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10430
10431
10432def fpZero(s, negative):
10433 """Create a Z3 floating-point +0.0 or -0.0 term."""
10434 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10435 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10436 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10437
10438
10439def FPVal(sig, exp=None, fps=None, ctx=None):
10440 """Return a floating-point value of value `val` and sort `fps`.
10441 If `ctx=None`, then the global context is used.
10442
10443 >>> v = FPVal(20.0, FPSort(8, 24))
10444 >>> v
10445 1.25*(2**4)
10446 >>> print("0x%.8x" % v.exponent_as_long(False))
10447 0x00000004
10448 >>> v = FPVal(2.25, FPSort(8, 24))
10449 >>> v
10450 1.125*(2**1)
10451 >>> v = FPVal(-2.25, FPSort(8, 24))
10452 >>> v
10453 -1.125*(2**1)
10454 >>> FPVal(-0.0, FPSort(8, 24))
10455 -0.0
10456 >>> FPVal(0.0, FPSort(8, 24))
10457 +0.0
10458 >>> FPVal(+0.0, FPSort(8, 24))
10459 +0.0
10460 """
10461 ctx = _get_ctx(ctx)
10462 if is_fp_sort(exp):
10463 fps = exp
10464 exp = None
10465 elif fps is None:
10466 fps = _dflt_fps(ctx)
10467 _z3_assert(is_fp_sort(fps), "sort mismatch")
10468 if exp is None:
10469 exp = 0
10470 val = _to_float_str(sig)
10471 if val == "NaN" or val == "nan":
10472 return fpNaN(fps)
10473 elif val == "-0.0":
10474 return fpMinusZero(fps)
10475 elif val == "0.0" or val == "+0.0":
10476 return fpPlusZero(fps)
10477 elif val == "+oo" or val == "+inf" or val == "+Inf":
10478 return fpPlusInfinity(fps)
10479 elif val == "-oo" or val == "-inf" or val == "-Inf":
10480 return fpMinusInfinity(fps)
10481 else:
10482 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10483
10484
10485def FP(name, fpsort, ctx=None):
10486 """Return a floating-point constant named `name`.
10487 `fpsort` is the floating-point sort.
10488 If `ctx=None`, then the global context is used.
10489
10490 >>> x = FP('x', FPSort(8, 24))
10491 >>> is_fp(x)
10492 True
10493 >>> x.ebits()
10494 8
10495 >>> x.sort()
10496 FPSort(8, 24)
10497 >>> word = FPSort(8, 24)
10498 >>> x2 = FP('x', word)
10499 >>> eq(x, x2)
10500 True
10501 """
10502 if isinstance(fpsort, FPSortRef) and ctx is None:
10503 ctx = fpsort.ctx
10504 else:
10505 ctx = _get_ctx(ctx)
10506 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10507
10508
10509def FPs(names, fpsort, ctx=None):
10510 """Return an array of floating-point constants.
10511
10512 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10513 >>> x.sort()
10514 FPSort(8, 24)
10515 >>> x.sbits()
10516 24
10517 >>> x.ebits()
10518 8
10519 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10520 (x + y) * z
10521 """
10522 ctx = _get_ctx(ctx)
10523 if isinstance(names, str):
10524 names = names.split(" ")
10525 return [FP(name, fpsort, ctx) for name in names]
10526
10527
10528def fpAbs(a, ctx=None):
10529 """Create a Z3 floating-point absolute value expression.
10530
10531 >>> s = FPSort(8, 24)
10532 >>> rm = RNE()
10533 >>> x = FPVal(1.0, s)
10534 >>> fpAbs(x)
10535 fpAbs(1)
10536 >>> y = FPVal(-20.0, s)
10537 >>> y
10538 -1.25*(2**4)
10539 >>> fpAbs(y)
10540 fpAbs(-1.25*(2**4))
10541 >>> fpAbs(-1.25*(2**4))
10542 fpAbs(-1.25*(2**4))
10543 >>> fpAbs(x).sort()
10544 FPSort(8, 24)
10545 """
10546 ctx = _get_ctx(ctx)
10547 [a] = _coerce_fp_expr_list([a], ctx)
10548 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10549
10550
10551def fpNeg(a, ctx=None):
10552 """Create a Z3 floating-point addition expression.
10553
10554 >>> s = FPSort(8, 24)
10555 >>> rm = RNE()
10556 >>> x = FP('x', s)
10557 >>> fpNeg(x)
10558 -x
10559 >>> fpNeg(x).sort()
10560 FPSort(8, 24)
10561 """
10562 ctx = _get_ctx(ctx)
10563 [a] = _coerce_fp_expr_list([a], ctx)
10564 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10565
10566
10567def _mk_fp_unary(f, rm, a, ctx):
10568 ctx = _get_ctx(ctx)
10569 [a] = _coerce_fp_expr_list([a], ctx)
10570 if z3_debug():
10571 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10572 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10573 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10574
10575
10576def _mk_fp_unary_pred(f, a, ctx):
10577 ctx = _get_ctx(ctx)
10578 [a] = _coerce_fp_expr_list([a], ctx)
10579 if z3_debug():
10580 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10581 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10582
10583
10584def _mk_fp_bin(f, rm, a, b, ctx):
10585 ctx = _get_ctx(ctx)
10586 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10587 if z3_debug():
10588 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10589 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10590 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10591
10592
10593def _mk_fp_bin_norm(f, a, b, ctx):
10594 ctx = _get_ctx(ctx)
10595 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10596 if z3_debug():
10597 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10598 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10599
10600
10601def _mk_fp_bin_pred(f, a, b, ctx):
10602 ctx = _get_ctx(ctx)
10603 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10604 if z3_debug():
10605 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10606 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10607
10608
10609def _mk_fp_tern(f, rm, a, b, c, ctx):
10610 ctx = _get_ctx(ctx)
10611 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10612 if z3_debug():
10613 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10614 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10615 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10616 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10617
10618
10619def fpAdd(rm, a, b, ctx=None):
10620 """Create a Z3 floating-point addition expression.
10621
10622 >>> s = FPSort(8, 24)
10623 >>> rm = RNE()
10624 >>> x = FP('x', s)
10625 >>> y = FP('y', s)
10626 >>> fpAdd(rm, x, y)
10627 x + y
10628 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10629 fpAdd(RTZ(), x, y)
10630 >>> fpAdd(rm, x, y).sort()
10631 FPSort(8, 24)
10632 """
10633 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10634
10635
10636def fpSub(rm, a, b, ctx=None):
10637 """Create a Z3 floating-point subtraction expression.
10638
10639 >>> s = FPSort(8, 24)
10640 >>> rm = RNE()
10641 >>> x = FP('x', s)
10642 >>> y = FP('y', s)
10643 >>> fpSub(rm, x, y)
10644 x - y
10645 >>> fpSub(rm, x, y).sort()
10646 FPSort(8, 24)
10647 """
10648 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10649
10650
10651def fpMul(rm, a, b, ctx=None):
10652 """Create a Z3 floating-point multiplication expression.
10653
10654 >>> s = FPSort(8, 24)
10655 >>> rm = RNE()
10656 >>> x = FP('x', s)
10657 >>> y = FP('y', s)
10658 >>> fpMul(rm, x, y)
10659 x * y
10660 >>> fpMul(rm, x, y).sort()
10661 FPSort(8, 24)
10662 """
10663 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10664
10665
10666def fpDiv(rm, a, b, ctx=None):
10667 """Create a Z3 floating-point division expression.
10668
10669 >>> s = FPSort(8, 24)
10670 >>> rm = RNE()
10671 >>> x = FP('x', s)
10672 >>> y = FP('y', s)
10673 >>> fpDiv(rm, x, y)
10674 x / y
10675 >>> fpDiv(rm, x, y).sort()
10676 FPSort(8, 24)
10677 """
10678 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10679
10680
10681def fpRem(a, b, ctx=None):
10682 """Create a Z3 floating-point remainder expression.
10683
10684 >>> s = FPSort(8, 24)
10685 >>> x = FP('x', s)
10686 >>> y = FP('y', s)
10687 >>> fpRem(x, y)
10688 fpRem(x, y)
10689 >>> fpRem(x, y).sort()
10690 FPSort(8, 24)
10691 """
10692 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10693
10694
10695def fpMin(a, b, ctx=None):
10696 """Create a Z3 floating-point minimum expression.
10697
10698 >>> s = FPSort(8, 24)
10699 >>> rm = RNE()
10700 >>> x = FP('x', s)
10701 >>> y = FP('y', s)
10702 >>> fpMin(x, y)
10703 fpMin(x, y)
10704 >>> fpMin(x, y).sort()
10705 FPSort(8, 24)
10706 """
10707 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10708
10709
10710def fpMax(a, b, ctx=None):
10711 """Create a Z3 floating-point maximum expression.
10712
10713 >>> s = FPSort(8, 24)
10714 >>> rm = RNE()
10715 >>> x = FP('x', s)
10716 >>> y = FP('y', s)
10717 >>> fpMax(x, y)
10718 fpMax(x, y)
10719 >>> fpMax(x, y).sort()
10720 FPSort(8, 24)
10721 """
10722 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10723
10724
10725def fpFMA(rm, a, b, c, ctx=None):
10726 """Create a Z3 floating-point fused multiply-add expression.
10727 """
10728 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10729
10730
10731def fpSqrt(rm, a, ctx=None):
10732 """Create a Z3 floating-point square root expression.
10733 """
10734 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10735
10736
10737def fpRoundToIntegral(rm, a, ctx=None):
10738 """Create a Z3 floating-point roundToIntegral expression.
10739 """
10740 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10741
10742
10743def fpIsNaN(a, ctx=None):
10744 """Create a Z3 floating-point isNaN expression.
10745
10746 >>> s = FPSort(8, 24)
10747 >>> x = FP('x', s)
10748 >>> y = FP('y', s)
10749 >>> fpIsNaN(x)
10750 fpIsNaN(x)
10751 """
10752 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10753
10754
10755def fpIsInf(a, ctx=None):
10756 """Create a Z3 floating-point isInfinite expression.
10757
10758 >>> s = FPSort(8, 24)
10759 >>> x = FP('x', s)
10760 >>> fpIsInf(x)
10761 fpIsInf(x)
10762 """
10763 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10764
10765
10766def fpIsZero(a, ctx=None):
10767 """Create a Z3 floating-point isZero expression.
10768 """
10769 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10770
10771
10772def fpIsNormal(a, ctx=None):
10773 """Create a Z3 floating-point isNormal expression.
10774 """
10775 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10776
10777
10778def fpIsSubnormal(a, ctx=None):
10779 """Create a Z3 floating-point isSubnormal expression.
10780 """
10781 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10782
10783
10784def fpIsNegative(a, ctx=None):
10785 """Create a Z3 floating-point isNegative expression.
10786 """
10787 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10788
10789
10790def fpIsPositive(a, ctx=None):
10791 """Create a Z3 floating-point isPositive expression.
10792 """
10793 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10794
10795
10796def _check_fp_args(a, b):
10797 if z3_debug():
10798 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10799
10800
10801def fpLT(a, b, ctx=None):
10802 """Create the Z3 floating-point expression `other < self`.
10803
10804 >>> x, y = FPs('x y', FPSort(8, 24))
10805 >>> fpLT(x, y)
10806 x < y
10807 >>> (x < y).sexpr()
10808 '(fp.lt x y)'
10809 """
10810 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10811
10812
10813def fpLEQ(a, b, ctx=None):
10814 """Create the Z3 floating-point expression `other <= self`.
10815
10816 >>> x, y = FPs('x y', FPSort(8, 24))
10817 >>> fpLEQ(x, y)
10818 x <= y
10819 >>> (x <= y).sexpr()
10820 '(fp.leq x y)'
10821 """
10822 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10823
10824
10825def fpGT(a, b, ctx=None):
10826 """Create the Z3 floating-point expression `other > self`.
10827
10828 >>> x, y = FPs('x y', FPSort(8, 24))
10829 >>> fpGT(x, y)
10830 x > y
10831 >>> (x > y).sexpr()
10832 '(fp.gt x y)'
10833 """
10834 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10835
10836
10837def fpGEQ(a, b, ctx=None):
10838 """Create the Z3 floating-point expression `other >= self`.
10839
10840 >>> x, y = FPs('x y', FPSort(8, 24))
10841 >>> fpGEQ(x, y)
10842 x >= y
10843 >>> (x >= y).sexpr()
10844 '(fp.geq x y)'
10845 """
10846 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10847
10848
10849def fpEQ(a, b, ctx=None):
10850 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10851
10852 >>> x, y = FPs('x y', FPSort(8, 24))
10853 >>> fpEQ(x, y)
10854 fpEQ(x, y)
10855 >>> fpEQ(x, y).sexpr()
10856 '(fp.eq x y)'
10857 """
10858 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10859
10860
10861def fpNEQ(a, b, ctx=None):
10862 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10863
10864 >>> x, y = FPs('x y', FPSort(8, 24))
10865 >>> fpNEQ(x, y)
10866 Not(fpEQ(x, y))
10867 >>> (x != y).sexpr()
10868 '(distinct x y)'
10869 """
10870 return Not(fpEQ(a, b, ctx))
10871
10872
10873def fpFP(sgn, exp, sig, ctx=None):
10874 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10875
10876 >>> s = FPSort(8, 24)
10877 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10878 >>> print(x)
10879 fpFP(1, 127, 4194304)
10880 >>> xv = FPVal(-1.5, s)
10881 >>> print(xv)
10882 -1.5
10883 >>> slvr = Solver()
10884 >>> slvr.add(fpEQ(x, xv))
10885 >>> slvr.check()
10886 sat
10887 >>> xv = FPVal(+1.5, s)
10888 >>> print(xv)
10889 1.5
10890 >>> slvr = Solver()
10891 >>> slvr.add(fpEQ(x, xv))
10892 >>> slvr.check()
10893 unsat
10894 """
10895 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10896 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10897 ctx = _get_ctx(ctx)
10898 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10899 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10900
10901
10902def fpToFP(a1, a2=None, a3=None, ctx=None):
10903 """Create a Z3 floating-point conversion expression from other term sorts
10904 to floating-point.
10905
10906 From a bit-vector term in IEEE 754-2008 format:
10907 >>> x = FPVal(1.0, Float32())
10908 >>> x_bv = fpToIEEEBV(x)
10909 >>> simplify(fpToFP(x_bv, Float32()))
10910 1
10911
10912 From a floating-point term with different precision:
10913 >>> x = FPVal(1.0, Float32())
10914 >>> x_db = fpToFP(RNE(), x, Float64())
10915 >>> x_db.sort()
10916 FPSort(11, 53)
10917
10918 From a real term:
10919 >>> x_r = RealVal(1.5)
10920 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10921 1.5
10922
10923 From a signed bit-vector term:
10924 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10925 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10926 -1.25*(2**2)
10927 """
10928 ctx = _get_ctx(ctx)
10929 if is_bv(a1) and is_fp_sort(a2):
10930 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10931 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10932 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10933 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10934 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10935 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10936 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10937 else:
10938 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10939
10940
10941def fpBVToFP(v, sort, ctx=None):
10942 """Create a Z3 floating-point conversion expression that represents the
10943 conversion from a bit-vector term to a floating-point term.
10944
10945 >>> x_bv = BitVecVal(0x3F800000, 32)
10946 >>> x_fp = fpBVToFP(x_bv, Float32())
10947 >>> x_fp
10948 fpToFP(1065353216)
10949 >>> simplify(x_fp)
10950 1
10951 """
10952 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10953 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10954 ctx = _get_ctx(ctx)
10955 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10956
10957
10958def fpFPToFP(rm, v, sort, ctx=None):
10959 """Create a Z3 floating-point conversion expression that represents the
10960 conversion from a floating-point term to a floating-point term of different precision.
10961
10962 >>> x_sgl = FPVal(1.0, Float32())
10963 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10964 >>> x_dbl
10965 fpToFP(RNE(), 1)
10966 >>> simplify(x_dbl)
10967 1
10968 >>> x_dbl.sort()
10969 FPSort(11, 53)
10970 """
10971 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10972 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10973 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10974 ctx = _get_ctx(ctx)
10975 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10976
10977
10978def fpRealToFP(rm, v, sort, ctx=None):
10979 """Create a Z3 floating-point conversion expression that represents the
10980 conversion from a real term to a floating-point term.
10981
10982 >>> x_r = RealVal(1.5)
10983 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10984 >>> x_fp
10985 fpToFP(RNE(), 3/2)
10986 >>> simplify(x_fp)
10987 1.5
10988 """
10989 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10990 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10991 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10992 ctx = _get_ctx(ctx)
10993 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10994
10995
10996def fpSignedToFP(rm, v, sort, ctx=None):
10997 """Create a Z3 floating-point conversion expression that represents the
10998 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10999
11000 >>> x_signed = BitVecVal(-5, BitVecSort(32))
11001 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
11002 >>> x_fp
11003 fpToFP(RNE(), 4294967291)
11004 >>> simplify(x_fp)
11005 -1.25*(2**2)
11006 """
11007 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11008 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
11009 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11010 ctx = _get_ctx(ctx)
11011 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11012
11013
11014def fpUnsignedToFP(rm, v, sort, ctx=None):
11015 """Create a Z3 floating-point conversion expression that represents the
11016 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
11017
11018 >>> x_signed = BitVecVal(-5, BitVecSort(32))
11019 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
11020 >>> x_fp
11021 fpToFPUnsigned(RNE(), 4294967291)
11022 >>> simplify(x_fp)
11023 1*(2**32)
11024 """
11025 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
11026 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
11027 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
11028 ctx = _get_ctx(ctx)
11029 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
11030
11031
11032def fpToFPUnsigned(rm, x, s, ctx=None):
11033 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
11034 if z3_debug():
11035 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11036 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
11037 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
11038 ctx = _get_ctx(ctx)
11039 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
11040
11041
11042def fpToSBV(rm, x, s, ctx=None):
11043 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
11044
11045 >>> x = FP('x', FPSort(8, 24))
11046 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
11047 >>> print(is_fp(x))
11048 True
11049 >>> print(is_bv(y))
11050 True
11051 >>> print(is_fp(y))
11052 False
11053 >>> print(is_bv(x))
11054 False
11055 """
11056 if z3_debug():
11057 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11058 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11059 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11060 ctx = _get_ctx(ctx)
11061 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11062
11063
11064def fpToUBV(rm, x, s, ctx=None):
11065 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
11066
11067 >>> x = FP('x', FPSort(8, 24))
11068 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
11069 >>> print(is_fp(x))
11070 True
11071 >>> print(is_bv(y))
11072 True
11073 >>> print(is_fp(y))
11074 False
11075 >>> print(is_bv(x))
11076 False
11077 """
11078 if z3_debug():
11079 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11080 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11081 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11082 ctx = _get_ctx(ctx)
11083 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11084
11085
11086def fpToReal(x, ctx=None):
11087 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
11088
11089 >>> x = FP('x', FPSort(8, 24))
11090 >>> y = fpToReal(x)
11091 >>> print(is_fp(x))
11092 True
11093 >>> print(is_real(y))
11094 True
11095 >>> print(is_fp(y))
11096 False
11097 >>> print(is_real(x))
11098 False
11099 """
11100 if z3_debug():
11101 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11102 ctx = _get_ctx(ctx)
11103 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
11104
11105
11106def fpToIEEEBV(x, ctx=None):
11107 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
11108
11109 The size of the resulting bit-vector is automatically determined.
11110
11111 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
11112 knows only one NaN and it will always produce the same bit-vector representation of
11113 that NaN.
11114
11115 >>> x = FP('x', FPSort(8, 24))
11116 >>> y = fpToIEEEBV(x)
11117 >>> print(is_fp(x))
11118 True
11119 >>> print(is_bv(y))
11120 True
11121 >>> print(is_fp(y))
11122 False
11123 >>> print(is_bv(x))
11124 False
11125 """
11126 if z3_debug():
11127 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11128 ctx = _get_ctx(ctx)
11129 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
11130
11131
11132#########################################
11133#
11134# Strings, Sequences and Regular expressions
11135#
11136#########################################
11137
11138class SeqSortRef(SortRef):
11139 """Sequence sort."""
11140
11141 def is_string(self):
11142 """Determine if sort is a string
11143 >>> s = StringSort()
11144 >>> s.is_string()
11145 True
11146 >>> s = SeqSort(IntSort())
11147 >>> s.is_string()
11148 False
11149 """
11150 return Z3_is_string_sort(self.ctx_ref(), self.ast)
11151
11152 def basis(self):
11153 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11154
11155class CharSortRef(SortRef):
11156 """Character sort."""
11157
11158
11159def StringSort(ctx=None):
11160 """Create a string sort
11161 >>> s = StringSort()
11162 >>> print(s)
11163 String
11164 """
11165 ctx = _get_ctx(ctx)
11166 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
11167
11168def CharSort(ctx=None):
11169 """Create a character sort
11170 >>> ch = CharSort()
11171 >>> print(ch)
11172 Char
11173 """
11174 ctx = _get_ctx(ctx)
11175 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11176
11177
11178def SeqSort(s):
11179 """Create a sequence sort over elements provided in the argument
11180 >>> s = SeqSort(IntSort())
11181 >>> s == Unit(IntVal(1)).sort()
11182 True
11183 """
11184 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11185
11186
11187class SeqRef(ExprRef):
11188 """Sequence expression."""
11189
11190 def sort(self):
11191 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11192
11193 def __add__(self, other):
11194 return Concat(self, other)
11195
11196 def __radd__(self, other):
11197 return Concat(other, self)
11198
11199 def __getitem__(self, i):
11200 if _is_int(i):
11201 i = IntVal(i, self.ctx)
11202 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11203
11204 def at(self, i):
11205 if _is_int(i):
11206 i = IntVal(i, self.ctx)
11207 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11208
11209 def is_string(self):
11210 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11211
11212 def is_string_value(self):
11213 return Z3_is_string(self.ctx_ref(), self.as_ast())
11214
11215 def as_string(self):
11216 """Return a string representation of sequence expression."""
11217 if self.is_string_value():
11218 string_length = ctypes.c_uint()
11219 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11220 return string_at(chars, size=string_length.value).decode("latin-1")
11221 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11222
11223 def py_value(self):
11224 return self.as_string()
11225
11226 def __le__(self, other):
11227 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11228
11229 def __lt__(self, other):
11230 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11231
11232 def __ge__(self, other):
11233 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11234
11235 def __gt__(self, other):
11236 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11237
11238
11239def _coerce_char(ch, ctx=None):
11240 if isinstance(ch, str):
11241 ctx = _get_ctx(ctx)
11242 ch = CharVal(ch, ctx)
11243 if not is_expr(ch):
11244 raise Z3Exception("Character expression expected")
11245 return ch
11246
11247class CharRef(ExprRef):
11248 """Character expression."""
11249
11250 def __le__(self, other):
11251 other = _coerce_char(other, self.ctx)
11252 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11253
11254 def to_int(self):
11255 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11256
11257 def to_bv(self):
11258 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11259
11260 def is_digit(self):
11261 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11262
11263
11264def CharVal(ch, ctx=None):
11265 ctx = _get_ctx(ctx)
11266 if isinstance(ch, str):
11267 ch = ord(ch)
11268 if not isinstance(ch, int):
11269 raise Z3Exception("character value should be an ordinal")
11270 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11271
11272def CharFromBv(bv):
11273 if not is_expr(bv):
11274 raise Z3Exception("Bit-vector expression needed")
11275 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11276
11277def CharToBv(ch, ctx=None):
11278 ch = _coerce_char(ch, ctx)
11279 return ch.to_bv()
11280
11281def CharToInt(ch, ctx=None):
11282 ch = _coerce_char(ch, ctx)
11283 return ch.to_int()
11284
11285def CharIsDigit(ch, ctx=None):
11286 ch = _coerce_char(ch, ctx)
11287 return ch.is_digit()
11288
11289def _coerce_seq(s, ctx=None):
11290 if isinstance(s, str):
11291 ctx = _get_ctx(ctx)
11292 s = StringVal(s, ctx)
11293 if not is_expr(s):
11294 raise Z3Exception("Non-expression passed as a sequence")
11295 if not is_seq(s):
11296 raise Z3Exception("Non-sequence passed as a sequence")
11297 return s
11298
11299
11300def _get_ctx2(a, b, ctx=None):
11301 if is_expr(a):
11302 return a.ctx
11303 if is_expr(b):
11304 return b.ctx
11305 if ctx is None:
11306 ctx = main_ctx()
11307 return ctx
11308
11309
11310def is_seq(a):
11311 """Return `True` if `a` is a Z3 sequence expression.
11312 >>> print (is_seq(Unit(IntVal(0))))
11313 True
11314 >>> print (is_seq(StringVal("abc")))
11315 True
11316 """
11317 return isinstance(a, SeqRef)
11318
11319
11320def is_string(a: Any) -> bool:
11321 """Return `True` if `a` is a Z3 string expression.
11322 >>> print (is_string(StringVal("ab")))
11323 True
11324 """
11325 return isinstance(a, SeqRef) and a.is_string()
11326
11327
11328def is_string_value(a: Any) -> bool:
11329 """return 'True' if 'a' is a Z3 string constant expression.
11330 >>> print (is_string_value(StringVal("a")))
11331 True
11332 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11333 False
11334 """
11335 return isinstance(a, SeqRef) and a.is_string_value()
11336
11337def StringVal(s, ctx=None):
11338 """create a string expression"""
11339 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11340 ctx = _get_ctx(ctx)
11341 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11342
11343
11344def String(name, ctx=None):
11345 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11346
11347 >>> x = String('x')
11348 """
11349 ctx = _get_ctx(ctx)
11350 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11351
11352
11353def Strings(names, ctx=None):
11354 """Return a tuple of String constants. """
11355 ctx = _get_ctx(ctx)
11356 if isinstance(names, str):
11357 names = names.split(" ")
11358 return [String(name, ctx) for name in names]
11359
11360
11361def SubString(s, offset, length):
11362 """Extract substring or subsequence starting at offset.
11363
11364 This is a convenience function that redirects to Extract(s, offset, length).
11365
11366 >>> s = StringVal("hello world")
11367 >>> SubString(s, 6, 5) # Extract "world"
11368 str.substr("hello world", 6, 5)
11369 >>> simplify(SubString(StringVal("hello"), 1, 3))
11370 "ell"
11371 """
11372 return Extract(s, offset, length)
11373
11374
11375def SubSeq(s, offset, length):
11376 """Extract substring or subsequence starting at offset.
11377
11378 This is a convenience function that redirects to Extract(s, offset, length).
11379
11380 >>> s = StringVal("hello world")
11381 >>> SubSeq(s, 0, 5) # Extract "hello"
11382 str.substr("hello world", 0, 5)
11383 >>> simplify(SubSeq(StringVal("testing"), 2, 4))
11384 "stin"
11385 """
11386 return Extract(s, offset, length)
11387
11388
11389def Empty(s):
11390 """Create the empty sequence of the given sort
11391 >>> e = Empty(StringSort())
11392 >>> e2 = StringVal("")
11393 >>> print(e.eq(e2))
11394 True
11395 >>> e3 = Empty(SeqSort(IntSort()))
11396 >>> print(e3)
11397 Empty(Seq(Int))
11398 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11399 >>> print(e4)
11400 Empty(ReSort(Seq(Int)))
11401 """
11402 if isinstance(s, SeqSortRef):
11403 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11404 if isinstance(s, ReSortRef):
11405 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11406 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11407
11408
11409def Full(s):
11410 """Create the regular expression that accepts the universal language
11411 >>> e = Full(ReSort(SeqSort(IntSort())))
11412 >>> print(e)
11413 Full(ReSort(Seq(Int)))
11414 >>> e1 = Full(ReSort(StringSort()))
11415 >>> print(e1)
11416 Full(ReSort(String))
11417 """
11418 if isinstance(s, ReSortRef):
11419 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11420 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11421
11422
11423
11424def Unit(a):
11425 """Create a singleton sequence"""
11426 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11427
11428
11429def PrefixOf(a, b):
11430 """Check if 'a' is a prefix of 'b'
11431 >>> s1 = PrefixOf("ab", "abc")
11432 >>> simplify(s1)
11433 True
11434 >>> s2 = PrefixOf("bc", "abc")
11435 >>> simplify(s2)
11436 False
11437 """
11438 ctx = _get_ctx2(a, b)
11439 a = _coerce_seq(a, ctx)
11440 b = _coerce_seq(b, ctx)
11441 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11442
11443
11444def SuffixOf(a, b):
11445 """Check if 'a' is a suffix of 'b'
11446 >>> s1 = SuffixOf("ab", "abc")
11447 >>> simplify(s1)
11448 False
11449 >>> s2 = SuffixOf("bc", "abc")
11450 >>> simplify(s2)
11451 True
11452 """
11453 ctx = _get_ctx2(a, b)
11454 a = _coerce_seq(a, ctx)
11455 b = _coerce_seq(b, ctx)
11456 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11457
11458
11459def Contains(a, b):
11460 """Check if 'a' contains 'b'
11461 >>> s1 = Contains("abc", "ab")
11462 >>> simplify(s1)
11463 True
11464 >>> s2 = Contains("abc", "bc")
11465 >>> simplify(s2)
11466 True
11467 >>> x, y, z = Strings('x y z')
11468 >>> s3 = Contains(Concat(x,y,z), y)
11469 >>> simplify(s3)
11470 True
11471 """
11472 ctx = _get_ctx2(a, b)
11473 a = _coerce_seq(a, ctx)
11474 b = _coerce_seq(b, ctx)
11475 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11476
11477
11478def Replace(s, src, dst):
11479 """Replace the first occurrence of 'src' by 'dst' in 's'
11480 >>> r = Replace("aaa", "a", "b")
11481 >>> simplify(r)
11482 "baa"
11483 """
11484 ctx = _get_ctx2(dst, s)
11485 if ctx is None and is_expr(src):
11486 ctx = src.ctx
11487 src = _coerce_seq(src, ctx)
11488 dst = _coerce_seq(dst, ctx)
11489 s = _coerce_seq(s, ctx)
11490 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11491
11492
11493def IndexOf(s, substr, offset=None):
11494 """Retrieve the index of substring within a string starting at a specified offset.
11495 >>> simplify(IndexOf("abcabc", "bc", 0))
11496 1
11497 >>> simplify(IndexOf("abcabc", "bc", 2))
11498 4
11499 """
11500 if offset is None:
11501 offset = IntVal(0)
11502 ctx = None
11503 if is_expr(offset):
11504 ctx = offset.ctx
11505 ctx = _get_ctx2(s, substr, ctx)
11506 s = _coerce_seq(s, ctx)
11507 substr = _coerce_seq(substr, ctx)
11508 if _is_int(offset):
11509 offset = IntVal(offset, ctx)
11510 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11511
11512
11513def LastIndexOf(s, substr):
11514 """Retrieve the last index of substring within a string"""
11515 ctx = None
11516 ctx = _get_ctx2(s, substr, ctx)
11517 s = _coerce_seq(s, ctx)
11518 substr = _coerce_seq(substr, ctx)
11519 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11520
11521
11522def Length(s):
11523 """Obtain the length of a sequence 's'
11524 >>> l = Length(StringVal("abc"))
11525 >>> simplify(l)
11526 3
11527 """
11528 s = _coerce_seq(s)
11529 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11530
11531def SeqMap(f, s):
11532 """Map function 'f' over sequence 's'"""
11533 ctx = _get_ctx2(f, s)
11534 s = _coerce_seq(s, ctx)
11535 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11536
11537def SeqMapI(f, i, s):
11538 """Map function 'f' over sequence 's' at index 'i'"""
11539 ctx = _get_ctx2(f, s)
11540 s = _coerce_seq(s, ctx)
11541 if not is_expr(i):
11542 i = _py2expr(i)
11543 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11544
11545def SeqFoldLeft(f, a, s):
11546 ctx = _get_ctx2(f, s)
11547 s = _coerce_seq(s, ctx)
11548 a = _py2expr(a)
11549 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11550
11551def SeqFoldLeftI(f, i, a, s):
11552 ctx = _get_ctx2(f, s)
11553 s = _coerce_seq(s, ctx)
11554 a = _py2expr(a)
11555 i = _py2expr(i)
11556 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11557
11558def StrToInt(s):
11559 """Convert string expression to integer
11560 >>> a = StrToInt("1")
11561 >>> simplify(1 == a)
11562 True
11563 >>> b = StrToInt("2")
11564 >>> simplify(1 == b)
11565 False
11566 >>> c = StrToInt(IntToStr(2))
11567 >>> simplify(1 == c)
11568 False
11569 """
11570 s = _coerce_seq(s)
11571 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11572
11573
11574def IntToStr(s):
11575 """Convert integer expression to string"""
11576 if not is_expr(s):
11577 s = _py2expr(s)
11578 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11579
11580
11581def StrToCode(s):
11582 """Convert a unit length string to integer code"""
11583 if not is_expr(s):
11584 s = _py2expr(s)
11585 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11586
11587def StrFromCode(c):
11588 """Convert code to a string"""
11589 if not is_expr(c):
11590 c = _py2expr(c)
11591 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11592
11593def Re(s, ctx=None):
11594 """The regular expression that accepts sequence 's'
11595 >>> s1 = Re("ab")
11596 >>> s2 = Re(StringVal("ab"))
11597 >>> s3 = Re(Unit(BoolVal(True)))
11598 """
11599 s = _coerce_seq(s, ctx)
11600 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11601
11602
11603# Regular expressions
11604
11605class ReSortRef(SortRef):
11606 """Regular expression sort."""
11607
11608 def basis(self):
11609 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11610
11611
11612def ReSort(s):
11613 if is_ast(s):
11614 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11615 if s is None or isinstance(s, Context):
11616 ctx = _get_ctx(s)
11617 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11618 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11619
11620
11621class ReRef(ExprRef):
11622 """Regular expressions."""
11623
11624 def __add__(self, other):
11625 return Union(self, other)
11626
11627
11628def is_re(s):
11629 return isinstance(s, ReRef)
11630
11631
11632def InRe(s, re):
11633 """Create regular expression membership test
11634 >>> re = Union(Re("a"),Re("b"))
11635 >>> print (simplify(InRe("a", re)))
11636 True
11637 >>> print (simplify(InRe("b", re)))
11638 True
11639 >>> print (simplify(InRe("c", re)))
11640 False
11641 """
11642 s = _coerce_seq(s, re.ctx)
11643 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11644
11645
11646def Union(*args):
11647 """Create union of regular expressions.
11648 >>> re = Union(Re("a"), Re("b"), Re("c"))
11649 >>> print (simplify(InRe("d", re)))
11650 False
11651 """
11652 args = _get_args(args)
11653 sz = len(args)
11654 if z3_debug():
11655 _z3_assert(sz > 0, "At least one argument expected.")
11656 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11657 if sz == 1:
11658 return args[0]
11659 ctx = args[0].ctx
11660 v = (Ast * sz)()
11661 for i in range(sz):
11662 v[i] = args[i].as_ast()
11663 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11664
11665
11666def Intersect(*args):
11667 """Create intersection of regular expressions.
11668 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11669 """
11670 args = _get_args(args)
11671 sz = len(args)
11672 if z3_debug():
11673 _z3_assert(sz > 0, "At least one argument expected.")
11674 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11675 if sz == 1:
11676 return args[0]
11677 ctx = args[0].ctx
11678 v = (Ast * sz)()
11679 for i in range(sz):
11680 v[i] = args[i].as_ast()
11681 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11682
11683
11684def Plus(re):
11685 """Create the regular expression accepting one or more repetitions of argument.
11686 >>> re = Plus(Re("a"))
11687 >>> print(simplify(InRe("aa", re)))
11688 True
11689 >>> print(simplify(InRe("ab", re)))
11690 False
11691 >>> print(simplify(InRe("", re)))
11692 False
11693 """
11694 if z3_debug():
11695 _z3_assert(is_expr(re), "expression expected")
11696 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11697
11698
11699def Option(re):
11700 """Create the regular expression that optionally accepts the argument.
11701 >>> re = Option(Re("a"))
11702 >>> print(simplify(InRe("a", re)))
11703 True
11704 >>> print(simplify(InRe("", re)))
11705 True
11706 >>> print(simplify(InRe("aa", re)))
11707 False
11708 """
11709 if z3_debug():
11710 _z3_assert(is_expr(re), "expression expected")
11711 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11712
11713
11714def Complement(re):
11715 """Create the complement regular expression."""
11716 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11717
11718
11719def Star(re):
11720 """Create the regular expression accepting zero or more repetitions of argument.
11721 >>> re = Star(Re("a"))
11722 >>> print(simplify(InRe("aa", re)))
11723 True
11724 >>> print(simplify(InRe("ab", re)))
11725 False
11726 >>> print(simplify(InRe("", re)))
11727 True
11728 """
11729 if z3_debug():
11730 _z3_assert(is_expr(re), "expression expected")
11731 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11732
11733
11734def Loop(re, lo, hi=0):
11735 """Create the regular expression accepting between a lower and upper bound repetitions
11736 >>> re = Loop(Re("a"), 1, 3)
11737 >>> print(simplify(InRe("aa", re)))
11738 True
11739 >>> print(simplify(InRe("aaaa", re)))
11740 False
11741 >>> print(simplify(InRe("", re)))
11742 False
11743 """
11744 if z3_debug():
11745 _z3_assert(is_expr(re), "expression expected")
11746 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11747
11748
11749def Range(lo, hi, ctx=None):
11750 """Create the range regular expression over two sequences of length 1
11751 >>> range = Range("a","z")
11752 >>> print(simplify(InRe("b", range)))
11753 True
11754 >>> print(simplify(InRe("bb", range)))
11755 False
11756 """
11757 lo = _coerce_seq(lo, ctx)
11758 hi = _coerce_seq(hi, ctx)
11759 if z3_debug():
11760 _z3_assert(is_expr(lo), "expression expected")
11761 _z3_assert(is_expr(hi), "expression expected")
11762 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11763
11764def Diff(a, b, ctx=None):
11765 """Create the difference regular expression
11766 """
11767 if z3_debug():
11768 _z3_assert(is_expr(a), "expression expected")
11769 _z3_assert(is_expr(b), "expression expected")
11770 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11771
11772def AllChar(regex_sort, ctx=None):
11773 """Create a regular expression that accepts all single character strings
11774 """
11775 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11776
11777# Special Relations
11778
11779
11780def PartialOrder(a, index):
11781 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11782
11783
11784def LinearOrder(a, index):
11785 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11786
11787
11788def TreeOrder(a, index):
11789 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11790
11791
11792def PiecewiseLinearOrder(a, index):
11793 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11794
11795
11796def TransitiveClosure(f):
11797 """Given a binary relation R, such that the two arguments have the same sort
11798 create the transitive closure relation R+.
11799 The transitive closure R+ is a new relation.
11800 """
11801 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11802
11803def to_Ast(ptr,):
11804 ast = Ast(ptr)
11805 super(ctypes.c_void_p, ast).__init__(ptr)
11806 return ast
11807
11808def to_ContextObj(ptr,):
11809 ctx = ContextObj(ptr)
11810 super(ctypes.c_void_p, ctx).__init__(ptr)
11811 return ctx
11812
11813def to_AstVectorObj(ptr,):
11814 v = AstVectorObj(ptr)
11815 super(ctypes.c_void_p, v).__init__(ptr)
11816 return v
11817
11818# NB. my-hacky-class only works for a single instance of OnClause
11819# it should be replaced with a proper correlation between OnClause
11820# and object references that can be passed over the FFI.
11821# for UserPropagator we use a global dictionary, which isn't great code.
11822
11823_my_hacky_class = None
11824def on_clause_eh(ctx, p, n, dep, clause):
11825 onc = _my_hacky_class
11826 p = _to_expr_ref(to_Ast(p), onc.ctx)
11827 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11828 deps = [dep[i] for i in range(n)]
11829 onc.on_clause(p, deps, clause)
11830
11831_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11832
11833class OnClause:
11834 def __init__(self, s, on_clause):
11835 self.s = s
11836 self.ctx = s.ctx
11837 self.on_clause = on_clause
11838 self.idx = 22
11839 global _my_hacky_class
11840 _my_hacky_class = self
11841 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11842
11843
11844class PropClosures:
11845 def __init__(self):
11846 self.bases = {}
11847 self.lock = None
11848
11849 def set_threaded(self):
11850 if self.lock is None:
11851 import threading
11852 self.lock = threading.Lock()
11853
11854 def get(self, ctx):
11855 if self.lock:
11856 with self.lock:
11857 r = self.bases[ctx]
11858 else:
11859 r = self.bases[ctx]
11860 return r
11861
11862 def set(self, ctx, r):
11863 if self.lock:
11864 with self.lock:
11865 self.bases[ctx] = r
11866 else:
11867 self.bases[ctx] = r
11868
11869 def insert(self, r):
11870 if self.lock:
11871 with self.lock:
11872 id = len(self.bases) + 3
11873 self.bases[id] = r
11874 else:
11875 id = len(self.bases) + 3
11876 self.bases[id] = r
11877 return id
11878
11879
11880_prop_closures = None
11881
11882
11883def ensure_prop_closures():
11884 global _prop_closures
11885 if _prop_closures is None:
11886 _prop_closures = PropClosures()
11887
11888
11889def user_prop_push(ctx, cb):
11890 prop = _prop_closures.get(ctx)
11891 prop.cb = cb
11892 prop.push()
11893
11894
11895def user_prop_pop(ctx, cb, num_scopes):
11896 prop = _prop_closures.get(ctx)
11897 prop.cb = cb
11898 prop.pop(num_scopes)
11899
11900
11901def user_prop_fresh(ctx, _new_ctx):
11902 _prop_closures.set_threaded()
11903 prop = _prop_closures.get(ctx)
11904 nctx = Context()
11905 Z3_del_context(nctx.ctx)
11906 new_ctx = to_ContextObj(_new_ctx)
11907 nctx.ctx = new_ctx
11908 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11909 nctx.owner = False
11910 new_prop = prop.fresh(nctx)
11911 _prop_closures.set(new_prop.id, new_prop)
11912 return new_prop.id
11913
11914
11915def user_prop_fixed(ctx, cb, id, value):
11916 prop = _prop_closures.get(ctx)
11917 old_cb = prop.cb
11918 prop.cb = cb
11919 id = _to_expr_ref(to_Ast(id), prop.ctx())
11920 value = _to_expr_ref(to_Ast(value), prop.ctx())
11921 prop.fixed(id, value)
11922 prop.cb = old_cb
11923
11924def user_prop_created(ctx, cb, id):
11925 prop = _prop_closures.get(ctx)
11926 old_cb = prop.cb
11927 prop.cb = cb
11928 id = _to_expr_ref(to_Ast(id), prop.ctx())
11929 prop.created(id)
11930 prop.cb = old_cb
11931
11932
11933def user_prop_final(ctx, cb):
11934 prop = _prop_closures.get(ctx)
11935 old_cb = prop.cb
11936 prop.cb = cb
11937 prop.final()
11938 prop.cb = old_cb
11939
11940def user_prop_eq(ctx, cb, x, y):
11941 prop = _prop_closures.get(ctx)
11942 old_cb = prop.cb
11943 prop.cb = cb
11944 x = _to_expr_ref(to_Ast(x), prop.ctx())
11945 y = _to_expr_ref(to_Ast(y), prop.ctx())
11946 prop.eq(x, y)
11947 prop.cb = old_cb
11948
11949def user_prop_diseq(ctx, cb, x, y):
11950 prop = _prop_closures.get(ctx)
11951 old_cb = prop.cb
11952 prop.cb = cb
11953 x = _to_expr_ref(to_Ast(x), prop.ctx())
11954 y = _to_expr_ref(to_Ast(y), prop.ctx())
11955 prop.diseq(x, y)
11956 prop.cb = old_cb
11957
11958def user_prop_decide(ctx, cb, t_ref, idx, phase):
11959 prop = _prop_closures.get(ctx)
11960 old_cb = prop.cb
11961 prop.cb = cb
11962 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11963 prop.decide(t, idx, phase)
11964 prop.cb = old_cb
11965
11966def user_prop_binding(ctx, cb, q_ref, inst_ref):
11967 prop = _prop_closures.get(ctx)
11968 old_cb = prop.cb
11969 prop.cb = cb
11970 q = _to_expr_ref(to_Ast(q_ref), prop.ctx())
11971 inst = _to_expr_ref(to_Ast(inst_ref), prop.ctx())
11972 r = prop.binding(q, inst)
11973 prop.cb = old_cb
11974 return r
11975
11976
11977_user_prop_push = Z3_push_eh(user_prop_push)
11978_user_prop_pop = Z3_pop_eh(user_prop_pop)
11979_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11980_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11981_user_prop_created = Z3_created_eh(user_prop_created)
11982_user_prop_final = Z3_final_eh(user_prop_final)
11983_user_prop_eq = Z3_eq_eh(user_prop_eq)
11984_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11985_user_prop_decide = Z3_decide_eh(user_prop_decide)
11986_user_prop_binding = Z3_on_binding_eh(user_prop_binding)
11987
11988
11989def PropagateFunction(name, *sig):
11990 """Create a function that gets tracked by user propagator.
11991 Every term headed by this function symbol is tracked.
11992 If a term is fixed and the fixed callback is registered a
11993 callback is invoked that the term headed by this function is fixed.
11994 """
11995 sig = _get_args(sig)
11996 if z3_debug():
11997 _z3_assert(len(sig) > 0, "At least two arguments expected")
11998 arity = len(sig) - 1
11999 rng = sig[arity]
12000 if z3_debug():
12001 _z3_assert(is_sort(rng), "Z3 sort expected")
12002 dom = (Sort * arity)()
12003 for i in range(arity):
12004 if z3_debug():
12005 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
12006 dom[i] = sig[i].ast
12007 ctx = rng.ctx
12008 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
12009
12010
12011
12012class UserPropagateBase:
12013
12014 #
12015 # Either solver is set or ctx is set.
12016 # Propagators that are created through callbacks
12017 # to "fresh" inherit the context of that is supplied
12018 # as argument to the callback.
12019 # This context should not be deleted. It is owned by the solver.
12020 #
12021 def __init__(self, s, ctx=None):
12022 assert s is None or ctx is None
12023 ensure_prop_closures()
12024 self.solver = s
12025 self._ctx = None
12026 self.fresh_ctx = None
12027 self.cb = None
12028 self.id = _prop_closures.insert(self)
12029 self.fixed = None
12030 self.final = None
12031 self.eq = None
12032 self.diseq = None
12033 self.decide = None
12034 self.created = None
12035 self.binding = None
12036 if ctx:
12037 self.fresh_ctx = ctx
12038 if s:
12039 Z3_solver_propagate_init(self.ctx_ref(),
12040 s.solver,
12041 ctypes.c_void_p(self.id),
12042 _user_prop_push,
12043 _user_prop_pop,
12044 _user_prop_fresh)
12045
12046 def __del__(self):
12047 if self._ctx:
12048 self._ctx.ctx = None
12049
12050 def ctx(self):
12051 if self.fresh_ctx:
12052 return self.fresh_ctx
12053 else:
12054 return self.solver.ctx
12055
12056 def ctx_ref(self):
12057 return self.ctx().ref()
12058
12059 def add_fixed(self, fixed):
12060 if self.fixed:
12061 raise Z3Exception("fixed callback already registered")
12062 if self._ctx:
12063 raise Z3Exception("context already initialized")
12064 if self.solver:
12065 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
12066 self.fixed = fixed
12067
12068 def add_created(self, created):
12069 if self.created:
12070 raise Z3Exception("created callback already registered")
12071 if self._ctx:
12072 raise Z3Exception("context already initialized")
12073 if self.solver:
12074 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
12075 self.created = created
12076
12077 def add_final(self, final):
12078 if self.final:
12079 raise Z3Exception("final callback already registered")
12080 if self._ctx:
12081 raise Z3Exception("context already initialized")
12082 if self.solver:
12083 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
12084 self.final = final
12085
12086 def add_eq(self, eq):
12087 if self.eq:
12088 raise Z3Exception("eq callback already registered")
12089 if self._ctx:
12090 raise Z3Exception("context already initialized")
12091 if self.solver:
12092 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
12093 self.eq = eq
12094
12095 def add_diseq(self, diseq):
12096 if self.diseq:
12097 raise Z3Exception("diseq callback already registered")
12098 if self._ctx:
12099 raise Z3Exception("context already initialized")
12100 if self.solver:
12101 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
12102 self.diseq = diseq
12103
12104 def add_decide(self, decide):
12105 if self.decide:
12106 raise Z3Exception("decide callback already registered")
12107 if self._ctx:
12108 raise Z3Exception("context already initialized")
12109 if self.solver:
12110 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
12111 self.decide = decide
12112
12113 def add_on_binding(self, binding):
12114 if self.binding:
12115 raise Z3Exception("binding callback already registered")
12116 if self._ctx:
12117 raise Z3Exception("context already initialized")
12118 if self.solver:
12119 Z3_solver_propagate_on_binding(self.ctx_ref(), self.solver.solver, _user_prop_binding)
12120 self.binding = binding
12121
12122 def push(self):
12123 raise Z3Exception("push needs to be overwritten")
12124
12125 def pop(self, num_scopes):
12126 raise Z3Exception("pop needs to be overwritten")
12127
12128 def fresh(self, new_ctx):
12129 raise Z3Exception("fresh needs to be overwritten")
12130
12131 def add(self, e):
12132 if self._ctx:
12133 raise Z3Exception("context already initialized")
12134 if self.solver:
12135 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
12136 else:
12137 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
12138
12139 #
12140 # Tell the solver to perform the next split on a given term
12141 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
12142 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
12143 #
12144 def next_split(self, t, idx, phase):
12145 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
12146
12147 #
12148 # Propagation can only be invoked as during a fixed or final callback.
12149 #
12150 def propagate(self, e, ids, eqs=[]):
12151 _ids, num_fixed = _to_ast_array(ids)
12152 num_eqs = len(eqs)
12153 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
12154 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
12155 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
12156 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
12157
12158 def conflict(self, deps = [], eqs = []):
12159 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3252
as_decimal(self, prec)
Definition z3py.py:3264
__rmod__(self, other)
Definition z3py.py:2723
__mod__(self, other)
Definition z3py.py:2708
__pow__(self, other)
Definition z3py.py:2632
__gt__(self, other)
Definition z3py.py:2781
__lt__(self, other)
Definition z3py.py:2768
__rtruediv__(self, other)
Definition z3py.py:2704
__rmul__(self, other)
Definition z3py.py:2599
__abs__(self)
Definition z3py.py:2807
__rsub__(self, other)
Definition z3py.py:2622
__add__(self, other)
Definition z3py.py:2561
__sub__(self, other)
Definition z3py.py:2609
is_real(self)
Definition z3py.py:2550
is_int(self)
Definition z3py.py:2536
__radd__(self, other)
Definition z3py.py:2574
__truediv__(self, other)
Definition z3py.py:2683
__le__(self, other)
Definition z3py.py:2755
__rpow__(self, other)
Definition z3py.py:2646
__pos__(self)
Definition z3py.py:2746
sort(self)
Definition z3py.py:2526
__mul__(self, other)
Definition z3py.py:2584
__rdiv__(self, other)
Definition z3py.py:2687
__ge__(self, other)
Definition z3py.py:2794
__neg__(self)
Definition z3py.py:2735
__div__(self, other)
Definition z3py.py:2660
Arithmetic.
Definition z3py.py:2431
subsort(self, other)
Definition z3py.py:2465
cast(self, val)
Definition z3py.py:2469
domain(self)
Definition z3py.py:4750
domain_n(self, i)
Definition z3py.py:4759
__getitem__(self, arg)
Definition z3py.py:4772
range(self)
Definition z3py.py:4763
sort(self)
Definition z3py.py:4741
default(self)
Definition z3py.py:4784
domain_n(self, i)
Definition z3py.py:4723
erase(self, k)
Definition z3py.py:6325
__deepcopy__(self, memo={})
Definition z3py.py:6262
__init__(self, m=None, ctx=None)
Definition z3py.py:6251
__repr__(self)
Definition z3py.py:6322
__len__(self)
Definition z3py.py:6269
keys(self)
Definition z3py.py:6354
__setitem__(self, k, v)
Definition z3py.py:6306
__contains__(self, key)
Definition z3py.py:6282
__del__(self)
Definition z3py.py:6265
__getitem__(self, key)
Definition z3py.py:6295
reset(self)
Definition z3py.py:6339
__deepcopy__(self, memo={})
Definition z3py.py:382
__nonzero__(self)
Definition z3py.py:397
as_ast(self)
Definition z3py.py:419
translate(self, target)
Definition z3py.py:448
__hash__(self)
Definition z3py.py:394
__init__(self, ast, ctx=None)
Definition z3py.py:372
__str__(self)
Definition z3py.py:385
ctx_ref(self)
Definition z3py.py:427
py_value(self)
Definition z3py.py:477
__repr__(self)
Definition z3py.py:388
get_id(self)
Definition z3py.py:423
hash(self)
Definition z3py.py:467
__eq__(self, other)
Definition z3py.py:391
eq(self, other)
Definition z3py.py:431
sexpr(self)
Definition z3py.py:410
__del__(self)
Definition z3py.py:377
__bool__(self)
Definition z3py.py:400
__copy__(self)
Definition z3py.py:464
__deepcopy__(self, memo={})
Definition z3py.py:6231
translate(self, other_ctx)
Definition z3py.py:6212
__repr__(self)
Definition z3py.py:6234
__len__(self)
Definition z3py.py:6104
__init__(self, v=None, ctx=None)
Definition z3py.py:6089
push(self, v)
Definition z3py.py:6164
__getitem__(self, i)
Definition z3py.py:6117
sexpr(self)
Definition z3py.py:6237
__del__(self)
Definition z3py.py:6100
__setitem__(self, i, v)
Definition z3py.py:6146
__contains__(self, item)
Definition z3py.py:6189
__copy__(self)
Definition z3py.py:6228
resize(self, sz)
Definition z3py.py:6176
as_binary_string(self)
Definition z3py.py:4102
as_signed_long(self)
Definition z3py.py:4076
as_string(self)
Definition z3py.py:4099
__and__(self, other)
Definition z3py.py:3766
__rmod__(self, other)
Definition z3py.py:3907
__rrshift__(self, other)
Definition z3py.py:4033
__mod__(self, other)
Definition z3py.py:3886
__or__(self, other)
Definition z3py.py:3743
__rlshift__(self, other)
Definition z3py.py:4047
__gt__(self, other)
Definition z3py.py:3957
__lt__(self, other)
Definition z3py.py:3941
__invert__(self)
Definition z3py.py:3832
__rtruediv__(self, other)
Definition z3py.py:3882
__rmul__(self, other)
Definition z3py.py:3710
__rxor__(self, other)
Definition z3py.py:3802
__ror__(self, other)
Definition z3py.py:3756
__rsub__(self, other)
Definition z3py.py:3733
__add__(self, other)
Definition z3py.py:3674
__sub__(self, other)
Definition z3py.py:3720
__radd__(self, other)
Definition z3py.py:3687
size(self)
Definition z3py.py:3663
__rand__(self, other)
Definition z3py.py:3779
__truediv__(self, other)
Definition z3py.py:3862
__le__(self, other)
Definition z3py.py:3925
__xor__(self, other)
Definition z3py.py:3789
__lshift__(self, other)
Definition z3py.py:4019
__pos__(self)
Definition z3py.py:3812
sort(self)
Definition z3py.py:3652
__mul__(self, other)
Definition z3py.py:3697
__rdiv__(self, other)
Definition z3py.py:3866
__ge__(self, other)
Definition z3py.py:3973
__neg__(self)
Definition z3py.py:3821
__rshift__(self, other)
Definition z3py.py:3989
__div__(self, other)
Definition z3py.py:3843
Bit-Vectors.
Definition z3py.py:3605
subsort(self, other)
Definition z3py.py:3617
cast(self, val)
Definition z3py.py:3620
__and__(self, other)
Definition z3py.py:1682
__or__(self, other)
Definition z3py.py:1685
__invert__(self)
Definition z3py.py:1691
__rmul__(self, other)
Definition z3py.py:1668
__add__(self, other)
Definition z3py.py:1660
py_value(self)
Definition z3py.py:1694
__radd__(self, other)
Definition z3py.py:1665
__xor__(self, other)
Definition z3py.py:1688
sort(self)
Definition z3py.py:1657
__mul__(self, other)
Definition z3py.py:1671
Booleans.
Definition z3py.py:1618
subsort(self, other)
Definition z3py.py:1644
is_bool(self)
Definition z3py.py:1650
cast(self, val)
Definition z3py.py:1621
__deepcopy__(self, memo={})
Definition z3py.py:7121
__eq__(self, other)
Definition z3py.py:7124
__ne__(self, other)
Definition z3py.py:7127
__init__(self, r)
Definition z3py.py:7118
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:5261
create(self)
Definition z3py.py:5300
__init__(self, name, ctx=None)
Definition z3py.py:5256
__repr__(self)
Definition z3py.py:5297
declare(self, name, *args)
Definition z3py.py:5276
declare_core(self, name, rec_name, *args)
Definition z3py.py:5266
update_field(self, field_accessor, new_value)
Definition z3py.py:5541
constructor(self, idx)
Definition z3py.py:5453
accessor(self, i, j)
Definition z3py.py:5500
num_constructors(self)
Definition z3py.py:5440
recognizer(self, idx)
Definition z3py.py:5472
Expressions.
Definition z3py.py:1018
update(self, *args)
Definition z3py.py:1174
as_ast(self)
Definition z3py.py:1029
__hash__(self)
Definition z3py.py:1075
kind(self)
Definition z3py.py:1115
children(self)
Definition z3py.py:1159
serialize(self)
Definition z3py.py:1201
get_id(self)
Definition z3py.py:1032
num_args(self)
Definition z3py.py:1122
__eq__(self, other)
Definition z3py.py:1058
__ne__(self, other)
Definition z3py.py:1079
from_string(self, s)
Definition z3py.py:1198
sort_kind(self)
Definition z3py.py:1047
arg(self, idx)
Definition z3py.py:1138
sort(self)
Definition z3py.py:1035
params(self)
Definition z3py.py:1097
decl(self)
Definition z3py.py:1100
Function Declarations.
Definition z3py.py:775
as_func_decl(self)
Definition z3py.py:789
domain(self, i)
Definition z3py.py:813
as_ast(self)
Definition z3py.py:783
__call__(self, *args)
Definition z3py.py:876
arity(self)
Definition z3py.py:803
get_id(self)
Definition z3py.py:786
range(self)
Definition z3py.py:825
params(self)
Definition z3py.py:848
Definition z3py.py:6373
__deepcopy__(self, memo={})
Definition z3py.py:6381
ctx
Definition z3py.py:6378
__repr__(self)
Definition z3py.py:6478
num_args(self)
Definition z3py.py:6388
entry
Definition z3py.py:6377
value(self)
Definition z3py.py:6437
__init__(self, entry, ctx)
Definition z3py.py:6376
__del__(self)
Definition z3py.py:6384
as_list(self)
Definition z3py.py:6459
arg_value(self, idx)
Definition z3py.py:6406
__deepcopy__(self, memo={})
Definition z3py.py:6576
translate(self, other_ctx)
Definition z3py.py:6568
arity(self)
Definition z3py.py:6534
__repr__(self)
Definition z3py.py:6596
num_entries(self)
Definition z3py.py:6518
__init__(self, f, ctx)
Definition z3py.py:6485
__del__(self)
Definition z3py.py:6491
as_list(self)
Definition z3py.py:6579
else_value(self)
Definition z3py.py:6495
entry(self, idx)
Definition z3py.py:6548
__copy__(self)
Definition z3py.py:6573
__deepcopy__(self, memo={})
Definition z3py.py:6034
get(self, i)
Definition z3py.py:5890
prec(self)
Definition z3py.py:5834
translate(self, target)
Definition z3py.py:6008
append(self, *args)
Definition z3py.py:5935
as_expr(self)
Definition z3py.py:6057
assert_exprs(self, *args)
Definition z3py.py:5920
__repr__(self)
Definition z3py.py:5997
__len__(self)
Definition z3py.py:5877
inconsistent(self)
Definition z3py.py:5816
dimacs(self, include_names=True)
Definition z3py.py:6004
__getitem__(self, arg)
Definition z3py.py:5903
size(self)
Definition z3py.py:5864
precision(self)
Definition z3py.py:5855
simplify(self, *arguments, **keywords)
Definition z3py.py:6037
sexpr(self)
Definition z3py.py:6000
add(self, *args)
Definition z3py.py:5957
__del__(self)
Definition z3py.py:5794
convert_model(self, model)
Definition z3py.py:5968
insert(self, *args)
Definition z3py.py:5946
depth(self)
Definition z3py.py:5798
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5784
__copy__(self)
Definition z3py.py:6031
as_binary_string(self)
Definition z3py.py:3137
py_value(self)
Definition z3py.py:3145
as_long(self)
Definition z3py.py:3116
as_string(self)
Definition z3py.py:3129
__deepcopy__(self, memo={})
Definition z3py.py:6944
eval(self, t, model_completion=False)
Definition z3py.py:6620
translate(self, target)
Definition z3py.py:6909
__getitem__(self, idx)
Definition z3py.py:6821
num_sorts(self)
Definition z3py.py:6746
get_universe(self, s)
Definition z3py.py:6801
get_sort(self, idx)
Definition z3py.py:6761
project(self, vars, fml)
Definition z3py.py:6917
__repr__(self)
Definition z3py.py:6613
__len__(self)
Definition z3py.py:6677
get_interp(self, decl)
Definition z3py.py:6694
__init__(self, m, ctx)
Definition z3py.py:6603
sexpr(self)
Definition z3py.py:6616
sorts(self)
Definition z3py.py:6784
__del__(self)
Definition z3py.py:6609
decls(self)
Definition z3py.py:6868
project_with_witness(self, vars, fml)
Definition z3py.py:6929
update_value(self, x, value)
Definition z3py.py:6887
evaluate(self, t, model_completion=False)
Definition z3py.py:6651
__copy__(self)
Definition z3py.py:6941
__deepcopy__(self, memo={})
Definition z3py.py:5728
__init__(self, descr, ctx=None)
Definition z3py.py:5722
get_kind(self, n)
Definition z3py.py:5750
get_documentation(self, n)
Definition z3py.py:5755
__getitem__(self, arg)
Definition z3py.py:5760
get_name(self, i)
Definition z3py.py:5745
Parameter Sets.
Definition z3py.py:5649
__deepcopy__(self, memo={})
Definition z3py.py:5663
validate(self, ds)
Definition z3py.py:5690
__repr__(self)
Definition z3py.py:5687
__init__(self, ctx=None, params=None)
Definition z3py.py:5655
set(self, name, val)
Definition z3py.py:5670
__del__(self)
Definition z3py.py:5666
Patterns.
Definition z3py.py:2054
as_ast(self)
Definition z3py.py:2059
get_id(self)
Definition z3py.py:2062
Quantifiers.
Definition z3py.py:2121
num_no_patterns(self)
Definition z3py.py:2239
no_pattern(self, idx)
Definition z3py.py:2243
num_patterns(self)
Definition z3py.py:2209
var_name(self, idx)
Definition z3py.py:2272
__getitem__(self, arg)
Definition z3py.py:2178
var_sort(self, idx)
Definition z3py.py:2288
pattern(self, idx)
Definition z3py.py:2221
numerator_as_long(self)
Definition z3py.py:3178
is_int_value(self)
Definition z3py.py:3208
as_fraction(self)
Definition z3py.py:3236
py_value(self)
Definition z3py.py:3245
numerator(self)
Definition z3py.py:3152
is_real(self)
Definition z3py.py:3205
as_long(self)
Definition z3py.py:3211
is_int(self)
Definition z3py.py:3202
denominator_as_long(self)
Definition z3py.py:3191
as_string(self)
Definition z3py.py:3227
denominator(self)
Definition z3py.py:3167
as_decimal(self, prec)
Definition z3py.py:3215
__init__(self, c, ctx)
Definition z3py.py:5320
__init__(self, c, ctx)
Definition z3py.py:5332
Strings, Sequences and Regular expressions.
Definition z3py.py:11138
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7165
assert_and_track(self, a, p)
Definition z3py.py:7334
num_scopes(self)
Definition z3py.py:7246
append(self, *args)
Definition z3py.py:7312
__iadd__(self, fml)
Definition z3py.py:7308
backtrack_level
Definition z3py.py:7168
pop(self, num=1)
Definition z3py.py:7224
import_model_converter(self, other)
Definition z3py.py:7412
assert_exprs(self, *args)
Definition z3py.py:7278
model(self)
Definition z3py.py:7393
set(self, *args, **keys)
Definition z3py.py:7189
__enter__(self)
Definition z3py.py:7182
add(self, *args)
Definition z3py.py:7297
__del__(self)
Definition z3py.py:7178
insert(self, *args)
Definition z3py.py:7323
check(self, *assumptions)
Definition z3py.py:7364
push(self)
Definition z3py.py:7202
__exit__(self, *exc_info)
Definition z3py.py:7186
reset(self)
Definition z3py.py:7264
subsort(self, other)
Definition z3py.py:616
as_ast(self)
Definition z3py.py:593
__hash__(self)
Definition z3py.py:677
kind(self)
Definition z3py.py:599
__gt__(self, other)
Definition z3py.py:673
get_id(self)
Definition z3py.py:596
__eq__(self, other)
Definition z3py.py:649
__ne__(self, other)
Definition z3py.py:662
cast(self, val)
Definition z3py.py:624
name(self)
Definition z3py.py:639
Statistics.
Definition z3py.py:6974
__deepcopy__(self, memo={})
Definition z3py.py:6982
__getattr__(self, name)
Definition z3py.py:7077
__getitem__(self, idx)
Definition z3py.py:7021
__init__(self, stats, ctx)
Definition z3py.py:6977
__repr__(self)
Definition z3py.py:6989
__len__(self)
Definition z3py.py:7007
__del__(self)
Definition z3py.py:6985
get_key_value(self, key)
Definition z3py.py:7057
subsort(self, other)
Definition z3py.py:751
cast(self, val)
Definition z3py.py:754
ASTs base class.
Definition z3py.py:355
_repr_html_(self)
Definition z3py.py:361
use_pp(self)
Definition z3py.py:358
Z3_ast Z3_API Z3_model_get_const_interp(Z3_context c, Z3_model m, Z3_func_decl a)
Return the interpretation (i.e., assignment) of constant a in the model m. Return NULL,...
Z3_sort Z3_API Z3_mk_int_sort(Z3_context c)
Create the integer type.
Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const *domain, Z3_sort range)
Create an array type with N arguments.
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 ...
Z3_ast Z3_API Z3_datatype_update_field(Z3_context c, Z3_func_decl field_access, Z3_ast t, Z3_ast value)
Update record field with a value.
unsigned Z3_API Z3_model_get_num_sorts(Z3_context c, Z3_model m)
Return the number of uninterpreted sorts that m assigns an interpretation to.
Z3_ast_vector Z3_API Z3_ast_vector_translate(Z3_context s, Z3_ast_vector v, Z3_context t)
Translate the AST vector v from context s into an AST vector in context t.
void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e)
Increment the reference counter of the given Z3_func_entry object.
Z3_ast Z3_API Z3_mk_fresh_const(Z3_context c, Z3_string prefix, Z3_sort ty)
Declare and create a fresh constant.
Z3_ast Z3_API Z3_mk_bvsub_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed subtraction of t1 and t2 does not overflow.
void Z3_API Z3_solver_push(Z3_context c, Z3_solver s)
Create a backtracking point.
Z3_ast Z3_API Z3_mk_bvsub_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise subtraction of t1 and t2 does not underflow.
Z3_goal Z3_API Z3_goal_translate(Z3_context source, Z3_goal g, Z3_context target)
Copy a goal g from the context source to the context target.
Z3_ast Z3_API Z3_mk_bvudiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned division.
Z3_string Z3_API Z3_ast_vector_to_string(Z3_context c, Z3_ast_vector v)
Convert AST vector into a string.
Z3_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:3283
RotateRight(a, b)
Definition z3py.py:4537
_symbol2py(ctx, s)
Definition z3py.py:140
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4187
BVSNegNoOverflow(a)
Definition z3py.py:4684
SetAdd(s, e)
Definition z3py.py:5149
SetSort(s)
Sets.
Definition z3py.py:5100
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1302
UGT(a, b)
Definition z3py.py:4408
is_probe(p)
Definition z3py.py:9040
SetDel(s, e)
Definition z3py.py:5160
bool is_le(Any a)
Definition z3py.py:3023
BoolSort(ctx=None)
Definition z3py.py:1824
is_bv_sort(s)
Definition z3py.py:3638
_ctx_from_ast_args(*args)
Definition z3py.py:542
RatVal(a, b, ctx=None)
Definition z3py.py:3375
_to_func_decl_ref(a, ctx)
Definition z3py.py:962
SetUnion(*args)
Definition z3py.py:5123
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5220
BitVec(name, bv, ctx=None)
Definition z3py.py:4204
EmptySet(s)
Definition z3py.py:5105
BVMulNoUnderflow(a, b)
Definition z3py.py:4698
CreateDatatypes(*ds)
Definition z3py.py:5341
is_func_decl(a)
Definition z3py.py:907
get_as_array_func(n)
Definition z3py.py:6961
Distinct(*args)
Definition z3py.py:1507
RecAddDefinition(f, args, body)
Definition z3py.py:984
ToInt(a)
Definition z3py.py:3538
Implies(a, b, ctx=None)
Definition z3py.py:1918
UGE(a, b)
Definition z3py.py:4390
Ext(a, b)
Definition z3py.py:5058
_to_ast_array(args)
Definition z3py.py:554
bool is_sort(Any s)
Definition z3py.py:682
_check_bv_args(a, b)
Definition z3py.py:4349
RealSort(ctx=None)
Definition z3py.py:3315
IsSubset(a, b)
Definition z3py.py:5203
DeclareTypeVar(name, ctx=None)
Definition z3py.py:758
_get_args_ast_list(args)
Definition z3py.py:168
bool is_to_real(Any a)
Definition z3py.py:3083
_to_ref_array(ref, args)
Definition z3py.py:562
get_map_func(a)
Definition z3py.py:4866
_z3_check_cint_overflow(n, name)
Definition z3py.py:118
bool is_and(Any a)
Definition z3py.py:1754
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5592
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1333
is_select(a)
Definition z3py.py:5069
SignExt(n, a)
Definition z3py.py:4553
Int(name, ctx=None)
Definition z3py.py:3408
Bools(names, ctx=None)
Definition z3py.py:1873
_probe_and(args, ctx)
Definition z3py.py:9107
Int2BV(a, num_bits)
Definition z3py.py:4163
Lambda(vs, body)
Definition z3py.py:2404
_to_param_value(val)
Definition z3py.py:178
FreshFunction(*sig)
Definition z3py.py:943
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3489
BVRedOr(a)
Definition z3py.py:4642
SRem(a, b)
Definition z3py.py:4468
SortRef _sort(Context ctx, Any a)
Definition z3py.py:726
set_option(*args, **kws)
Definition z3py.py:328
ExprRef RealVar(int idx, ctx=None)
Definition z3py.py:1590
bool is_sub(Any a)
Definition z3py.py:2970
is_bv(a)
Definition z3py.py:4111
SetDifference(a, b)
Definition z3py.py:5181
bool is_arith_sort(Any s)
Definition z3py.py:2507
BitVecs(names, bv, ctx=None)
Definition z3py.py:4228
_check_same_sort(a, b, ctx=None)
Definition z3py.py:1289
bool is_mod(Any a)
Definition z3py.py:3011
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1889
_has_probe(args)
Definition z3py.py:1974
IsMember(e, s)
Definition z3py.py:5192
get_param(name)
Definition z3py.py:334
BVAddNoUnderflow(a, b)
Definition z3py.py:4656
deserialize(st)
Definition z3py.py:1207
bool is_not(Any a)
Definition z3py.py:1790
Extract(high, low, a)
Definition z3py.py:4295
Function(name, *sig)
Definition z3py.py:920
get_version()
Definition z3py.py:100
FreshConst(sort, prefix="c")
Definition z3py.py:1567
ULT(a, b)
Definition z3py.py:4372
EnumSort(name, values, ctx=None)
Definition z3py.py:5616
bool is_is_int(Any a)
Definition z3py.py:3071
_to_int_str(val)
Definition z3py.py:3332
is_algebraic_value(a)
Definition z3py.py:2932
is_bv_value(a)
Definition z3py.py:4125
BVSDivNoOverflow(a, b)
Definition z3py.py:4677
bool is_eq(Any a)
Definition z3py.py:1802
Context main_ctx()
Definition z3py.py:266
SetIntersect(*args)
Definition z3py.py:5136
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9174
BV2Int(a, is_signed=False)
Definition z3py.py:4140
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3447
_to_ast_ref(a, ctx)
Definition z3py.py:570
_to_func_decl_array(args)
Definition z3py.py:546
disable_trace(msg)
Definition z3py.py:87
bool is_to_int(Any a)
Definition z3py.py:3098
is_map(a)
Definition z3py.py:4841
Context _get_ctx(ctx)
Definition z3py.py:287
Or(*args)
Definition z3py.py:2015
is_re(s)
Definition z3py.py:11628
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5695
bool is_idiv(Any a)
Definition z3py.py:2999
Consts(names, sort)
Definition z3py.py:1552
Cond(p, t1, t2, ctx=None)
Definition z3py.py:9157
_to_pattern(arg)
Definition z3py.py:2108
RealVarVector(int n, ctx=None)
Definition z3py.py:1600
is_arith(a)
Definition z3py.py:2819
bool is_true(Any a)
Definition z3py.py:1722
bool is_false(Any a)
Definition z3py.py:1740
bool is_int(a)
Definition z3py.py:2840
If(a, b, c, ctx=None)
Definition z3py.py:1484
bool eq(AstRef a, AstRef b)
Definition z3py.py:503
is_app_of(a, k)
Definition z3py.py:1471
is_app(a)
Definition z3py.py:1368
bool is_add(Any a)
Definition z3py.py:2946
z3_error_handler(c, e)
Definition z3py.py:184
None reset_params()
Definition z3py.py:322
Reals(names, ctx=None)
Definition z3py.py:3474
is_int_value(a)
Definition z3py.py:2886
set_param(*args, **kws)
Definition z3py.py:298
is_pattern(a)
Definition z3py.py:2066
_coerce_seq(s, ctx=None)
Definition z3py.py:11289
bool is_distinct(Any a)
Definition z3py.py:1812
bool is_lt(Any a)
Definition z3py.py:3035
ULE(a, b)
Definition z3py.py:4354
is_real(a)
Definition z3py.py:2859
Abs(arg)
Definition z3py.py:9335
FullSet(s)
Definition z3py.py:5114
to_symbol(s, ctx=None)
Definition z3py.py:132
bool is_mul(Any a)
Definition z3py.py:2958
bool is_ast(Any a)
Definition z3py.py:482
_get_args(args)
Definition z3py.py:152
And(*args)
Definition z3py.py:1982
RepeatBitVec(n, a)
Definition z3py.py:4611
get_version_string()
Definition z3py.py:91
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3504
Array(name, *sorts)
Definition z3py.py:4923
Concat(*args)
Definition z3py.py:4249
_reduce(func, sequence, initial)
Definition z3py.py:1326
_is_algebraic(ctx, a)
Definition z3py.py:2882
Ints(names, ctx=None)
Definition z3py.py:3421
Select(a, *args)
Definition z3py.py:4997
Const(name, sort)
Definition z3py.py:1540
is_array_sort(a)
Definition z3py.py:4797
bool is_div(Any a)
Definition z3py.py:2982
ExprRef Var(int idx, SortRef s)
Definition z3py.py:1575
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4649
Real(name, ctx=None)
Definition z3py.py:3461
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1904
BitVecSort(sz, ctx=None)
Definition z3py.py:4172
open_log(fname)
Definition z3py.py:122
RecFunction(name, *sig)
Definition z3py.py:966
bool is_ge(Any a)
Definition z3py.py:3047
Model(ctx=None, eval={})
Definition z3py.py:6948
BVSubNoOverflow(a, b)
Definition z3py.py:4663
bool is_gt(Any a)
Definition z3py.py:3059
is_default(a)
Definition z3py.py:4857
is_K(a)
Definition z3py.py:4828
Bool(name, ctx=None)
Definition z3py.py:1861
_is_int(v)
Definition z3py.py:76
is_const_array(a)
Definition z3py.py:4815
Sqrt(a, ctx=None)
Definition z3py.py:3573
Default(a)
Definition z3py.py:4969
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:528
SetComplement(s)
Definition z3py.py:5171
is_as_array(n)
Definition z3py.py:6956
is_store(a)
Definition z3py.py:5082
bool is_or(Any a)
Definition z3py.py:1766
is_quantifier(a)
Definition z3py.py:2316
_mk_bin(f, a, b)
Definition z3py.py:1531
K(dom, v)
Definition z3py.py:5036
Xor(a, b, ctx=None)
Definition z3py.py:1932
Store(a, *args)
Definition z3py.py:4980
bool is_array(Any a)
Definition z3py.py:4801
mk_not(a)
Definition z3py.py:1967
is_expr(a)
Definition z3py.py:1345
_array_select(ar, arg)
Definition z3py.py:4788
is_const(a)
Definition z3py.py:1394
BoolVal(val, ctx=None)
Definition z3py.py:1842
RealVal(val, ctx=None)
Definition z3py.py:3356
bool is_implies(Any a)
Definition z3py.py:1778
z3_debug()
Definition z3py.py:70
get_full_version()
Definition z3py.py:109
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3434
_coerce_expr_merge(s, a)
Definition z3py.py:1271
Context get_ctx(ctx)
Definition z3py.py:294
LShR(a, b)
Definition z3py.py:4489
ArraySort(*sig)
Definition z3py.py:4890
Map(f, *args)
Definition z3py.py:5013
is_rational_value(a)
Definition z3py.py:2910
_probe_or(args, ctx)
Definition z3py.py:9111
BVRedAnd(a)
Definition z3py.py:4635
Cbrt(a, ctx=None)
Definition z3py.py:3586
_to_expr_ref(a, ctx)
Definition z3py.py:1221
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5604
IntSort(ctx=None)
Definition z3py.py:3298
is_seq(a)
Definition z3py.py:11310
Not(a, ctx=None)
Definition z3py.py:1948
_to_sort_ref(s, ctx)
Definition z3py.py:695
enable_trace(msg)
Definition z3py.py:83
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2383
ToReal(a)
Definition z3py.py:3518
URem(a, b)
Definition z3py.py:4447
bool is_bool(Any a)
Definition z3py.py:1704
StringVal(s, ctx=None)
Definition z3py.py:11337
IsInt(a)
Definition z3py.py:3556
_is_numeral(ctx, a)
Definition z3py.py:2878
MultiPattern(*args)
Definition z3py.py:2084
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2365
ZeroExt(n, a)
Definition z3py.py:4583
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:586
int _ast_kind(Context ctx, Any a)
Definition z3py.py:522
DatatypeSort(name, params=None, ctx=None)
Definition z3py.py:5567
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4670
UDiv(a, b)
Definition z3py.py:4426
Q(a, b, ctx=None)
Definition z3py.py:3395
Update(a, *args)
Definition z3py.py:4937
get_var_index(a)
Definition z3py.py:1438
append_log(s)
Definition z3py.py:127
is_var(a)
Definition z3py.py:1413
SortRef DeclareSort(name, ctx=None)
Definition z3py.py:730
IntVal(val, ctx=None)
Definition z3py.py:3344
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4691
RotateLeft(a, b)
Definition z3py.py:4521
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2330
_z3_assert(cond, msg)
Definition z3py.py:113