Z3
Loading...
Searching...
No Matches
z3py.py
Go to the documentation of this file.
8
9"""Z3 is a high performance theorem prover developed at Microsoft Research.
10
11Z3 is used in many applications such as: software/hardware verification and testing,
12constraint solving, analysis of hybrid systems, security, biology (in silico analysis),
13and geometrical problems.
14
15
16Please send feedback, comments and/or corrections on the Issue tracker for
17https://github.com/Z3prover/z3.git. Your comments are very valuable.
18
19Small example:
20
21>>> x = Int('x')
22>>> y = Int('y')
23>>> s = Solver()
24>>> s.add(x > 0)
25>>> s.add(x < 2)
26>>> s.add(y == x + 1)
27>>> s.check()
28sat
29>>> m = s.model()
30>>> m[x]
311
32>>> m[y]
332
34
35Z3 exceptions:
36
37>>> try:
38... x = BitVec('x', 32)
39... y = Bool('y')
40... # the expression x + y is type incorrect
41... n = x + y
42... except Z3Exception as ex:
43... print("failed: %s" % ex)
44failed: sort mismatch
45"""
46from . import z3core
47from .z3core import *
48from .z3types import *
49from .z3consts import *
50from .z3printer import *
51from fractions import Fraction
52import sys
53import io
54import math
55import copy
56if sys.version_info.major >= 3:
57 from typing import Iterable, Iterator
58
59from collections.abc import Callable
60from typing import (
61 Any,
62 Iterable,
63 Sequence
64)
65
66
67Z3_DEBUG = __debug__
68
69
71 global Z3_DEBUG
72 return Z3_DEBUG
73
74
75if sys.version_info.major < 3:
76 def _is_int(v):
77 return isinstance(v, (int, long))
78else:
79 def _is_int(v):
80 return isinstance(v, int)
81
82
83def enable_trace(msg):
85
86
89
90
92 major = ctypes.c_uint(0)
93 minor = ctypes.c_uint(0)
94 build = ctypes.c_uint(0)
95 rev = ctypes.c_uint(0)
96 Z3_get_version(major, minor, build, rev)
97 return "%s.%s.%s" % (major.value, minor.value, build.value)
98
99
101 major = ctypes.c_uint(0)
102 minor = ctypes.c_uint(0)
103 build = ctypes.c_uint(0)
104 rev = ctypes.c_uint(0)
105 Z3_get_version(major, minor, build, rev)
106 return (major.value, minor.value, build.value, rev.value)
107
108
110 return Z3_get_full_version()
111
112
113def _z3_assert(cond, msg):
114 if not cond:
115 raise Z3Exception(msg)
116
117
119 _z3_assert(ctypes.c_int(n).value == n, name + " is too large")
120
121
122def open_log(fname):
123 """Log interaction to a file. This function must be invoked immediately after init(). """
124 Z3_open_log(fname)
125
126
128 """Append user-defined string to interaction log. """
130
131
132def to_symbol(s, ctx = None):
133 """Convert an integer or string into a Z3 symbol."""
134 if _is_int(s):
135 return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
136 else:
137 return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
138
139
140def _symbol2py(ctx, s):
141 """Convert a Z3 symbol back into a Python object. """
142 if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
143 return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
144 else:
145 return Z3_get_symbol_string(ctx.ref(), s)
146
147# Hack for having nary functions that can receive one argument that is the
148# list of arguments.
149# Use this when function takes a single list of arguments
150
151
152def _get_args(args):
153 try:
154 if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
155 return args[0]
156 elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)):
157 return [arg for arg in args[0]]
158 elif len(args) == 1 and isinstance(args[0], Iterator):
159 return list(args[0])
160 else:
161 return args
162 except TypeError: # len is not necessarily defined when args is not a sequence (use reflection?)
163 return args
164
165# Use this when function takes multiple arguments
166
167
169 try:
170 if isinstance(args, (set, AstVector, tuple)):
171 return [arg for arg in args]
172 else:
173 return args
174 except Exception:
175 return args
176
177
179 if isinstance(val, bool):
180 return "true" if val else "false"
181 return str(val)
182
183
185 # Do nothing error handler, just avoid exit(0)
186 # The wrappers in z3core.py will raise a Z3Exception if an error is detected
187 return
188
189
190class Context:
191 """A Context manages all other Z3 objects, global configuration options, etc.
192
193 Z3Py uses a default global context. For most applications this is sufficient.
194 An application may use multiple Z3 contexts. Objects created in one context
195 cannot be used in another one. However, several objects may be "translated" from
196 one context to another. It is not safe to access Z3 objects from multiple threads.
197 The only exception is the method `interrupt()` that can be used to interrupt() a long
198 computation.
199 The initialization method receives global configuration options for the new context.
200 """
201
202 def __init__(self, *args, **kws):
203 if z3_debug():
204 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
205 conf = Z3_mk_config()
206 for key in kws:
207 value = kws[key]
208 Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
209 prev = None
210 for a in args:
211 if prev is None:
212 prev = a
213 else:
214 Z3_set_param_value(conf, str(prev), _to_param_value(a))
215 prev = None
217 self.owner = True
218 self.eh = Z3_set_error_handler(self.ctx, z3_error_handler)
219 Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
220 Z3_del_config(conf)
221
222 def __del__(self):
223 if Z3_del_context is not None and self.owner:
224 Z3_del_context(self.ctx)
225 self.ctx = None
226 self.eh = None
227
228 def ref(self):
229 """Return a reference to the actual C pointer to the Z3 context."""
230 return self.ctx
231
232 def interrupt(self):
233 """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
234
235 This method can be invoked from a thread different from the one executing the
236 interruptible procedure.
237 """
238 Z3_interrupt(self.ref())
239
240 def param_descrs(self):
241 """Return the global parameter description set."""
242 return ParamDescrsRef(Z3_get_global_param_descrs(self.ref()), self)
243
244 def set_ast_print_mode(self, mode):
245 """Set the pretty printing mode for ASTs.
246
247 The following modes are available:
248 - Z3_PRINT_SMTLIB_FULL (0): Print AST nodes in SMTLIB verbose format.
249 - Z3_PRINT_LOW_LEVEL (1): Print AST nodes using a low-level format.
250 - Z3_PRINT_SMTLIB2_COMPLIANT (2): Print AST nodes in SMTLIB 2.x compliant format.
251
252 Example:
253 >>> c = Context()
254 >>> x = Int('x', c)
255 >>> c.set_ast_print_mode(Z3_PRINT_SMTLIB2_COMPLIANT)
256 >>> print(x)
257 x
258 """
259 Z3_set_ast_print_mode(self.ref(), mode)
260
261
262# Global Z3 context
263_main_ctx = None
264
265
266def main_ctx() -> Context:
267 """Return a reference to the global Z3 context.
268
269 >>> x = Real('x')
270 >>> x.ctx == main_ctx()
271 True
272 >>> c = Context()
273 >>> c == main_ctx()
274 False
275 >>> x2 = Real('x', c)
276 >>> x2.ctx == c
277 True
278 >>> eq(x, x2)
279 False
280 """
281 global _main_ctx
282 if _main_ctx is None:
283 _main_ctx = Context()
284 return _main_ctx
285
286
287def _get_ctx(ctx) -> Context:
288 if ctx is None:
289 return main_ctx()
290 else:
291 return ctx
292
293
294def get_ctx(ctx) -> Context:
295 return _get_ctx(ctx)
296
297
298def set_param(*args, **kws):
299 """Set Z3 global (or module) parameters.
300
301 >>> set_param(precision=10)
302 """
303 if z3_debug():
304 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
305 new_kws = {}
306 for k in kws:
307 v = kws[k]
308 if not set_pp_option(k, v):
309 new_kws[k] = v
310 for key in new_kws:
311 value = new_kws[key]
312 Z3_global_param_set(str(key).upper(), _to_param_value(value))
313 prev = None
314 for a in args:
315 if prev is None:
316 prev = a
317 else:
319 prev = None
320
321
322def reset_params() -> None:
323 """Reset all global (or module) parameters.
324 """
326
327
328def set_option(*args, **kws):
329 """Alias for 'set_param' for backward compatibility.
330 """
331 return set_param(*args, **kws)
332
333
334def get_param(name):
335 """Return the value of a Z3 global (or module) parameter
336
337 >>> get_param('nlsat.reorder')
338 'true'
339 """
340 ptr = (ctypes.c_char_p * 1)()
341 if Z3_global_param_get(str(name), ptr):
342 r = z3core._to_pystr(ptr[0])
343 return r
344 raise Z3Exception("failed to retrieve value for '%s'" % name)
345
346
351
352# Mark objects that use pretty printer
353
354
356 """Superclass for all Z3 objects that have support for pretty printing."""
357
358 def use_pp(self):
359 return True
360
361 def _repr_html_(self):
362 in_html = in_html_mode()
363 set_html_mode(True)
364 res = repr(self)
365 set_html_mode(in_html)
366 return res
367
368
370 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
371
372 def __init__(self, ast, ctx=None):
373 self.ast = ast
374 self.ctx = _get_ctx(ctx)
375 Z3_inc_ref(self.ctx.ref(), self.as_ast())
376
377 def __del__(self):
378 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
379 Z3_dec_ref(self.ctx.ref(), self.as_ast())
380 self.ast = None
381
382 def __deepcopy__(self, memo={}):
383 return _to_ast_ref(self.ast, self.ctx)
384
385 def __str__(self):
386 return obj_to_string(self)
387
388 def __repr__(self):
389 return obj_to_string(self)
390
391 def __eq__(self, other):
392 return self.eq(other)
393
394 def __hash__(self):
395 return self.hash()
396
397 def __nonzero__(self):
398 return self.__bool__()
399
400 def __bool__(self):
401 if is_true(self):
402 return True
403 elif is_false(self):
404 return False
405 elif is_eq(self) and self.num_args() == 2:
406 return self.arg(0).eq(self.arg(1))
407 else:
408 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
409
410 def sexpr(self):
411 """Return a string representing the AST node in s-expression notation.
412
413 >>> x = Int('x')
414 >>> ((x + 1)*x).sexpr()
415 '(* (+ x 1) x)'
416 """
417 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
418
419 def as_ast(self):
420 """Return a pointer to the corresponding C Z3_ast object."""
421 return self.ast
422
423 def get_id(self):
424 """Return unique identifier for object. It can be used for hash-tables and maps."""
425 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
426
427 def ctx_ref(self):
428 """Return a reference to the C context where this AST node is stored."""
429 return self.ctx.ref()
430
431 def eq(self, other):
432 """Return `True` if `self` and `other` are structurally identical.
433
434 >>> x = Int('x')
435 >>> n1 = x + 1
436 >>> n2 = 1 + x
437 >>> n1.eq(n2)
438 False
439 >>> n1 = simplify(n1)
440 >>> n2 = simplify(n2)
441 >>> n1.eq(n2)
442 True
443 """
444 if z3_debug():
445 _z3_assert(is_ast(other), "Z3 AST expected")
446 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
447
448 def translate(self, target):
449 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
450
451 >>> c1 = Context()
452 >>> c2 = Context()
453 >>> x = Int('x', c1)
454 >>> y = Int('y', c2)
455 >>> # Nodes in different contexts can't be mixed.
456 >>> # However, we can translate nodes from one context to another.
457 >>> x.translate(c2) + y
458 x + y
459 """
460 if z3_debug():
461 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
462 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
463
464 def __copy__(self):
465 return self.translate(self.ctx)
466
467 def hash(self):
468 """Return a hashcode for the `self`.
469
470 >>> n1 = simplify(Int('x') + 1)
471 >>> n2 = simplify(2 + Int('x') - 1)
472 >>> n1.hash() == n2.hash()
473 True
474 """
475 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
476
477 def py_value(self):
478 """Return a Python value that is equivalent to `self`."""
479 return None
480
481
482def is_ast(a : Any) -> bool:
483 """Return `True` if `a` is an AST node.
484
485 >>> is_ast(10)
486 False
487 >>> is_ast(IntVal(10))
488 True
489 >>> is_ast(Int('x'))
490 True
491 >>> is_ast(BoolSort())
492 True
493 >>> is_ast(Function('f', IntSort(), IntSort()))
494 True
495 >>> is_ast("x")
496 False
497 >>> is_ast(Solver())
498 False
499 """
500 return isinstance(a, AstRef)
501
502
503def eq(a : AstRef, b : AstRef) -> bool:
504 """Return `True` if `a` and `b` are structurally identical AST nodes.
505
506 >>> x = Int('x')
507 >>> y = Int('y')
508 >>> eq(x, y)
509 False
510 >>> eq(x + 1, x + 1)
511 True
512 >>> eq(x + 1, 1 + x)
513 False
514 >>> eq(simplify(x + 1), simplify(1 + x))
515 True
516 """
517 if z3_debug():
518 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
519 return a.eq(b)
520
521
522def _ast_kind(ctx : Context, a : Any) -> int:
523 if is_ast(a):
524 a = a.as_ast()
525 return Z3_get_ast_kind(ctx.ref(), a)
526
527
528def _ctx_from_ast_arg_list(args, default_ctx=None):
529 ctx = None
530 for a in args:
531 if is_ast(a) or is_probe(a):
532 if ctx is None:
533 ctx = a.ctx
534 else:
535 if z3_debug():
536 _z3_assert(ctx == a.ctx, "Context mismatch")
537 if ctx is None:
538 ctx = default_ctx
539 return ctx
540
541
543 return _ctx_from_ast_arg_list(args)
544
545
547 sz = len(args)
548 _args = (FuncDecl * sz)()
549 for i in range(sz):
550 _args[i] = args[i].as_func_decl()
551 return _args, sz
552
553
555 sz = len(args)
556 _args = (Ast * sz)()
557 for i in range(sz):
558 _args[i] = args[i].as_ast()
559 return _args, sz
560
561
562def _to_ref_array(ref, args):
563 sz = len(args)
564 _args = (ref * sz)()
565 for i in range(sz):
566 _args[i] = args[i].as_ast()
567 return _args, sz
568
569
570def _to_ast_ref(a, ctx):
571 k = _ast_kind(ctx, a)
572 if k == Z3_SORT_AST:
573 return _to_sort_ref(a, ctx)
574 elif k == Z3_FUNC_DECL_AST:
575 return _to_func_decl_ref(a, ctx)
576 else:
577 return _to_expr_ref(a, ctx)
578
579
580
585
586def _sort_kind(ctx, s):
587 return Z3_get_sort_kind(ctx.ref(), s)
588
589
591 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
592
593 def as_ast(self):
594 return Z3_sort_to_ast(self.ctx_ref(), self.ast)
595
596 def get_id(self):
597 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
598
599 def kind(self):
600 """Return the Z3 internal kind of a sort.
601 This method can be used to test if `self` is one of the Z3 builtin sorts.
602
603 >>> b = BoolSort()
604 >>> b.kind() == Z3_BOOL_SORT
605 True
606 >>> b.kind() == Z3_INT_SORT
607 False
608 >>> A = ArraySort(IntSort(), IntSort())
609 >>> A.kind() == Z3_ARRAY_SORT
610 True
611 >>> A.kind() == Z3_INT_SORT
612 False
613 """
614 return _sort_kind(self.ctx, self.ast)
615
616 def subsort(self, other):
617 """Return `True` if `self` is a subsort of `other`.
618
619 >>> IntSort().subsort(RealSort())
620 True
621 """
622 return False
623
624 def cast(self, val):
625 """Try to cast `val` as an element of sort `self`.
626
627 This method is used in Z3Py to convert Python objects such as integers,
628 floats, longs and strings into Z3 expressions.
629
630 >>> x = Int('x')
631 >>> RealSort().cast(x)
632 ToReal(x)
633 """
634 if z3_debug():
635 _z3_assert(is_expr(val), "Z3 expression expected")
636 _z3_assert(self.eq(val.sort()), "Sort mismatch")
637 return val
638
639 def name(self):
640 """Return the name (string) of sort `self`.
641
642 >>> BoolSort().name()
643 'Bool'
644 >>> ArraySort(IntSort(), IntSort()).name()
645 'Array'
646 """
647 return _symbol2py(self.ctx, Z3_get_sort_name(self.ctx_ref(), self.ast))
648
649 def __eq__(self, other):
650 """Return `True` if `self` and `other` are the same Z3 sort.
651
652 >>> p = Bool('p')
653 >>> p.sort() == BoolSort()
654 True
655 >>> p.sort() == IntSort()
656 False
657 """
658 if other is None:
659 return False
660 return Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
661
662 def __ne__(self, other):
663 """Return `True` if `self` and `other` are not the same Z3 sort.
664
665 >>> p = Bool('p')
666 >>> p.sort() != BoolSort()
667 False
668 >>> p.sort() != IntSort()
669 True
670 """
671 return not Z3_is_eq_sort(self.ctx_ref(), self.ast, other.ast)
672
673 def __gt__(self, other):
674 """Create the function space Array(self, other)"""
675 return ArraySort(self, other)
676
677 def __hash__(self):
678 """ Hash code. """
679 return AstRef.__hash__(self)
680
681
682def is_sort(s : Any) -> bool:
683 """Return `True` if `s` is a Z3 sort.
684
685 >>> is_sort(IntSort())
686 True
687 >>> is_sort(Int('x'))
688 False
689 >>> is_expr(Int('x'))
690 True
691 """
692 return isinstance(s, SortRef)
693
694
695def _to_sort_ref(s, ctx):
696 if z3_debug():
697 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
698 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.ast)
785
786 def get_id(self):
787 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
788
789 def as_func_decl(self):
790 return self.ast
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.ctx, Z3_get_decl_name(self.ctx_ref(), self.ast))
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.ast))
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.ast, i), self.ctx)
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.ast), self.ctx)
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.ast)
847
848 def params(self):
849 ctx = self.ctx
850 n = Z3_get_decl_num_parameters(self.ctx_ref(), self.ast)
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.ast, i)
854 if k == Z3_PARAMETER_INT:
855 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.ast, i)
856 elif k == Z3_PARAMETER_DOUBLE:
857 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.ast, i)
858 elif k == Z3_PARAMETER_RATIONAL:
859 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.ast, i)
860 elif k == Z3_PARAMETER_SYMBOL:
861 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.ast, i)
862 elif k == Z3_PARAMETER_SORT:
863 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.ast, i), ctx)
864 elif k == Z3_PARAMETER_AST:
865 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.ast, i), ctx)
866 elif k == Z3_PARAMETER_FUNC_DECL:
867 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.ast, 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 assert(False)
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.ast, len(args), _args), self.ctx)
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.ast
1031
1032 def get_id(self):
1033 return Z3_get_ast_id(self.ctx_ref(), self.as_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.ctx, self.as_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.ctx)
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.ctx)
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_ast()), self.ctx)
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_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_ast(), idx), self.ctx)
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_ast(), num, _args), self.ctx)
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.ctx)
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):
1658 return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
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.ctx)
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):
2060 return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
2061
2062 def get_id(self):
2063 return Z3_get_ast_id(self.ctx_ref(), self.as_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.ast
2126
2127 def get_id(self):
2128 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
2129
2130 def sort(self):
2131 """Return the Boolean sort or sort of Lambda."""
2132 if self.is_lambda():
2133 return _sort(self.ctx, self.as_ast())
2134 return BoolSort(self.ctx)
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.ast)
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.ast)
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.ast))
2198
2199 def skolem_id(self):
2200 """Return the skolem id of `self`.
2201 """
2202 return _symbol2py(self.ctx, Z3_get_quantifier_skolem_id(self.ctx_ref(), self.ast))
2203
2204 def qid(self):
2205 """Return the quantifier id of `self`.
2206 """
2207 return _symbol2py(self.ctx, Z3_get_quantifier_id(self.ctx_ref(), self.ast))
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.ast))
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")
2237 return PatternRef(Z3_get_quantifier_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
2238
2240 """Return the number of no-patterns."""
2241 return Z3_get_quantifier_num_no_patterns(self.ctx_ref(), self.ast)
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")
2247 return _to_expr_ref(Z3_get_quantifier_no_pattern_ast(self.ctx_ref(), self.ast, idx), self.ctx)
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 """
2258 return _to_expr_ref(Z3_get_quantifier_body(self.ctx_ref(), self.ast), self.ctx)
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.ast))
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")
2286 return _symbol2py(self.ctx, Z3_get_quantifier_bound_name(self.ctx_ref(), self.ast, 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")
2302 return _to_sort_ref(Z3_get_quantifier_bound_sort(self.ctx_ref(), self.ast, idx), self.ctx)
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.ctx == 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.ctx)
2500 if self.is_real():
2501 return RealVal(val, self.ctx)
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 """
2534 return ArithSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
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.sort().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.sort().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.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
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_ast()), self.ctx)
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.ctx)
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.ctx)
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.ctx)
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.ctx)
2806
2807
2809 """Return `True` if `a` is an arithmetical expression.
2810
2811 >>> x = Int('x')
2812 >>> is_arith(x)
2813 True
2814 >>> is_arith(x + 1)
2815 True
2816 >>> is_arith(1)
2817 False
2818 >>> is_arith(IntVal(1))
2819 True
2820 >>> y = Real('y')
2821 >>> is_arith(y)
2822 True
2823 >>> is_arith(y + 1)
2824 True
2825 """
2826 return isinstance(a, ArithRef)
2827
2828
2829def is_int(a) -> bool:
2830 """Return `True` if `a` is an integer expression.
2831
2832 >>> x = Int('x')
2833 >>> is_int(x + 1)
2834 True
2835 >>> is_int(1)
2836 False
2837 >>> is_int(IntVal(1))
2838 True
2839 >>> y = Real('y')
2840 >>> is_int(y)
2841 False
2842 >>> is_int(y + 1)
2843 False
2844 """
2845 return is_arith(a) and a.is_int()
2846
2847
2848def is_real(a):
2849 """Return `True` if `a` is a real expression.
2850
2851 >>> x = Int('x')
2852 >>> is_real(x + 1)
2853 False
2854 >>> y = Real('y')
2855 >>> is_real(y)
2856 True
2857 >>> is_real(y + 1)
2858 True
2859 >>> is_real(1)
2860 False
2861 >>> is_real(RealVal(1))
2862 True
2863 """
2864 return is_arith(a) and a.is_real()
2865
2866
2867def _is_numeral(ctx, a):
2868 return Z3_is_numeral_ast(ctx.ref(), a)
2869
2870
2871def _is_algebraic(ctx, a):
2872 return Z3_is_algebraic_number(ctx.ref(), a)
2873
2874
2876 """Return `True` if `a` is an integer value of sort Int.
2877
2878 >>> is_int_value(IntVal(1))
2879 True
2880 >>> is_int_value(1)
2881 False
2882 >>> is_int_value(Int('x'))
2883 False
2884 >>> n = Int('x') + 1
2885 >>> n
2886 x + 1
2887 >>> n.arg(1)
2888 1
2889 >>> is_int_value(n.arg(1))
2890 True
2891 >>> is_int_value(RealVal("1/3"))
2892 False
2893 >>> is_int_value(RealVal(1))
2894 False
2895 """
2896 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2897
2898
2900 """Return `True` if `a` is rational value of sort Real.
2901
2902 >>> is_rational_value(RealVal(1))
2903 True
2904 >>> is_rational_value(RealVal("3/5"))
2905 True
2906 >>> is_rational_value(IntVal(1))
2907 False
2908 >>> is_rational_value(1)
2909 False
2910 >>> n = Real('x') + 1
2911 >>> n.arg(1)
2912 1
2913 >>> is_rational_value(n.arg(1))
2914 True
2915 >>> is_rational_value(Real('x'))
2916 False
2917 """
2918 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2919
2920
2922 """Return `True` if `a` is an algebraic value of sort Real.
2923
2924 >>> is_algebraic_value(RealVal("3/5"))
2925 False
2926 >>> n = simplify(Sqrt(2))
2927 >>> n
2928 1.4142135623?
2929 >>> is_algebraic_value(n)
2930 True
2931 """
2932 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2933
2934
2935def is_add(a : Any) -> bool:
2936 """Return `True` if `a` is an expression of the form b + c.
2937
2938 >>> x, y = Ints('x y')
2939 >>> is_add(x + y)
2940 True
2941 >>> is_add(x - y)
2942 False
2943 """
2944 return is_app_of(a, Z3_OP_ADD)
2945
2946
2947def is_mul(a : Any) -> bool:
2948 """Return `True` if `a` is an expression of the form b * c.
2949
2950 >>> x, y = Ints('x y')
2951 >>> is_mul(x * y)
2952 True
2953 >>> is_mul(x - y)
2954 False
2955 """
2956 return is_app_of(a, Z3_OP_MUL)
2957
2958
2959def is_sub(a : Any) -> bool:
2960 """Return `True` if `a` is an expression of the form b - c.
2961
2962 >>> x, y = Ints('x y')
2963 >>> is_sub(x - y)
2964 True
2965 >>> is_sub(x + y)
2966 False
2967 """
2968 return is_app_of(a, Z3_OP_SUB)
2969
2970
2971def is_div(a : Any) -> bool:
2972 """Return `True` if `a` is an expression of the form b / c.
2973
2974 >>> x, y = Reals('x y')
2975 >>> is_div(x / y)
2976 True
2977 >>> is_div(x + y)
2978 False
2979 >>> x, y = Ints('x y')
2980 >>> is_div(x / y)
2981 False
2982 >>> is_idiv(x / y)
2983 True
2984 """
2985 return is_app_of(a, Z3_OP_DIV)
2986
2987
2988def is_idiv(a : Any) -> bool:
2989 """Return `True` if `a` is an expression of the form b div c.
2990
2991 >>> x, y = Ints('x y')
2992 >>> is_idiv(x / y)
2993 True
2994 >>> is_idiv(x + y)
2995 False
2996 """
2997 return is_app_of(a, Z3_OP_IDIV)
2998
2999
3000def is_mod(a : Any) -> bool:
3001 """Return `True` if `a` is an expression of the form b % c.
3002
3003 >>> x, y = Ints('x y')
3004 >>> is_mod(x % y)
3005 True
3006 >>> is_mod(x + y)
3007 False
3008 """
3009 return is_app_of(a, Z3_OP_MOD)
3010
3011
3012def is_le(a : Any) -> bool:
3013 """Return `True` if `a` is an expression of the form b <= c.
3014
3015 >>> x, y = Ints('x y')
3016 >>> is_le(x <= y)
3017 True
3018 >>> is_le(x < y)
3019 False
3020 """
3021 return is_app_of(a, Z3_OP_LE)
3022
3023
3024def is_lt(a : Any) -> bool:
3025 """Return `True` if `a` is an expression of the form b < c.
3026
3027 >>> x, y = Ints('x y')
3028 >>> is_lt(x < y)
3029 True
3030 >>> is_lt(x == y)
3031 False
3032 """
3033 return is_app_of(a, Z3_OP_LT)
3034
3035
3036def is_ge(a : Any) -> bool:
3037 """Return `True` if `a` is an expression of the form b >= c.
3038
3039 >>> x, y = Ints('x y')
3040 >>> is_ge(x >= y)
3041 True
3042 >>> is_ge(x == y)
3043 False
3044 """
3045 return is_app_of(a, Z3_OP_GE)
3046
3047
3048def is_gt(a : Any) -> bool:
3049 """Return `True` if `a` is an expression of the form b > c.
3050
3051 >>> x, y = Ints('x y')
3052 >>> is_gt(x > y)
3053 True
3054 >>> is_gt(x == y)
3055 False
3056 """
3057 return is_app_of(a, Z3_OP_GT)
3058
3059
3060def is_is_int(a : Any) -> bool:
3061 """Return `True` if `a` is an expression of the form IsInt(b).
3062
3063 >>> x = Real('x')
3064 >>> is_is_int(IsInt(x))
3065 True
3066 >>> is_is_int(x)
3067 False
3068 """
3069 return is_app_of(a, Z3_OP_IS_INT)
3070
3071
3072def is_to_real(a : Any) -> bool:
3073 """Return `True` if `a` is an expression of the form ToReal(b).
3074
3075 >>> x = Int('x')
3076 >>> n = ToReal(x)
3077 >>> n
3078 ToReal(x)
3079 >>> is_to_real(n)
3080 True
3081 >>> is_to_real(x)
3082 False
3083 """
3084 return is_app_of(a, Z3_OP_TO_REAL)
3085
3086
3087def is_to_int(a : Any) -> bool:
3088 """Return `True` if `a` is an expression of the form ToInt(b).
3089
3090 >>> x = Real('x')
3091 >>> n = ToInt(x)
3092 >>> n
3093 ToInt(x)
3094 >>> is_to_int(n)
3095 True
3096 >>> is_to_int(x)
3097 False
3098 """
3099 return is_app_of(a, Z3_OP_TO_INT)
3100
3101
3103 """Integer values."""
3104
3105 def as_long(self):
3106 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3107
3108 >>> v = IntVal(1)
3109 >>> v + 1
3110 1 + 1
3111 >>> v.as_long() + 1
3112 2
3113 """
3114 if z3_debug():
3115 _z3_assert(self.is_int(), "Integer value expected")
3116 return int(self.as_string())
3117
3118 def as_string(self):
3119 """Return a Z3 integer numeral as a Python string.
3120 >>> v = IntVal(100)
3121 >>> v.as_string()
3122 '100'
3123 """
3124 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3125
3127 """Return a Z3 integer numeral as a Python binary string.
3128 >>> v = IntVal(10)
3129 >>> v.as_binary_string()
3130 '1010'
3131 """
3132 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
3133
3134 def py_value(self):
3135 return self.as_long()
3136
3137
3139 """Rational values."""
3140
3141 def numerator(self):
3142 """ Return the numerator of a Z3 rational numeral.
3143
3144 >>> is_rational_value(RealVal("3/5"))
3145 True
3146 >>> n = RealVal("3/5")
3147 >>> n.numerator()
3148 3
3149 >>> is_rational_value(Q(3,5))
3150 True
3151 >>> Q(3,5).numerator()
3152 3
3153 """
3154 return IntNumRef(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
3155
3156 def denominator(self):
3157 """ Return the denominator of a Z3 rational numeral.
3158
3159 >>> is_rational_value(Q(3,5))
3160 True
3161 >>> n = Q(3,5)
3162 >>> n.denominator()
3163 5
3164 """
3165 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_ast()), self.ctx)
3166
3168 """ Return the numerator as a Python long.
3169
3170 >>> v = RealVal(10000000000)
3171 >>> v
3172 10000000000
3173 >>> v + 1
3174 10000000000 + 1
3175 >>> v.numerator_as_long() + 1 == 10000000001
3176 True
3177 """
3178 return self.numerator().as_long()
3179
3181 """ Return the denominator as a Python long.
3182
3183 >>> v = RealVal("1/3")
3184 >>> v
3185 1/3
3186 >>> v.denominator_as_long()
3187 3
3188 """
3189 return self.denominator().as_long()
3190
3191 def is_int(self):
3192 return False
3193
3194 def is_real(self):
3195 return True
3196
3197 def is_int_value(self):
3198 return self.denominator().is_int() and self.denominator_as_long() == 1
3199
3200 def as_long(self):
3201 _z3_assert(self.is_int_value(), "Expected integer fraction")
3202 return self.numerator_as_long()
3203
3204 def as_decimal(self, prec):
3205 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3206
3207 >>> v = RealVal("1/5")
3208 >>> v.as_decimal(3)
3209 '0.2'
3210 >>> v = RealVal("1/3")
3211 >>> v.as_decimal(3)
3212 '0.333?'
3213 """
3214 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3215
3216 def as_string(self):
3217 """Return a Z3 rational numeral as a Python string.
3218
3219 >>> v = Q(3,6)
3220 >>> v.as_string()
3221 '1/2'
3222 """
3223 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
3224
3225 def as_fraction(self):
3226 """Return a Z3 rational as a Python Fraction object.
3227
3228 >>> v = RealVal("1/5")
3229 >>> v.as_fraction()
3230 Fraction(1, 5)
3231 """
3232 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3233
3234 def py_value(self):
3235 return Z3_get_numeral_double(self.ctx_ref(), self.as_ast())
3236
3237
3239 """Algebraic irrational values."""
3240
3241 def approx(self, precision=10):
3242 """Return a Z3 rational number that approximates the algebraic number `self`.
3243 The result `r` is such that |r - self| <= 1/10^precision
3244
3245 >>> x = simplify(Sqrt(2))
3246 >>> x.approx(20)
3247 6838717160008073720548335/4835703278458516698824704
3248 >>> x.approx(5)
3249 2965821/2097152
3250 """
3251 return RatNumRef(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
3252
3253 def as_decimal(self, prec):
3254 """Return a string representation of the algebraic number `self` in decimal notation
3255 using `prec` decimal places.
3256
3257 >>> x = simplify(Sqrt(2))
3258 >>> x.as_decimal(10)
3259 '1.4142135623?'
3260 >>> x.as_decimal(20)
3261 '1.41421356237309504880?'
3262 """
3263 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_ast(), prec)
3264
3265 def poly(self):
3266 return AstVector(Z3_algebraic_get_poly(self.ctx_ref(), self.as_ast()), self.ctx)
3267
3268 def index(self):
3269 return Z3_algebraic_get_i(self.ctx_ref(), self.as_ast())
3270
3271
3272def _py2expr(a, ctx=None):
3273 if isinstance(a, bool):
3274 return BoolVal(a, ctx)
3275 if _is_int(a):
3276 return IntVal(a, ctx)
3277 if isinstance(a, float):
3278 return RealVal(a, ctx)
3279 if isinstance(a, str):
3280 return StringVal(a, ctx)
3281 if is_expr(a):
3282 return a
3283 if z3_debug():
3284 _z3_assert(False, "Python bool, int, long or float expected")
3285
3286
3287def IntSort(ctx=None):
3288 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3289
3290 >>> IntSort()
3291 Int
3292 >>> x = Const('x', IntSort())
3293 >>> is_int(x)
3294 True
3295 >>> x.sort() == IntSort()
3296 True
3297 >>> x.sort() == BoolSort()
3298 False
3299 """
3300 ctx = _get_ctx(ctx)
3301 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3302
3303
3304def RealSort(ctx=None):
3305 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3306
3307 >>> RealSort()
3308 Real
3309 >>> x = Const('x', RealSort())
3310 >>> is_real(x)
3311 True
3312 >>> is_int(x)
3313 False
3314 >>> x.sort() == RealSort()
3315 True
3316 """
3317 ctx = _get_ctx(ctx)
3318 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3319
3320
3322 if isinstance(val, float):
3323 return str(int(val))
3324 elif isinstance(val, bool):
3325 if val:
3326 return "1"
3327 else:
3328 return "0"
3329 else:
3330 return str(val)
3331
3332
3333def IntVal(val, ctx=None):
3334 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3335
3336 >>> IntVal(1)
3337 1
3338 >>> IntVal("100")
3339 100
3340 """
3341 ctx = _get_ctx(ctx)
3342 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3343
3344
3345def RealVal(val, ctx=None):
3346 """Return a Z3 real value.
3347
3348 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3349 If `ctx=None`, then the global context is used.
3350
3351 >>> RealVal(1)
3352 1
3353 >>> RealVal(1).sort()
3354 Real
3355 >>> RealVal("3/5")
3356 3/5
3357 >>> RealVal("1.5")
3358 3/2
3359 """
3360 ctx = _get_ctx(ctx)
3361 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3362
3363
3364def RatVal(a, b, ctx=None):
3365 """Return a Z3 rational a/b.
3366
3367 If `ctx=None`, then the global context is used.
3368
3369 >>> RatVal(3,5)
3370 3/5
3371 >>> RatVal(3,5).sort()
3372 Real
3373 """
3374 if z3_debug():
3375 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3376 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3377 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3378
3379
3380def Q(a, b, ctx=None):
3381 """Return a Z3 rational a/b.
3382
3383 If `ctx=None`, then the global context is used.
3384
3385 >>> Q(3,5)
3386 3/5
3387 >>> Q(3,5).sort()
3388 Real
3389 """
3390 return simplify(RatVal(a, b, ctx=ctx))
3391
3392
3393def Int(name, ctx=None):
3394 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3395
3396 >>> x = Int('x')
3397 >>> is_int(x)
3398 True
3399 >>> is_int(x + 1)
3400 True
3401 """
3402 ctx = _get_ctx(ctx)
3403 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3404
3405
3406def Ints(names, ctx=None):
3407 """Return a tuple of Integer constants.
3408
3409 >>> x, y, z = Ints('x y z')
3410 >>> Sum(x, y, z)
3411 x + y + z
3412 """
3413 ctx = _get_ctx(ctx)
3414 if isinstance(names, str):
3415 names = names.split(" ")
3416 return [Int(name, ctx) for name in names]
3417
3418
3419def IntVector(prefix, sz, ctx=None):
3420 """Return a list of integer constants of size `sz`.
3421
3422 >>> X = IntVector('x', 3)
3423 >>> X
3424 [x__0, x__1, x__2]
3425 >>> Sum(X)
3426 x__0 + x__1 + x__2
3427 """
3428 ctx = _get_ctx(ctx)
3429 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3430
3431
3432def FreshInt(prefix="x", ctx=None):
3433 """Return a fresh integer constant in the given context using the given prefix.
3434
3435 >>> x = FreshInt()
3436 >>> y = FreshInt()
3437 >>> eq(x, y)
3438 False
3439 >>> x.sort()
3440 Int
3441 """
3442 ctx = _get_ctx(ctx)
3443 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3444
3445
3446def Real(name, ctx=None):
3447 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3448
3449 >>> x = Real('x')
3450 >>> is_real(x)
3451 True
3452 >>> is_real(x + 1)
3453 True
3454 """
3455 ctx = _get_ctx(ctx)
3456 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3457
3458
3459def Reals(names, ctx=None):
3460 """Return a tuple of real constants.
3461
3462 >>> x, y, z = Reals('x y z')
3463 >>> Sum(x, y, z)
3464 x + y + z
3465 >>> Sum(x, y, z).sort()
3466 Real
3467 """
3468 ctx = _get_ctx(ctx)
3469 if isinstance(names, str):
3470 names = names.split(" ")
3471 return [Real(name, ctx) for name in names]
3472
3473
3474def RealVector(prefix, sz, ctx=None):
3475 """Return a list of real constants of size `sz`.
3476
3477 >>> X = RealVector('x', 3)
3478 >>> X
3479 [x__0, x__1, x__2]
3480 >>> Sum(X)
3481 x__0 + x__1 + x__2
3482 >>> Sum(X).sort()
3483 Real
3484 """
3485 ctx = _get_ctx(ctx)
3486 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3487
3488
3489def FreshReal(prefix="b", ctx=None):
3490 """Return a fresh real constant in the given context using the given prefix.
3491
3492 >>> x = FreshReal()
3493 >>> y = FreshReal()
3494 >>> eq(x, y)
3495 False
3496 >>> x.sort()
3497 Real
3498 """
3499 ctx = _get_ctx(ctx)
3500 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3501
3502
3503def ToReal(a):
3504 """ Return the Z3 expression ToReal(a).
3505
3506 >>> x = Int('x')
3507 >>> x.sort()
3508 Int
3509 >>> n = ToReal(x)
3510 >>> n
3511 ToReal(x)
3512 >>> n.sort()
3513 Real
3514 """
3515 ctx = a.ctx
3516 if isinstance(a, BoolRef):
3517 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3518 if z3_debug():
3519 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3520 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3521
3522
3523def ToInt(a):
3524 """ Return the Z3 expression ToInt(a).
3525
3526 >>> x = Real('x')
3527 >>> x.sort()
3528 Real
3529 >>> n = ToInt(x)
3530 >>> n
3531 ToInt(x)
3532 >>> n.sort()
3533 Int
3534 """
3535 if z3_debug():
3536 _z3_assert(a.is_real(), "Z3 real expression expected.")
3537 ctx = a.ctx
3538 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3539
3540
3541def IsInt(a):
3542 """ Return the Z3 predicate IsInt(a).
3543
3544 >>> x = Real('x')
3545 >>> IsInt(x + "1/2")
3546 IsInt(x + 1/2)
3547 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3548 [x = 1/2]
3549 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3550 no solution
3551 """
3552 if z3_debug():
3553 _z3_assert(a.is_real(), "Z3 real expression expected.")
3554 ctx = a.ctx
3555 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3556
3557
3558def Sqrt(a, ctx=None):
3559 """ Return a Z3 expression which represents the square root of a.
3560
3561 >>> x = Real('x')
3562 >>> Sqrt(x)
3563 x**(1/2)
3564 """
3565 if not is_expr(a):
3566 ctx = _get_ctx(ctx)
3567 a = RealVal(a, ctx)
3568 return a ** "1/2"
3569
3570
3571def Cbrt(a, ctx=None):
3572 """ Return a Z3 expression which represents the cubic root of a.
3573
3574 >>> x = Real('x')
3575 >>> Cbrt(x)
3576 x**(1/3)
3577 """
3578 if not is_expr(a):
3579 ctx = _get_ctx(ctx)
3580 a = RealVal(a, ctx)
3581 return a ** "1/3"
3582
3583
3588
3589
3591 """Bit-vector sort."""
3592
3593 def size(self):
3594 """Return the size (number of bits) of the bit-vector sort `self`.
3595
3596 >>> b = BitVecSort(32)
3597 >>> b.size()
3598 32
3599 """
3600 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.ast))
3601
3602 def subsort(self, other):
3603 return is_bv_sort(other) and self.size() < other.size()
3604
3605 def cast(self, val):
3606 """Try to cast `val` as a Bit-Vector.
3607
3608 >>> b = BitVecSort(32)
3609 >>> b.cast(10)
3610 10
3611 >>> b.cast(10).sexpr()
3612 '#x0000000a'
3613 """
3614 if is_expr(val):
3615 if z3_debug():
3616 _z3_assert(self.ctx == val.ctx, "Context mismatch")
3617 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3618 return val
3619 else:
3620 return BitVecVal(val, self)
3621
3622
3624 """Return True if `s` is a Z3 bit-vector sort.
3625
3626 >>> is_bv_sort(BitVecSort(32))
3627 True
3628 >>> is_bv_sort(IntSort())
3629 False
3630 """
3631 return isinstance(s, BitVecSortRef)
3632
3633
3635 """Bit-vector expressions."""
3636
3637 def sort(self):
3638 """Return the sort of the bit-vector expression `self`.
3639
3640 >>> x = BitVec('x', 32)
3641 >>> x.sort()
3642 BitVec(32)
3643 >>> x.sort() == BitVecSort(32)
3644 True
3645 """
3646 return BitVecSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
3647
3648 def size(self):
3649 """Return the number of bits of the bit-vector expression `self`.
3650
3651 >>> x = BitVec('x', 32)
3652 >>> (x + 1).size()
3653 32
3654 >>> Concat(x, x).size()
3655 64
3656 """
3657 return self.sort().size()
3658
3659 def __add__(self, other):
3660 """Create the Z3 expression `self + other`.
3661
3662 >>> x = BitVec('x', 32)
3663 >>> y = BitVec('y', 32)
3664 >>> x + y
3665 x + y
3666 >>> (x + y).sort()
3667 BitVec(32)
3668 """
3669 a, b = _coerce_exprs(self, other)
3670 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3671
3672 def __radd__(self, other):
3673 """Create the Z3 expression `other + self`.
3674
3675 >>> x = BitVec('x', 32)
3676 >>> 10 + x
3677 10 + x
3678 """
3679 a, b = _coerce_exprs(self, other)
3680 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3681
3682 def __mul__(self, other):
3683 """Create the Z3 expression `self * other`.
3684
3685 >>> x = BitVec('x', 32)
3686 >>> y = BitVec('y', 32)
3687 >>> x * y
3688 x*y
3689 >>> (x * y).sort()
3690 BitVec(32)
3691 """
3692 a, b = _coerce_exprs(self, other)
3693 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3694
3695 def __rmul__(self, other):
3696 """Create the Z3 expression `other * self`.
3697
3698 >>> x = BitVec('x', 32)
3699 >>> 10 * x
3700 10*x
3701 """
3702 a, b = _coerce_exprs(self, other)
3703 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3704
3705 def __sub__(self, other):
3706 """Create the Z3 expression `self - other`.
3707
3708 >>> x = BitVec('x', 32)
3709 >>> y = BitVec('y', 32)
3710 >>> x - y
3711 x - y
3712 >>> (x - y).sort()
3713 BitVec(32)
3714 """
3715 a, b = _coerce_exprs(self, other)
3716 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3717
3718 def __rsub__(self, other):
3719 """Create the Z3 expression `other - self`.
3720
3721 >>> x = BitVec('x', 32)
3722 >>> 10 - x
3723 10 - x
3724 """
3725 a, b = _coerce_exprs(self, other)
3726 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3727
3728 def __or__(self, other):
3729 """Create the Z3 expression bitwise-or `self | other`.
3730
3731 >>> x = BitVec('x', 32)
3732 >>> y = BitVec('y', 32)
3733 >>> x | y
3734 x | y
3735 >>> (x | y).sort()
3736 BitVec(32)
3737 """
3738 a, b = _coerce_exprs(self, other)
3739 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3740
3741 def __ror__(self, other):
3742 """Create the Z3 expression bitwise-or `other | self`.
3743
3744 >>> x = BitVec('x', 32)
3745 >>> 10 | x
3746 10 | x
3747 """
3748 a, b = _coerce_exprs(self, other)
3749 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3750
3751 def __and__(self, other):
3752 """Create the Z3 expression bitwise-and `self & other`.
3753
3754 >>> x = BitVec('x', 32)
3755 >>> y = BitVec('y', 32)
3756 >>> x & y
3757 x & y
3758 >>> (x & y).sort()
3759 BitVec(32)
3760 """
3761 a, b = _coerce_exprs(self, other)
3762 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3763
3764 def __rand__(self, other):
3765 """Create the Z3 expression bitwise-or `other & self`.
3766
3767 >>> x = BitVec('x', 32)
3768 >>> 10 & x
3769 10 & x
3770 """
3771 a, b = _coerce_exprs(self, other)
3772 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3773
3774 def __xor__(self, other):
3775 """Create the Z3 expression bitwise-xor `self ^ other`.
3776
3777 >>> x = BitVec('x', 32)
3778 >>> y = BitVec('y', 32)
3779 >>> x ^ y
3780 x ^ y
3781 >>> (x ^ y).sort()
3782 BitVec(32)
3783 """
3784 a, b = _coerce_exprs(self, other)
3785 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3786
3787 def __rxor__(self, other):
3788 """Create the Z3 expression bitwise-xor `other ^ self`.
3789
3790 >>> x = BitVec('x', 32)
3791 >>> 10 ^ x
3792 10 ^ x
3793 """
3794 a, b = _coerce_exprs(self, other)
3795 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3796
3797 def __pos__(self):
3798 """Return `self`.
3799
3800 >>> x = BitVec('x', 32)
3801 >>> +x
3802 x
3803 """
3804 return self
3805
3806 def __neg__(self):
3807 """Return an expression representing `-self`.
3808
3809 >>> x = BitVec('x', 32)
3810 >>> -x
3811 -x
3812 >>> simplify(-(-x))
3813 x
3814 """
3815 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_ast()), self.ctx)
3816
3817 def __invert__(self):
3818 """Create the Z3 expression bitwise-not `~self`.
3819
3820 >>> x = BitVec('x', 32)
3821 >>> ~x
3822 ~x
3823 >>> simplify(~(~x))
3824 x
3825 """
3826 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_ast()), self.ctx)
3827
3828 def __div__(self, other):
3829 """Create the Z3 expression (signed) division `self / other`.
3830
3831 Use the function UDiv() for unsigned division.
3832
3833 >>> x = BitVec('x', 32)
3834 >>> y = BitVec('y', 32)
3835 >>> x / y
3836 x/y
3837 >>> (x / y).sort()
3838 BitVec(32)
3839 >>> (x / y).sexpr()
3840 '(bvsdiv x y)'
3841 >>> UDiv(x, y).sexpr()
3842 '(bvudiv x y)'
3843 """
3844 a, b = _coerce_exprs(self, other)
3845 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3846
3847 def __truediv__(self, other):
3848 """Create the Z3 expression (signed) division `self / other`."""
3849 return self.__div__(other)
3850
3851 def __rdiv__(self, other):
3852 """Create the Z3 expression (signed) division `other / self`.
3853
3854 Use the function UDiv() for unsigned division.
3855
3856 >>> x = BitVec('x', 32)
3857 >>> 10 / x
3858 10/x
3859 >>> (10 / x).sexpr()
3860 '(bvsdiv #x0000000a x)'
3861 >>> UDiv(10, x).sexpr()
3862 '(bvudiv #x0000000a x)'
3863 """
3864 a, b = _coerce_exprs(self, other)
3865 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3866
3867 def __rtruediv__(self, other):
3868 """Create the Z3 expression (signed) division `other / self`."""
3869 return self.__rdiv__(other)
3870
3871 def __mod__(self, other):
3872 """Create the Z3 expression (signed) mod `self % other`.
3873
3874 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3875
3876 >>> x = BitVec('x', 32)
3877 >>> y = BitVec('y', 32)
3878 >>> x % y
3879 x%y
3880 >>> (x % y).sort()
3881 BitVec(32)
3882 >>> (x % y).sexpr()
3883 '(bvsmod x y)'
3884 >>> URem(x, y).sexpr()
3885 '(bvurem x y)'
3886 >>> SRem(x, y).sexpr()
3887 '(bvsrem x y)'
3888 """
3889 a, b = _coerce_exprs(self, other)
3890 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3891
3892 def __rmod__(self, other):
3893 """Create the Z3 expression (signed) mod `other % self`.
3894
3895 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3896
3897 >>> x = BitVec('x', 32)
3898 >>> 10 % x
3899 10%x
3900 >>> (10 % x).sexpr()
3901 '(bvsmod #x0000000a x)'
3902 >>> URem(10, x).sexpr()
3903 '(bvurem #x0000000a x)'
3904 >>> SRem(10, x).sexpr()
3905 '(bvsrem #x0000000a x)'
3906 """
3907 a, b = _coerce_exprs(self, other)
3908 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
3909
3910 def __le__(self, other):
3911 """Create the Z3 expression (signed) `other <= self`.
3912
3913 Use the function ULE() for unsigned less than or equal to.
3914
3915 >>> x, y = BitVecs('x y', 32)
3916 >>> x <= y
3917 x <= y
3918 >>> (x <= y).sexpr()
3919 '(bvsle x y)'
3920 >>> ULE(x, y).sexpr()
3921 '(bvule x y)'
3922 """
3923 a, b = _coerce_exprs(self, other)
3924 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3925
3926 def __lt__(self, other):
3927 """Create the Z3 expression (signed) `other < self`.
3928
3929 Use the function ULT() for unsigned less than.
3930
3931 >>> x, y = BitVecs('x y', 32)
3932 >>> x < y
3933 x < y
3934 >>> (x < y).sexpr()
3935 '(bvslt x y)'
3936 >>> ULT(x, y).sexpr()
3937 '(bvult x y)'
3938 """
3939 a, b = _coerce_exprs(self, other)
3940 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3941
3942 def __gt__(self, other):
3943 """Create the Z3 expression (signed) `other > self`.
3944
3945 Use the function UGT() for unsigned greater than.
3946
3947 >>> x, y = BitVecs('x y', 32)
3948 >>> x > y
3949 x > y
3950 >>> (x > y).sexpr()
3951 '(bvsgt x y)'
3952 >>> UGT(x, y).sexpr()
3953 '(bvugt x y)'
3954 """
3955 a, b = _coerce_exprs(self, other)
3956 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3957
3958 def __ge__(self, other):
3959 """Create the Z3 expression (signed) `other >= self`.
3960
3961 Use the function UGE() for unsigned greater than or equal to.
3962
3963 >>> x, y = BitVecs('x y', 32)
3964 >>> x >= y
3965 x >= y
3966 >>> (x >= y).sexpr()
3967 '(bvsge x y)'
3968 >>> UGE(x, y).sexpr()
3969 '(bvuge x y)'
3970 """
3971 a, b = _coerce_exprs(self, other)
3972 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
3973
3974 def __rshift__(self, other):
3975 """Create the Z3 expression (arithmetical) right shift `self >> other`
3976
3977 Use the function LShR() for the right logical shift
3978
3979 >>> x, y = BitVecs('x y', 32)
3980 >>> x >> y
3981 x >> y
3982 >>> (x >> y).sexpr()
3983 '(bvashr x y)'
3984 >>> LShR(x, y).sexpr()
3985 '(bvlshr x y)'
3986 >>> BitVecVal(4, 3)
3987 4
3988 >>> BitVecVal(4, 3).as_signed_long()
3989 -4
3990 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3991 -2
3992 >>> simplify(BitVecVal(4, 3) >> 1)
3993 6
3994 >>> simplify(LShR(BitVecVal(4, 3), 1))
3995 2
3996 >>> simplify(BitVecVal(2, 3) >> 1)
3997 1
3998 >>> simplify(LShR(BitVecVal(2, 3), 1))
3999 1
4000 """
4001 a, b = _coerce_exprs(self, other)
4002 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4003
4004 def __lshift__(self, other):
4005 """Create the Z3 expression left shift `self << other`
4006
4007 >>> x, y = BitVecs('x y', 32)
4008 >>> x << y
4009 x << y
4010 >>> (x << y).sexpr()
4011 '(bvshl x y)'
4012 >>> simplify(BitVecVal(2, 3) << 1)
4013 4
4014 """
4015 a, b = _coerce_exprs(self, other)
4016 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
4017
4018 def __rrshift__(self, other):
4019 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
4020
4021 Use the function LShR() for the right logical shift
4022
4023 >>> x = BitVec('x', 32)
4024 >>> 10 >> x
4025 10 >> x
4026 >>> (10 >> x).sexpr()
4027 '(bvashr #x0000000a x)'
4028 """
4029 a, b = _coerce_exprs(self, other)
4030 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
4031
4032 def __rlshift__(self, other):
4033 """Create the Z3 expression left shift `other << self`.
4034
4035 Use the function LShR() for the right logical shift
4036
4037 >>> x = BitVec('x', 32)
4038 >>> 10 << x
4039 10 << x
4040 >>> (10 << x).sexpr()
4041 '(bvshl #x0000000a x)'
4042 """
4043 a, b = _coerce_exprs(self, other)
4044 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctx)
4045
4046
4048 """Bit-vector values."""
4049
4050 def as_long(self):
4051 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4052
4053 >>> v = BitVecVal(0xbadc0de, 32)
4054 >>> v
4055 195936478
4056 >>> print("0x%.8x" % v.as_long())
4057 0x0badc0de
4058 """
4059 return int(self.as_string())
4060
4062 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4063 The most significant bit is assumed to be the sign.
4064
4065 >>> BitVecVal(4, 3).as_signed_long()
4066 -4
4067 >>> BitVecVal(7, 3).as_signed_long()
4068 -1
4069 >>> BitVecVal(3, 3).as_signed_long()
4070 3
4071 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4072 -1
4073 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4074 -1
4075 """
4076 sz = self.size()
4077 val = self.as_long()
4078 if val >= 2**(sz - 1):
4079 val = val - 2**sz
4080 if val < -2**(sz - 1):
4081 val = val + 2**sz
4082 return int(val)
4083
4084 def as_string(self):
4085 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
4086
4088 return Z3_get_numeral_binary_string(self.ctx_ref(), self.as_ast())
4089
4090 def py_value(self):
4091 """Return the Python value of a Z3 bit-vector numeral."""
4092 return self.as_long()
4093
4094
4095
4096def is_bv(a):
4097 """Return `True` if `a` is a Z3 bit-vector expression.
4098
4099 >>> b = BitVec('b', 32)
4100 >>> is_bv(b)
4101 True
4102 >>> is_bv(b + 10)
4103 True
4104 >>> is_bv(Int('x'))
4105 False
4106 """
4107 return isinstance(a, BitVecRef)
4108
4109
4111 """Return `True` if `a` is a Z3 bit-vector numeral value.
4112
4113 >>> b = BitVec('b', 32)
4114 >>> is_bv_value(b)
4115 False
4116 >>> b = BitVecVal(10, 32)
4117 >>> b
4118 10
4119 >>> is_bv_value(b)
4120 True
4121 """
4122 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4123
4124
4125def BV2Int(a, is_signed=False):
4126 """Return the Z3 expression BV2Int(a).
4127
4128 >>> b = BitVec('b', 3)
4129 >>> BV2Int(b).sort()
4130 Int
4131 >>> x = Int('x')
4132 >>> x > BV2Int(b)
4133 x > BV2Int(b)
4134 >>> x > BV2Int(b, is_signed=False)
4135 x > BV2Int(b)
4136 >>> x > BV2Int(b, is_signed=True)
4137 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4138 >>> solve(x > BV2Int(b), b == 1, x < 3)
4139 [x = 2, b = 1]
4140 """
4141 if z3_debug():
4142 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4143 ctx = a.ctx
4144 # investigate problem with bv2int
4145 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4146
4147
4148def Int2BV(a, num_bits):
4149 """Return the z3 expression Int2BV(a, num_bits).
4150 It is a bit-vector of width num_bits and represents the
4151 modulo of a by 2^num_bits
4152 """
4153 ctx = a.ctx
4154 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4155
4156
4157def BitVecSort(sz, ctx=None):
4158 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4159
4160 >>> Byte = BitVecSort(8)
4161 >>> Word = BitVecSort(16)
4162 >>> Byte
4163 BitVec(8)
4164 >>> x = Const('x', Byte)
4165 >>> eq(x, BitVec('x', 8))
4166 True
4167 """
4168 ctx = _get_ctx(ctx)
4169 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4170
4171
4172def BitVecVal(val, bv, ctx=None):
4173 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4174
4175 >>> v = BitVecVal(10, 32)
4176 >>> v
4177 10
4178 >>> print("0x%.8x" % v.as_long())
4179 0x0000000a
4180 """
4181 if is_bv_sort(bv):
4182 ctx = bv.ctx
4183 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4184 else:
4185 ctx = _get_ctx(ctx)
4186 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4187
4188
4189def BitVec(name, bv, ctx=None):
4190 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4191 If `ctx=None`, then the global context is used.
4192
4193 >>> x = BitVec('x', 16)
4194 >>> is_bv(x)
4195 True
4196 >>> x.size()
4197 16
4198 >>> x.sort()
4199 BitVec(16)
4200 >>> word = BitVecSort(16)
4201 >>> x2 = BitVec('x', word)
4202 >>> eq(x, x2)
4203 True
4204 """
4205 if isinstance(bv, BitVecSortRef):
4206 ctx = bv.ctx
4207 else:
4208 ctx = _get_ctx(ctx)
4209 bv = BitVecSort(bv, ctx)
4210 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4211
4212
4213def BitVecs(names, bv, ctx=None):
4214 """Return a tuple of bit-vector constants of size bv.
4215
4216 >>> x, y, z = BitVecs('x y z', 16)
4217 >>> x.size()
4218 16
4219 >>> x.sort()
4220 BitVec(16)
4221 >>> Sum(x, y, z)
4222 0 + x + y + z
4223 >>> Product(x, y, z)
4224 1*x*y*z
4225 >>> simplify(Product(x, y, z))
4226 x*y*z
4227 """
4228 ctx = _get_ctx(ctx)
4229 if isinstance(names, str):
4230 names = names.split(" ")
4231 return [BitVec(name, bv, ctx) for name in names]
4232
4233
4234def Concat(*args):
4235 """Create a Z3 bit-vector concatenation expression.
4236
4237 >>> v = BitVecVal(1, 4)
4238 >>> Concat(v, v+1, v)
4239 Concat(Concat(1, 1 + 1), 1)
4240 >>> simplify(Concat(v, v+1, v))
4241 289
4242 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4243 121
4244 """
4245 args = _get_args(args)
4246 sz = len(args)
4247 if z3_debug():
4248 _z3_assert(sz >= 2, "At least two arguments expected.")
4249
4250 ctx = None
4251 for a in args:
4252 if is_expr(a):
4253 ctx = a.ctx
4254 break
4255 if is_seq(args[0]) or isinstance(args[0], str):
4256 args = [_coerce_seq(s, ctx) for s in args]
4257 if z3_debug():
4258 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4259 v = (Ast * sz)()
4260 for i in range(sz):
4261 v[i] = args[i].as_ast()
4262 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4263
4264 if is_re(args[0]):
4265 if z3_debug():
4266 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4267 v = (Ast * sz)()
4268 for i in range(sz):
4269 v[i] = args[i].as_ast()
4270 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4271
4272 if z3_debug():
4273 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4274 r = args[0]
4275 for i in range(sz - 1):
4276 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4277 return r
4278
4279
4280def Extract(high, low, a):
4281 """Create a Z3 bit-vector extraction expression or sequence extraction expression.
4282
4283 Extract is overloaded to work with both bit-vectors and sequences:
4284
4285 **Bit-vector extraction**: Extract(high, low, bitvector)
4286 Extracts bits from position `high` down to position `low` (both inclusive).
4287 - high: int - the highest bit position to extract (0-indexed from right)
4288 - low: int - the lowest bit position to extract (0-indexed from right)
4289 - bitvector: BitVecRef - the bit-vector to extract from
4290 Returns a new bit-vector containing bits [high:low]
4291
4292 **Sequence extraction**: Extract(sequence, offset, length)
4293 Extracts a subsequence starting at the given offset with the specified length.
4294 The functions SubString and SubSeq are redirected to this form of Extract.
4295 - sequence: SeqRef or str - the sequence to extract from
4296 - offset: int - the starting position (0-indexed)
4297 - length: int - the number of elements to extract
4298 Returns a new sequence containing the extracted subsequence
4299
4300 >>> # Bit-vector extraction examples
4301 >>> x = BitVec('x', 8)
4302 >>> Extract(6, 2, x) # Extract bits 6 down to 2 (5 bits total)
4303 Extract(6, 2, x)
4304 >>> Extract(6, 2, x).sort() # Result is a 5-bit vector
4305 BitVec(5)
4306 >>> Extract(7, 0, x) # Extract all 8 bits
4307 Extract(7, 0, x)
4308 >>> Extract(3, 3, x) # Extract single bit at position 3
4309 Extract(3, 3, x)
4310
4311 >>> # Sequence extraction examples
4312 >>> s = StringVal("hello")
4313 >>> Extract(s, 1, 3) # Extract 3 characters starting at position 1
4314 str.substr("hello", 1, 3)
4315 >>> simplify(Extract(StringVal("abcd"), 2, 1)) # Extract 1 character at position 2
4316 "c"
4317 >>> simplify(Extract(StringVal("abcd"), 0, 2)) # Extract first 2 characters
4318 "ab"
4319 """
4320 if isinstance(high, str):
4321 high = StringVal(high)
4322 if is_seq(high):
4323 s = high
4324 offset, length = _coerce_exprs(low, a, s.ctx)
4325 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4326 if z3_debug():
4327 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4328 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4329 "First and second arguments must be non negative integers")
4330 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4331 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4332
4333
4335 if z3_debug():
4336 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4337
4338
4339def ULE(a, b):
4340 """Create the Z3 expression (unsigned) `other <= self`.
4341
4342 Use the operator <= for signed less than or equal to.
4343
4344 >>> x, y = BitVecs('x y', 32)
4345 >>> ULE(x, y)
4346 ULE(x, y)
4347 >>> (x <= y).sexpr()
4348 '(bvsle x y)'
4349 >>> ULE(x, y).sexpr()
4350 '(bvule x y)'
4351 """
4352 _check_bv_args(a, b)
4353 a, b = _coerce_exprs(a, b)
4354 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4355
4356
4357def ULT(a, b):
4358 """Create the Z3 expression (unsigned) `other < self`.
4359
4360 Use the operator < for signed less than.
4361
4362 >>> x, y = BitVecs('x y', 32)
4363 >>> ULT(x, y)
4364 ULT(x, y)
4365 >>> (x < y).sexpr()
4366 '(bvslt x y)'
4367 >>> ULT(x, y).sexpr()
4368 '(bvult x y)'
4369 """
4370 _check_bv_args(a, b)
4371 a, b = _coerce_exprs(a, b)
4372 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4373
4374
4375def UGE(a, b):
4376 """Create the Z3 expression (unsigned) `other >= self`.
4377
4378 Use the operator >= for signed greater than or equal to.
4379
4380 >>> x, y = BitVecs('x y', 32)
4381 >>> UGE(x, y)
4382 UGE(x, y)
4383 >>> (x >= y).sexpr()
4384 '(bvsge x y)'
4385 >>> UGE(x, y).sexpr()
4386 '(bvuge x y)'
4387 """
4388 _check_bv_args(a, b)
4389 a, b = _coerce_exprs(a, b)
4390 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4391
4392
4393def UGT(a, b):
4394 """Create the Z3 expression (unsigned) `other > self`.
4395
4396 Use the operator > for signed greater than.
4397
4398 >>> x, y = BitVecs('x y', 32)
4399 >>> UGT(x, y)
4400 UGT(x, y)
4401 >>> (x > y).sexpr()
4402 '(bvsgt x y)'
4403 >>> UGT(x, y).sexpr()
4404 '(bvugt x y)'
4405 """
4406 _check_bv_args(a, b)
4407 a, b = _coerce_exprs(a, b)
4408 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4409
4410
4411def UDiv(a, b):
4412 """Create the Z3 expression (unsigned) division `self / other`.
4413
4414 Use the operator / for signed division.
4415
4416 >>> x = BitVec('x', 32)
4417 >>> y = BitVec('y', 32)
4418 >>> UDiv(x, y)
4419 UDiv(x, y)
4420 >>> UDiv(x, y).sort()
4421 BitVec(32)
4422 >>> (x / y).sexpr()
4423 '(bvsdiv x y)'
4424 >>> UDiv(x, y).sexpr()
4425 '(bvudiv x y)'
4426 """
4427 _check_bv_args(a, b)
4428 a, b = _coerce_exprs(a, b)
4429 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4430
4431
4432def URem(a, b):
4433 """Create the Z3 expression (unsigned) remainder `self % other`.
4434
4435 Use the operator % for signed modulus, and SRem() for signed remainder.
4436
4437 >>> x = BitVec('x', 32)
4438 >>> y = BitVec('y', 32)
4439 >>> URem(x, y)
4440 URem(x, y)
4441 >>> URem(x, y).sort()
4442 BitVec(32)
4443 >>> (x % y).sexpr()
4444 '(bvsmod x y)'
4445 >>> URem(x, y).sexpr()
4446 '(bvurem x y)'
4447 """
4448 _check_bv_args(a, b)
4449 a, b = _coerce_exprs(a, b)
4450 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4451
4452
4453def SRem(a, b):
4454 """Create the Z3 expression signed remainder.
4455
4456 Use the operator % for signed modulus, and URem() for unsigned remainder.
4457
4458 >>> x = BitVec('x', 32)
4459 >>> y = BitVec('y', 32)
4460 >>> SRem(x, y)
4461 SRem(x, y)
4462 >>> SRem(x, y).sort()
4463 BitVec(32)
4464 >>> (x % y).sexpr()
4465 '(bvsmod x y)'
4466 >>> SRem(x, y).sexpr()
4467 '(bvsrem x y)'
4468 """
4469 _check_bv_args(a, b)
4470 a, b = _coerce_exprs(a, b)
4471 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4472
4473
4474def LShR(a, b):
4475 """Create the Z3 expression logical right shift.
4476
4477 Use the operator >> for the arithmetical right shift.
4478
4479 >>> x, y = BitVecs('x y', 32)
4480 >>> LShR(x, y)
4481 LShR(x, y)
4482 >>> (x >> y).sexpr()
4483 '(bvashr x y)'
4484 >>> LShR(x, y).sexpr()
4485 '(bvlshr x y)'
4486 >>> BitVecVal(4, 3)
4487 4
4488 >>> BitVecVal(4, 3).as_signed_long()
4489 -4
4490 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4491 -2
4492 >>> simplify(BitVecVal(4, 3) >> 1)
4493 6
4494 >>> simplify(LShR(BitVecVal(4, 3), 1))
4495 2
4496 >>> simplify(BitVecVal(2, 3) >> 1)
4497 1
4498 >>> simplify(LShR(BitVecVal(2, 3), 1))
4499 1
4500 """
4501 _check_bv_args(a, b)
4502 a, b = _coerce_exprs(a, b)
4503 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4504
4505
4506def RotateLeft(a, b):
4507 """Return an expression representing `a` rotated to the left `b` times.
4508
4509 >>> a, b = BitVecs('a b', 16)
4510 >>> RotateLeft(a, b)
4511 RotateLeft(a, b)
4512 >>> simplify(RotateLeft(a, 0))
4513 a
4514 >>> simplify(RotateLeft(a, 16))
4515 a
4516 """
4517 _check_bv_args(a, b)
4518 a, b = _coerce_exprs(a, b)
4519 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4520
4521
4522def RotateRight(a, b):
4523 """Return an expression representing `a` rotated to the right `b` times.
4524
4525 >>> a, b = BitVecs('a b', 16)
4526 >>> RotateRight(a, b)
4527 RotateRight(a, b)
4528 >>> simplify(RotateRight(a, 0))
4529 a
4530 >>> simplify(RotateRight(a, 16))
4531 a
4532 """
4533 _check_bv_args(a, b)
4534 a, b = _coerce_exprs(a, b)
4535 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4536
4537
4538def SignExt(n, a):
4539 """Return a bit-vector expression with `n` extra sign-bits.
4540
4541 >>> x = BitVec('x', 16)
4542 >>> n = SignExt(8, x)
4543 >>> n.size()
4544 24
4545 >>> n
4546 SignExt(8, x)
4547 >>> n.sort()
4548 BitVec(24)
4549 >>> v0 = BitVecVal(2, 2)
4550 >>> v0
4551 2
4552 >>> v0.size()
4553 2
4554 >>> v = simplify(SignExt(6, v0))
4555 >>> v
4556 254
4557 >>> v.size()
4558 8
4559 >>> print("%.x" % v.as_long())
4560 fe
4561 """
4562 if z3_debug():
4563 _z3_assert(_is_int(n), "First argument must be an integer")
4564 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4565 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4566
4567
4568def ZeroExt(n, a):
4569 """Return a bit-vector expression with `n` extra zero-bits.
4570
4571 >>> x = BitVec('x', 16)
4572 >>> n = ZeroExt(8, x)
4573 >>> n.size()
4574 24
4575 >>> n
4576 ZeroExt(8, x)
4577 >>> n.sort()
4578 BitVec(24)
4579 >>> v0 = BitVecVal(2, 2)
4580 >>> v0
4581 2
4582 >>> v0.size()
4583 2
4584 >>> v = simplify(ZeroExt(6, v0))
4585 >>> v
4586 2
4587 >>> v.size()
4588 8
4589 """
4590 if z3_debug():
4591 _z3_assert(_is_int(n), "First argument must be an integer")
4592 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4593 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4594
4595
4597 """Return an expression representing `n` copies of `a`.
4598
4599 >>> x = BitVec('x', 8)
4600 >>> n = RepeatBitVec(4, x)
4601 >>> n
4602 RepeatBitVec(4, x)
4603 >>> n.size()
4604 32
4605 >>> v0 = BitVecVal(10, 4)
4606 >>> print("%.x" % v0.as_long())
4607 a
4608 >>> v = simplify(RepeatBitVec(4, v0))
4609 >>> v.size()
4610 16
4611 >>> print("%.x" % v.as_long())
4612 aaaa
4613 """
4614 if z3_debug():
4615 _z3_assert(_is_int(n), "First argument must be an integer")
4616 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4617 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4618
4619
4621 """Return the reduction-and expression of `a`."""
4622 if z3_debug():
4623 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4624 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4625
4626
4627def BVRedOr(a):
4628 """Return the reduction-or expression of `a`."""
4629 if z3_debug():
4630 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4631 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4632
4633
4634def BVAddNoOverflow(a, b, signed):
4635 """A predicate the determines that bit-vector addition does not overflow"""
4636 _check_bv_args(a, b)
4637 a, b = _coerce_exprs(a, b)
4638 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4639
4640
4642 """A predicate the determines that signed bit-vector addition does not underflow"""
4643 _check_bv_args(a, b)
4644 a, b = _coerce_exprs(a, b)
4645 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4646
4647
4649 """A predicate the determines that bit-vector subtraction does not overflow"""
4650 _check_bv_args(a, b)
4651 a, b = _coerce_exprs(a, b)
4652 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4653
4654
4655def BVSubNoUnderflow(a, b, signed):
4656 """A predicate the determines that bit-vector subtraction does not underflow"""
4657 _check_bv_args(a, b)
4658 a, b = _coerce_exprs(a, b)
4659 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4660
4661
4663 """A predicate the determines that bit-vector signed division does not overflow"""
4664 _check_bv_args(a, b)
4665 a, b = _coerce_exprs(a, b)
4666 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4667
4668
4670 """A predicate the determines that bit-vector unary negation does not overflow"""
4671 if z3_debug():
4672 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4673 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4674
4675
4676def BVMulNoOverflow(a, b, signed):
4677 """A predicate the determines that bit-vector multiplication does not overflow"""
4678 _check_bv_args(a, b)
4679 a, b = _coerce_exprs(a, b)
4680 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4681
4682
4684 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4685 _check_bv_args(a, b)
4686 a, b = _coerce_exprs(a, b)
4687 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4688
4689
4690
4695
4697 """Array sorts."""
4698
4699 def domain(self):
4700 """Return the domain of the array sort `self`.
4701
4702 >>> A = ArraySort(IntSort(), BoolSort())
4703 >>> A.domain()
4704 Int
4705 """
4707
4708 def domain_n(self, i):
4709 """Return the domain of the array sort `self`.
4710 """
4711 return _to_sort_ref(Z3_get_array_sort_domain_n(self.ctx_ref(), self.ast, i), self.ctx)
4712
4713 def range(self):
4714 """Return the range of the array sort `self`.
4715
4716 >>> A = ArraySort(IntSort(), BoolSort())
4717 >>> A.range()
4718 Bool
4719 """
4720 return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
4721
4722
4724 """Array expressions. """
4725
4726 def sort(self):
4727 """Return the array sort of the array expression `self`.
4728
4729 >>> a = Array('a', IntSort(), BoolSort())
4730 >>> a.sort()
4731 Array(Int, Bool)
4732 """
4733 return ArraySortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
4734
4735 def domain(self):
4736 """Shorthand for `self.sort().domain()`.
4737
4738 >>> a = Array('a', IntSort(), BoolSort())
4739 >>> a.domain()
4740 Int
4741 """
4742 return self.sort().domain()
4743
4744 def domain_n(self, i):
4745 """Shorthand for self.sort().domain_n(i)`."""
4746 return self.sort().domain_n(i)
4747
4748 def range(self):
4749 """Shorthand for `self.sort().range()`.
4750
4751 >>> a = Array('a', IntSort(), BoolSort())
4752 >>> a.range()
4753 Bool
4754 """
4755 return self.sort().range()
4756
4757 def __getitem__(self, arg):
4758 """Return the Z3 expression `self[arg]`.
4759
4760 >>> a = Array('a', IntSort(), BoolSort())
4761 >>> i = Int('i')
4762 >>> a[i]
4763 a[i]
4764 >>> a[i].sexpr()
4765 '(select a i)'
4766 """
4767 return _array_select(self, arg)
4768
4769 def default(self):
4770 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx)
4771
4772
4773def _array_select(ar, arg):
4774 if isinstance(arg, tuple):
4775 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4776 _args, sz = _to_ast_array(args)
4777 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4778 arg = ar.sort().domain().cast(arg)
4779 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4780
4781
4783 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4784
4785
4786def is_array(a : Any) -> bool:
4787 """Return `True` if `a` is a Z3 array expression.
4788
4789 >>> a = Array('a', IntSort(), IntSort())
4790 >>> is_array(a)
4791 True
4792 >>> is_array(Store(a, 0, 1))
4793 True
4794 >>> is_array(a[0])
4795 False
4796 """
4797 return isinstance(a, ArrayRef)
4798
4799
4801 """Return `True` if `a` is a Z3 constant array.
4802
4803 >>> a = K(IntSort(), 10)
4804 >>> is_const_array(a)
4805 True
4806 >>> a = Array('a', IntSort(), IntSort())
4807 >>> is_const_array(a)
4808 False
4809 """
4810 return is_app_of(a, Z3_OP_CONST_ARRAY)
4811
4812
4813def is_K(a):
4814 """Return `True` if `a` is a Z3 constant array.
4815
4816 >>> a = K(IntSort(), 10)
4817 >>> is_K(a)
4818 True
4819 >>> a = Array('a', IntSort(), IntSort())
4820 >>> is_K(a)
4821 False
4822 """
4823 return is_app_of(a, Z3_OP_CONST_ARRAY)
4824
4825
4826def is_map(a):
4827 """Return `True` if `a` is a Z3 map array expression.
4828
4829 >>> f = Function('f', IntSort(), IntSort())
4830 >>> b = Array('b', IntSort(), IntSort())
4831 >>> a = Map(f, b)
4832 >>> a
4833 Map(f, b)
4834 >>> is_map(a)
4835 True
4836 >>> is_map(b)
4837 False
4838 """
4839 return is_app_of(a, Z3_OP_ARRAY_MAP)
4840
4841
4843 """Return `True` if `a` is a Z3 default array expression.
4844 >>> d = Default(K(IntSort(), 10))
4845 >>> is_default(d)
4846 True
4847 """
4848 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4849
4850
4852 """Return the function declaration associated with a Z3 map array expression.
4853
4854 >>> f = Function('f', IntSort(), IntSort())
4855 >>> b = Array('b', IntSort(), IntSort())
4856 >>> a = Map(f, b)
4857 >>> eq(f, get_map_func(a))
4858 True
4859 >>> get_map_func(a)
4860 f
4861 >>> get_map_func(a)(0)
4862 f(0)
4863 """
4864 if z3_debug():
4865 _z3_assert(is_map(a), "Z3 array map expression expected.")
4866 return FuncDeclRef(
4868 a.ctx_ref(),
4869 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4870 ),
4871 ctx=a.ctx,
4872 )
4873
4874
4875def ArraySort(*sig):
4876 """Return the Z3 array sort with the given domain and range sorts.
4877
4878 >>> A = ArraySort(IntSort(), BoolSort())
4879 >>> A
4880 Array(Int, Bool)
4881 >>> A.domain()
4882 Int
4883 >>> A.range()
4884 Bool
4885 >>> AA = ArraySort(IntSort(), A)
4886 >>> AA
4887 Array(Int, Array(Int, Bool))
4888 """
4889 sig = _get_args(sig)
4890 if z3_debug():
4891 _z3_assert(len(sig) > 1, "At least two arguments expected")
4892 arity = len(sig) - 1
4893 r = sig[arity]
4894 d = sig[0]
4895 if z3_debug():
4896 for s in sig:
4897 _z3_assert(is_sort(s), "Z3 sort expected")
4898 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4899 ctx = d.ctx
4900 if len(sig) == 2:
4901 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4902 dom = (Sort * arity)()
4903 for i in range(arity):
4904 dom[i] = sig[i].ast
4905 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4906
4907
4908def Array(name, *sorts):
4909 """Return an array constant named `name` with the given domain and range sorts.
4910
4911 >>> a = Array('a', IntSort(), IntSort())
4912 >>> a.sort()
4913 Array(Int, Int)
4914 >>> a[0]
4915 a[0]
4916 """
4917 s = ArraySort(sorts)
4918 ctx = s.ctx
4919 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4920
4921
4922def Update(a, *args):
4923 """Return a Z3 store array expression.
4924
4925 >>> a = Array('a', IntSort(), IntSort())
4926 >>> i, v = Ints('i v')
4927 >>> s = Update(a, i, v)
4928 >>> s.sort()
4929 Array(Int, Int)
4930 >>> prove(s[i] == v)
4931 proved
4932 >>> j = Int('j')
4933 >>> prove(Implies(i != j, s[j] == a[j]))
4934 proved
4935 """
4936 if z3_debug():
4937 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4938 args = _get_args(args)
4939 ctx = a.ctx
4940 if len(args) <= 1:
4941 raise Z3Exception("array update requires index and value arguments")
4942 if len(args) == 2:
4943 i = args[0]
4944 v = args[1]
4945 i = a.sort().domain().cast(i)
4946 v = a.sort().range().cast(v)
4947 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4948 v = a.sort().range().cast(args[-1])
4949 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4950 _args, sz = _to_ast_array(idxs)
4951 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4952
4953
4954def Default(a):
4955 """ Return a default value for array expression.
4956 >>> b = K(IntSort(), 1)
4957 >>> prove(Default(b) == 1)
4958 proved
4959 """
4960 if z3_debug():
4961 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4962 return a.default()
4963
4964
4965def Store(a, *args):
4966 """Return a Z3 store array expression.
4967
4968 >>> a = Array('a', IntSort(), IntSort())
4969 >>> i, v = Ints('i v')
4970 >>> s = Store(a, i, v)
4971 >>> s.sort()
4972 Array(Int, Int)
4973 >>> prove(s[i] == v)
4974 proved
4975 >>> j = Int('j')
4976 >>> prove(Implies(i != j, s[j] == a[j]))
4977 proved
4978 """
4979 return Update(a, args)
4980
4981
4982def Select(a, *args):
4983 """Return a Z3 select array expression.
4984
4985 >>> a = Array('a', IntSort(), IntSort())
4986 >>> i = Int('i')
4987 >>> Select(a, i)
4988 a[i]
4989 >>> eq(Select(a, i), a[i])
4990 True
4991 """
4992 args = _get_args(args)
4993 if z3_debug():
4994 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4995 return a[args]
4996
4997
4998def Map(f, *args):
4999 """Return a Z3 map array expression.
5000
5001 >>> f = Function('f', IntSort(), IntSort(), IntSort())
5002 >>> a1 = Array('a1', IntSort(), IntSort())
5003 >>> a2 = Array('a2', IntSort(), IntSort())
5004 >>> b = Map(f, a1, a2)
5005 >>> b
5006 Map(f, a1, a2)
5007 >>> prove(b[0] == f(a1[0], a2[0]))
5008 proved
5009 """
5010 args = _get_args(args)
5011 if z3_debug():
5012 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
5013 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
5014 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
5015 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
5016 _args, sz = _to_ast_array(args)
5017 ctx = f.ctx
5018 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
5019
5020
5021def K(dom, v):
5022 """Return a Z3 constant array expression.
5023
5024 >>> a = K(IntSort(), 10)
5025 >>> a
5026 K(Int, 10)
5027 >>> a.sort()
5028 Array(Int, Int)
5029 >>> i = Int('i')
5030 >>> a[i]
5031 K(Int, 10)[i]
5032 >>> simplify(a[i])
5033 10
5034 """
5035 if z3_debug():
5036 _z3_assert(is_sort(dom), "Z3 sort expected")
5037 ctx = dom.ctx
5038 if not is_expr(v):
5039 v = _py2expr(v, ctx)
5040 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
5041
5042
5043def Ext(a, b):
5044 """Return extensionality index for one-dimensional arrays.
5045 >> a, b = Consts('a b', SetSort(IntSort()))
5046 >> Ext(a, b)
5047 Ext(a, b)
5048 """
5049 ctx = a.ctx
5050 if z3_debug():
5051 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
5052 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5053
5055 """Return `True` if `a` is a Z3 array select application.
5056
5057 >>> a = Array('a', IntSort(), IntSort())
5058 >>> is_select(a)
5059 False
5060 >>> i = Int('i')
5061 >>> is_select(a[i])
5062 True
5063 """
5064 return is_app_of(a, Z3_OP_SELECT)
5065
5066
5068 """Return `True` if `a` is a Z3 array store application.
5069
5070 >>> a = Array('a', IntSort(), IntSort())
5071 >>> is_store(a)
5072 False
5073 >>> is_store(Store(a, 0, 1))
5074 True
5075 """
5076 return is_app_of(a, Z3_OP_STORE)
5077
5078
5083
5084
5085def SetSort(s):
5086 """ Create a set sort over element sort s"""
5087 return ArraySort(s, BoolSort())
5088
5089
5091 """Create the empty set
5092 >>> EmptySet(IntSort())
5093 K(Int, False)
5094 """
5095 ctx = s.ctx
5096 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5097
5098
5099def FullSet(s):
5100 """Create the full set
5101 >>> FullSet(IntSort())
5102 K(Int, True)
5103 """
5104 ctx = s.ctx
5105 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5106
5107
5108def SetUnion(*args):
5109 """ Take the union of sets
5110 >>> a = Const('a', SetSort(IntSort()))
5111 >>> b = Const('b', SetSort(IntSort()))
5112 >>> SetUnion(a, b)
5113 union(a, b)
5114 """
5115 args = _get_args(args)
5116 ctx = _ctx_from_ast_arg_list(args)
5117 _args, sz = _to_ast_array(args)
5118 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5119
5120
5121def SetIntersect(*args):
5122 """ Take the union of sets
5123 >>> a = Const('a', SetSort(IntSort()))
5124 >>> b = Const('b', SetSort(IntSort()))
5125 >>> SetIntersect(a, b)
5126 intersection(a, b)
5127 """
5128 args = _get_args(args)
5129 ctx = _ctx_from_ast_arg_list(args)
5130 _args, sz = _to_ast_array(args)
5131 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5132
5133
5134def SetAdd(s, e):
5135 """ Add element e to set s
5136 >>> a = Const('a', SetSort(IntSort()))
5137 >>> SetAdd(a, 1)
5138 Store(a, 1, True)
5139 """
5140 ctx = _ctx_from_ast_arg_list([s, e])
5141 e = _py2expr(e, ctx)
5142 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5143
5144
5145def SetDel(s, e):
5146 """ Remove element e to set s
5147 >>> a = Const('a', SetSort(IntSort()))
5148 >>> SetDel(a, 1)
5149 Store(a, 1, False)
5150 """
5151 ctx = _ctx_from_ast_arg_list([s, e])
5152 e = _py2expr(e, ctx)
5153 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5154
5155
5157 """ The complement of set s
5158 >>> a = Const('a', SetSort(IntSort()))
5159 >>> SetComplement(a)
5160 complement(a)
5161 """
5162 ctx = s.ctx
5163 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5164
5165
5167 """ The set difference of a and b
5168 >>> a = Const('a', SetSort(IntSort()))
5169 >>> b = Const('b', SetSort(IntSort()))
5170 >>> SetDifference(a, b)
5171 setminus(a, b)
5172 """
5173 ctx = _ctx_from_ast_arg_list([a, b])
5174 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5175
5176
5177def IsMember(e, s):
5178 """ Check if e is a member of set s
5179 >>> a = Const('a', SetSort(IntSort()))
5180 >>> IsMember(1, a)
5181 a[1]
5182 """
5183 ctx = _ctx_from_ast_arg_list([s, e])
5184 e = _py2expr(e, ctx)
5185 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5186
5187
5188def IsSubset(a, b):
5189 """ Check if a is a subset of b
5190 >>> a = Const('a', SetSort(IntSort()))
5191 >>> b = Const('b', SetSort(IntSort()))
5192 >>> IsSubset(a, b)
5193 subset(a, b)
5194 """
5195 ctx = _ctx_from_ast_arg_list([a, b])
5196 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5197
5198
5199
5204
5206 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5207 if not isinstance(acc, tuple):
5208 return False
5209 if len(acc) != 2:
5210 return False
5211 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5212
5213
5215 """Helper class for declaring Z3 datatypes.
5216
5217 >>> List = Datatype('List')
5218 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5219 >>> List.declare('nil')
5220 >>> List = List.create()
5221 >>> # List is now a Z3 declaration
5222 >>> List.nil
5223 nil
5224 >>> List.cons(10, List.nil)
5225 cons(10, nil)
5226 >>> List.cons(10, List.nil).sort()
5227 List
5228 >>> cons = List.cons
5229 >>> nil = List.nil
5230 >>> car = List.car
5231 >>> cdr = List.cdr
5232 >>> n = cons(1, cons(0, nil))
5233 >>> n
5234 cons(1, cons(0, nil))
5235 >>> simplify(cdr(n))
5236 cons(0, nil)
5237 >>> simplify(car(n))
5238 1
5239 """
5240
5241 def __init__(self, name, ctx=None):
5242 self.ctx = _get_ctx(ctx)
5243 self.name = name
5245
5246 def __deepcopy__(self, memo={}):
5247 r = Datatype(self.name, self.ctx)
5248 r.constructors = copy.deepcopy(self.constructors)
5249 return r
5250
5251 def declare_core(self, name, rec_name, *args):
5252 if z3_debug():
5253 _z3_assert(isinstance(name, str), "String expected")
5254 _z3_assert(isinstance(rec_name, str), "String expected")
5255 _z3_assert(
5256 all([_valid_accessor(a) for a in args]),
5257 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5258 )
5259 self.constructors.append((name, rec_name, args))
5260
5261 def declare(self, name, *args):
5262 """Declare constructor named `name` with the given accessors `args`.
5263 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5264 or a reference to the datatypes being declared.
5265
5266 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5267 declares the constructor named `cons` that builds a new List using an integer and a List.
5268 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5269 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5270 we use the method create() to create the actual datatype in Z3.
5271
5272 >>> List = Datatype('List')
5273 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5274 >>> List.declare('nil')
5275 >>> List = List.create()
5276 """
5277 if z3_debug():
5278 _z3_assert(isinstance(name, str), "String expected")
5279 _z3_assert(name != "", "Constructor name cannot be empty")
5280 return self.declare_core(name, "is-" + name, *args)
5281
5282 def __repr__(self):
5283 return "Datatype(%s, %s)" % (self.name, self.constructors)
5284
5285 def create(self):
5286 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5287
5288 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5289
5290 >>> List = Datatype('List')
5291 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5292 >>> List.declare('nil')
5293 >>> List = List.create()
5294 >>> List.nil
5295 nil
5296 >>> List.cons(10, List.nil)
5297 cons(10, nil)
5298 """
5299 return CreateDatatypes([self])[0]
5300
5301
5303 """Auxiliary object used to create Z3 datatypes."""
5304
5305 def __init__(self, c, ctx):
5306 self.c = c
5307 self.ctx = ctx
5308
5309 def __del__(self):
5310 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5311 Z3_del_constructor(self.ctx.ref(), self.c)
5312
5313
5315 """Auxiliary object used to create Z3 datatypes."""
5316
5317 def __init__(self, c, ctx):
5318 self.c = c
5319 self.ctx = ctx
5320
5321 def __del__(self):
5322 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5323 Z3_del_constructor_list(self.ctx.ref(), self.c)
5324
5325
5327 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5328
5329 In the following example we define a Tree-List using two mutually recursive datatypes.
5330
5331 >>> TreeList = Datatype('TreeList')
5332 >>> Tree = Datatype('Tree')
5333 >>> # Tree has two constructors: leaf and node
5334 >>> Tree.declare('leaf', ('val', IntSort()))
5335 >>> # a node contains a list of trees
5336 >>> Tree.declare('node', ('children', TreeList))
5337 >>> TreeList.declare('nil')
5338 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5339 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5340 >>> Tree.val(Tree.leaf(10))
5341 val(leaf(10))
5342 >>> simplify(Tree.val(Tree.leaf(10)))
5343 10
5344 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5345 >>> n1
5346 node(cons(leaf(10), cons(leaf(20), nil)))
5347 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5348 >>> simplify(n2 == n1)
5349 False
5350 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5351 True
5352 """
5353 ds = _get_args(ds)
5354 if z3_debug():
5355 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5356 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5357 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5358 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5359 ctx = ds[0].ctx
5360 num = len(ds)
5361 names = (Symbol * num)()
5362 out = (Sort * num)()
5363 clists = (ConstructorList * num)()
5364 to_delete = []
5365 for i in range(num):
5366 d = ds[i]
5367 names[i] = to_symbol(d.name, ctx)
5368 num_cs = len(d.constructors)
5369 cs = (Constructor * num_cs)()
5370 for j in range(num_cs):
5371 c = d.constructors[j]
5372 cname = to_symbol(c[0], ctx)
5373 rname = to_symbol(c[1], ctx)
5374 fs = c[2]
5375 num_fs = len(fs)
5376 fnames = (Symbol * num_fs)()
5377 sorts = (Sort * num_fs)()
5378 refs = (ctypes.c_uint * num_fs)()
5379 for k in range(num_fs):
5380 fname = fs[k][0]
5381 ftype = fs[k][1]
5382 fnames[k] = to_symbol(fname, ctx)
5383 if isinstance(ftype, Datatype):
5384 if z3_debug():
5385 _z3_assert(
5386 ds.count(ftype) == 1,
5387 "One and only one occurrence of each datatype is expected",
5388 )
5389 sorts[k] = None
5390 refs[k] = ds.index(ftype)
5391 else:
5392 if z3_debug():
5393 _z3_assert(is_sort(ftype), "Z3 sort expected")
5394 sorts[k] = ftype.ast
5395 refs[k] = 0
5396 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5397 to_delete.append(ScopedConstructor(cs[j], ctx))
5398 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5399 to_delete.append(ScopedConstructorList(clists[i], ctx))
5400 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5401 result = []
5402 # Create a field for every constructor, recognizer and accessor
5403 for i in range(num):
5404 dref = DatatypeSortRef(out[i], ctx)
5405 num_cs = dref.num_constructors()
5406 for j in range(num_cs):
5407 cref = dref.constructor(j)
5408 cref_name = cref.name()
5409 cref_arity = cref.arity()
5410 if cref.arity() == 0:
5411 cref = cref()
5412 setattr(dref, cref_name, cref)
5413 rref = dref.recognizer(j)
5414 setattr(dref, "is_" + cref_name, rref)
5415 for k in range(cref_arity):
5416 aref = dref.accessor(j, k)
5417 setattr(dref, aref.name(), aref)
5418 result.append(dref)
5419 return tuple(result)
5420
5421
5423 """Datatype sorts."""
5424
5426 """Return the number of constructors in the given Z3 datatype.
5427
5428 >>> List = Datatype('List')
5429 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5430 >>> List.declare('nil')
5431 >>> List = List.create()
5432 >>> # List is now a Z3 declaration
5433 >>> List.num_constructors()
5434 2
5435 """
5437
5438 def constructor(self, idx):
5439 """Return a constructor of the datatype `self`.
5440
5441 >>> List = Datatype('List')
5442 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5443 >>> List.declare('nil')
5444 >>> List = List.create()
5445 >>> # List is now a Z3 declaration
5446 >>> List.num_constructors()
5447 2
5448 >>> List.constructor(0)
5449 cons
5450 >>> List.constructor(1)
5451 nil
5452 """
5453 if z3_debug():
5454 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5456
5457 def recognizer(self, idx):
5458 """In Z3, each constructor has an associated recognizer predicate.
5459
5460 If the constructor is named `name`, then the recognizer `is_name`.
5461
5462 >>> List = Datatype('List')
5463 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5464 >>> List.declare('nil')
5465 >>> List = List.create()
5466 >>> # List is now a Z3 declaration
5467 >>> List.num_constructors()
5468 2
5469 >>> List.recognizer(0)
5470 is(cons)
5471 >>> List.recognizer(1)
5472 is(nil)
5473 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5474 False
5475 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5476 True
5477 >>> l = Const('l', List)
5478 >>> simplify(List.is_cons(l))
5479 is(cons, l)
5480 """
5481 if z3_debug():
5482 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5483 return FuncDeclRef(Z3_get_datatype_sort_recognizer(self.ctx_ref(), self.ast, idx), self.ctx)
5484
5485 def accessor(self, i, j):
5486 """In Z3, each constructor has 0 or more accessor.
5487 The number of accessors is equal to the arity of the constructor.
5488
5489 >>> List = Datatype('List')
5490 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5491 >>> List.declare('nil')
5492 >>> List = List.create()
5493 >>> List.num_constructors()
5494 2
5495 >>> List.constructor(0)
5496 cons
5497 >>> num_accs = List.constructor(0).arity()
5498 >>> num_accs
5499 2
5500 >>> List.accessor(0, 0)
5501 car
5502 >>> List.accessor(0, 1)
5503 cdr
5504 >>> List.constructor(1)
5505 nil
5506 >>> num_accs = List.constructor(1).arity()
5507 >>> num_accs
5508 0
5509 """
5510 if z3_debug():
5511 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5512 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5513 return FuncDeclRef(
5515 ctx=self.ctx,
5516 )
5517
5518
5520 """Datatype expressions."""
5521
5522 def sort(self):
5523 """Return the datatype sort of the datatype expression `self`."""
5524 return DatatypeSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
5525
5526 def update_field(self, field_accessor, new_value):
5527 """Return a new datatype expression with the specified field updated.
5528
5529 Args:
5530 field_accessor: The accessor function declaration for the field to update
5531 new_value: The new value for the field
5532
5533 Returns:
5534 A new datatype expression with the field updated, other fields unchanged
5535
5536 Example:
5537 >>> Person = Datatype('Person')
5538 >>> Person.declare('person', ('name', StringSort()), ('age', IntSort()))
5539 >>> Person = Person.create()
5540 >>> person_age = Person.accessor(0, 1) # age accessor
5541 >>> p = Const('p', Person)
5542 >>> p2 = p.update_field(person_age, IntVal(30))
5543 """
5544 if z3_debug():
5545 _z3_assert(is_func_decl(field_accessor), "Z3 function declaration expected")
5546 _z3_assert(is_expr(new_value), "Z3 expression expected")
5547 return _to_expr_ref(
5548 Z3_datatype_update_field(self.ctx_ref(), field_accessor.ast, self.as_ast(), new_value.as_ast()),
5549 self.ctx
5550 )
5551
5552def DatatypeSort(name, params=None, ctx=None):
5553 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype.
5554
5555 Args:
5556 name: name of the datatype sort
5557 params: optional list/tuple of sort parameters for parametric datatypes
5558 ctx: Z3 context (optional)
5559
5560 Example:
5561 >>> # Non-parametric datatype
5562 >>> TreeRef = DatatypeSort('Tree')
5563 >>> # Parametric datatype with one parameter
5564 >>> ListIntRef = DatatypeSort('List', [IntSort()])
5565 >>> # Parametric datatype with multiple parameters
5566 >>> PairRef = DatatypeSort('Pair', [IntSort(), BoolSort()])
5567 """
5568 ctx = _get_ctx(ctx)
5569 if params is None or len(params) == 0:
5570 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), 0, (Sort * 0)()), ctx)
5571 else:
5572 _params = (Sort * len(params))()
5573 for i in range(len(params)):
5574 _params[i] = params[i].ast
5575 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), len(params), _params), ctx)
5576
5577def TupleSort(name, sorts, ctx=None):
5578 """Create a named tuple sort base on a set of underlying sorts
5579 Example:
5580 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5581 """
5582 tuple = Datatype(name, ctx)
5583 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5584 tuple.declare(name, *projects)
5585 tuple = tuple.create()
5586 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5587
5588
5589def DisjointSum(name, sorts, ctx=None):
5590 """Create a named tagged union sort base on a set of underlying sorts
5591 Example:
5592 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5593 """
5594 sum = Datatype(name, ctx)
5595 for i in range(len(sorts)):
5596 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5597 sum = sum.create()
5598 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5599
5600
5601def EnumSort(name, values, ctx=None):
5602 """Return a new enumeration sort named `name` containing the given values.
5603
5604 The result is a pair (sort, list of constants).
5605 Example:
5606 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5607 """
5608 if z3_debug():
5609 _z3_assert(isinstance(name, str), "Name must be a string")
5610 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5611 _z3_assert(len(values) > 0, "At least one value expected")
5612 ctx = _get_ctx(ctx)
5613 num = len(values)
5614 _val_names = (Symbol * num)()
5615 for i in range(num):
5616 _val_names[i] = to_symbol(values[i], ctx)
5617 _values = (FuncDecl * num)()
5618 _testers = (FuncDecl * num)()
5619 name = to_symbol(name, ctx)
5620 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5621 V = []
5622 for i in range(num):
5623 V.append(FuncDeclRef(_values[i], ctx))
5624 V = [a() for a in V]
5625 return S, V
5626
5627
5632
5633
5635 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5636
5637 Consider using the function `args2params` to create instances of this object.
5638 """
5639
5640 def __init__(self, ctx=None, params=None):
5641 self.ctx = _get_ctx(ctx)
5642 if params is None:
5643 self.params = Z3_mk_params(self.ctx.ref())
5644 else:
5645 self.params = params
5646 Z3_params_inc_ref(self.ctx.ref(), self.params)
5647
5648 def __deepcopy__(self, memo={}):
5649 return ParamsRef(self.ctx, self.params)
5650
5651 def __del__(self):
5652 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5653 Z3_params_dec_ref(self.ctx.ref(), self.params)
5654
5655 def set(self, name, val):
5656 """Set parameter name with value val."""
5657 if z3_debug():
5658 _z3_assert(isinstance(name, str), "parameter name must be a string")
5659 name_sym = to_symbol(name, self.ctx)
5660 if isinstance(val, bool):
5661 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5662 elif _is_int(val):
5663 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5664 elif isinstance(val, float):
5665 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5666 elif isinstance(val, str):
5667 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5668 else:
5669 if z3_debug():
5670 _z3_assert(False, "invalid parameter value")
5671
5672 def __repr__(self):
5673 return Z3_params_to_string(self.ctx.ref(), self.params)
5674
5675 def validate(self, ds):
5676 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5677 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5678
5679
5680def args2params(arguments, keywords, ctx=None):
5681 """Convert python arguments into a Z3_params object.
5682 A ':' is added to the keywords, and '_' is replaced with '-'
5683
5684 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5685 (params model true relevancy 2 elim_and true)
5686 """
5687 if z3_debug():
5688 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5689 prev = None
5690 r = ParamsRef(ctx)
5691 for a in arguments:
5692 if prev is None:
5693 prev = a
5694 else:
5695 r.set(prev, a)
5696 prev = None
5697 for k in keywords:
5698 v = keywords[k]
5699 r.set(k, v)
5700 return r
5701
5702
5704 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5705 """
5706
5707 def __init__(self, descr, ctx=None):
5708 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5709 self.ctx = _get_ctx(ctx)
5710 self.descr = descr
5711 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5712
5713 def __deepcopy__(self, memo={}):
5714 return ParamsDescrsRef(self.descr, self.ctx)
5715
5716 def __del__(self):
5717 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5718 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5719
5720 def size(self):
5721 """Return the size of in the parameter description `self`.
5722 """
5723 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5724
5725 def __len__(self):
5726 """Return the size of in the parameter description `self`.
5727 """
5728 return self.size()
5729
5730 def get_name(self, i):
5731 """Return the i-th parameter name in the parameter description `self`.
5732 """
5733 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5734
5735 def get_kind(self, n):
5736 """Return the kind of the parameter named `n`.
5737 """
5738 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5739
5740 def get_documentation(self, n):
5741 """Return the documentation string of the parameter named `n`.
5742 """
5743 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5744
5745 def __getitem__(self, arg):
5746 if _is_int(arg):
5747 return self.get_name(arg)
5748 else:
5749 return self.get_kind(arg)
5750
5751 def __repr__(self):
5752 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5753
5754
5759
5760
5762 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5763
5764 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5765 A goal has a solution if one of its subgoals has a solution.
5766 A goal is unsatisfiable if all subgoals are unsatisfiable.
5767 """
5768
5769 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5770 if z3_debug():
5771 _z3_assert(goal is None or ctx is not None,
5772 "If goal is different from None, then ctx must be also different from None")
5773 self.ctx = _get_ctx(ctx)
5774 self.goal = goal
5775 if self.goal is None:
5776 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5777 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5778
5779 def __del__(self):
5780 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5781 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5782
5783 def depth(self):
5784 """Return the depth of the goal `self`.
5785 The depth corresponds to the number of tactics applied to `self`.
5786
5787 >>> x, y = Ints('x y')
5788 >>> g = Goal()
5789 >>> g.add(x == 0, y >= x + 1)
5790 >>> g.depth()
5791 0
5792 >>> r = Then('simplify', 'solve-eqs')(g)
5793 >>> # r has 1 subgoal
5794 >>> len(r)
5795 1
5796 >>> r[0].depth()
5797 2
5798 """
5799 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5800
5801 def inconsistent(self):
5802 """Return `True` if `self` contains the `False` constraints.
5803
5804 >>> x, y = Ints('x y')
5805 >>> g = Goal()
5806 >>> g.inconsistent()
5807 False
5808 >>> g.add(x == 0, x == 1)
5809 >>> g
5810 [x == 0, x == 1]
5811 >>> g.inconsistent()
5812 False
5813 >>> g2 = Tactic('propagate-values')(g)[0]
5814 >>> g2.inconsistent()
5815 True
5816 """
5817 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5818
5819 def prec(self):
5820 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5821
5822 >>> g = Goal()
5823 >>> g.prec() == Z3_GOAL_PRECISE
5824 True
5825 >>> x, y = Ints('x y')
5826 >>> g.add(x == y + 1)
5827 >>> g.prec() == Z3_GOAL_PRECISE
5828 True
5829 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5830 >>> g2 = t(g)[0]
5831 >>> g2
5832 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5833 >>> g2.prec() == Z3_GOAL_PRECISE
5834 False
5835 >>> g2.prec() == Z3_GOAL_UNDER
5836 True
5837 """
5838 return Z3_goal_precision(self.ctx.ref(), self.goal)
5839
5840 def precision(self):
5841 """Alias for `prec()`.
5842
5843 >>> g = Goal()
5844 >>> g.precision() == Z3_GOAL_PRECISE
5845 True
5846 """
5847 return self.prec()
5848
5849 def size(self):
5850 """Return the number of constraints in the goal `self`.
5851
5852 >>> g = Goal()
5853 >>> g.size()
5854 0
5855 >>> x, y = Ints('x y')
5856 >>> g.add(x == 0, y > x)
5857 >>> g.size()
5858 2
5859 """
5860 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5861
5862 def __len__(self):
5863 """Return the number of constraints in the goal `self`.
5864
5865 >>> g = Goal()
5866 >>> len(g)
5867 0
5868 >>> x, y = Ints('x y')
5869 >>> g.add(x == 0, y > x)
5870 >>> len(g)
5871 2
5872 """
5873 return self.size()
5874
5875 def get(self, i):
5876 """Return a constraint in the goal `self`.
5877
5878 >>> g = Goal()
5879 >>> x, y = Ints('x y')
5880 >>> g.add(x == 0, y > x)
5881 >>> g.get(0)
5882 x == 0
5883 >>> g.get(1)
5884 y > x
5885 """
5886 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5887
5888 def __getitem__(self, arg):
5889 """Return a constraint in the goal `self`.
5890
5891 >>> g = Goal()
5892 >>> x, y = Ints('x y')
5893 >>> g.add(x == 0, y > x)
5894 >>> g[0]
5895 x == 0
5896 >>> g[1]
5897 y > x
5898 """
5899 if arg >= len(self):
5900 raise IndexError
5901 return self.get(arg)
5902
5903 def assert_exprs(self, *args):
5904 """Assert constraints into the goal.
5905
5906 >>> x = Int('x')
5907 >>> g = Goal()
5908 >>> g.assert_exprs(x > 0, x < 2)
5909 >>> g
5910 [x > 0, x < 2]
5911 """
5912 args = _get_args(args)
5913 s = BoolSort(self.ctx)
5914 for arg in args:
5915 arg = s.cast(arg)
5916 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5917
5918 def append(self, *args):
5919 """Add constraints.
5920
5921 >>> x = Int('x')
5922 >>> g = Goal()
5923 >>> g.append(x > 0, x < 2)
5924 >>> g
5925 [x > 0, x < 2]
5926 """
5927 self.assert_exprs(*args)
5928
5929 def insert(self, *args):
5930 """Add constraints.
5931
5932 >>> x = Int('x')
5933 >>> g = Goal()
5934 >>> g.insert(x > 0, x < 2)
5935 >>> g
5936 [x > 0, x < 2]
5937 """
5938 self.assert_exprs(*args)
5939
5940 def add(self, *args):
5941 """Add constraints.
5942
5943 >>> x = Int('x')
5944 >>> g = Goal()
5945 >>> g.add(x > 0, x < 2)
5946 >>> g
5947 [x > 0, x < 2]
5948 """
5949 self.assert_exprs(*args)
5950
5951 def convert_model(self, model):
5952 """Retrieve model from a satisfiable goal
5953 >>> a, b = Ints('a b')
5954 >>> g = Goal()
5955 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5956 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5957 >>> r = t(g)
5958 >>> r[0]
5959 [Or(b == 0, b == 1), Not(0 <= b)]
5960 >>> r[1]
5961 [Or(b == 0, b == 1), Not(1 <= b)]
5962 >>> # Remark: the subgoal r[0] is unsatisfiable
5963 >>> # Creating a solver for solving the second subgoal
5964 >>> s = Solver()
5965 >>> s.add(r[1])
5966 >>> s.check()
5967 sat
5968 >>> s.model()
5969 [b = 0]
5970 >>> # Model s.model() does not assign a value to `a`
5971 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5972 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5973 >>> r[1].convert_model(s.model())
5974 [b = 0, a = 1]
5975 """
5976 if z3_debug():
5977 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5978 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5979
5980 def __repr__(self):
5981 return obj_to_string(self)
5982
5983 def sexpr(self):
5984 """Return a textual representation of the s-expression representing the goal."""
5985 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5986
5987 def dimacs(self, include_names=True):
5988 """Return a textual representation of the goal in DIMACS format."""
5989 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5990
5991 def translate(self, target):
5992 """Copy goal `self` to context `target`.
5993
5994 >>> x = Int('x')
5995 >>> g = Goal()
5996 >>> g.add(x > 10)
5997 >>> g
5998 [x > 10]
5999 >>> c2 = Context()
6000 >>> g2 = g.translate(c2)
6001 >>> g2
6002 [x > 10]
6003 >>> g.ctx == main_ctx()
6004 True
6005 >>> g2.ctx == c2
6006 True
6007 >>> g2.ctx == main_ctx()
6008 False
6009 """
6010 if z3_debug():
6011 _z3_assert(isinstance(target, Context), "target must be a context")
6012 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
6013
6014 def __copy__(self):
6015 return self.translate(self.ctx)
6016
6017 def __deepcopy__(self, memo={}):
6018 return self.translate(self.ctx)
6019
6020 def simplify(self, *arguments, **keywords):
6021 """Return a new simplified goal.
6022
6023 This method is essentially invoking the simplify tactic.
6024
6025 >>> g = Goal()
6026 >>> x = Int('x')
6027 >>> g.add(x + 1 >= 2)
6028 >>> g
6029 [x + 1 >= 2]
6030 >>> g2 = g.simplify()
6031 >>> g2
6032 [x >= 1]
6033 >>> # g was not modified
6034 >>> g
6035 [x + 1 >= 2]
6036 """
6037 t = Tactic("simplify")
6038 return t.apply(self, *arguments, **keywords)[0]
6039
6040 def as_expr(self):
6041 """Return goal `self` as a single Z3 expression.
6042
6043 >>> x = Int('x')
6044 >>> g = Goal()
6045 >>> g.as_expr()
6046 True
6047 >>> g.add(x > 1)
6048 >>> g.as_expr()
6049 x > 1
6050 >>> g.add(x < 10)
6051 >>> g.as_expr()
6052 And(x > 1, x < 10)
6053 """
6054 sz = len(self)
6055 if sz == 0:
6056 return BoolVal(True, self.ctx)
6057 elif sz == 1:
6058 return self.get(0)
6059 else:
6060 return And([self.get(i) for i in range(len(self))], self.ctx)
6061
6062
6067
6068
6070 """A collection (vector) of ASTs."""
6071
6072 def __init__(self, v=None, ctx=None):
6073 self.vector = None
6074 if v is None:
6075 self.ctx = _get_ctx(ctx)
6076 self.vector = Z3_mk_ast_vector(self.ctx.ref())
6077 else:
6078 self.vector = v
6079 assert ctx is not None
6080 self.ctx = ctx
6081 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
6082
6083 def __del__(self):
6084 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
6085 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
6086
6087 def __len__(self):
6088 """Return the size of the vector `self`.
6089
6090 >>> A = AstVector()
6091 >>> len(A)
6092 0
6093 >>> A.push(Int('x'))
6094 >>> A.push(Int('x'))
6095 >>> len(A)
6096 2
6097 """
6098 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
6099
6100 def __getitem__(self, i):
6101 """Return the AST at position `i`.
6102
6103 >>> A = AstVector()
6104 >>> A.push(Int('x') + 1)
6105 >>> A.push(Int('y'))
6106 >>> A[0]
6107 x + 1
6108 >>> A[1]
6109 y
6110 """
6111
6112 if isinstance(i, int):
6113 if i < 0:
6114 i += self.__len__()
6115
6116 if i >= self.__len__():
6117 raise IndexError
6118 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
6119
6120 elif isinstance(i, slice):
6121 result = []
6122 for ii in range(*i.indices(self.__len__())):
6123 result.append(_to_ast_ref(
6124 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6125 self.ctx,
6126 ))
6127 return result
6128
6129 def __setitem__(self, i, v):
6130 """Update AST at position `i`.
6131
6132 >>> A = AstVector()
6133 >>> A.push(Int('x') + 1)
6134 >>> A.push(Int('y'))
6135 >>> A[0]
6136 x + 1
6137 >>> A[0] = Int('x')
6138 >>> A[0]
6139 x
6140 """
6141 if i >= self.__len__():
6142 raise IndexError
6143 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6144
6145 def push(self, v):
6146 """Add `v` in the end of the vector.
6147
6148 >>> A = AstVector()
6149 >>> len(A)
6150 0
6151 >>> A.push(Int('x'))
6152 >>> len(A)
6153 1
6154 """
6155 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6156
6157 def resize(self, sz):
6158 """Resize the vector to `sz` elements.
6159
6160 >>> A = AstVector()
6161 >>> A.resize(10)
6162 >>> len(A)
6163 10
6164 >>> for i in range(10): A[i] = Int('x')
6165 >>> A[5]
6166 x
6167 """
6168 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6169
6170 def __contains__(self, item):
6171 """Return `True` if the vector contains `item`.
6172
6173 >>> x = Int('x')
6174 >>> A = AstVector()
6175 >>> x in A
6176 False
6177 >>> A.push(x)
6178 >>> x in A
6179 True
6180 >>> (x+1) in A
6181 False
6182 >>> A.push(x+1)
6183 >>> (x+1) in A
6184 True
6185 >>> A
6186 [x, x + 1]
6187 """
6188 for elem in self:
6189 if elem.eq(item):
6190 return True
6191 return False
6192
6193 def translate(self, other_ctx):
6194 """Copy vector `self` to context `other_ctx`.
6195
6196 >>> x = Int('x')
6197 >>> A = AstVector()
6198 >>> A.push(x)
6199 >>> c2 = Context()
6200 >>> B = A.translate(c2)
6201 >>> B
6202 [x]
6203 """
6204 return AstVector(
6205 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6206 ctx=other_ctx,
6207 )
6208
6209 def __copy__(self):
6210 return self.translate(self.ctx)
6211
6212 def __deepcopy__(self, memo={}):
6213 return self.translate(self.ctx)
6214
6215 def __repr__(self):
6216 return obj_to_string(self)
6217
6218 def sexpr(self):
6219 """Return a textual representation of the s-expression representing the vector."""
6220 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6221
6222
6227
6228
6230 """A mapping from ASTs to ASTs."""
6231
6232 def __init__(self, m=None, ctx=None):
6233 self.map = None
6234 if m is None:
6235 self.ctx = _get_ctx(ctx)
6236 self.map = Z3_mk_ast_map(self.ctx.ref())
6237 else:
6238 self.map = m
6239 assert ctx is not None
6240 self.ctx = ctx
6241 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6242
6243 def __deepcopy__(self, memo={}):
6244 return AstMap(self.map, self.ctx)
6245
6246 def __del__(self):
6247 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6248 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6249
6250 def __len__(self):
6251 """Return the size of the map.
6252
6253 >>> M = AstMap()
6254 >>> len(M)
6255 0
6256 >>> x = Int('x')
6257 >>> M[x] = IntVal(1)
6258 >>> len(M)
6259 1
6260 """
6261 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6262
6263 def __contains__(self, key):
6264 """Return `True` if the map contains key `key`.
6265
6266 >>> M = AstMap()
6267 >>> x = Int('x')
6268 >>> M[x] = x + 1
6269 >>> x in M
6270 True
6271 >>> x+1 in M
6272 False
6273 """
6274 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6275
6276 def __getitem__(self, key):
6277 """Retrieve the value associated with key `key`.
6278
6279 >>> M = AstMap()
6280 >>> x = Int('x')
6281 >>> M[x] = x + 1
6282 >>> M[x]
6283 x + 1
6284 """
6285 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6286
6287 def __setitem__(self, k, v):
6288 """Add/Update key `k` with value `v`.
6289
6290 >>> M = AstMap()
6291 >>> x = Int('x')
6292 >>> M[x] = x + 1
6293 >>> len(M)
6294 1
6295 >>> M[x]
6296 x + 1
6297 >>> M[x] = IntVal(1)
6298 >>> M[x]
6299 1
6300 """
6301 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6302
6303 def __repr__(self):
6304 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6305
6306 def erase(self, k):
6307 """Remove the entry associated with key `k`.
6308
6309 >>> M = AstMap()
6310 >>> x = Int('x')
6311 >>> M[x] = x + 1
6312 >>> len(M)
6313 1
6314 >>> M.erase(x)
6315 >>> len(M)
6316 0
6317 """
6318 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6319
6320 def reset(self):
6321 """Remove all entries from the map.
6322
6323 >>> M = AstMap()
6324 >>> x = Int('x')
6325 >>> M[x] = x + 1
6326 >>> M[x+x] = IntVal(1)
6327 >>> len(M)
6328 2
6329 >>> M.reset()
6330 >>> len(M)
6331 0
6332 """
6333 Z3_ast_map_reset(self.ctx.ref(), self.map)
6334
6335 def keys(self):
6336 """Return an AstVector containing all keys in the map.
6337
6338 >>> M = AstMap()
6339 >>> x = Int('x')
6340 >>> M[x] = x + 1
6341 >>> M[x+x] = IntVal(1)
6342 >>> M.keys()
6343 [x, x + x]
6344 """
6345 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6346
6347
6352
6353
6355 """Store the value of the interpretation of a function in a particular point."""
6356
6357 def __init__(self, entry, ctx):
6358 self.entry = entry
6359 self.ctx = ctx
6360 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6361
6362 def __deepcopy__(self, memo={}):
6363 return FuncEntry(self.entry, self.ctx)
6364
6365 def __del__(self):
6366 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6367 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6368
6369 def num_args(self):
6370 """Return the number of arguments in the given entry.
6371
6372 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6373 >>> s = Solver()
6374 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6375 >>> s.check()
6376 sat
6377 >>> m = s.model()
6378 >>> f_i = m[f]
6379 >>> f_i.num_entries()
6380 1
6381 >>> e = f_i.entry(0)
6382 >>> e.num_args()
6383 2
6384 """
6385 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6386
6387 def arg_value(self, idx):
6388 """Return the value of argument `idx`.
6389
6390 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6391 >>> s = Solver()
6392 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6393 >>> s.check()
6394 sat
6395 >>> m = s.model()
6396 >>> f_i = m[f]
6397 >>> f_i.num_entries()
6398 1
6399 >>> e = f_i.entry(0)
6400 >>> e
6401 [1, 2, 20]
6402 >>> e.num_args()
6403 2
6404 >>> e.arg_value(0)
6405 1
6406 >>> e.arg_value(1)
6407 2
6408 >>> try:
6409 ... e.arg_value(2)
6410 ... except IndexError:
6411 ... print("index error")
6412 index error
6413 """
6414 if idx >= self.num_args():
6415 raise IndexError
6416 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6417
6418 def value(self):
6419 """Return the value of the function at point `self`.
6420
6421 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6422 >>> s = Solver()
6423 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6424 >>> s.check()
6425 sat
6426 >>> m = s.model()
6427 >>> f_i = m[f]
6428 >>> f_i.num_entries()
6429 1
6430 >>> e = f_i.entry(0)
6431 >>> e
6432 [1, 2, 20]
6433 >>> e.num_args()
6434 2
6435 >>> e.value()
6436 20
6437 """
6438 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6439
6440 def as_list(self):
6441 """Return entry `self` as a Python list.
6442 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6443 >>> s = Solver()
6444 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6445 >>> s.check()
6446 sat
6447 >>> m = s.model()
6448 >>> f_i = m[f]
6449 >>> f_i.num_entries()
6450 1
6451 >>> e = f_i.entry(0)
6452 >>> e.as_list()
6453 [1, 2, 20]
6454 """
6455 args = [self.arg_value(i) for i in range(self.num_args())]
6456 args.append(self.value())
6457 return args
6458
6459 def __repr__(self):
6460 return repr(self.as_list())
6461
6462
6464 """Stores the interpretation of a function in a Z3 model."""
6465
6466 def __init__(self, f, ctx):
6467 self.f = f
6468 self.ctx = ctx
6469 if self.f is not None:
6470 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6471
6472 def __del__(self):
6473 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6474 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6475
6476 def else_value(self):
6477 """
6478 Return the `else` value for a function interpretation.
6479 Return None if Z3 did not specify the `else` value for
6480 this object.
6481
6482 >>> f = Function('f', IntSort(), IntSort())
6483 >>> s = Solver()
6484 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6485 >>> s.check()
6486 sat
6487 >>> m = s.model()
6488 >>> m[f]
6489 [2 -> 0, else -> 1]
6490 >>> m[f].else_value()
6491 1
6492 """
6493 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6494 if r:
6495 return _to_expr_ref(r, self.ctx)
6496 else:
6497 return None
6498
6499 def num_entries(self):
6500 """Return the number of entries/points in the function interpretation `self`.
6501
6502 >>> f = Function('f', IntSort(), IntSort())
6503 >>> s = Solver()
6504 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6505 >>> s.check()
6506 sat
6507 >>> m = s.model()
6508 >>> m[f]
6509 [2 -> 0, else -> 1]
6510 >>> m[f].num_entries()
6511 1
6512 """
6513 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6514
6515 def arity(self):
6516 """Return the number of arguments for each entry in the function interpretation `self`.
6517
6518 >>> f = Function('f', IntSort(), IntSort())
6519 >>> s = Solver()
6520 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6521 >>> s.check()
6522 sat
6523 >>> m = s.model()
6524 >>> m[f].arity()
6525 1
6526 """
6527 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6528
6529 def entry(self, idx):
6530 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6531
6532 >>> f = Function('f', IntSort(), IntSort())
6533 >>> s = Solver()
6534 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6535 >>> s.check()
6536 sat
6537 >>> m = s.model()
6538 >>> m[f]
6539 [2 -> 0, else -> 1]
6540 >>> m[f].num_entries()
6541 1
6542 >>> m[f].entry(0)
6543 [2, 0]
6544 """
6545 if idx >= self.num_entries():
6546 raise IndexError
6547 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6548
6549 def translate(self, other_ctx):
6550 """Copy model 'self' to context 'other_ctx'.
6551 """
6552 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6553
6554 def __copy__(self):
6555 return self.translate(self.ctx)
6556
6557 def __deepcopy__(self, memo={}):
6558 return self.translate(self.ctx)
6559
6560 def as_list(self):
6561 """Return the function interpretation as a Python list.
6562 >>> f = Function('f', IntSort(), IntSort())
6563 >>> s = Solver()
6564 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6565 >>> s.check()
6566 sat
6567 >>> m = s.model()
6568 >>> m[f]
6569 [2 -> 0, else -> 1]
6570 >>> m[f].as_list()
6571 [[2, 0], 1]
6572 """
6573 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6574 r.append(self.else_value())
6575 return r
6576
6577 def __repr__(self):
6578 return obj_to_string(self)
6579
6580
6582 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6583
6584 def __init__(self, m, ctx):
6585 assert ctx is not None
6586 self.model = m
6587 self.ctx = ctx
6588 Z3_model_inc_ref(self.ctx.ref(), self.model)
6589
6590 def __del__(self):
6591 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6592 Z3_model_dec_ref(self.ctx.ref(), self.model)
6593
6594 def __repr__(self):
6595 return obj_to_string(self)
6596
6597 def sexpr(self):
6598 """Return a textual representation of the s-expression representing the model."""
6599 return Z3_model_to_string(self.ctx.ref(), self.model)
6600
6601 def eval(self, t, model_completion=False):
6602 """Evaluate the expression `t` in the model `self`.
6603 If `model_completion` is enabled, then a default interpretation is automatically added
6604 for symbols that do not have an interpretation in the model `self`.
6605
6606 >>> x = Int('x')
6607 >>> s = Solver()
6608 >>> s.add(x > 0, x < 2)
6609 >>> s.check()
6610 sat
6611 >>> m = s.model()
6612 >>> m.eval(x + 1)
6613 2
6614 >>> m.eval(x == 1)
6615 True
6616 >>> y = Int('y')
6617 >>> m.eval(y + x)
6618 1 + y
6619 >>> m.eval(y)
6620 y
6621 >>> m.eval(y, model_completion=True)
6622 0
6623 >>> # Now, m contains an interpretation for y
6624 >>> m.eval(y + x)
6625 1
6626 """
6627 r = (Ast * 1)()
6628 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6629 return _to_expr_ref(r[0], self.ctx)
6630 raise Z3Exception("failed to evaluate expression in the model")
6631
6632 def evaluate(self, t, model_completion=False):
6633 """Alias for `eval`.
6634
6635 >>> x = Int('x')
6636 >>> s = Solver()
6637 >>> s.add(x > 0, x < 2)
6638 >>> s.check()
6639 sat
6640 >>> m = s.model()
6641 >>> m.evaluate(x + 1)
6642 2
6643 >>> m.evaluate(x == 1)
6644 True
6645 >>> y = Int('y')
6646 >>> m.evaluate(y + x)
6647 1 + y
6648 >>> m.evaluate(y)
6649 y
6650 >>> m.evaluate(y, model_completion=True)
6651 0
6652 >>> # Now, m contains an interpretation for y
6653 >>> m.evaluate(y + x)
6654 1
6655 """
6656 return self.eval(t, model_completion)
6657
6658 def __len__(self):
6659 """Return the number of constant and function declarations in the model `self`.
6660
6661 >>> f = Function('f', IntSort(), IntSort())
6662 >>> x = Int('x')
6663 >>> s = Solver()
6664 >>> s.add(x > 0, f(x) != x)
6665 >>> s.check()
6666 sat
6667 >>> m = s.model()
6668 >>> len(m)
6669 2
6670 """
6671 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6672 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6673 return num_consts + num_funcs
6674
6675 def get_interp(self, decl):
6676 """Return the interpretation for a given declaration or constant.
6677
6678 >>> f = Function('f', IntSort(), IntSort())
6679 >>> x = Int('x')
6680 >>> s = Solver()
6681 >>> s.add(x > 0, x < 2, f(x) == 0)
6682 >>> s.check()
6683 sat
6684 >>> m = s.model()
6685 >>> m[x]
6686 1
6687 >>> m[f]
6688 [else -> 0]
6689 """
6690 if z3_debug():
6691 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6692 if is_const(decl):
6693 decl = decl.decl()
6694 try:
6695 if decl.arity() == 0:
6696 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6697 if _r.value is None:
6698 return None
6699 r = _to_expr_ref(_r, self.ctx)
6700 if is_as_array(r):
6701 fi = self.get_interp(get_as_array_func(r))
6702 if fi is None:
6703 return fi
6704 e = fi.else_value()
6705 if e is None:
6706 return fi
6707 if fi.arity() != 1:
6708 return fi
6709 srt = decl.range()
6710 dom = srt.domain()
6711 e = K(dom, e)
6712 i = 0
6713 sz = fi.num_entries()
6714 n = fi.arity()
6715 while i < sz:
6716 fe = fi.entry(i)
6717 e = Store(e, fe.arg_value(0), fe.value())
6718 i += 1
6719 return e
6720 else:
6721 return r
6722 else:
6723 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6724 except Z3Exception:
6725 return None
6726
6727 def num_sorts(self):
6728 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6729
6730 >>> A = DeclareSort('A')
6731 >>> a, b = Consts('a b', A)
6732 >>> s = Solver()
6733 >>> s.add(a != b)
6734 >>> s.check()
6735 sat
6736 >>> m = s.model()
6737 >>> m.num_sorts()
6738 1
6739 """
6740 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6741
6742 def get_sort(self, idx):
6743 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6744
6745 >>> A = DeclareSort('A')
6746 >>> B = DeclareSort('B')
6747 >>> a1, a2 = Consts('a1 a2', A)
6748 >>> b1, b2 = Consts('b1 b2', B)
6749 >>> s = Solver()
6750 >>> s.add(a1 != a2, b1 != b2)
6751 >>> s.check()
6752 sat
6753 >>> m = s.model()
6754 >>> m.num_sorts()
6755 2
6756 >>> m.get_sort(0)
6757 A
6758 >>> m.get_sort(1)
6759 B
6760 """
6761 if idx >= self.num_sorts():
6762 raise IndexError
6763 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6764
6765 def sorts(self):
6766 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6767
6768 >>> A = DeclareSort('A')
6769 >>> B = DeclareSort('B')
6770 >>> a1, a2 = Consts('a1 a2', A)
6771 >>> b1, b2 = Consts('b1 b2', B)
6772 >>> s = Solver()
6773 >>> s.add(a1 != a2, b1 != b2)
6774 >>> s.check()
6775 sat
6776 >>> m = s.model()
6777 >>> m.sorts()
6778 [A, B]
6779 """
6780 return [self.get_sort(i) for i in range(self.num_sorts())]
6781
6782 def get_universe(self, s):
6783 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6784
6785 >>> A = DeclareSort('A')
6786 >>> a, b = Consts('a b', A)
6787 >>> s = Solver()
6788 >>> s.add(a != b)
6789 >>> s.check()
6790 sat
6791 >>> m = s.model()
6792 >>> m.get_universe(A)
6793 [A!val!1, A!val!0]
6794 """
6795 if z3_debug():
6796 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6797 try:
6798 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6799 except Z3Exception:
6800 return None
6801
6802 def __getitem__(self, idx):
6803 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6804 If `idx` is a declaration, then the actual interpretation is returned.
6805
6806 The elements can be retrieved using position or the actual declaration.
6807
6808 >>> f = Function('f', IntSort(), IntSort())
6809 >>> x = Int('x')
6810 >>> s = Solver()
6811 >>> s.add(x > 0, x < 2, f(x) == 0)
6812 >>> s.check()
6813 sat
6814 >>> m = s.model()
6815 >>> len(m)
6816 2
6817 >>> m[0]
6818 x
6819 >>> m[1]
6820 f
6821 >>> m[x]
6822 1
6823 >>> m[f]
6824 [else -> 0]
6825 >>> for d in m: print("%s -> %s" % (d, m[d]))
6826 x -> 1
6827 f -> [else -> 0]
6828 """
6829 if _is_int(idx):
6830 if idx >= len(self):
6831 raise IndexError
6832 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6833 if (idx < num_consts):
6834 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6835 else:
6836 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6837 if isinstance(idx, FuncDeclRef):
6838 return self.get_interp(idx)
6839 if is_const(idx):
6840 return self.get_interp(idx.decl())
6841 if isinstance(idx, SortRef):
6842 return self.get_universe(idx)
6843 if z3_debug():
6844 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6845 return None
6846
6847 def decls(self):
6848 """Return a list with all symbols that have an interpretation in the model `self`.
6849 >>> f = Function('f', IntSort(), IntSort())
6850 >>> x = Int('x')
6851 >>> s = Solver()
6852 >>> s.add(x > 0, x < 2, f(x) == 0)
6853 >>> s.check()
6854 sat
6855 >>> m = s.model()
6856 >>> m.decls()
6857 [x, f]
6858 """
6859 r = []
6860 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6861 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6862 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6863 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6864 return r
6865
6866 def update_value(self, x, value):
6867 """Update the interpretation of a constant"""
6868 if is_expr(x):
6869 x = x.decl()
6870 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6871 fi1 = value.f
6872 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6873 fi2 = FuncInterp(fi2, x.ctx)
6874 for i in range(value.num_entries()):
6875 e = value.entry(i)
6876 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6877 v = AstVector()
6878 for j in range(n):
6879 v.push(e.arg_value(j))
6880 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6881 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6882 return
6883 if not is_func_decl(x) or x.arity() != 0:
6884 raise Z3Exception("Expecting 0-ary function or constant expression")
6885 value = _py2expr(value)
6886 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6887
6888 def translate(self, target):
6889 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6890 """
6891 if z3_debug():
6892 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6893 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6894 return ModelRef(model, target)
6895
6896 def project(self, vars, fml):
6897 """Perform model-based projection on fml with respect to vars.
6898 Assume that the model satisfies fml. Then compute a projection fml_p, such
6899 that vars do not occur free in fml_p, fml_p is true in the model and
6900 fml_p => exists vars . fml
6901 """
6902 ctx = self.ctx.ref()
6903 _vars = (Ast * len(vars))()
6904 for i in range(len(vars)):
6905 _vars[i] = vars[i].as_ast()
6906 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6907
6908 def project_with_witness(self, vars, fml):
6909 """Perform model-based projection, but also include realizer terms for the projected variables"""
6910 ctx = self.ctx.ref()
6911 _vars = (Ast * len(vars))()
6912 for i in range(len(vars)):
6913 _vars[i] = vars[i].as_ast()
6914 defs = AstMap()
6915 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6916 result = _to_expr_ref(result, self.ctx)
6917 return result, defs
6918
6919
6920 def __copy__(self):
6921 return self.translate(self.ctx)
6922
6923 def __deepcopy__(self, memo={}):
6924 return self.translate(self.ctx)
6925
6926
6927def Model(ctx=None, eval = {}):
6928 ctx = _get_ctx(ctx)
6929 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6930 for k, v in eval.items():
6931 mdl.update_value(k, v)
6932 return mdl
6933
6934
6936 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6937 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6938
6939
6941 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6942 if z3_debug():
6943 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6944 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6945
6946
6951
6952
6954 """Statistics for `Solver.check()`."""
6955
6956 def __init__(self, stats, ctx):
6957 self.stats = stats
6958 self.ctx = ctx
6959 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6960
6961 def __deepcopy__(self, memo={}):
6962 return Statistics(self.stats, self.ctx)
6963
6964 def __del__(self):
6965 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6966 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6967
6968 def __repr__(self):
6969 if in_html_mode():
6970 out = io.StringIO()
6971 even = True
6972 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6973 for k, v in self:
6974 if even:
6975 out.write(u('<tr style="background-color:#CFCFCF">'))
6976 even = False
6977 else:
6978 out.write(u("<tr>"))
6979 even = True
6980 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6981 out.write(u("</table>"))
6982 return out.getvalue()
6983 else:
6984 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6985
6986 def __len__(self):
6987 """Return the number of statistical counters.
6988
6989 >>> x = Int('x')
6990 >>> s = Then('simplify', 'nlsat').solver()
6991 >>> s.add(x > 0)
6992 >>> s.check()
6993 sat
6994 >>> st = s.statistics()
6995 >>> len(st)
6996 7
6997 """
6998 return int(Z3_stats_size(self.ctx.ref(), self.stats))
6999
7000 def __getitem__(self, idx):
7001 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
7002
7003 >>> x = Int('x')
7004 >>> s = Then('simplify', 'nlsat').solver()
7005 >>> s.add(x > 0)
7006 >>> s.check()
7007 sat
7008 >>> st = s.statistics()
7009 >>> len(st)
7010 7
7011 >>> st[0]
7012 ('nlsat propagations', 2)
7013 >>> st[1]
7014 ('nlsat restarts', 1)
7015 """
7016 if idx >= len(self):
7017 raise IndexError
7018 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7019 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7020 else:
7021 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7022 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
7023
7024 def keys(self):
7025 """Return the list of statistical counters.
7026
7027 >>> x = Int('x')
7028 >>> s = Then('simplify', 'nlsat').solver()
7029 >>> s.add(x > 0)
7030 >>> s.check()
7031 sat
7032 >>> st = s.statistics()
7033 """
7034 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
7035
7036 def get_key_value(self, key):
7037 """Return the value of a particular statistical counter.
7038
7039 >>> x = Int('x')
7040 >>> s = Then('simplify', 'nlsat').solver()
7041 >>> s.add(x > 0)
7042 >>> s.check()
7043 sat
7044 >>> st = s.statistics()
7045 >>> st.get_key_value('nlsat propagations')
7046 2
7047 """
7048 for idx in range(len(self)):
7049 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
7050 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7051 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7052 else:
7053 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7054 raise Z3Exception("unknown key")
7055
7056 def __getattr__(self, name):
7057 """Access the value of statistical using attributes.
7058
7059 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
7060 we should use '_' (e.g., 'nlsat_propagations').
7061
7062 >>> x = Int('x')
7063 >>> s = Then('simplify', 'nlsat').solver()
7064 >>> s.add(x > 0)
7065 >>> s.check()
7066 sat
7067 >>> st = s.statistics()
7068 >>> st.nlsat_propagations
7069 2
7070 >>> st.nlsat_stages
7071 2
7072 """
7073 key = name.replace("_", " ")
7074 try:
7075 return self.get_key_value(key)
7076 except Z3Exception:
7077 raise AttributeError
7078
7079
7084
7085
7087 """Represents the result of a satisfiability check: sat, unsat, unknown.
7088
7089 >>> s = Solver()
7090 >>> s.check()
7091 sat
7092 >>> r = s.check()
7093 >>> isinstance(r, CheckSatResult)
7094 True
7095 """
7096
7097 def __init__(self, r):
7098 self.r = r
7099
7100 def __deepcopy__(self, memo={}):
7101 return CheckSatResult(self.r)
7102
7103 def __eq__(self, other):
7104 return isinstance(other, CheckSatResult) and self.r == other.r
7105
7106 def __ne__(self, other):
7107 return not self.__eq__(other)
7108
7109 def __repr__(self):
7110 if in_html_mode():
7111 if self.r == Z3_L_TRUE:
7112 return "<b>sat</b>"
7113 elif self.r == Z3_L_FALSE:
7114 return "<b>unsat</b>"
7115 else:
7116 return "<b>unknown</b>"
7117 else:
7118 if self.r == Z3_L_TRUE:
7119 return "sat"
7120 elif self.r == Z3_L_FALSE:
7121 return "unsat"
7122 else:
7123 return "unknown"
7124
7125 def _repr_html_(self):
7126 in_html = in_html_mode()
7127 set_html_mode(True)
7128 res = repr(self)
7129 set_html_mode(in_html)
7130 return res
7131
7132
7133sat = CheckSatResult(Z3_L_TRUE)
7134unsat = CheckSatResult(Z3_L_FALSE)
7135unknown = CheckSatResult(Z3_L_UNDEF)
7136
7137
7139 """
7140 Solver API provides methods for implementing the main SMT 2.0 commands:
7141 push, pop, check, get-model, etc.
7142 """
7143
7144 def __init__(self, solver=None, ctx=None, logFile=None):
7145 assert solver is None or ctx is not None
7146 self.ctx = _get_ctx(ctx)
7147 self.backtrack_level = 4000000000
7148 self.solver = None
7149 if solver is None:
7150 self.solver = Z3_mk_solver(self.ctx.ref())
7151 else:
7152 self.solver = solver
7153 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7154 if logFile is not None:
7155 self.set("smtlib2_log", logFile)
7156
7157 def __del__(self):
7158 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7159 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7160
7161 def __enter__(self):
7162 self.push()
7163 return self
7164
7165 def __exit__(self, *exc_info):
7166 self.pop()
7167
7168 def set(self, *args, **keys):
7169 """Set a configuration option.
7170 The method `help()` return a string containing all available options.
7171
7172 >>> s = Solver()
7173 >>> # The option MBQI can be set using three different approaches.
7174 >>> s.set(mbqi=True)
7175 >>> s.set('MBQI', True)
7176 >>> s.set(':mbqi', True)
7177 """
7178 p = args2params(args, keys, self.ctx)
7179 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7180
7181 def push(self):
7182 """Create a backtracking point.
7183
7184 >>> x = Int('x')
7185 >>> s = Solver()
7186 >>> s.add(x > 0)
7187 >>> s
7188 [x > 0]
7189 >>> s.push()
7190 >>> s.add(x < 1)
7191 >>> s
7192 [x > 0, x < 1]
7193 >>> s.check()
7194 unsat
7195 >>> s.pop()
7196 >>> s.check()
7197 sat
7198 >>> s
7199 [x > 0]
7200 """
7201 Z3_solver_push(self.ctx.ref(), self.solver)
7202
7203 def pop(self, num=1):
7204 """Backtrack \\c num backtracking points.
7205
7206 >>> x = Int('x')
7207 >>> s = Solver()
7208 >>> s.add(x > 0)
7209 >>> s
7210 [x > 0]
7211 >>> s.push()
7212 >>> s.add(x < 1)
7213 >>> s
7214 [x > 0, x < 1]
7215 >>> s.check()
7216 unsat
7217 >>> s.pop()
7218 >>> s.check()
7219 sat
7220 >>> s
7221 [x > 0]
7222 """
7223 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7224
7225 def num_scopes(self):
7226 """Return the current number of backtracking points.
7227
7228 >>> s = Solver()
7229 >>> s.num_scopes()
7230 0
7231 >>> s.push()
7232 >>> s.num_scopes()
7233 1
7234 >>> s.push()
7235 >>> s.num_scopes()
7236 2
7237 >>> s.pop()
7238 >>> s.num_scopes()
7239 1
7240 """
7241 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7242
7243 def reset(self):
7244 """Remove all asserted constraints and backtracking points created using `push()`.
7245
7246 >>> x = Int('x')
7247 >>> s = Solver()
7248 >>> s.add(x > 0)
7249 >>> s
7250 [x > 0]
7251 >>> s.reset()
7252 >>> s
7253 []
7254 """
7255 Z3_solver_reset(self.ctx.ref(), self.solver)
7256
7257 def assert_exprs(self, *args):
7258 """Assert constraints into the solver.
7259
7260 >>> x = Int('x')
7261 >>> s = Solver()
7262 >>> s.assert_exprs(x > 0, x < 2)
7263 >>> s
7264 [x > 0, x < 2]
7265 """
7266 args = _get_args(args)
7267 s = BoolSort(self.ctx)
7268 for arg in args:
7269 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7270 for f in arg:
7271 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7272 else:
7273 arg = s.cast(arg)
7274 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7275
7276 def add(self, *args):
7277 """Assert constraints into the solver.
7278
7279 >>> x = Int('x')
7280 >>> s = Solver()
7281 >>> s.add(x > 0, x < 2)
7282 >>> s
7283 [x > 0, x < 2]
7284 """
7285 self.assert_exprs(*args)
7286
7287 def __iadd__(self, fml):
7288 self.add(fml)
7289 return self
7290
7291 def append(self, *args):
7292 """Assert constraints into the solver.
7293
7294 >>> x = Int('x')
7295 >>> s = Solver()
7296 >>> s.append(x > 0, x < 2)
7297 >>> s
7298 [x > 0, x < 2]
7299 """
7300 self.assert_exprs(*args)
7301
7302 def insert(self, *args):
7303 """Assert constraints into the solver.
7304
7305 >>> x = Int('x')
7306 >>> s = Solver()
7307 >>> s.insert(x > 0, x < 2)
7308 >>> s
7309 [x > 0, x < 2]
7310 """
7311 self.assert_exprs(*args)
7312
7313 def assert_and_track(self, a, p):
7314 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7315
7316 If `p` is a string, it will be automatically converted into a Boolean constant.
7317
7318 >>> x = Int('x')
7319 >>> p3 = Bool('p3')
7320 >>> s = Solver()
7321 >>> s.set(unsat_core=True)
7322 >>> s.assert_and_track(x > 0, 'p1')
7323 >>> s.assert_and_track(x != 1, 'p2')
7324 >>> s.assert_and_track(x < 0, p3)
7325 >>> print(s.check())
7326 unsat
7327 >>> c = s.unsat_core()
7328 >>> len(c)
7329 2
7330 >>> Bool('p1') in c
7331 True
7332 >>> Bool('p2') in c
7333 False
7334 >>> p3 in c
7335 True
7336 """
7337 if isinstance(p, str):
7338 p = Bool(p, self.ctx)
7339 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7340 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7341 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7342
7343 def check(self, *assumptions):
7344 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7345
7346 >>> x = Int('x')
7347 >>> s = Solver()
7348 >>> s.check()
7349 sat
7350 >>> s.add(x > 0, x < 2)
7351 >>> s.check()
7352 sat
7353 >>> s.model().eval(x)
7354 1
7355 >>> s.add(x < 1)
7356 >>> s.check()
7357 unsat
7358 >>> s.reset()
7359 >>> s.add(2**x == 4)
7360 >>> s.check()
7361 sat
7362 """
7363 s = BoolSort(self.ctx)
7364 assumptions = _get_args(assumptions)
7365 num = len(assumptions)
7366 _assumptions = (Ast * num)()
7367 for i in range(num):
7368 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7369 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7370 return CheckSatResult(r)
7371
7372 def model(self):
7373 """Return a model for the last `check()`.
7374
7375 This function raises an exception if
7376 a model is not available (e.g., last `check()` returned unsat).
7377
7378 >>> s = Solver()
7379 >>> a = Int('a')
7380 >>> s.add(a + 2 == 0)
7381 >>> s.check()
7382 sat
7383 >>> s.model()
7384 [a = -2]
7385 """
7386 try:
7387 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7388 except Z3Exception:
7389 raise Z3Exception("model is not available")
7390
7391 def import_model_converter(self, other):
7392 """Import model converter from other into the current solver"""
7393 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7394
7395 def interrupt(self):
7396 """Interrupt the execution of the solver object.
7397 Remarks: This ensures that the interrupt applies only
7398 to the given solver object and it applies only if it is running.
7399 """
7400 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7401
7402 def unsat_core(self):
7403 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7404
7405 These are the assumptions Z3 used in the unsatisfiability proof.
7406 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7407 They may be also used to "retract" assumptions. Note that, assumptions are not really
7408 "soft constraints", but they can be used to implement them.
7409
7410 >>> p1, p2, p3 = Bools('p1 p2 p3')
7411 >>> x, y = Ints('x y')
7412 >>> s = Solver()
7413 >>> s.add(Implies(p1, x > 0))
7414 >>> s.add(Implies(p2, y > x))
7415 >>> s.add(Implies(p2, y < 1))
7416 >>> s.add(Implies(p3, y > -3))
7417 >>> s.check(p1, p2, p3)
7418 unsat
7419 >>> core = s.unsat_core()
7420 >>> len(core)
7421 2
7422 >>> p1 in core
7423 True
7424 >>> p2 in core
7425 True
7426 >>> p3 in core
7427 False
7428 >>> # "Retracting" p2
7429 >>> s.check(p1, p3)
7430 sat
7431 """
7432 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7433
7434 def consequences(self, assumptions, variables):
7435 """Determine fixed values for the variables based on the solver state and assumptions.
7436 >>> s = Solver()
7437 >>> a, b, c, d = Bools('a b c d')
7438 >>> s.add(Implies(a,b), Implies(b, c))
7439 >>> s.consequences([a],[b,c,d])
7440 (sat, [Implies(a, b), Implies(a, c)])
7441 >>> s.consequences([Not(c),d],[a,b,c,d])
7442 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7443 """
7444 if isinstance(assumptions, list):
7445 _asms = AstVector(None, self.ctx)
7446 for a in assumptions:
7447 _asms.push(a)
7448 assumptions = _asms
7449 if isinstance(variables, list):
7450 _vars = AstVector(None, self.ctx)
7451 for a in variables:
7452 _vars.push(a)
7453 variables = _vars
7454 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7455 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7456 consequences = AstVector(None, self.ctx)
7457 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7458 variables.vector, consequences.vector)
7459 sz = len(consequences)
7460 consequences = [consequences[i] for i in range(sz)]
7461 return CheckSatResult(r), consequences
7462
7463 def from_file(self, filename):
7464 """Parse assertions from a file"""
7465 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7466
7467 def from_string(self, s):
7468 """Parse assertions from a string"""
7469 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7470
7471 def cube(self, vars=None):
7472 """Get set of cubes
7473 The method takes an optional set of variables that restrict which
7474 variables may be used as a starting point for cubing.
7475 If vars is not None, then the first case split is based on a variable in
7476 this set.
7477 """
7478 self.cube_vs = AstVector(None, self.ctx)
7479 if vars is not None:
7480 for v in vars:
7481 self.cube_vs.push(v)
7482 while True:
7483 lvl = self.backtrack_level
7484 self.backtrack_level = 4000000000
7485 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7486 if (len(r) == 1 and is_false(r[0])):
7487 return
7488 yield r
7489 if (len(r) == 0):
7490 return
7491
7492 def cube_vars(self):
7493 """Access the set of variables that were touched by the most recently generated cube.
7494 This set of variables can be used as a starting point for additional cubes.
7495 The idea is that variables that appear in clauses that are reduced by the most recent
7496 cube are likely more useful to cube on."""
7497 return self.cube_vs
7498
7499 def root(self, t):
7500 """Retrieve congruence closure root of the term t relative to the current search state
7501 The function primarily works for SimpleSolver. Terms and variables that are
7502 eliminated during pre-processing are not visible to the congruence closure.
7503 """
7504 t = _py2expr(t, self.ctx)
7505 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7506
7507 def next(self, t):
7508 """Retrieve congruence closure sibling of the term t relative to the current search state
7509 The function primarily works for SimpleSolver. Terms and variables that are
7510 eliminated during pre-processing are not visible to the congruence closure.
7511 """
7512 t = _py2expr(t, self.ctx)
7513 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7514
7515 def explain_congruent(self, a, b):
7516 """Explain congruence of a and b relative to the current search state"""
7517 a = _py2expr(a, self.ctx)
7518 b = _py2expr(b, self.ctx)
7519 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7520
7521
7522 def solve_for(self, ts):
7523 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7524 vars = AstVector(ctx=self.ctx);
7525 terms = AstVector(ctx=self.ctx);
7526 guards = AstVector(ctx=self.ctx);
7527 for t in ts:
7528 t = _py2expr(t, self.ctx)
7529 vars.push(t)
7530 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7531 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7532
7533
7534 def proof(self):
7535 """Return a proof for the last `check()`. Proof construction must be enabled."""
7536 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7537
7538 def assertions(self):
7539 """Return an AST vector containing all added constraints.
7540
7541 >>> s = Solver()
7542 >>> s.assertions()
7543 []
7544 >>> a = Int('a')
7545 >>> s.add(a > 0)
7546 >>> s.add(a < 10)
7547 >>> s.assertions()
7548 [a > 0, a < 10]
7549 """
7550 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7551
7552 def units(self):
7553 """Return an AST vector containing all currently inferred units.
7554 """
7555 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7556
7557 def non_units(self):
7558 """Return an AST vector containing all atomic formulas in solver state that are not units.
7559 """
7560 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7561
7562 def trail_levels(self):
7563 """Return trail and decision levels of the solver state after a check() call.
7564 """
7565 trail = self.trail()
7566 levels = (ctypes.c_uint * len(trail))()
7567 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7568 return trail, levels
7569
7570 def set_initial_value(self, var, value):
7571 """initialize the solver's state by setting the initial value of var to value
7572 """
7573 s = var.sort()
7574 value = s.cast(value)
7575 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7576
7577 def trail(self):
7578 """Return trail of the solver state after a check() call.
7579 """
7580 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7581
7582 def statistics(self):
7583 """Return statistics for the last `check()`.
7584
7585 >>> s = SimpleSolver()
7586 >>> x = Int('x')
7587 >>> s.add(x > 0)
7588 >>> s.check()
7589 sat
7590 >>> st = s.statistics()
7591 >>> st.get_key_value('final checks')
7592 1
7593 >>> len(st) > 0
7594 True
7595 >>> st[0] != 0
7596 True
7597 """
7598 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7599
7600 def reason_unknown(self):
7601 """Return a string describing why the last `check()` returned `unknown`.
7602
7603 >>> x = Int('x')
7604 >>> s = SimpleSolver()
7605 >>> s.add(x == 2**x)
7606 >>> s.check()
7607 unknown
7608 >>> s.reason_unknown()
7609 '(incomplete (theory arithmetic))'
7610 """
7611 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7612
7613 def help(self):
7614 """Display a string describing all available options."""
7615 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7616
7617 def param_descrs(self):
7618 """Return the parameter description set."""
7619 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7620
7621 def __repr__(self):
7622 """Return a formatted string with all added constraints."""
7623 return obj_to_string(self)
7624
7625 def translate(self, target):
7626 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7627
7628 >>> c1 = Context()
7629 >>> c2 = Context()
7630 >>> s1 = Solver(ctx=c1)
7631 >>> s2 = s1.translate(c2)
7632 """
7633 if z3_debug():
7634 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7635 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7636 return Solver(solver, target)
7637
7638 def __copy__(self):
7639 return self.translate(self.ctx)
7640
7641 def __deepcopy__(self, memo={}):
7642 return self.translate(self.ctx)
7643
7644 def sexpr(self):
7645 """Return a formatted string (in Lisp-like format) with all added constraints.
7646 We say the string is in s-expression format.
7647
7648 >>> x = Int('x')
7649 >>> s = Solver()
7650 >>> s.add(x > 0)
7651 >>> s.add(x < 2)
7652 >>> r = s.sexpr()
7653 """
7654 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7655
7656 def dimacs(self, include_names=True):
7657 """Return a textual representation of the solver in DIMACS format."""
7658 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7659
7660 def to_smt2(self):
7661 """return SMTLIB2 formatted benchmark for solver's assertions"""
7662 es = self.assertions()
7663 sz = len(es)
7664 sz1 = sz
7665 if sz1 > 0:
7666 sz1 -= 1
7667 v = (Ast * sz1)()
7668 for i in range(sz1):
7669 v[i] = es[i].as_ast()
7670 if sz > 0:
7671 e = es[sz1].as_ast()
7672 else:
7673 e = BoolVal(True, self.ctx).as_ast()
7674 return Z3_benchmark_to_smtlib_string(
7675 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7676 )
7677
7678
7679def SolverFor(logic, ctx=None, logFile=None):
7680 """Create a solver customized for the given logic.
7681
7682 The parameter `logic` is a string. It should be contains
7683 the name of a SMT-LIB logic.
7684 See http://www.smtlib.org/ for the name of all available logics.
7685
7686 >>> s = SolverFor("QF_LIA")
7687 >>> x = Int('x')
7688 >>> s.add(x > 0)
7689 >>> s.add(x < 2)
7690 >>> s.check()
7691 sat
7692 >>> s.model()
7693 [x = 1]
7694 """
7695 ctx = _get_ctx(ctx)
7696 logic = to_symbol(logic)
7697 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7698
7699
7700def SimpleSolver(ctx=None, logFile=None):
7701 """Return a simple general purpose solver with limited amount of preprocessing.
7702
7703 >>> s = SimpleSolver()
7704 >>> x = Int('x')
7705 >>> s.add(x > 0)
7706 >>> s.check()
7707 sat
7708 """
7709 ctx = _get_ctx(ctx)
7710 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7711
7712#########################################
7713#
7714# Fixedpoint
7715#
7716#########################################
7717
7718
7719class Fixedpoint(Z3PPObject):
7720 """Fixedpoint API provides methods for solving with recursive predicates"""
7721
7722 def __init__(self, fixedpoint=None, ctx=None):
7723 assert fixedpoint is None or ctx is not None
7724 self.ctx = _get_ctx(ctx)
7725 self.fixedpoint = None
7726 if fixedpoint is None:
7727 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7728 else:
7729 self.fixedpoint = fixedpoint
7730 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7731 self.vars = []
7732
7733 def __deepcopy__(self, memo={}):
7734 return FixedPoint(self.fixedpoint, self.ctx)
7735
7736 def __del__(self):
7737 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7738 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7739
7740 def set(self, *args, **keys):
7741 """Set a configuration option. The method `help()` return a string containing all available options.
7742 """
7743 p = args2params(args, keys, self.ctx)
7744 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7745
7746 def help(self):
7747 """Display a string describing all available options."""
7748 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7749
7750 def param_descrs(self):
7751 """Return the parameter description set."""
7752 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7753
7754 def assert_exprs(self, *args):
7755 """Assert constraints as background axioms for the fixedpoint solver."""
7756 args = _get_args(args)
7757 s = BoolSort(self.ctx)
7758 for arg in args:
7759 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7760 for f in arg:
7761 f = self.abstract(f)
7762 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7763 else:
7764 arg = s.cast(arg)
7765 arg = self.abstract(arg)
7766 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7767
7768 def add(self, *args):
7769 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7770 self.assert_exprs(*args)
7771
7772 def __iadd__(self, fml):
7773 self.add(fml)
7774 return self
7775
7776 def append(self, *args):
7777 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7778 self.assert_exprs(*args)
7779
7780 def insert(self, *args):
7781 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7782 self.assert_exprs(*args)
7783
7784 def add_rule(self, head, body=None, name=None):
7785 """Assert rules defining recursive predicates to the fixedpoint solver.
7786 >>> a = Bool('a')
7787 >>> b = Bool('b')
7788 >>> s = Fixedpoint()
7789 >>> s.register_relation(a.decl())
7790 >>> s.register_relation(b.decl())
7791 >>> s.fact(a)
7792 >>> s.rule(b, a)
7793 >>> s.query(b)
7794 sat
7795 """
7796 if name is None:
7797 name = ""
7798 name = to_symbol(name, self.ctx)
7799 if body is None:
7800 head = self.abstract(head)
7801 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7802 else:
7803 body = _get_args(body)
7804 f = self.abstract(Implies(And(body, self.ctx), head))
7805 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7806
7807 def rule(self, head, body=None, name=None):
7808 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7809 self.add_rule(head, body, name)
7810
7811 def fact(self, head, name=None):
7812 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7813 self.add_rule(head, None, name)
7814
7815 def query(self, *query):
7816 """Query the fixedpoint engine whether formula is derivable.
7817 You can also pass an tuple or list of recursive predicates.
7818 """
7819 query = _get_args(query)
7820 sz = len(query)
7821 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7822 _decls = (FuncDecl * sz)()
7823 i = 0
7824 for q in query:
7825 _decls[i] = q.ast
7826 i = i + 1
7827 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7828 else:
7829 if sz == 1:
7830 query = query[0]
7831 else:
7832 query = And(query, self.ctx)
7833 query = self.abstract(query, False)
7834 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7835 return CheckSatResult(r)
7836
7837 def query_from_lvl(self, lvl, *query):
7838 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7839 """
7840 query = _get_args(query)
7841 sz = len(query)
7842 if sz >= 1 and isinstance(query[0], FuncDecl):
7843 _z3_assert(False, "unsupported")
7844 else:
7845 if sz == 1:
7846 query = query[0]
7847 else:
7848 query = And(query)
7849 query = self.abstract(query, False)
7850 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7851 return CheckSatResult(r)
7852
7853 def update_rule(self, head, body, name):
7854 """update rule"""
7855 if name is None:
7856 name = ""
7857 name = to_symbol(name, self.ctx)
7858 body = _get_args(body)
7859 f = self.abstract(Implies(And(body, self.ctx), head))
7860 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7861
7862 def get_answer(self):
7863 """Retrieve answer from last query call."""
7864 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7865 return _to_expr_ref(r, self.ctx)
7866
7867 def get_ground_sat_answer(self):
7868 """Retrieve a ground cex from last query call."""
7869 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7870 return _to_expr_ref(r, self.ctx)
7871
7872 def get_rules_along_trace(self):
7873 """retrieve rules along the counterexample trace"""
7874 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7875
7876 def get_rule_names_along_trace(self):
7877 """retrieve rule names along the counterexample trace"""
7878 # this is a hack as I don't know how to return a list of symbols from C++;
7879 # obtain names as a single string separated by semicolons
7880 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7881 # split into individual names
7882 return names.split(";")
7883
7884 def get_num_levels(self, predicate):
7885 """Retrieve number of levels used for predicate in PDR engine"""
7886 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7887
7888 def get_cover_delta(self, level, predicate):
7889 """Retrieve properties known about predicate for the level'th unfolding.
7890 -1 is treated as the limit (infinity)
7891 """
7892 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7893 return _to_expr_ref(r, self.ctx)
7894
7895 def add_cover(self, level, predicate, property):
7896 """Add property to predicate for the level'th unfolding.
7897 -1 is treated as infinity (infinity)
7898 """
7899 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7900
7901 def register_relation(self, *relations):
7902 """Register relation as recursive"""
7903 relations = _get_args(relations)
7904 for f in relations:
7905 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7906
7907 def set_predicate_representation(self, f, *representations):
7908 """Control how relation is represented"""
7909 representations = _get_args(representations)
7910 representations = [to_symbol(s) for s in representations]
7911 sz = len(representations)
7912 args = (Symbol * sz)()
7913 for i in range(sz):
7914 args[i] = representations[i]
7915 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7916
7917 def parse_string(self, s):
7918 """Parse rules and queries from a string"""
7919 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7920
7921 def parse_file(self, f):
7922 """Parse rules and queries from a file"""
7923 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7924
7925 def get_rules(self):
7926 """retrieve rules that have been added to fixedpoint context"""
7927 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7928
7929 def get_assertions(self):
7930 """retrieve assertions that have been added to fixedpoint context"""
7931 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7932
7933 def __repr__(self):
7934 """Return a formatted string with all added rules and constraints."""
7935 return self.sexpr()
7936
7937 def sexpr(self):
7938 """Return a formatted string (in Lisp-like format) with all added constraints.
7939 We say the string is in s-expression format.
7940 """
7941 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7942
7943 def to_string(self, queries):
7944 """Return a formatted string (in Lisp-like format) with all added constraints.
7945 We say the string is in s-expression format.
7946 Include also queries.
7947 """
7948 args, len = _to_ast_array(queries)
7949 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7950
7951 def statistics(self):
7952 """Return statistics for the last `query()`.
7953 """
7954 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7955
7956 def reason_unknown(self):
7957 """Return a string describing why the last `query()` returned `unknown`.
7958 """
7959 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7960
7961 def declare_var(self, *vars):
7962 """Add variable or several variables.
7963 The added variable or variables will be bound in the rules
7964 and queries
7965 """
7966 vars = _get_args(vars)
7967 for v in vars:
7968 self.vars += [v]
7969
7970 def abstract(self, fml, is_forall=True):
7971 if self.vars == []:
7972 return fml
7973 if is_forall:
7974 return ForAll(self.vars, fml)
7975 else:
7976 return Exists(self.vars, fml)
7977
7978
7979#########################################
7980#
7981# Finite domains
7982#
7983#########################################
7984
7985class FiniteDomainSortRef(SortRef):
7986 """Finite domain sort."""
7987
7988 def size(self):
7989 """Return the size of the finite domain sort"""
7990 r = (ctypes.c_ulonglong * 1)()
7991 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7992 return r[0]
7993 else:
7994 raise Z3Exception("Failed to retrieve finite domain sort size")
7995
7996
7997def FiniteDomainSort(name, sz, ctx=None):
7998 """Create a named finite domain sort of a given size sz"""
7999 if not isinstance(name, Symbol):
8000 name = to_symbol(name)
8001 ctx = _get_ctx(ctx)
8002 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
8003
8004
8005def is_finite_domain_sort(s):
8006 """Return True if `s` is a Z3 finite-domain sort.
8007
8008 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
8009 True
8010 >>> is_finite_domain_sort(IntSort())
8011 False
8012 """
8013 return isinstance(s, FiniteDomainSortRef)
8014
8015
8016class FiniteDomainRef(ExprRef):
8017 """Finite-domain expressions."""
8018
8019 def sort(self):
8020 """Return the sort of the finite-domain expression `self`."""
8021 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
8022
8023 def as_string(self):
8024 """Return a Z3 floating point expression as a Python string."""
8025 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
8026
8027
8028def is_finite_domain(a):
8029 """Return `True` if `a` is a Z3 finite-domain expression.
8030
8031 >>> s = FiniteDomainSort('S', 100)
8032 >>> b = Const('b', s)
8033 >>> is_finite_domain(b)
8034 True
8035 >>> is_finite_domain(Int('x'))
8036 False
8037 """
8038 return isinstance(a, FiniteDomainRef)
8039
8040
8041class FiniteDomainNumRef(FiniteDomainRef):
8042 """Integer values."""
8043
8044 def as_long(self):
8045 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
8046
8047 >>> s = FiniteDomainSort('S', 100)
8048 >>> v = FiniteDomainVal(3, s)
8049 >>> v
8050 3
8051 >>> v.as_long() + 1
8052 4
8053 """
8054 return int(self.as_string())
8055
8056 def as_string(self):
8057 """Return a Z3 finite-domain numeral as a Python string.
8058
8059 >>> s = FiniteDomainSort('S', 100)
8060 >>> v = FiniteDomainVal(42, s)
8061 >>> v.as_string()
8062 '42'
8063 """
8064 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
8065
8066
8067def FiniteDomainVal(val, sort, ctx=None):
8068 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
8069
8070 >>> s = FiniteDomainSort('S', 256)
8071 >>> FiniteDomainVal(255, s)
8072 255
8073 >>> FiniteDomainVal('100', s)
8074 100
8075 """
8076 if z3_debug():
8077 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
8078 ctx = sort.ctx
8079 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
8080
8081
8082def is_finite_domain_value(a):
8083 """Return `True` if `a` is a Z3 finite-domain value.
8084
8085 >>> s = FiniteDomainSort('S', 100)
8086 >>> b = Const('b', s)
8087 >>> is_finite_domain_value(b)
8088 False
8089 >>> b = FiniteDomainVal(10, s)
8090 >>> b
8091 10
8092 >>> is_finite_domain_value(b)
8093 True
8094 """
8095 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
8096
8097
8098#########################################
8099#
8100# Optimize
8101#
8102#########################################
8103
8104class OptimizeObjective:
8105 def __init__(self, opt, value, is_max):
8106 self._opt = opt
8107 self._value = value
8108 self._is_max = is_max
8109
8110 def lower(self):
8111 opt = self._opt
8112 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8113
8114 def upper(self):
8115 opt = self._opt
8116 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8117
8118 def lower_values(self):
8119 opt = self._opt
8120 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8121
8122 def upper_values(self):
8123 opt = self._opt
8124 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8125
8126 def value(self):
8127 if self._is_max:
8128 return self.upper()
8129 else:
8130 return self.lower()
8131
8132 def __str__(self):
8133 return "%s:%s" % (self._value, self._is_max)
8134
8135
8136_on_models = {}
8137
8138
8139def _global_on_model(ctx):
8140 (fn, mdl) = _on_models[ctx]
8141 fn(mdl)
8142
8143
8144_on_model_eh = on_model_eh_type(_global_on_model)
8145
8146
8147class Optimize(Z3PPObject):
8148 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8149
8150 def __init__(self, optimize=None, ctx=None):
8151 self.ctx = _get_ctx(ctx)
8152 if optimize is None:
8153 self.optimize = Z3_mk_optimize(self.ctx.ref())
8154 else:
8155 self.optimize = optimize
8156 self._on_models_id = None
8157 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8158
8159 def __deepcopy__(self, memo={}):
8160 return Optimize(self.optimize, self.ctx)
8161
8162 def __del__(self):
8163 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8164 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8165 if self._on_models_id is not None:
8166 del _on_models[self._on_models_id]
8167
8168 def __enter__(self):
8169 self.push()
8170 return self
8171
8172 def __exit__(self, *exc_info):
8173 self.pop()
8174
8175 def set(self, *args, **keys):
8176 """Set a configuration option.
8177 The method `help()` return a string containing all available options.
8178 """
8179 p = args2params(args, keys, self.ctx)
8180 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8181
8182 def help(self):
8183 """Display a string describing all available options."""
8184 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8185
8186 def param_descrs(self):
8187 """Return the parameter description set."""
8188 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8189
8190 def assert_exprs(self, *args):
8191 """Assert constraints as background axioms for the optimize solver."""
8192 args = _get_args(args)
8193 s = BoolSort(self.ctx)
8194 for arg in args:
8195 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8196 for f in arg:
8197 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8198 else:
8199 arg = s.cast(arg)
8200 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8201
8202 def add(self, *args):
8203 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8204 self.assert_exprs(*args)
8205
8206 def __iadd__(self, fml):
8207 self.add(fml)
8208 return self
8209
8210 def assert_and_track(self, a, p):
8211 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8212
8213 If `p` is a string, it will be automatically converted into a Boolean constant.
8214
8215 >>> x = Int('x')
8216 >>> p3 = Bool('p3')
8217 >>> s = Optimize()
8218 >>> s.assert_and_track(x > 0, 'p1')
8219 >>> s.assert_and_track(x != 1, 'p2')
8220 >>> s.assert_and_track(x < 0, p3)
8221 >>> print(s.check())
8222 unsat
8223 >>> c = s.unsat_core()
8224 >>> len(c)
8225 2
8226 >>> Bool('p1') in c
8227 True
8228 >>> Bool('p2') in c
8229 False
8230 >>> p3 in c
8231 True
8232 """
8233 if isinstance(p, str):
8234 p = Bool(p, self.ctx)
8235 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8236 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8237 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8238
8239 def add_soft(self, arg, weight="1", id=None):
8240 """Add soft constraint with optional weight and optional identifier.
8241 If no weight is supplied, then the penalty for violating the soft constraint
8242 is 1.
8243 Soft constraints are grouped by identifiers. Soft constraints that are
8244 added without identifiers are grouped by default.
8245 """
8246 if _is_int(weight):
8247 weight = "%d" % weight
8248 elif isinstance(weight, float):
8249 weight = "%f" % weight
8250 if not isinstance(weight, str):
8251 raise Z3Exception("weight should be a string or an integer")
8252 if id is None:
8253 id = ""
8254 id = to_symbol(id, self.ctx)
8255
8256 def asoft(a):
8257 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8258 return OptimizeObjective(self, v, False)
8259 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8260 return [asoft(a) for a in arg]
8261 return asoft(arg)
8262
8263 def set_initial_value(self, var, value):
8264 """initialize the solver's state by setting the initial value of var to value
8265 """
8266 s = var.sort()
8267 value = s.cast(value)
8268 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8269
8270 def maximize(self, arg):
8271 """Add objective function to maximize."""
8272 return OptimizeObjective(
8273 self,
8274 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8275 is_max=True,
8276 )
8277
8278 def minimize(self, arg):
8279 """Add objective function to minimize."""
8280 return OptimizeObjective(
8281 self,
8282 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8283 is_max=False,
8284 )
8285
8286 def push(self):
8287 """create a backtracking point for added rules, facts and assertions"""
8288 Z3_optimize_push(self.ctx.ref(), self.optimize)
8289
8290 def pop(self):
8291 """restore to previously created backtracking point"""
8292 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8293
8294 def check(self, *assumptions):
8295 """Check consistency and produce optimal values."""
8296 assumptions = _get_args(assumptions)
8297 num = len(assumptions)
8298 _assumptions = (Ast * num)()
8299 for i in range(num):
8300 _assumptions[i] = assumptions[i].as_ast()
8301 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8302
8303 def reason_unknown(self):
8304 """Return a string that describes why the last `check()` returned `unknown`."""
8305 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8306
8307 def model(self):
8308 """Return a model for the last check()."""
8309 try:
8310 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8311 except Z3Exception:
8312 raise Z3Exception("model is not available")
8313
8314 def unsat_core(self):
8315 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8316
8317 def lower(self, obj):
8318 if not isinstance(obj, OptimizeObjective):
8319 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8320 return obj.lower()
8321
8322 def upper(self, obj):
8323 if not isinstance(obj, OptimizeObjective):
8324 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8325 return obj.upper()
8326
8327 def lower_values(self, obj):
8328 if not isinstance(obj, OptimizeObjective):
8329 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8330 return obj.lower_values()
8331
8332 def upper_values(self, obj):
8333 if not isinstance(obj, OptimizeObjective):
8334 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8335 return obj.upper_values()
8336
8337 def from_file(self, filename):
8338 """Parse assertions and objectives from a file"""
8339 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8340
8341 def from_string(self, s):
8342 """Parse assertions and objectives from a string"""
8343 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8344
8345 def assertions(self):
8346 """Return an AST vector containing all added constraints."""
8347 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8348
8349 def objectives(self):
8350 """returns set of objective functions"""
8351 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8352
8353 def __repr__(self):
8354 """Return a formatted string with all added rules and constraints."""
8355 return self.sexpr()
8356
8357 def sexpr(self):
8358 """Return a formatted string (in Lisp-like format) with all added constraints.
8359 We say the string is in s-expression format.
8360 """
8361 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8362
8363 def statistics(self):
8364 """Return statistics for the last check`.
8365 """
8366 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8367
8368 def set_on_model(self, on_model):
8369 """Register a callback that is invoked with every incremental improvement to
8370 objective values. The callback takes a model as argument.
8371 The life-time of the model is limited to the callback so the
8372 model has to be (deep) copied if it is to be used after the callback
8373 """
8374 id = len(_on_models) + 41
8375 mdl = Model(self.ctx)
8376 _on_models[id] = (on_model, mdl)
8377 self._on_models_id = id
8378 Z3_optimize_register_model_eh(
8379 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8380 )
8381
8382
8383#########################################
8384#
8385# ApplyResult
8386#
8387#########################################
8388class ApplyResult(Z3PPObject):
8389 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8390 It also contains model and proof converters.
8391 """
8392
8393 def __init__(self, result, ctx):
8394 self.result = result
8395 self.ctx = ctx
8396 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8397
8398 def __deepcopy__(self, memo={}):
8399 return ApplyResult(self.result, self.ctx)
8400
8401 def __del__(self):
8402 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8403 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8404
8405 def __len__(self):
8406 """Return the number of subgoals in `self`.
8407
8408 >>> a, b = Ints('a b')
8409 >>> g = Goal()
8410 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8411 >>> t = Tactic('split-clause')
8412 >>> r = t(g)
8413 >>> len(r)
8414 2
8415 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8416 >>> len(t(g))
8417 4
8418 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8419 >>> len(t(g))
8420 1
8421 """
8422 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8423
8424 def __getitem__(self, idx):
8425 """Return one of the subgoals stored in ApplyResult object `self`.
8426
8427 >>> a, b = Ints('a b')
8428 >>> g = Goal()
8429 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8430 >>> t = Tactic('split-clause')
8431 >>> r = t(g)
8432 >>> r[0]
8433 [a == 0, Or(b == 0, b == 1), a > b]
8434 >>> r[1]
8435 [a == 1, Or(b == 0, b == 1), a > b]
8436 """
8437 if idx >= len(self):
8438 raise IndexError
8439 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8440
8441 def __repr__(self):
8442 return obj_to_string(self)
8443
8444 def sexpr(self):
8445 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8446 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8447
8448 def as_expr(self):
8449 """Return a Z3 expression consisting of all subgoals.
8450
8451 >>> x = Int('x')
8452 >>> g = Goal()
8453 >>> g.add(x > 1)
8454 >>> g.add(Or(x == 2, x == 3))
8455 >>> r = Tactic('simplify')(g)
8456 >>> r
8457 [[Not(x <= 1), Or(x == 2, x == 3)]]
8458 >>> r.as_expr()
8459 And(Not(x <= 1), Or(x == 2, x == 3))
8460 >>> r = Tactic('split-clause')(g)
8461 >>> r
8462 [[x > 1, x == 2], [x > 1, x == 3]]
8463 >>> r.as_expr()
8464 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8465 """
8466 sz = len(self)
8467 if sz == 0:
8468 return BoolVal(False, self.ctx)
8469 elif sz == 1:
8470 return self[0].as_expr()
8471 else:
8472 return Or([self[i].as_expr() for i in range(len(self))])
8473
8474#########################################
8475#
8476# Simplifiers
8477#
8478#########################################
8479
8480class Simplifier:
8481 """Simplifiers act as pre-processing utilities for solvers.
8482 Build a custom simplifier and add it to a solver"""
8483
8484 def __init__(self, simplifier, ctx=None):
8485 self.ctx = _get_ctx(ctx)
8486 self.simplifier = None
8487 if isinstance(simplifier, SimplifierObj):
8488 self.simplifier = simplifier
8489 elif isinstance(simplifier, list):
8490 simps = [Simplifier(s, ctx) for s in simplifier]
8491 self.simplifier = simps[0].simplifier
8492 for i in range(1, len(simps)):
8493 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8494 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8495 return
8496 else:
8497 if z3_debug():
8498 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8499 try:
8500 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8501 except Z3Exception:
8502 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8503 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8504
8505 def __deepcopy__(self, memo={}):
8506 return Simplifier(self.simplifier, self.ctx)
8507
8508 def __del__(self):
8509 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8510 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8511
8512 def using_params(self, *args, **keys):
8513 """Return a simplifier that uses the given configuration options"""
8514 p = args2params(args, keys, self.ctx)
8515 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8516
8517 def add(self, solver):
8518 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8519 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8520
8521 def help(self):
8522 """Display a string containing a description of the available options for the `self` simplifier."""
8523 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8524
8525 def param_descrs(self):
8526 """Return the parameter description set."""
8527 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8528
8529
8530#########################################
8531#
8532# Tactics
8533#
8534#########################################
8535
8536
8537class Tactic:
8538 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8539 A Tactic can be converted into a Solver using the method solver().
8540
8541 Several combinators are available for creating new tactics using the built-in ones:
8542 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8543 """
8544
8545 def __init__(self, tactic, ctx=None):
8546 self.ctx = _get_ctx(ctx)
8547 self.tactic = None
8548 if isinstance(tactic, TacticObj):
8549 self.tactic = tactic
8550 else:
8551 if z3_debug():
8552 _z3_assert(isinstance(tactic, str), "tactic name expected")
8553 try:
8554 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8555 except Z3Exception:
8556 raise Z3Exception("unknown tactic '%s'" % tactic)
8557 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8558
8559 def __deepcopy__(self, memo={}):
8560 return Tactic(self.tactic, self.ctx)
8561
8562 def __del__(self):
8563 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8564 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8565
8566 def solver(self, logFile=None):
8567 """Create a solver using the tactic `self`.
8568
8569 The solver supports the methods `push()` and `pop()`, but it
8570 will always solve each `check()` from scratch.
8571
8572 >>> t = Then('simplify', 'nlsat')
8573 >>> s = t.solver()
8574 >>> x = Real('x')
8575 >>> s.add(x**2 == 2, x > 0)
8576 >>> s.check()
8577 sat
8578 >>> s.model()
8579 [x = 1.4142135623?]
8580 """
8581 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8582
8583 def apply(self, goal, *arguments, **keywords):
8584 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8585
8586 >>> x, y = Ints('x y')
8587 >>> t = Tactic('solve-eqs')
8588 >>> t.apply(And(x == 0, y >= x + 1))
8589 [[y >= 1]]
8590 """
8591 if z3_debug():
8592 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8593 goal = _to_goal(goal)
8594 if len(arguments) > 0 or len(keywords) > 0:
8595 p = args2params(arguments, keywords, self.ctx)
8596 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8597 else:
8598 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8599
8600 def __call__(self, goal, *arguments, **keywords):
8601 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8602
8603 >>> x, y = Ints('x y')
8604 >>> t = Tactic('solve-eqs')
8605 >>> t(And(x == 0, y >= x + 1))
8606 [[y >= 1]]
8607 """
8608 return self.apply(goal, *arguments, **keywords)
8609
8610 def help(self):
8611 """Display a string containing a description of the available options for the `self` tactic."""
8612 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8613
8614 def param_descrs(self):
8615 """Return the parameter description set."""
8616 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8617
8618
8619def _to_goal(a):
8620 if isinstance(a, BoolRef):
8621 goal = Goal(ctx=a.ctx)
8622 goal.add(a)
8623 return goal
8624 else:
8625 return a
8626
8627
8628def _to_tactic(t, ctx=None):
8629 if isinstance(t, Tactic):
8630 return t
8631 else:
8632 return Tactic(t, ctx)
8633
8634
8635def _and_then(t1, t2, ctx=None):
8636 t1 = _to_tactic(t1, ctx)
8637 t2 = _to_tactic(t2, ctx)
8638 if z3_debug():
8639 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8640 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8641
8642
8643def _or_else(t1, t2, ctx=None):
8644 t1 = _to_tactic(t1, ctx)
8645 t2 = _to_tactic(t2, ctx)
8646 if z3_debug():
8647 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8648 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8649
8650
8651def AndThen(*ts, **ks):
8652 """Return a tactic that applies the tactics in `*ts` in sequence.
8653
8654 >>> x, y = Ints('x y')
8655 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8656 >>> t(And(x == 0, y > x + 1))
8657 [[Not(y <= 1)]]
8658 >>> t(And(x == 0, y > x + 1)).as_expr()
8659 Not(y <= 1)
8660 """
8661 if z3_debug():
8662 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8663 ctx = ks.get("ctx", None)
8664 num = len(ts)
8665 r = ts[0]
8666 for i in range(num - 1):
8667 r = _and_then(r, ts[i + 1], ctx)
8668 return r
8669
8670
8671def Then(*ts, **ks):
8672 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8673
8674 >>> x, y = Ints('x y')
8675 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8676 >>> t(And(x == 0, y > x + 1))
8677 [[Not(y <= 1)]]
8678 >>> t(And(x == 0, y > x + 1)).as_expr()
8679 Not(y <= 1)
8680 """
8681 return AndThen(*ts, **ks)
8682
8683
8684def OrElse(*ts, **ks):
8685 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8686
8687 >>> x = Int('x')
8688 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8689 >>> # Tactic split-clause fails if there is no clause in the given goal.
8690 >>> t(x == 0)
8691 [[x == 0]]
8692 >>> t(Or(x == 0, x == 1))
8693 [[x == 0], [x == 1]]
8694 """
8695 if z3_debug():
8696 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8697 ctx = ks.get("ctx", None)
8698 num = len(ts)
8699 r = ts[0]
8700 for i in range(num - 1):
8701 r = _or_else(r, ts[i + 1], ctx)
8702 return r
8703
8704
8705def ParOr(*ts, **ks):
8706 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8707
8708 >>> x = Int('x')
8709 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8710 >>> t(x + 1 == 2)
8711 [[x == 1]]
8712 """
8713 if z3_debug():
8714 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8715 ctx = _get_ctx(ks.get("ctx", None))
8716 ts = [_to_tactic(t, ctx) for t in ts]
8717 sz = len(ts)
8718 _args = (TacticObj * sz)()
8719 for i in range(sz):
8720 _args[i] = ts[i].tactic
8721 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8722
8723
8724def ParThen(t1, t2, ctx=None):
8725 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8726 The subgoals are processed in parallel.
8727
8728 >>> x, y = Ints('x y')
8729 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8730 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8731 [[x == 1, y == 2], [x == 2, y == 3]]
8732 """
8733 t1 = _to_tactic(t1, ctx)
8734 t2 = _to_tactic(t2, ctx)
8735 if z3_debug():
8736 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8737 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8738
8739
8740def ParAndThen(t1, t2, ctx=None):
8741 """Alias for ParThen(t1, t2, ctx)."""
8742 return ParThen(t1, t2, ctx)
8743
8744
8745def With(t, *args, **keys):
8746 """Return a tactic that applies tactic `t` using the given configuration options.
8747
8748 >>> x, y = Ints('x y')
8749 >>> t = With(Tactic('simplify'), som=True)
8750 >>> t((x + 1)*(y + 2) == 0)
8751 [[2*x + y + x*y == -2]]
8752 """
8753 ctx = keys.pop("ctx", None)
8754 t = _to_tactic(t, ctx)
8755 p = args2params(args, keys, t.ctx)
8756 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8757
8758
8759def WithParams(t, p):
8760 """Return a tactic that applies tactic `t` using the given configuration options.
8761
8762 >>> x, y = Ints('x y')
8763 >>> p = ParamsRef()
8764 >>> p.set("som", True)
8765 >>> t = WithParams(Tactic('simplify'), p)
8766 >>> t((x + 1)*(y + 2) == 0)
8767 [[2*x + y + x*y == -2]]
8768 """
8769 t = _to_tactic(t, None)
8770 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8771
8772
8773def Repeat(t, max=4294967295, ctx=None):
8774 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8775 or the maximum number of iterations `max` is reached.
8776
8777 >>> x, y = Ints('x y')
8778 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8779 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8780 >>> r = t(c)
8781 >>> for subgoal in r: print(subgoal)
8782 [x == 0, y == 0, x > y]
8783 [x == 0, y == 1, x > y]
8784 [x == 1, y == 0, x > y]
8785 [x == 1, y == 1, x > y]
8786 >>> t = Then(t, Tactic('propagate-values'))
8787 >>> t(c)
8788 [[x == 1, y == 0]]
8789 """
8790 t = _to_tactic(t, ctx)
8791 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8792
8793
8794def TryFor(t, ms, ctx=None):
8795 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8796
8797 If `t` does not terminate in `ms` milliseconds, then it fails.
8798 """
8799 t = _to_tactic(t, ctx)
8800 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8801
8802
8803def tactics(ctx=None):
8804 """Return a list of all available tactics in Z3.
8805
8806 >>> l = tactics()
8807 >>> l.count('simplify') == 1
8808 True
8809 """
8810 ctx = _get_ctx(ctx)
8811 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8812
8813
8814def tactic_description(name, ctx=None):
8815 """Return a short description for the tactic named `name`.
8816
8817 >>> d = tactic_description('simplify')
8818 """
8819 ctx = _get_ctx(ctx)
8820 return Z3_tactic_get_descr(ctx.ref(), name)
8821
8822
8823def describe_tactics():
8824 """Display a (tabular) description of all available tactics in Z3."""
8825 if in_html_mode():
8826 even = True
8827 print('<table border="1" cellpadding="2" cellspacing="0">')
8828 for t in tactics():
8829 if even:
8830 print('<tr style="background-color:#CFCFCF">')
8831 even = False
8832 else:
8833 print("<tr>")
8834 even = True
8835 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8836 print("</table>")
8837 else:
8838 for t in tactics():
8839 print("%s : %s" % (t, tactic_description(t)))
8840
8841
8842class Probe:
8843 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8844 to decide which solver and/or preprocessing step will be used.
8845 """
8846
8847 def __init__(self, probe, ctx=None):
8848 self.ctx = _get_ctx(ctx)
8849 self.probe = None
8850 if isinstance(probe, ProbeObj):
8851 self.probe = probe
8852 elif isinstance(probe, float):
8853 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8854 elif _is_int(probe):
8855 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8856 elif isinstance(probe, bool):
8857 if probe:
8858 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8859 else:
8860 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8861 else:
8862 if z3_debug():
8863 _z3_assert(isinstance(probe, str), "probe name expected")
8864 try:
8865 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8866 except Z3Exception:
8867 raise Z3Exception("unknown probe '%s'" % probe)
8868 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8869
8870 def __deepcopy__(self, memo={}):
8871 return Probe(self.probe, self.ctx)
8872
8873 def __del__(self):
8874 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8875 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8876
8877 def __lt__(self, other):
8878 """Return a probe that evaluates to "true" when the value returned by `self`
8879 is less than the value returned by `other`.
8880
8881 >>> p = Probe('size') < 10
8882 >>> x = Int('x')
8883 >>> g = Goal()
8884 >>> g.add(x > 0)
8885 >>> g.add(x < 10)
8886 >>> p(g)
8887 1.0
8888 """
8889 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8890
8891 def __gt__(self, other):
8892 """Return a probe that evaluates to "true" when the value returned by `self`
8893 is greater than the value returned by `other`.
8894
8895 >>> p = Probe('size') > 10
8896 >>> x = Int('x')
8897 >>> g = Goal()
8898 >>> g.add(x > 0)
8899 >>> g.add(x < 10)
8900 >>> p(g)
8901 0.0
8902 """
8903 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8904
8905 def __le__(self, other):
8906 """Return a probe that evaluates to "true" when the value returned by `self`
8907 is less than or equal to the value returned by `other`.
8908
8909 >>> p = Probe('size') <= 2
8910 >>> x = Int('x')
8911 >>> g = Goal()
8912 >>> g.add(x > 0)
8913 >>> g.add(x < 10)
8914 >>> p(g)
8915 1.0
8916 """
8917 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8918
8919 def __ge__(self, other):
8920 """Return a probe that evaluates to "true" when the value returned by `self`
8921 is greater than or equal to the value returned by `other`.
8922
8923 >>> p = Probe('size') >= 2
8924 >>> x = Int('x')
8925 >>> g = Goal()
8926 >>> g.add(x > 0)
8927 >>> g.add(x < 10)
8928 >>> p(g)
8929 1.0
8930 """
8931 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8932
8933 def __eq__(self, other):
8934 """Return a probe that evaluates to "true" when the value returned by `self`
8935 is equal to the value returned by `other`.
8936
8937 >>> p = Probe('size') == 2
8938 >>> x = Int('x')
8939 >>> g = Goal()
8940 >>> g.add(x > 0)
8941 >>> g.add(x < 10)
8942 >>> p(g)
8943 1.0
8944 """
8945 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8946
8947 def __ne__(self, other):
8948 """Return a probe that evaluates to "true" when the value returned by `self`
8949 is not equal to the value returned by `other`.
8950
8951 >>> p = Probe('size') != 2
8952 >>> x = Int('x')
8953 >>> g = Goal()
8954 >>> g.add(x > 0)
8955 >>> g.add(x < 10)
8956 >>> p(g)
8957 0.0
8958 """
8959 p = self.__eq__(other)
8960 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8961
8962 def __call__(self, goal):
8963 """Evaluate the probe `self` in the given goal.
8964
8965 >>> p = Probe('size')
8966 >>> x = Int('x')
8967 >>> g = Goal()
8968 >>> g.add(x > 0)
8969 >>> g.add(x < 10)
8970 >>> p(g)
8971 2.0
8972 >>> g.add(x < 20)
8973 >>> p(g)
8974 3.0
8975 >>> p = Probe('num-consts')
8976 >>> p(g)
8977 1.0
8978 >>> p = Probe('is-propositional')
8979 >>> p(g)
8980 0.0
8981 >>> p = Probe('is-qflia')
8982 >>> p(g)
8983 1.0
8984 """
8985 if z3_debug():
8986 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8987 goal = _to_goal(goal)
8988 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8989
8990
8991def is_probe(p):
8992 """Return `True` if `p` is a Z3 probe.
8993
8994 >>> is_probe(Int('x'))
8995 False
8996 >>> is_probe(Probe('memory'))
8997 True
8998 """
8999 return isinstance(p, Probe)
9000
9001
9002def _to_probe(p, ctx=None):
9003 if is_probe(p):
9004 return p
9005 else:
9006 return Probe(p, ctx)
9007
9008
9009def probes(ctx=None):
9010 """Return a list of all available probes in Z3.
9011
9012 >>> l = probes()
9013 >>> l.count('memory') == 1
9014 True
9015 """
9016 ctx = _get_ctx(ctx)
9017 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
9018
9019
9020def probe_description(name, ctx=None):
9021 """Return a short description for the probe named `name`.
9022
9023 >>> d = probe_description('memory')
9024 """
9025 ctx = _get_ctx(ctx)
9026 return Z3_probe_get_descr(ctx.ref(), name)
9027
9028
9029def describe_probes():
9030 """Display a (tabular) description of all available probes in Z3."""
9031 if in_html_mode():
9032 even = True
9033 print('<table border="1" cellpadding="2" cellspacing="0">')
9034 for p in probes():
9035 if even:
9036 print('<tr style="background-color:#CFCFCF">')
9037 even = False
9038 else:
9039 print("<tr>")
9040 even = True
9041 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
9042 print("</table>")
9043 else:
9044 for p in probes():
9045 print("%s : %s" % (p, probe_description(p)))
9046
9047
9048def _probe_nary(f, args, ctx):
9049 if z3_debug():
9050 _z3_assert(len(args) > 0, "At least one argument expected")
9051 num = len(args)
9052 r = _to_probe(args[0], ctx)
9053 for i in range(num - 1):
9054 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
9055 return r
9056
9057
9058def _probe_and(args, ctx):
9059 return _probe_nary(Z3_probe_and, args, ctx)
9060
9061
9062def _probe_or(args, ctx):
9063 return _probe_nary(Z3_probe_or, args, ctx)
9064
9065
9066def FailIf(p, ctx=None):
9067 """Return a tactic that fails if the probe `p` evaluates to true.
9068 Otherwise, it returns the input goal unmodified.
9069
9070 In the following example, the tactic applies 'simplify' if and only if there are
9071 more than 2 constraints in the goal.
9072
9073 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
9074 >>> x, y = Ints('x y')
9075 >>> g = Goal()
9076 >>> g.add(x > 0)
9077 >>> g.add(y > 0)
9078 >>> t(g)
9079 [[x > 0, y > 0]]
9080 >>> g.add(x == y + 1)
9081 >>> t(g)
9082 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9083 """
9084 p = _to_probe(p, ctx)
9085 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
9086
9087
9088def When(p, t, ctx=None):
9089 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
9090 Otherwise, it returns the input goal unmodified.
9091
9092 >>> t = When(Probe('size') > 2, Tactic('simplify'))
9093 >>> x, y = Ints('x y')
9094 >>> g = Goal()
9095 >>> g.add(x > 0)
9096 >>> g.add(y > 0)
9097 >>> t(g)
9098 [[x > 0, y > 0]]
9099 >>> g.add(x == y + 1)
9100 >>> t(g)
9101 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9102 """
9103 p = _to_probe(p, ctx)
9104 t = _to_tactic(t, ctx)
9105 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
9106
9107
9108def Cond(p, t1, t2, ctx=None):
9109 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
9110
9111 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
9112 """
9113 p = _to_probe(p, ctx)
9114 t1 = _to_tactic(t1, ctx)
9115 t2 = _to_tactic(t2, ctx)
9116 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
9117
9118#########################################
9119#
9120# Utils
9121#
9122#########################################
9123
9124
9125def simplify(a, *arguments, **keywords):
9126 """Simplify the expression `a` using the given options.
9127
9128 This function has many options. Use `help_simplify` to obtain the complete list.
9129
9130 >>> x = Int('x')
9131 >>> y = Int('y')
9132 >>> simplify(x + 1 + y + x + 1)
9133 2 + 2*x + y
9134 >>> simplify((x + 1)*(y + 1), som=True)
9135 1 + x + y + x*y
9136 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9137 And(Not(x == y), Not(x == 1), Not(y == 1))
9138 >>> simplify(And(x == 0, y == 1), elim_and=True)
9139 Not(Or(Not(x == 0), Not(y == 1)))
9140 """
9141 if z3_debug():
9142 _z3_assert(is_expr(a), "Z3 expression expected")
9143 if len(arguments) > 0 or len(keywords) > 0:
9144 p = args2params(arguments, keywords, a.ctx)
9145 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9146 else:
9147 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9148
9149
9150def help_simplify():
9151 """Return a string describing all options available for Z3 `simplify` procedure."""
9152 print(Z3_simplify_get_help(main_ctx().ref()))
9153
9154
9155def simplify_param_descrs():
9156 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9157 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9158
9159
9160def substitute(t, *m):
9161 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9162 Every occurrence in t of from is replaced with to.
9163
9164 >>> x = Int('x')
9165 >>> y = Int('y')
9166 >>> substitute(x + 1, (x, y + 1))
9167 y + 1 + 1
9168 >>> f = Function('f', IntSort(), IntSort())
9169 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9170 1 + 1
9171 """
9172 if isinstance(m, tuple):
9173 m1 = _get_args(m)
9174 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9175 m = m1
9176 if z3_debug():
9177 _z3_assert(is_expr(t), "Z3 expression expected")
9178 _z3_assert(
9179 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9180 "Z3 invalid substitution, expression pairs expected.")
9181 _z3_assert(
9182 all([p[0].sort().eq(p[1].sort()) for p in m]),
9183 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9184 num = len(m)
9185 _from = (Ast * num)()
9186 _to = (Ast * num)()
9187 for i in range(num):
9188 _from[i] = m[i][0].as_ast()
9189 _to[i] = m[i][1].as_ast()
9190 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9191
9192
9193def substitute_vars(t, *m):
9194 """Substitute the free variables in t with the expression in m.
9195
9196 >>> v0 = Var(0, IntSort())
9197 >>> v1 = Var(1, IntSort())
9198 >>> x = Int('x')
9199 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9200 >>> # replace v0 with x+1 and v1 with x
9201 >>> substitute_vars(f(v0, v1), x + 1, x)
9202 f(x + 1, x)
9203 """
9204 if z3_debug():
9205 _z3_assert(is_expr(t), "Z3 expression expected")
9206 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9207 num = len(m)
9208 _to = (Ast * num)()
9209 for i in range(num):
9210 _to[i] = m[i].as_ast()
9211 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9212
9213def substitute_funs(t, *m):
9214 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9215 Every occurrence in to of the function from is replaced with the expression to.
9216 The expression to can have free variables, that refer to the arguments of from.
9217 For examples, see
9218 """
9219 if isinstance(m, tuple):
9220 m1 = _get_args(m)
9221 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9222 m = m1
9223 if z3_debug():
9224 _z3_assert(is_expr(t), "Z3 expression expected")
9225 _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.")
9226 num = len(m)
9227 _from = (FuncDecl * num)()
9228 _to = (Ast * num)()
9229 for i in range(num):
9230 _from[i] = m[i][0].as_func_decl()
9231 _to[i] = m[i][1].as_ast()
9232 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9233
9234
9235def Sum(*args):
9236 """Create the sum of the Z3 expressions.
9237
9238 >>> a, b, c = Ints('a b c')
9239 >>> Sum(a, b, c)
9240 a + b + c
9241 >>> Sum([a, b, c])
9242 a + b + c
9243 >>> A = IntVector('a', 5)
9244 >>> Sum(A)
9245 a__0 + a__1 + a__2 + a__3 + a__4
9246 """
9247 args = _get_args(args)
9248 if len(args) == 0:
9249 return 0
9250 ctx = _ctx_from_ast_arg_list(args)
9251 if ctx is None:
9252 return _reduce(lambda a, b: a + b, args, 0)
9253 args = _coerce_expr_list(args, ctx)
9254 if is_bv(args[0]):
9255 return _reduce(lambda a, b: a + b, args, 0)
9256 else:
9257 _args, sz = _to_ast_array(args)
9258 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9259
9260
9261def Product(*args):
9262 """Create the product of the Z3 expressions.
9263
9264 >>> a, b, c = Ints('a b c')
9265 >>> Product(a, b, c)
9266 a*b*c
9267 >>> Product([a, b, c])
9268 a*b*c
9269 >>> A = IntVector('a', 5)
9270 >>> Product(A)
9271 a__0*a__1*a__2*a__3*a__4
9272 """
9273 args = _get_args(args)
9274 if len(args) == 0:
9275 return 1
9276 ctx = _ctx_from_ast_arg_list(args)
9277 if ctx is None:
9278 return _reduce(lambda a, b: a * b, args, 1)
9279 args = _coerce_expr_list(args, ctx)
9280 if is_bv(args[0]):
9281 return _reduce(lambda a, b: a * b, args, 1)
9282 else:
9283 _args, sz = _to_ast_array(args)
9284 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9285
9286def Abs(arg):
9287 """Create the absolute value of an arithmetic expression"""
9288 return If(arg > 0, arg, -arg)
9289
9290
9291def AtMost(*args):
9292 """Create an at-most Pseudo-Boolean k constraint.
9293
9294 >>> a, b, c = Bools('a b c')
9295 >>> f = AtMost(a, b, c, 2)
9296 """
9297 args = _get_args(args)
9298 if z3_debug():
9299 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9300 ctx = _ctx_from_ast_arg_list(args)
9301 if z3_debug():
9302 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9303 args1 = _coerce_expr_list(args[:-1], ctx)
9304 k = args[-1]
9305 _args, sz = _to_ast_array(args1)
9306 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9307
9308
9309def AtLeast(*args):
9310 """Create an at-least Pseudo-Boolean k constraint.
9311
9312 >>> a, b, c = Bools('a b c')
9313 >>> f = AtLeast(a, b, c, 2)
9314 """
9315 args = _get_args(args)
9316 if z3_debug():
9317 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9318 ctx = _ctx_from_ast_arg_list(args)
9319 if z3_debug():
9320 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9321 args1 = _coerce_expr_list(args[:-1], ctx)
9322 k = args[-1]
9323 _args, sz = _to_ast_array(args1)
9324 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9325
9326
9327def _reorder_pb_arg(arg):
9328 a, b = arg
9329 if not _is_int(b) and _is_int(a):
9330 return b, a
9331 return arg
9332
9333
9334def _pb_args_coeffs(args, default_ctx=None):
9335 args = _get_args_ast_list(args)
9336 if len(args) == 0:
9337 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9338 args = [_reorder_pb_arg(arg) for arg in args]
9339 args, coeffs = zip(*args)
9340 if z3_debug():
9341 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9342 ctx = _ctx_from_ast_arg_list(args)
9343 if z3_debug():
9344 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9345 args = _coerce_expr_list(args, ctx)
9346 _args, sz = _to_ast_array(args)
9347 _coeffs = (ctypes.c_int * len(coeffs))()
9348 for i in range(len(coeffs)):
9349 _z3_check_cint_overflow(coeffs[i], "coefficient")
9350 _coeffs[i] = coeffs[i]
9351 return ctx, sz, _args, _coeffs, args
9352
9353
9354def PbLe(args, k):
9355 """Create a Pseudo-Boolean inequality k constraint.
9356
9357 >>> a, b, c = Bools('a b c')
9358 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9359 """
9360 _z3_check_cint_overflow(k, "k")
9361 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9362 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9363
9364
9365def PbGe(args, k):
9366 """Create a Pseudo-Boolean inequality k constraint.
9367
9368 >>> a, b, c = Bools('a b c')
9369 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9370 """
9371 _z3_check_cint_overflow(k, "k")
9372 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9373 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9374
9375
9376def PbEq(args, k, ctx=None):
9377 """Create a Pseudo-Boolean equality k constraint.
9378
9379 >>> a, b, c = Bools('a b c')
9380 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9381 """
9382 _z3_check_cint_overflow(k, "k")
9383 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9384 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9385
9386
9387def solve(*args, **keywords):
9388 """Solve the constraints `*args`.
9389
9390 This is a simple function for creating demonstrations. It creates a solver,
9391 configure it using the options in `keywords`, adds the constraints
9392 in `args`, and invokes check.
9393
9394 >>> a = Int('a')
9395 >>> solve(a > 0, a < 2)
9396 [a = 1]
9397 """
9398 show = keywords.pop("show", False)
9399 s = Solver()
9400 s.set(**keywords)
9401 s.add(*args)
9402 if show:
9403 print(s)
9404 r = s.check()
9405 if r == unsat:
9406 print("no solution")
9407 elif r == unknown:
9408 print("failed to solve")
9409 try:
9410 print(s.model())
9411 except Z3Exception:
9412 return
9413 else:
9414 print(s.model())
9415
9416
9417def solve_using(s, *args, **keywords):
9418 """Solve the constraints `*args` using solver `s`.
9419
9420 This is a simple function for creating demonstrations. It is similar to `solve`,
9421 but it uses the given solver `s`.
9422 It configures solver `s` using the options in `keywords`, adds the constraints
9423 in `args`, and invokes check.
9424 """
9425 show = keywords.pop("show", False)
9426 if z3_debug():
9427 _z3_assert(isinstance(s, Solver), "Solver object expected")
9428 s.set(**keywords)
9429 s.add(*args)
9430 if show:
9431 print("Problem:")
9432 print(s)
9433 r = s.check()
9434 if r == unsat:
9435 print("no solution")
9436 elif r == unknown:
9437 print("failed to solve")
9438 try:
9439 print(s.model())
9440 except Z3Exception:
9441 return
9442 else:
9443 if show:
9444 print("Solution:")
9445 print(s.model())
9446
9447
9448def prove(claim, show=False, **keywords):
9449 """Try to prove the given claim.
9450
9451 This is a simple function for creating demonstrations. It tries to prove
9452 `claim` by showing the negation is unsatisfiable.
9453
9454 >>> p, q = Bools('p q')
9455 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9456 proved
9457 """
9458 if z3_debug():
9459 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9460 s = Solver()
9461 s.set(**keywords)
9462 s.add(Not(claim))
9463 if show:
9464 print(s)
9465 r = s.check()
9466 if r == unsat:
9467 print("proved")
9468 elif r == unknown:
9469 print("failed to prove")
9470 print(s.model())
9471 else:
9472 print("counterexample")
9473 print(s.model())
9474
9475
9476def _solve_html(*args, **keywords):
9477 """Version of function `solve` that renders HTML output."""
9478 show = keywords.pop("show", False)
9479 s = Solver()
9480 s.set(**keywords)
9481 s.add(*args)
9482 if show:
9483 print("<b>Problem:</b>")
9484 print(s)
9485 r = s.check()
9486 if r == unsat:
9487 print("<b>no solution</b>")
9488 elif r == unknown:
9489 print("<b>failed to solve</b>")
9490 try:
9491 print(s.model())
9492 except Z3Exception:
9493 return
9494 else:
9495 if show:
9496 print("<b>Solution:</b>")
9497 print(s.model())
9498
9499
9500def _solve_using_html(s, *args, **keywords):
9501 """Version of function `solve_using` that renders HTML."""
9502 show = keywords.pop("show", False)
9503 if z3_debug():
9504 _z3_assert(isinstance(s, Solver), "Solver object expected")
9505 s.set(**keywords)
9506 s.add(*args)
9507 if show:
9508 print("<b>Problem:</b>")
9509 print(s)
9510 r = s.check()
9511 if r == unsat:
9512 print("<b>no solution</b>")
9513 elif r == unknown:
9514 print("<b>failed to solve</b>")
9515 try:
9516 print(s.model())
9517 except Z3Exception:
9518 return
9519 else:
9520 if show:
9521 print("<b>Solution:</b>")
9522 print(s.model())
9523
9524
9525def _prove_html(claim, show=False, **keywords):
9526 """Version of function `prove` that renders HTML."""
9527 if z3_debug():
9528 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9529 s = Solver()
9530 s.set(**keywords)
9531 s.add(Not(claim))
9532 if show:
9533 print(s)
9534 r = s.check()
9535 if r == unsat:
9536 print("<b>proved</b>")
9537 elif r == unknown:
9538 print("<b>failed to prove</b>")
9539 print(s.model())
9540 else:
9541 print("<b>counterexample</b>")
9542 print(s.model())
9543
9544
9545def _dict2sarray(sorts, ctx):
9546 sz = len(sorts)
9547 _names = (Symbol * sz)()
9548 _sorts = (Sort * sz)()
9549 i = 0
9550 for k in sorts:
9551 v = sorts[k]
9552 if z3_debug():
9553 _z3_assert(isinstance(k, str), "String expected")
9554 _z3_assert(is_sort(v), "Z3 sort expected")
9555 _names[i] = to_symbol(k, ctx)
9556 _sorts[i] = v.ast
9557 i = i + 1
9558 return sz, _names, _sorts
9559
9560
9561def _dict2darray(decls, ctx):
9562 sz = len(decls)
9563 _names = (Symbol * sz)()
9564 _decls = (FuncDecl * sz)()
9565 i = 0
9566 for k in decls:
9567 v = decls[k]
9568 if z3_debug():
9569 _z3_assert(isinstance(k, str), "String expected")
9570 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9571 _names[i] = to_symbol(k, ctx)
9572 if is_const(v):
9573 _decls[i] = v.decl().ast
9574 else:
9575 _decls[i] = v.ast
9576 i = i + 1
9577 return sz, _names, _decls
9578
9579class ParserContext:
9580 def __init__(self, ctx= None):
9581 self.ctx = _get_ctx(ctx)
9582 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9583 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9584
9585 def __del__(self):
9586 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9587 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9588 self.pctx = None
9589
9590 def add_sort(self, sort):
9591 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9592
9593 def add_decl(self, decl):
9594 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9595
9596 def from_string(self, s):
9597 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9598
9599def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9600 """Parse a string in SMT 2.0 format using the given sorts and decls.
9601
9602 The arguments sorts and decls are Python dictionaries used to initialize
9603 the symbol table used for the SMT 2.0 parser.
9604
9605 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9606 [x > 0, x < 10]
9607 >>> x, y = Ints('x y')
9608 >>> f = Function('f', IntSort(), IntSort())
9609 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9610 [x + f(y) > 0]
9611 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9612 [a > 0]
9613 """
9614 ctx = _get_ctx(ctx)
9615 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9616 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9617 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9618
9619
9620def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9621 """Parse a file in SMT 2.0 format using the given sorts and decls.
9622
9623 This function is similar to parse_smt2_string().
9624 """
9625 ctx = _get_ctx(ctx)
9626 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9627 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9628 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9629
9630
9631#########################################
9632#
9633# Floating-Point Arithmetic
9634#
9635#########################################
9636
9637
9638# Global default rounding mode
9639_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9640_dflt_fpsort_ebits = 11
9641_dflt_fpsort_sbits = 53
9642
9643
9644def get_default_rounding_mode(ctx=None):
9645 """Retrieves the global default rounding mode."""
9646 global _dflt_rounding_mode
9647 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9648 return RTZ(ctx)
9649 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9650 return RTN(ctx)
9651 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9652 return RTP(ctx)
9653 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9654 return RNE(ctx)
9655 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9656 return RNA(ctx)
9657
9658
9659_ROUNDING_MODES = frozenset({
9660 Z3_OP_FPA_RM_TOWARD_ZERO,
9661 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9662 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9663 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9664 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9665})
9666
9667
9668def set_default_rounding_mode(rm, ctx=None):
9669 global _dflt_rounding_mode
9670 if is_fprm_value(rm):
9671 _dflt_rounding_mode = rm.kind()
9672 else:
9673 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9674 _dflt_rounding_mode = rm
9675
9676
9677def get_default_fp_sort(ctx=None):
9678 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9679
9680
9681def set_default_fp_sort(ebits, sbits, ctx=None):
9682 global _dflt_fpsort_ebits
9683 global _dflt_fpsort_sbits
9684 _dflt_fpsort_ebits = ebits
9685 _dflt_fpsort_sbits = sbits
9686
9687
9688def _dflt_rm(ctx=None):
9689 return get_default_rounding_mode(ctx)
9690
9691
9692def _dflt_fps(ctx=None):
9693 return get_default_fp_sort(ctx)
9694
9695
9696def _coerce_fp_expr_list(alist, ctx):
9697 first_fp_sort = None
9698 for a in alist:
9699 if is_fp(a):
9700 if first_fp_sort is None:
9701 first_fp_sort = a.sort()
9702 elif first_fp_sort == a.sort():
9703 pass # OK, same as before
9704 else:
9705 # we saw at least 2 different float sorts; something will
9706 # throw a sort mismatch later, for now assume None.
9707 first_fp_sort = None
9708 break
9709
9710 r = []
9711 for i in range(len(alist)):
9712 a = alist[i]
9713 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9714 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9715 r.append(FPVal(a, None, first_fp_sort, ctx))
9716 else:
9717 r.append(a)
9718 return _coerce_expr_list(r, ctx)
9719
9720
9721# FP Sorts
9722
9723class FPSortRef(SortRef):
9724 """Floating-point sort."""
9725
9726 def ebits(self):
9727 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9728 >>> b = FPSort(8, 24)
9729 >>> b.ebits()
9730 8
9731 """
9732 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9733
9734 def sbits(self):
9735 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9736 >>> b = FPSort(8, 24)
9737 >>> b.sbits()
9738 24
9739 """
9740 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9741
9742 def cast(self, val):
9743 """Try to cast `val` as a floating-point expression.
9744 >>> b = FPSort(8, 24)
9745 >>> b.cast(1.0)
9746 1
9747 >>> b.cast(1.0).sexpr()
9748 '(fp #b0 #x7f #b00000000000000000000000)'
9749 """
9750 if is_expr(val):
9751 if z3_debug():
9752 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9753 return val
9754 else:
9755 return FPVal(val, None, self, self.ctx)
9756
9757
9758def Float16(ctx=None):
9759 """Floating-point 16-bit (half) sort."""
9760 ctx = _get_ctx(ctx)
9761 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9762
9763
9764def FloatHalf(ctx=None):
9765 """Floating-point 16-bit (half) sort."""
9766 ctx = _get_ctx(ctx)
9767 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9768
9769
9770def Float32(ctx=None):
9771 """Floating-point 32-bit (single) sort."""
9772 ctx = _get_ctx(ctx)
9773 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9774
9775
9776def FloatSingle(ctx=None):
9777 """Floating-point 32-bit (single) sort."""
9778 ctx = _get_ctx(ctx)
9779 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9780
9781
9782def Float64(ctx=None):
9783 """Floating-point 64-bit (double) sort."""
9784 ctx = _get_ctx(ctx)
9785 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9786
9787
9788def FloatDouble(ctx=None):
9789 """Floating-point 64-bit (double) sort."""
9790 ctx = _get_ctx(ctx)
9791 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9792
9793
9794def Float128(ctx=None):
9795 """Floating-point 128-bit (quadruple) sort."""
9796 ctx = _get_ctx(ctx)
9797 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9798
9799
9800def FloatQuadruple(ctx=None):
9801 """Floating-point 128-bit (quadruple) sort."""
9802 ctx = _get_ctx(ctx)
9803 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9804
9805
9806class FPRMSortRef(SortRef):
9807 """"Floating-point rounding mode sort."""
9808
9809
9810def is_fp_sort(s):
9811 """Return True if `s` is a Z3 floating-point sort.
9812
9813 >>> is_fp_sort(FPSort(8, 24))
9814 True
9815 >>> is_fp_sort(IntSort())
9816 False
9817 """
9818 return isinstance(s, FPSortRef)
9819
9820
9821def is_fprm_sort(s):
9822 """Return True if `s` is a Z3 floating-point rounding mode sort.
9823
9824 >>> is_fprm_sort(FPSort(8, 24))
9825 False
9826 >>> is_fprm_sort(RNE().sort())
9827 True
9828 """
9829 return isinstance(s, FPRMSortRef)
9830
9831# FP Expressions
9832
9833
9834class FPRef(ExprRef):
9835 """Floating-point expressions."""
9836
9837 def sort(self):
9838 """Return the sort of the floating-point expression `self`.
9839
9840 >>> x = FP('1.0', FPSort(8, 24))
9841 >>> x.sort()
9842 FPSort(8, 24)
9843 >>> x.sort() == FPSort(8, 24)
9844 True
9845 """
9846 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9847
9848 def ebits(self):
9849 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9850 >>> b = FPSort(8, 24)
9851 >>> b.ebits()
9852 8
9853 """
9854 return self.sort().ebits()
9855
9856 def sbits(self):
9857 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9858 >>> b = FPSort(8, 24)
9859 >>> b.sbits()
9860 24
9861 """
9862 return self.sort().sbits()
9863
9864 def as_string(self):
9865 """Return a Z3 floating point expression as a Python string."""
9866 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9867
9868 def __le__(self, other):
9869 return fpLEQ(self, other, self.ctx)
9870
9871 def __lt__(self, other):
9872 return fpLT(self, other, self.ctx)
9873
9874 def __ge__(self, other):
9875 return fpGEQ(self, other, self.ctx)
9876
9877 def __gt__(self, other):
9878 return fpGT(self, other, self.ctx)
9879
9880 def __add__(self, other):
9881 """Create the Z3 expression `self + other`.
9882
9883 >>> x = FP('x', FPSort(8, 24))
9884 >>> y = FP('y', FPSort(8, 24))
9885 >>> x + y
9886 x + y
9887 >>> (x + y).sort()
9888 FPSort(8, 24)
9889 """
9890 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9891 return fpAdd(_dflt_rm(), a, b, self.ctx)
9892
9893 def __radd__(self, other):
9894 """Create the Z3 expression `other + self`.
9895
9896 >>> x = FP('x', FPSort(8, 24))
9897 >>> 10 + x
9898 1.25*(2**3) + x
9899 """
9900 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9901 return fpAdd(_dflt_rm(), a, b, self.ctx)
9902
9903 def __sub__(self, other):
9904 """Create the Z3 expression `self - other`.
9905
9906 >>> x = FP('x', FPSort(8, 24))
9907 >>> y = FP('y', FPSort(8, 24))
9908 >>> x - y
9909 x - y
9910 >>> (x - y).sort()
9911 FPSort(8, 24)
9912 """
9913 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9914 return fpSub(_dflt_rm(), a, b, self.ctx)
9915
9916 def __rsub__(self, other):
9917 """Create the Z3 expression `other - self`.
9918
9919 >>> x = FP('x', FPSort(8, 24))
9920 >>> 10 - x
9921 1.25*(2**3) - x
9922 """
9923 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9924 return fpSub(_dflt_rm(), a, b, self.ctx)
9925
9926 def __mul__(self, other):
9927 """Create the Z3 expression `self * other`.
9928
9929 >>> x = FP('x', FPSort(8, 24))
9930 >>> y = FP('y', FPSort(8, 24))
9931 >>> x * y
9932 x * y
9933 >>> (x * y).sort()
9934 FPSort(8, 24)
9935 >>> 10 * y
9936 1.25*(2**3) * y
9937 """
9938 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9939 return fpMul(_dflt_rm(), a, b, self.ctx)
9940
9941 def __rmul__(self, other):
9942 """Create the Z3 expression `other * self`.
9943
9944 >>> x = FP('x', FPSort(8, 24))
9945 >>> y = FP('y', FPSort(8, 24))
9946 >>> x * y
9947 x * y
9948 >>> x * 10
9949 x * 1.25*(2**3)
9950 """
9951 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9952 return fpMul(_dflt_rm(), a, b, self.ctx)
9953
9954 def __pos__(self):
9955 """Create the Z3 expression `+self`."""
9956 return self
9957
9958 def __neg__(self):
9959 """Create the Z3 expression `-self`.
9960
9961 >>> x = FP('x', Float32())
9962 >>> -x
9963 -x
9964 """
9965 return fpNeg(self)
9966
9967 def __div__(self, other):
9968 """Create the Z3 expression `self / other`.
9969
9970 >>> x = FP('x', FPSort(8, 24))
9971 >>> y = FP('y', FPSort(8, 24))
9972 >>> x / y
9973 x / y
9974 >>> (x / y).sort()
9975 FPSort(8, 24)
9976 >>> 10 / y
9977 1.25*(2**3) / y
9978 """
9979 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9980 return fpDiv(_dflt_rm(), a, b, self.ctx)
9981
9982 def __rdiv__(self, other):
9983 """Create the Z3 expression `other / self`.
9984
9985 >>> x = FP('x', FPSort(8, 24))
9986 >>> y = FP('y', FPSort(8, 24))
9987 >>> x / y
9988 x / y
9989 >>> x / 10
9990 x / 1.25*(2**3)
9991 """
9992 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9993 return fpDiv(_dflt_rm(), a, b, self.ctx)
9994
9995 def __truediv__(self, other):
9996 """Create the Z3 expression division `self / other`."""
9997 return self.__div__(other)
9998
9999 def __rtruediv__(self, other):
10000 """Create the Z3 expression division `other / self`."""
10001 return self.__rdiv__(other)
10002
10003 def __mod__(self, other):
10004 """Create the Z3 expression mod `self % other`."""
10005 return fpRem(self, other)
10006
10007 def __rmod__(self, other):
10008 """Create the Z3 expression mod `other % self`."""
10009 return fpRem(other, self)
10010
10011
10012class FPRMRef(ExprRef):
10013 """Floating-point rounding mode expressions"""
10014
10015 def as_string(self):
10016 """Return a Z3 floating point expression as a Python string."""
10017 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10018
10019
10020def RoundNearestTiesToEven(ctx=None):
10021 ctx = _get_ctx(ctx)
10022 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10023
10024
10025def RNE(ctx=None):
10026 ctx = _get_ctx(ctx)
10027 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10028
10029
10030def RoundNearestTiesToAway(ctx=None):
10031 ctx = _get_ctx(ctx)
10032 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10033
10034
10035def RNA(ctx=None):
10036 ctx = _get_ctx(ctx)
10037 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10038
10039
10040def RoundTowardPositive(ctx=None):
10041 ctx = _get_ctx(ctx)
10042 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10043
10044
10045def RTP(ctx=None):
10046 ctx = _get_ctx(ctx)
10047 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10048
10049
10050def RoundTowardNegative(ctx=None):
10051 ctx = _get_ctx(ctx)
10052 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10053
10054
10055def RTN(ctx=None):
10056 ctx = _get_ctx(ctx)
10057 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10058
10059
10060def RoundTowardZero(ctx=None):
10061 ctx = _get_ctx(ctx)
10062 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10063
10064
10065def RTZ(ctx=None):
10066 ctx = _get_ctx(ctx)
10067 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10068
10069
10070def is_fprm(a):
10071 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
10072
10073 >>> rm = RNE()
10074 >>> is_fprm(rm)
10075 True
10076 >>> rm = 1.0
10077 >>> is_fprm(rm)
10078 False
10079 """
10080 return isinstance(a, FPRMRef)
10081
10082
10083def is_fprm_value(a):
10084 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
10085 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
10086
10087# FP Numerals
10088
10089
10090class FPNumRef(FPRef):
10091 """The sign of the numeral.
10092
10093 >>> x = FPVal(+1.0, FPSort(8, 24))
10094 >>> x.sign()
10095 False
10096 >>> x = FPVal(-1.0, FPSort(8, 24))
10097 >>> x.sign()
10098 True
10099 """
10100
10101 def sign(self):
10102 num = ctypes.c_bool()
10103 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
10104 if nsign is False:
10105 raise Z3Exception("error retrieving the sign of a numeral.")
10106 return num.value != 0
10107
10108 """The sign of a floating-point numeral as a bit-vector expression.
10109
10110 Remark: NaN's are invalid arguments.
10111 """
10112
10113 def sign_as_bv(self):
10114 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10115
10116 """The significand of the numeral.
10117
10118 >>> x = FPVal(2.5, FPSort(8, 24))
10119 >>> x.significand()
10120 1.25
10121 """
10122
10123 def significand(self):
10124 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10125
10126 """The significand of the numeral as a long.
10127
10128 >>> x = FPVal(2.5, FPSort(8, 24))
10129 >>> x.significand_as_long()
10130 1.25
10131 """
10132
10133 def significand_as_long(self):
10134 ptr = (ctypes.c_ulonglong * 1)()
10135 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10136 raise Z3Exception("error retrieving the significand of a numeral.")
10137 return ptr[0]
10138
10139 """The significand of the numeral as a bit-vector expression.
10140
10141 Remark: NaN are invalid arguments.
10142 """
10143
10144 def significand_as_bv(self):
10145 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10146
10147 """The exponent of the numeral.
10148
10149 >>> x = FPVal(2.5, FPSort(8, 24))
10150 >>> x.exponent()
10151 1
10152 """
10153
10154 def exponent(self, biased=True):
10155 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10156
10157 """The exponent of the numeral as a long.
10158
10159 >>> x = FPVal(2.5, FPSort(8, 24))
10160 >>> x.exponent_as_long()
10161 1
10162 """
10163
10164 def exponent_as_long(self, biased=True):
10165 ptr = (ctypes.c_longlong * 1)()
10166 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10167 raise Z3Exception("error retrieving the exponent of a numeral.")
10168 return ptr[0]
10169
10170 """The exponent of the numeral as a bit-vector expression.
10171
10172 Remark: NaNs are invalid arguments.
10173 """
10174
10175 def exponent_as_bv(self, biased=True):
10176 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10177
10178 """Indicates whether the numeral is a NaN."""
10179
10180 def isNaN(self):
10181 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10182
10183 """Indicates whether the numeral is +oo or -oo."""
10184
10185 def isInf(self):
10186 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10187
10188 """Indicates whether the numeral is +zero or -zero."""
10189
10190 def isZero(self):
10191 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10192
10193 """Indicates whether the numeral is normal."""
10194
10195 def isNormal(self):
10196 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10197
10198 """Indicates whether the numeral is subnormal."""
10199
10200 def isSubnormal(self):
10201 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10202
10203 """Indicates whether the numeral is positive."""
10204
10205 def isPositive(self):
10206 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10207
10208 """Indicates whether the numeral is negative."""
10209
10210 def isNegative(self):
10211 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10212
10213 """
10214 The string representation of the numeral.
10215
10216 >>> x = FPVal(20, FPSort(8, 24))
10217 >>> x.as_string()
10218 1.25*(2**4)
10219 """
10220
10221 def as_string(self):
10222 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10223 return ("FPVal(%s, %s)" % (s, self.sort()))
10224
10225 def py_value(self):
10226 bv = simplify(fpToIEEEBV(self))
10227 binary = bv.py_value()
10228 if not isinstance(binary, int):
10229 return None
10230 # Decode the IEEE 754 binary representation
10231 import struct
10232 bytes_rep = binary.to_bytes(8, byteorder='big')
10233 return struct.unpack('>d', bytes_rep)[0]
10234
10235
10236def is_fp(a):
10237 """Return `True` if `a` is a Z3 floating-point expression.
10238
10239 >>> b = FP('b', FPSort(8, 24))
10240 >>> is_fp(b)
10241 True
10242 >>> is_fp(b + 1.0)
10243 True
10244 >>> is_fp(Int('x'))
10245 False
10246 """
10247 return isinstance(a, FPRef)
10248
10249
10250def is_fp_value(a):
10251 """Return `True` if `a` is a Z3 floating-point numeral value.
10252
10253 >>> b = FP('b', FPSort(8, 24))
10254 >>> is_fp_value(b)
10255 False
10256 >>> b = FPVal(1.0, FPSort(8, 24))
10257 >>> b
10258 1
10259 >>> is_fp_value(b)
10260 True
10261 """
10262 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10263
10264
10265def FPSort(ebits, sbits, ctx=None):
10266 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10267
10268 >>> Single = FPSort(8, 24)
10269 >>> Double = FPSort(11, 53)
10270 >>> Single
10271 FPSort(8, 24)
10272 >>> x = Const('x', Single)
10273 >>> eq(x, FP('x', FPSort(8, 24)))
10274 True
10275 """
10276 ctx = _get_ctx(ctx)
10277 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10278
10279
10280def _to_float_str(val, exp=0):
10281 if isinstance(val, float):
10282 if math.isnan(val):
10283 res = "NaN"
10284 elif val == 0.0:
10285 sone = math.copysign(1.0, val)
10286 if sone < 0.0:
10287 return "-0.0"
10288 else:
10289 return "+0.0"
10290 elif val == float("+inf"):
10291 res = "+oo"
10292 elif val == float("-inf"):
10293 res = "-oo"
10294 else:
10295 v = val.as_integer_ratio()
10296 num = v[0]
10297 den = v[1]
10298 rvs = str(num) + "/" + str(den)
10299 res = rvs + "p" + _to_int_str(exp)
10300 elif isinstance(val, bool):
10301 if val:
10302 res = "1.0"
10303 else:
10304 res = "0.0"
10305 elif _is_int(val):
10306 res = str(val)
10307 elif isinstance(val, str):
10308 inx = val.find("*(2**")
10309 if inx == -1:
10310 res = val
10311 elif val[-1] == ")":
10312 res = val[0:inx]
10313 exp = str(int(val[inx + 5:-1]) + int(exp))
10314 else:
10315 _z3_assert(False, "String does not have floating-point numeral form.")
10316 elif z3_debug():
10317 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10318 if exp == 0:
10319 return res
10320 else:
10321 return res + "p" + exp
10322
10323
10324def fpNaN(s):
10325 """Create a Z3 floating-point NaN term.
10326
10327 >>> s = FPSort(8, 24)
10328 >>> set_fpa_pretty(True)
10329 >>> fpNaN(s)
10330 NaN
10331 >>> pb = get_fpa_pretty()
10332 >>> set_fpa_pretty(False)
10333 >>> fpNaN(s)
10334 fpNaN(FPSort(8, 24))
10335 >>> set_fpa_pretty(pb)
10336 """
10337 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10338 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10339
10340
10341def fpPlusInfinity(s):
10342 """Create a Z3 floating-point +oo term.
10343
10344 >>> s = FPSort(8, 24)
10345 >>> pb = get_fpa_pretty()
10346 >>> set_fpa_pretty(True)
10347 >>> fpPlusInfinity(s)
10348 +oo
10349 >>> set_fpa_pretty(False)
10350 >>> fpPlusInfinity(s)
10351 fpPlusInfinity(FPSort(8, 24))
10352 >>> set_fpa_pretty(pb)
10353 """
10354 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10355 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10356
10357
10358def fpMinusInfinity(s):
10359 """Create a Z3 floating-point -oo term."""
10360 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10361 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10362
10363
10364def fpInfinity(s, negative):
10365 """Create a Z3 floating-point +oo or -oo term."""
10366 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10367 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10368 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10369
10370
10371def fpPlusZero(s):
10372 """Create a Z3 floating-point +0.0 term."""
10373 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10374 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10375
10376
10377def fpMinusZero(s):
10378 """Create a Z3 floating-point -0.0 term."""
10379 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10380 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10381
10382
10383def fpZero(s, negative):
10384 """Create a Z3 floating-point +0.0 or -0.0 term."""
10385 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10386 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10387 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10388
10389
10390def FPVal(sig, exp=None, fps=None, ctx=None):
10391 """Return a floating-point value of value `val` and sort `fps`.
10392 If `ctx=None`, then the global context is used.
10393
10394 >>> v = FPVal(20.0, FPSort(8, 24))
10395 >>> v
10396 1.25*(2**4)
10397 >>> print("0x%.8x" % v.exponent_as_long(False))
10398 0x00000004
10399 >>> v = FPVal(2.25, FPSort(8, 24))
10400 >>> v
10401 1.125*(2**1)
10402 >>> v = FPVal(-2.25, FPSort(8, 24))
10403 >>> v
10404 -1.125*(2**1)
10405 >>> FPVal(-0.0, FPSort(8, 24))
10406 -0.0
10407 >>> FPVal(0.0, FPSort(8, 24))
10408 +0.0
10409 >>> FPVal(+0.0, FPSort(8, 24))
10410 +0.0
10411 """
10412 ctx = _get_ctx(ctx)
10413 if is_fp_sort(exp):
10414 fps = exp
10415 exp = None
10416 elif fps is None:
10417 fps = _dflt_fps(ctx)
10418 _z3_assert(is_fp_sort(fps), "sort mismatch")
10419 if exp is None:
10420 exp = 0
10421 val = _to_float_str(sig)
10422 if val == "NaN" or val == "nan":
10423 return fpNaN(fps)
10424 elif val == "-0.0":
10425 return fpMinusZero(fps)
10426 elif val == "0.0" or val == "+0.0":
10427 return fpPlusZero(fps)
10428 elif val == "+oo" or val == "+inf" or val == "+Inf":
10429 return fpPlusInfinity(fps)
10430 elif val == "-oo" or val == "-inf" or val == "-Inf":
10431 return fpMinusInfinity(fps)
10432 else:
10433 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10434
10435
10436def FP(name, fpsort, ctx=None):
10437 """Return a floating-point constant named `name`.
10438 `fpsort` is the floating-point sort.
10439 If `ctx=None`, then the global context is used.
10440
10441 >>> x = FP('x', FPSort(8, 24))
10442 >>> is_fp(x)
10443 True
10444 >>> x.ebits()
10445 8
10446 >>> x.sort()
10447 FPSort(8, 24)
10448 >>> word = FPSort(8, 24)
10449 >>> x2 = FP('x', word)
10450 >>> eq(x, x2)
10451 True
10452 """
10453 if isinstance(fpsort, FPSortRef) and ctx is None:
10454 ctx = fpsort.ctx
10455 else:
10456 ctx = _get_ctx(ctx)
10457 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10458
10459
10460def FPs(names, fpsort, ctx=None):
10461 """Return an array of floating-point constants.
10462
10463 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10464 >>> x.sort()
10465 FPSort(8, 24)
10466 >>> x.sbits()
10467 24
10468 >>> x.ebits()
10469 8
10470 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10471 (x + y) * z
10472 """
10473 ctx = _get_ctx(ctx)
10474 if isinstance(names, str):
10475 names = names.split(" ")
10476 return [FP(name, fpsort, ctx) for name in names]
10477
10478
10479def fpAbs(a, ctx=None):
10480 """Create a Z3 floating-point absolute value expression.
10481
10482 >>> s = FPSort(8, 24)
10483 >>> rm = RNE()
10484 >>> x = FPVal(1.0, s)
10485 >>> fpAbs(x)
10486 fpAbs(1)
10487 >>> y = FPVal(-20.0, s)
10488 >>> y
10489 -1.25*(2**4)
10490 >>> fpAbs(y)
10491 fpAbs(-1.25*(2**4))
10492 >>> fpAbs(-1.25*(2**4))
10493 fpAbs(-1.25*(2**4))
10494 >>> fpAbs(x).sort()
10495 FPSort(8, 24)
10496 """
10497 ctx = _get_ctx(ctx)
10498 [a] = _coerce_fp_expr_list([a], ctx)
10499 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10500
10501
10502def fpNeg(a, ctx=None):
10503 """Create a Z3 floating-point addition expression.
10504
10505 >>> s = FPSort(8, 24)
10506 >>> rm = RNE()
10507 >>> x = FP('x', s)
10508 >>> fpNeg(x)
10509 -x
10510 >>> fpNeg(x).sort()
10511 FPSort(8, 24)
10512 """
10513 ctx = _get_ctx(ctx)
10514 [a] = _coerce_fp_expr_list([a], ctx)
10515 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10516
10517
10518def _mk_fp_unary(f, rm, a, ctx):
10519 ctx = _get_ctx(ctx)
10520 [a] = _coerce_fp_expr_list([a], ctx)
10521 if z3_debug():
10522 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10523 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10524 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10525
10526
10527def _mk_fp_unary_pred(f, a, ctx):
10528 ctx = _get_ctx(ctx)
10529 [a] = _coerce_fp_expr_list([a], ctx)
10530 if z3_debug():
10531 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10532 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10533
10534
10535def _mk_fp_bin(f, rm, a, b, ctx):
10536 ctx = _get_ctx(ctx)
10537 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10538 if z3_debug():
10539 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10540 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10541 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10542
10543
10544def _mk_fp_bin_norm(f, a, b, ctx):
10545 ctx = _get_ctx(ctx)
10546 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10547 if z3_debug():
10548 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10549 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10550
10551
10552def _mk_fp_bin_pred(f, a, b, ctx):
10553 ctx = _get_ctx(ctx)
10554 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10555 if z3_debug():
10556 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10557 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10558
10559
10560def _mk_fp_tern(f, rm, a, b, c, ctx):
10561 ctx = _get_ctx(ctx)
10562 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10563 if z3_debug():
10564 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10565 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10566 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10567 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10568
10569
10570def fpAdd(rm, a, b, ctx=None):
10571 """Create a Z3 floating-point addition expression.
10572
10573 >>> s = FPSort(8, 24)
10574 >>> rm = RNE()
10575 >>> x = FP('x', s)
10576 >>> y = FP('y', s)
10577 >>> fpAdd(rm, x, y)
10578 x + y
10579 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10580 fpAdd(RTZ(), x, y)
10581 >>> fpAdd(rm, x, y).sort()
10582 FPSort(8, 24)
10583 """
10584 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10585
10586
10587def fpSub(rm, a, b, ctx=None):
10588 """Create a Z3 floating-point subtraction expression.
10589
10590 >>> s = FPSort(8, 24)
10591 >>> rm = RNE()
10592 >>> x = FP('x', s)
10593 >>> y = FP('y', s)
10594 >>> fpSub(rm, x, y)
10595 x - y
10596 >>> fpSub(rm, x, y).sort()
10597 FPSort(8, 24)
10598 """
10599 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10600
10601
10602def fpMul(rm, a, b, ctx=None):
10603 """Create a Z3 floating-point multiplication expression.
10604
10605 >>> s = FPSort(8, 24)
10606 >>> rm = RNE()
10607 >>> x = FP('x', s)
10608 >>> y = FP('y', s)
10609 >>> fpMul(rm, x, y)
10610 x * y
10611 >>> fpMul(rm, x, y).sort()
10612 FPSort(8, 24)
10613 """
10614 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10615
10616
10617def fpDiv(rm, a, b, ctx=None):
10618 """Create a Z3 floating-point division expression.
10619
10620 >>> s = FPSort(8, 24)
10621 >>> rm = RNE()
10622 >>> x = FP('x', s)
10623 >>> y = FP('y', s)
10624 >>> fpDiv(rm, x, y)
10625 x / y
10626 >>> fpDiv(rm, x, y).sort()
10627 FPSort(8, 24)
10628 """
10629 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10630
10631
10632def fpRem(a, b, ctx=None):
10633 """Create a Z3 floating-point remainder expression.
10634
10635 >>> s = FPSort(8, 24)
10636 >>> x = FP('x', s)
10637 >>> y = FP('y', s)
10638 >>> fpRem(x, y)
10639 fpRem(x, y)
10640 >>> fpRem(x, y).sort()
10641 FPSort(8, 24)
10642 """
10643 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10644
10645
10646def fpMin(a, b, ctx=None):
10647 """Create a Z3 floating-point minimum expression.
10648
10649 >>> s = FPSort(8, 24)
10650 >>> rm = RNE()
10651 >>> x = FP('x', s)
10652 >>> y = FP('y', s)
10653 >>> fpMin(x, y)
10654 fpMin(x, y)
10655 >>> fpMin(x, y).sort()
10656 FPSort(8, 24)
10657 """
10658 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10659
10660
10661def fpMax(a, b, ctx=None):
10662 """Create a Z3 floating-point maximum expression.
10663
10664 >>> s = FPSort(8, 24)
10665 >>> rm = RNE()
10666 >>> x = FP('x', s)
10667 >>> y = FP('y', s)
10668 >>> fpMax(x, y)
10669 fpMax(x, y)
10670 >>> fpMax(x, y).sort()
10671 FPSort(8, 24)
10672 """
10673 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10674
10675
10676def fpFMA(rm, a, b, c, ctx=None):
10677 """Create a Z3 floating-point fused multiply-add expression.
10678 """
10679 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10680
10681
10682def fpSqrt(rm, a, ctx=None):
10683 """Create a Z3 floating-point square root expression.
10684 """
10685 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10686
10687
10688def fpRoundToIntegral(rm, a, ctx=None):
10689 """Create a Z3 floating-point roundToIntegral expression.
10690 """
10691 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10692
10693
10694def fpIsNaN(a, ctx=None):
10695 """Create a Z3 floating-point isNaN expression.
10696
10697 >>> s = FPSort(8, 24)
10698 >>> x = FP('x', s)
10699 >>> y = FP('y', s)
10700 >>> fpIsNaN(x)
10701 fpIsNaN(x)
10702 """
10703 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10704
10705
10706def fpIsInf(a, ctx=None):
10707 """Create a Z3 floating-point isInfinite expression.
10708
10709 >>> s = FPSort(8, 24)
10710 >>> x = FP('x', s)
10711 >>> fpIsInf(x)
10712 fpIsInf(x)
10713 """
10714 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10715
10716
10717def fpIsZero(a, ctx=None):
10718 """Create a Z3 floating-point isZero expression.
10719 """
10720 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10721
10722
10723def fpIsNormal(a, ctx=None):
10724 """Create a Z3 floating-point isNormal expression.
10725 """
10726 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10727
10728
10729def fpIsSubnormal(a, ctx=None):
10730 """Create a Z3 floating-point isSubnormal expression.
10731 """
10732 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10733
10734
10735def fpIsNegative(a, ctx=None):
10736 """Create a Z3 floating-point isNegative expression.
10737 """
10738 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10739
10740
10741def fpIsPositive(a, ctx=None):
10742 """Create a Z3 floating-point isPositive expression.
10743 """
10744 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10745
10746
10747def _check_fp_args(a, b):
10748 if z3_debug():
10749 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10750
10751
10752def fpLT(a, b, ctx=None):
10753 """Create the Z3 floating-point expression `other < self`.
10754
10755 >>> x, y = FPs('x y', FPSort(8, 24))
10756 >>> fpLT(x, y)
10757 x < y
10758 >>> (x < y).sexpr()
10759 '(fp.lt x y)'
10760 """
10761 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10762
10763
10764def fpLEQ(a, b, ctx=None):
10765 """Create the Z3 floating-point expression `other <= self`.
10766
10767 >>> x, y = FPs('x y', FPSort(8, 24))
10768 >>> fpLEQ(x, y)
10769 x <= y
10770 >>> (x <= y).sexpr()
10771 '(fp.leq x y)'
10772 """
10773 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10774
10775
10776def fpGT(a, b, ctx=None):
10777 """Create the Z3 floating-point expression `other > self`.
10778
10779 >>> x, y = FPs('x y', FPSort(8, 24))
10780 >>> fpGT(x, y)
10781 x > y
10782 >>> (x > y).sexpr()
10783 '(fp.gt x y)'
10784 """
10785 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10786
10787
10788def fpGEQ(a, b, ctx=None):
10789 """Create the Z3 floating-point expression `other >= self`.
10790
10791 >>> x, y = FPs('x y', FPSort(8, 24))
10792 >>> fpGEQ(x, y)
10793 x >= y
10794 >>> (x >= y).sexpr()
10795 '(fp.geq x y)'
10796 """
10797 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10798
10799
10800def fpEQ(a, b, ctx=None):
10801 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10802
10803 >>> x, y = FPs('x y', FPSort(8, 24))
10804 >>> fpEQ(x, y)
10805 fpEQ(x, y)
10806 >>> fpEQ(x, y).sexpr()
10807 '(fp.eq x y)'
10808 """
10809 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10810
10811
10812def fpNEQ(a, b, ctx=None):
10813 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10814
10815 >>> x, y = FPs('x y', FPSort(8, 24))
10816 >>> fpNEQ(x, y)
10817 Not(fpEQ(x, y))
10818 >>> (x != y).sexpr()
10819 '(distinct x y)'
10820 """
10821 return Not(fpEQ(a, b, ctx))
10822
10823
10824def fpFP(sgn, exp, sig, ctx=None):
10825 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10826
10827 >>> s = FPSort(8, 24)
10828 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10829 >>> print(x)
10830 fpFP(1, 127, 4194304)
10831 >>> xv = FPVal(-1.5, s)
10832 >>> print(xv)
10833 -1.5
10834 >>> slvr = Solver()
10835 >>> slvr.add(fpEQ(x, xv))
10836 >>> slvr.check()
10837 sat
10838 >>> xv = FPVal(+1.5, s)
10839 >>> print(xv)
10840 1.5
10841 >>> slvr = Solver()
10842 >>> slvr.add(fpEQ(x, xv))
10843 >>> slvr.check()
10844 unsat
10845 """
10846 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10847 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10848 ctx = _get_ctx(ctx)
10849 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10850 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10851
10852
10853def fpToFP(a1, a2=None, a3=None, ctx=None):
10854 """Create a Z3 floating-point conversion expression from other term sorts
10855 to floating-point.
10856
10857 From a bit-vector term in IEEE 754-2008 format:
10858 >>> x = FPVal(1.0, Float32())
10859 >>> x_bv = fpToIEEEBV(x)
10860 >>> simplify(fpToFP(x_bv, Float32()))
10861 1
10862
10863 From a floating-point term with different precision:
10864 >>> x = FPVal(1.0, Float32())
10865 >>> x_db = fpToFP(RNE(), x, Float64())
10866 >>> x_db.sort()
10867 FPSort(11, 53)
10868
10869 From a real term:
10870 >>> x_r = RealVal(1.5)
10871 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10872 1.5
10873
10874 From a signed bit-vector term:
10875 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10876 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10877 -1.25*(2**2)
10878 """
10879 ctx = _get_ctx(ctx)
10880 if is_bv(a1) and is_fp_sort(a2):
10881 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10882 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10883 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10884 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10885 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10886 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10887 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10888 else:
10889 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10890
10891
10892def fpBVToFP(v, sort, ctx=None):
10893 """Create a Z3 floating-point conversion expression that represents the
10894 conversion from a bit-vector term to a floating-point term.
10895
10896 >>> x_bv = BitVecVal(0x3F800000, 32)
10897 >>> x_fp = fpBVToFP(x_bv, Float32())
10898 >>> x_fp
10899 fpToFP(1065353216)
10900 >>> simplify(x_fp)
10901 1
10902 """
10903 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10904 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10905 ctx = _get_ctx(ctx)
10906 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10907
10908
10909def fpFPToFP(rm, v, sort, ctx=None):
10910 """Create a Z3 floating-point conversion expression that represents the
10911 conversion from a floating-point term to a floating-point term of different precision.
10912
10913 >>> x_sgl = FPVal(1.0, Float32())
10914 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10915 >>> x_dbl
10916 fpToFP(RNE(), 1)
10917 >>> simplify(x_dbl)
10918 1
10919 >>> x_dbl.sort()
10920 FPSort(11, 53)
10921 """
10922 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10923 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10924 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10925 ctx = _get_ctx(ctx)
10926 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10927
10928
10929def fpRealToFP(rm, v, sort, ctx=None):
10930 """Create a Z3 floating-point conversion expression that represents the
10931 conversion from a real term to a floating-point term.
10932
10933 >>> x_r = RealVal(1.5)
10934 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10935 >>> x_fp
10936 fpToFP(RNE(), 3/2)
10937 >>> simplify(x_fp)
10938 1.5
10939 """
10940 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10941 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10942 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10943 ctx = _get_ctx(ctx)
10944 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10945
10946
10947def fpSignedToFP(rm, v, sort, ctx=None):
10948 """Create a Z3 floating-point conversion expression that represents the
10949 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10950
10951 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10952 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10953 >>> x_fp
10954 fpToFP(RNE(), 4294967291)
10955 >>> simplify(x_fp)
10956 -1.25*(2**2)
10957 """
10958 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10959 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10960 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10961 ctx = _get_ctx(ctx)
10962 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10963
10964
10965def fpUnsignedToFP(rm, v, sort, ctx=None):
10966 """Create a Z3 floating-point conversion expression that represents the
10967 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10968
10969 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10970 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10971 >>> x_fp
10972 fpToFPUnsigned(RNE(), 4294967291)
10973 >>> simplify(x_fp)
10974 1*(2**32)
10975 """
10976 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10977 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10978 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10979 ctx = _get_ctx(ctx)
10980 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10981
10982
10983def fpToFPUnsigned(rm, x, s, ctx=None):
10984 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10985 if z3_debug():
10986 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10987 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10988 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10989 ctx = _get_ctx(ctx)
10990 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10991
10992
10993def fpToSBV(rm, x, s, ctx=None):
10994 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10995
10996 >>> x = FP('x', FPSort(8, 24))
10997 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10998 >>> print(is_fp(x))
10999 True
11000 >>> print(is_bv(y))
11001 True
11002 >>> print(is_fp(y))
11003 False
11004 >>> print(is_bv(x))
11005 False
11006 """
11007 if z3_debug():
11008 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11009 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11010 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11011 ctx = _get_ctx(ctx)
11012 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11013
11014
11015def fpToUBV(rm, x, s, ctx=None):
11016 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
11017
11018 >>> x = FP('x', FPSort(8, 24))
11019 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
11020 >>> print(is_fp(x))
11021 True
11022 >>> print(is_bv(y))
11023 True
11024 >>> print(is_fp(y))
11025 False
11026 >>> print(is_bv(x))
11027 False
11028 """
11029 if z3_debug():
11030 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11031 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11032 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11033 ctx = _get_ctx(ctx)
11034 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11035
11036
11037def fpToReal(x, ctx=None):
11038 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
11039
11040 >>> x = FP('x', FPSort(8, 24))
11041 >>> y = fpToReal(x)
11042 >>> print(is_fp(x))
11043 True
11044 >>> print(is_real(y))
11045 True
11046 >>> print(is_fp(y))
11047 False
11048 >>> print(is_real(x))
11049 False
11050 """
11051 if z3_debug():
11052 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11053 ctx = _get_ctx(ctx)
11054 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
11055
11056
11057def fpToIEEEBV(x, ctx=None):
11058 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
11059
11060 The size of the resulting bit-vector is automatically determined.
11061
11062 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
11063 knows only one NaN and it will always produce the same bit-vector representation of
11064 that NaN.
11065
11066 >>> x = FP('x', FPSort(8, 24))
11067 >>> y = fpToIEEEBV(x)
11068 >>> print(is_fp(x))
11069 True
11070 >>> print(is_bv(y))
11071 True
11072 >>> print(is_fp(y))
11073 False
11074 >>> print(is_bv(x))
11075 False
11076 """
11077 if z3_debug():
11078 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11079 ctx = _get_ctx(ctx)
11080 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
11081
11082
11083#########################################
11084#
11085# Strings, Sequences and Regular expressions
11086#
11087#########################################
11088
11089class SeqSortRef(SortRef):
11090 """Sequence sort."""
11091
11092 def is_string(self):
11093 """Determine if sort is a string
11094 >>> s = StringSort()
11095 >>> s.is_string()
11096 True
11097 >>> s = SeqSort(IntSort())
11098 >>> s.is_string()
11099 False
11100 """
11101 return Z3_is_string_sort(self.ctx_ref(), self.ast)
11102
11103 def basis(self):
11104 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11105
11106class CharSortRef(SortRef):
11107 """Character sort."""
11108
11109
11110def StringSort(ctx=None):
11111 """Create a string sort
11112 >>> s = StringSort()
11113 >>> print(s)
11114 String
11115 """
11116 ctx = _get_ctx(ctx)
11117 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
11118
11119def CharSort(ctx=None):
11120 """Create a character sort
11121 >>> ch = CharSort()
11122 >>> print(ch)
11123 Char
11124 """
11125 ctx = _get_ctx(ctx)
11126 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11127
11128
11129def SeqSort(s):
11130 """Create a sequence sort over elements provided in the argument
11131 >>> s = SeqSort(IntSort())
11132 >>> s == Unit(IntVal(1)).sort()
11133 True
11134 """
11135 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11136
11137
11138class SeqRef(ExprRef):
11139 """Sequence expression."""
11140
11141 def sort(self):
11142 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11143
11144 def __add__(self, other):
11145 return Concat(self, other)
11146
11147 def __radd__(self, other):
11148 return Concat(other, self)
11149
11150 def __getitem__(self, i):
11151 if _is_int(i):
11152 i = IntVal(i, self.ctx)
11153 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11154
11155 def at(self, i):
11156 if _is_int(i):
11157 i = IntVal(i, self.ctx)
11158 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11159
11160 def is_string(self):
11161 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11162
11163 def is_string_value(self):
11164 return Z3_is_string(self.ctx_ref(), self.as_ast())
11165
11166 def as_string(self):
11167 """Return a string representation of sequence expression."""
11168 if self.is_string_value():
11169 string_length = ctypes.c_uint()
11170 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11171 return string_at(chars, size=string_length.value).decode("latin-1")
11172 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11173
11174 def py_value(self):
11175 return self.as_string()
11176
11177 def __le__(self, other):
11178 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11179
11180 def __lt__(self, other):
11181 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11182
11183 def __ge__(self, other):
11184 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11185
11186 def __gt__(self, other):
11187 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11188
11189
11190def _coerce_char(ch, ctx=None):
11191 if isinstance(ch, str):
11192 ctx = _get_ctx(ctx)
11193 ch = CharVal(ch, ctx)
11194 if not is_expr(ch):
11195 raise Z3Exception("Character expression expected")
11196 return ch
11197
11198class CharRef(ExprRef):
11199 """Character expression."""
11200
11201 def __le__(self, other):
11202 other = _coerce_char(other, self.ctx)
11203 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11204
11205 def to_int(self):
11206 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11207
11208 def to_bv(self):
11209 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11210
11211 def is_digit(self):
11212 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11213
11214
11215def CharVal(ch, ctx=None):
11216 ctx = _get_ctx(ctx)
11217 if isinstance(ch, str):
11218 ch = ord(ch)
11219 if not isinstance(ch, int):
11220 raise Z3Exception("character value should be an ordinal")
11221 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11222
11223def CharFromBv(bv):
11224 if not is_expr(bv):
11225 raise Z3Exception("Bit-vector expression needed")
11226 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11227
11228def CharToBv(ch, ctx=None):
11229 ch = _coerce_char(ch, ctx)
11230 return ch.to_bv()
11231
11232def CharToInt(ch, ctx=None):
11233 ch = _coerce_char(ch, ctx)
11234 return ch.to_int()
11235
11236def CharIsDigit(ch, ctx=None):
11237 ch = _coerce_char(ch, ctx)
11238 return ch.is_digit()
11239
11240def _coerce_seq(s, ctx=None):
11241 if isinstance(s, str):
11242 ctx = _get_ctx(ctx)
11243 s = StringVal(s, ctx)
11244 if not is_expr(s):
11245 raise Z3Exception("Non-expression passed as a sequence")
11246 if not is_seq(s):
11247 raise Z3Exception("Non-sequence passed as a sequence")
11248 return s
11249
11250
11251def _get_ctx2(a, b, ctx=None):
11252 if is_expr(a):
11253 return a.ctx
11254 if is_expr(b):
11255 return b.ctx
11256 if ctx is None:
11257 ctx = main_ctx()
11258 return ctx
11259
11260
11261def is_seq(a):
11262 """Return `True` if `a` is a Z3 sequence expression.
11263 >>> print (is_seq(Unit(IntVal(0))))
11264 True
11265 >>> print (is_seq(StringVal("abc")))
11266 True
11267 """
11268 return isinstance(a, SeqRef)
11269
11270
11271def is_string(a: Any) -> bool:
11272 """Return `True` if `a` is a Z3 string expression.
11273 >>> print (is_string(StringVal("ab")))
11274 True
11275 """
11276 return isinstance(a, SeqRef) and a.is_string()
11277
11278
11279def is_string_value(a: Any) -> bool:
11280 """return 'True' if 'a' is a Z3 string constant expression.
11281 >>> print (is_string_value(StringVal("a")))
11282 True
11283 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11284 False
11285 """
11286 return isinstance(a, SeqRef) and a.is_string_value()
11287
11288def StringVal(s, ctx=None):
11289 """create a string expression"""
11290 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11291 ctx = _get_ctx(ctx)
11292 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11293
11294
11295def String(name, ctx=None):
11296 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11297
11298 >>> x = String('x')
11299 """
11300 ctx = _get_ctx(ctx)
11301 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11302
11303
11304def Strings(names, ctx=None):
11305 """Return a tuple of String constants. """
11306 ctx = _get_ctx(ctx)
11307 if isinstance(names, str):
11308 names = names.split(" ")
11309 return [String(name, ctx) for name in names]
11310
11311
11312def SubString(s, offset, length):
11313 """Extract substring or subsequence starting at offset.
11314
11315 This is a convenience function that redirects to Extract(s, offset, length).
11316
11317 >>> s = StringVal("hello world")
11318 >>> SubString(s, 6, 5) # Extract "world"
11319 str.substr("hello world", 6, 5)
11320 >>> simplify(SubString(StringVal("hello"), 1, 3))
11321 "ell"
11322 """
11323 return Extract(s, offset, length)
11324
11325
11326def SubSeq(s, offset, length):
11327 """Extract substring or subsequence starting at offset.
11328
11329 This is a convenience function that redirects to Extract(s, offset, length).
11330
11331 >>> s = StringVal("hello world")
11332 >>> SubSeq(s, 0, 5) # Extract "hello"
11333 str.substr("hello world", 0, 5)
11334 >>> simplify(SubSeq(StringVal("testing"), 2, 4))
11335 "stin"
11336 """
11337 return Extract(s, offset, length)
11338
11339
11340def Empty(s):
11341 """Create the empty sequence of the given sort
11342 >>> e = Empty(StringSort())
11343 >>> e2 = StringVal("")
11344 >>> print(e.eq(e2))
11345 True
11346 >>> e3 = Empty(SeqSort(IntSort()))
11347 >>> print(e3)
11348 Empty(Seq(Int))
11349 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11350 >>> print(e4)
11351 Empty(ReSort(Seq(Int)))
11352 """
11353 if isinstance(s, SeqSortRef):
11354 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11355 if isinstance(s, ReSortRef):
11356 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11357 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11358
11359
11360def Full(s):
11361 """Create the regular expression that accepts the universal language
11362 >>> e = Full(ReSort(SeqSort(IntSort())))
11363 >>> print(e)
11364 Full(ReSort(Seq(Int)))
11365 >>> e1 = Full(ReSort(StringSort()))
11366 >>> print(e1)
11367 Full(ReSort(String))
11368 """
11369 if isinstance(s, ReSortRef):
11370 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11371 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11372
11373
11374
11375def Unit(a):
11376 """Create a singleton sequence"""
11377 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11378
11379
11380def PrefixOf(a, b):
11381 """Check if 'a' is a prefix of 'b'
11382 >>> s1 = PrefixOf("ab", "abc")
11383 >>> simplify(s1)
11384 True
11385 >>> s2 = PrefixOf("bc", "abc")
11386 >>> simplify(s2)
11387 False
11388 """
11389 ctx = _get_ctx2(a, b)
11390 a = _coerce_seq(a, ctx)
11391 b = _coerce_seq(b, ctx)
11392 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11393
11394
11395def SuffixOf(a, b):
11396 """Check if 'a' is a suffix of 'b'
11397 >>> s1 = SuffixOf("ab", "abc")
11398 >>> simplify(s1)
11399 False
11400 >>> s2 = SuffixOf("bc", "abc")
11401 >>> simplify(s2)
11402 True
11403 """
11404 ctx = _get_ctx2(a, b)
11405 a = _coerce_seq(a, ctx)
11406 b = _coerce_seq(b, ctx)
11407 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11408
11409
11410def Contains(a, b):
11411 """Check if 'a' contains 'b'
11412 >>> s1 = Contains("abc", "ab")
11413 >>> simplify(s1)
11414 True
11415 >>> s2 = Contains("abc", "bc")
11416 >>> simplify(s2)
11417 True
11418 >>> x, y, z = Strings('x y z')
11419 >>> s3 = Contains(Concat(x,y,z), y)
11420 >>> simplify(s3)
11421 True
11422 """
11423 ctx = _get_ctx2(a, b)
11424 a = _coerce_seq(a, ctx)
11425 b = _coerce_seq(b, ctx)
11426 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11427
11428
11429def Replace(s, src, dst):
11430 """Replace the first occurrence of 'src' by 'dst' in 's'
11431 >>> r = Replace("aaa", "a", "b")
11432 >>> simplify(r)
11433 "baa"
11434 """
11435 ctx = _get_ctx2(dst, s)
11436 if ctx is None and is_expr(src):
11437 ctx = src.ctx
11438 src = _coerce_seq(src, ctx)
11439 dst = _coerce_seq(dst, ctx)
11440 s = _coerce_seq(s, ctx)
11441 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11442
11443
11444def IndexOf(s, substr, offset=None):
11445 """Retrieve the index of substring within a string starting at a specified offset.
11446 >>> simplify(IndexOf("abcabc", "bc", 0))
11447 1
11448 >>> simplify(IndexOf("abcabc", "bc", 2))
11449 4
11450 """
11451 if offset is None:
11452 offset = IntVal(0)
11453 ctx = None
11454 if is_expr(offset):
11455 ctx = offset.ctx
11456 ctx = _get_ctx2(s, substr, ctx)
11457 s = _coerce_seq(s, ctx)
11458 substr = _coerce_seq(substr, ctx)
11459 if _is_int(offset):
11460 offset = IntVal(offset, ctx)
11461 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11462
11463
11464def LastIndexOf(s, substr):
11465 """Retrieve the last index of substring within a string"""
11466 ctx = None
11467 ctx = _get_ctx2(s, substr, ctx)
11468 s = _coerce_seq(s, ctx)
11469 substr = _coerce_seq(substr, ctx)
11470 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11471
11472
11473def Length(s):
11474 """Obtain the length of a sequence 's'
11475 >>> l = Length(StringVal("abc"))
11476 >>> simplify(l)
11477 3
11478 """
11479 s = _coerce_seq(s)
11480 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11481
11482def SeqMap(f, s):
11483 """Map function 'f' over sequence 's'"""
11484 ctx = _get_ctx2(f, s)
11485 s = _coerce_seq(s, ctx)
11486 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11487
11488def SeqMapI(f, i, s):
11489 """Map function 'f' over sequence 's' at index 'i'"""
11490 ctx = _get_ctx2(f, s)
11491 s = _coerce_seq(s, ctx)
11492 if not is_expr(i):
11493 i = _py2expr(i)
11494 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11495
11496def SeqFoldLeft(f, a, s):
11497 ctx = _get_ctx2(f, s)
11498 s = _coerce_seq(s, ctx)
11499 a = _py2expr(a)
11500 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11501
11502def SeqFoldLeftI(f, i, a, s):
11503 ctx = _get_ctx2(f, s)
11504 s = _coerce_seq(s, ctx)
11505 a = _py2expr(a)
11506 i = _py2expr(i)
11507 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11508
11509def StrToInt(s):
11510 """Convert string expression to integer
11511 >>> a = StrToInt("1")
11512 >>> simplify(1 == a)
11513 True
11514 >>> b = StrToInt("2")
11515 >>> simplify(1 == b)
11516 False
11517 >>> c = StrToInt(IntToStr(2))
11518 >>> simplify(1 == c)
11519 False
11520 """
11521 s = _coerce_seq(s)
11522 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11523
11524
11525def IntToStr(s):
11526 """Convert integer expression to string"""
11527 if not is_expr(s):
11528 s = _py2expr(s)
11529 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11530
11531
11532def StrToCode(s):
11533 """Convert a unit length string to integer code"""
11534 if not is_expr(s):
11535 s = _py2expr(s)
11536 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11537
11538def StrFromCode(c):
11539 """Convert code to a string"""
11540 if not is_expr(c):
11541 c = _py2expr(c)
11542 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11543
11544def Re(s, ctx=None):
11545 """The regular expression that accepts sequence 's'
11546 >>> s1 = Re("ab")
11547 >>> s2 = Re(StringVal("ab"))
11548 >>> s3 = Re(Unit(BoolVal(True)))
11549 """
11550 s = _coerce_seq(s, ctx)
11551 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11552
11553
11554# Regular expressions
11555
11556class ReSortRef(SortRef):
11557 """Regular expression sort."""
11558
11559 def basis(self):
11560 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11561
11562
11563def ReSort(s):
11564 if is_ast(s):
11565 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11566 if s is None or isinstance(s, Context):
11567 ctx = _get_ctx(s)
11568 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11569 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11570
11571
11572class ReRef(ExprRef):
11573 """Regular expressions."""
11574
11575 def __add__(self, other):
11576 return Union(self, other)
11577
11578
11579def is_re(s):
11580 return isinstance(s, ReRef)
11581
11582
11583def InRe(s, re):
11584 """Create regular expression membership test
11585 >>> re = Union(Re("a"),Re("b"))
11586 >>> print (simplify(InRe("a", re)))
11587 True
11588 >>> print (simplify(InRe("b", re)))
11589 True
11590 >>> print (simplify(InRe("c", re)))
11591 False
11592 """
11593 s = _coerce_seq(s, re.ctx)
11594 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11595
11596
11597def Union(*args):
11598 """Create union of regular expressions.
11599 >>> re = Union(Re("a"), Re("b"), Re("c"))
11600 >>> print (simplify(InRe("d", re)))
11601 False
11602 """
11603 args = _get_args(args)
11604 sz = len(args)
11605 if z3_debug():
11606 _z3_assert(sz > 0, "At least one argument expected.")
11607 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11608 if sz == 1:
11609 return args[0]
11610 ctx = args[0].ctx
11611 v = (Ast * sz)()
11612 for i in range(sz):
11613 v[i] = args[i].as_ast()
11614 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11615
11616
11617def Intersect(*args):
11618 """Create intersection of regular expressions.
11619 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11620 """
11621 args = _get_args(args)
11622 sz = len(args)
11623 if z3_debug():
11624 _z3_assert(sz > 0, "At least one argument expected.")
11625 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11626 if sz == 1:
11627 return args[0]
11628 ctx = args[0].ctx
11629 v = (Ast * sz)()
11630 for i in range(sz):
11631 v[i] = args[i].as_ast()
11632 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11633
11634
11635def Plus(re):
11636 """Create the regular expression accepting one or more repetitions of argument.
11637 >>> re = Plus(Re("a"))
11638 >>> print(simplify(InRe("aa", re)))
11639 True
11640 >>> print(simplify(InRe("ab", re)))
11641 False
11642 >>> print(simplify(InRe("", re)))
11643 False
11644 """
11645 if z3_debug():
11646 _z3_assert(is_expr(re), "expression expected")
11647 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11648
11649
11650def Option(re):
11651 """Create the regular expression that optionally accepts the argument.
11652 >>> re = Option(Re("a"))
11653 >>> print(simplify(InRe("a", re)))
11654 True
11655 >>> print(simplify(InRe("", re)))
11656 True
11657 >>> print(simplify(InRe("aa", re)))
11658 False
11659 """
11660 if z3_debug():
11661 _z3_assert(is_expr(re), "expression expected")
11662 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11663
11664
11665def Complement(re):
11666 """Create the complement regular expression."""
11667 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11668
11669
11670def Star(re):
11671 """Create the regular expression accepting zero or more repetitions of argument.
11672 >>> re = Star(Re("a"))
11673 >>> print(simplify(InRe("aa", re)))
11674 True
11675 >>> print(simplify(InRe("ab", re)))
11676 False
11677 >>> print(simplify(InRe("", re)))
11678 True
11679 """
11680 if z3_debug():
11681 _z3_assert(is_expr(re), "expression expected")
11682 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11683
11684
11685def Loop(re, lo, hi=0):
11686 """Create the regular expression accepting between a lower and upper bound repetitions
11687 >>> re = Loop(Re("a"), 1, 3)
11688 >>> print(simplify(InRe("aa", re)))
11689 True
11690 >>> print(simplify(InRe("aaaa", re)))
11691 False
11692 >>> print(simplify(InRe("", re)))
11693 False
11694 """
11695 if z3_debug():
11696 _z3_assert(is_expr(re), "expression expected")
11697 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11698
11699
11700def Range(lo, hi, ctx=None):
11701 """Create the range regular expression over two sequences of length 1
11702 >>> range = Range("a","z")
11703 >>> print(simplify(InRe("b", range)))
11704 True
11705 >>> print(simplify(InRe("bb", range)))
11706 False
11707 """
11708 lo = _coerce_seq(lo, ctx)
11709 hi = _coerce_seq(hi, ctx)
11710 if z3_debug():
11711 _z3_assert(is_expr(lo), "expression expected")
11712 _z3_assert(is_expr(hi), "expression expected")
11713 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11714
11715def Diff(a, b, ctx=None):
11716 """Create the difference regular expression
11717 """
11718 if z3_debug():
11719 _z3_assert(is_expr(a), "expression expected")
11720 _z3_assert(is_expr(b), "expression expected")
11721 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11722
11723def AllChar(regex_sort, ctx=None):
11724 """Create a regular expression that accepts all single character strings
11725 """
11726 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11727
11728# Special Relations
11729
11730
11731def PartialOrder(a, index):
11732 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11733
11734
11735def LinearOrder(a, index):
11736 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11737
11738
11739def TreeOrder(a, index):
11740 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11741
11742
11743def PiecewiseLinearOrder(a, index):
11744 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11745
11746
11747def TransitiveClosure(f):
11748 """Given a binary relation R, such that the two arguments have the same sort
11749 create the transitive closure relation R+.
11750 The transitive closure R+ is a new relation.
11751 """
11752 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11753
11754def to_Ast(ptr,):
11755 ast = Ast(ptr)
11756 super(ctypes.c_void_p, ast).__init__(ptr)
11757 return ast
11758
11759def to_ContextObj(ptr,):
11760 ctx = ContextObj(ptr)
11761 super(ctypes.c_void_p, ctx).__init__(ptr)
11762 return ctx
11763
11764def to_AstVectorObj(ptr,):
11765 v = AstVectorObj(ptr)
11766 super(ctypes.c_void_p, v).__init__(ptr)
11767 return v
11768
11769# NB. my-hacky-class only works for a single instance of OnClause
11770# it should be replaced with a proper correlation between OnClause
11771# and object references that can be passed over the FFI.
11772# for UserPropagator we use a global dictionary, which isn't great code.
11773
11774_my_hacky_class = None
11775def on_clause_eh(ctx, p, n, dep, clause):
11776 onc = _my_hacky_class
11777 p = _to_expr_ref(to_Ast(p), onc.ctx)
11778 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11779 deps = [dep[i] for i in range(n)]
11780 onc.on_clause(p, deps, clause)
11781
11782_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11783
11784class OnClause:
11785 def __init__(self, s, on_clause):
11786 self.s = s
11787 self.ctx = s.ctx
11788 self.on_clause = on_clause
11789 self.idx = 22
11790 global _my_hacky_class
11791 _my_hacky_class = self
11792 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11793
11794
11795class PropClosures:
11796 def __init__(self):
11797 self.bases = {}
11798 self.lock = None
11799
11800 def set_threaded(self):
11801 if self.lock is None:
11802 import threading
11803 self.lock = threading.Lock()
11804
11805 def get(self, ctx):
11806 if self.lock:
11807 with self.lock:
11808 r = self.bases[ctx]
11809 else:
11810 r = self.bases[ctx]
11811 return r
11812
11813 def set(self, ctx, r):
11814 if self.lock:
11815 with self.lock:
11816 self.bases[ctx] = r
11817 else:
11818 self.bases[ctx] = r
11819
11820 def insert(self, r):
11821 if self.lock:
11822 with self.lock:
11823 id = len(self.bases) + 3
11824 self.bases[id] = r
11825 else:
11826 id = len(self.bases) + 3
11827 self.bases[id] = r
11828 return id
11829
11830
11831_prop_closures = None
11832
11833
11834def ensure_prop_closures():
11835 global _prop_closures
11836 if _prop_closures is None:
11837 _prop_closures = PropClosures()
11838
11839
11840def user_prop_push(ctx, cb):
11841 prop = _prop_closures.get(ctx)
11842 prop.cb = cb
11843 prop.push()
11844
11845
11846def user_prop_pop(ctx, cb, num_scopes):
11847 prop = _prop_closures.get(ctx)
11848 prop.cb = cb
11849 prop.pop(num_scopes)
11850
11851
11852def user_prop_fresh(ctx, _new_ctx):
11853 _prop_closures.set_threaded()
11854 prop = _prop_closures.get(ctx)
11855 nctx = Context()
11856 Z3_del_context(nctx.ctx)
11857 new_ctx = to_ContextObj(_new_ctx)
11858 nctx.ctx = new_ctx
11859 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11860 nctx.owner = False
11861 new_prop = prop.fresh(nctx)
11862 _prop_closures.set(new_prop.id, new_prop)
11863 return new_prop.id
11864
11865
11866def user_prop_fixed(ctx, cb, id, value):
11867 prop = _prop_closures.get(ctx)
11868 old_cb = prop.cb
11869 prop.cb = cb
11870 id = _to_expr_ref(to_Ast(id), prop.ctx())
11871 value = _to_expr_ref(to_Ast(value), prop.ctx())
11872 prop.fixed(id, value)
11873 prop.cb = old_cb
11874
11875def user_prop_created(ctx, cb, id):
11876 prop = _prop_closures.get(ctx)
11877 old_cb = prop.cb
11878 prop.cb = cb
11879 id = _to_expr_ref(to_Ast(id), prop.ctx())
11880 prop.created(id)
11881 prop.cb = old_cb
11882
11883
11884def user_prop_final(ctx, cb):
11885 prop = _prop_closures.get(ctx)
11886 old_cb = prop.cb
11887 prop.cb = cb
11888 prop.final()
11889 prop.cb = old_cb
11890
11891def user_prop_eq(ctx, cb, x, y):
11892 prop = _prop_closures.get(ctx)
11893 old_cb = prop.cb
11894 prop.cb = cb
11895 x = _to_expr_ref(to_Ast(x), prop.ctx())
11896 y = _to_expr_ref(to_Ast(y), prop.ctx())
11897 prop.eq(x, y)
11898 prop.cb = old_cb
11899
11900def user_prop_diseq(ctx, cb, x, y):
11901 prop = _prop_closures.get(ctx)
11902 old_cb = prop.cb
11903 prop.cb = cb
11904 x = _to_expr_ref(to_Ast(x), prop.ctx())
11905 y = _to_expr_ref(to_Ast(y), prop.ctx())
11906 prop.diseq(x, y)
11907 prop.cb = old_cb
11908
11909def user_prop_decide(ctx, cb, t_ref, idx, phase):
11910 prop = _prop_closures.get(ctx)
11911 old_cb = prop.cb
11912 prop.cb = cb
11913 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11914 prop.decide(t, idx, phase)
11915 prop.cb = old_cb
11916
11917def user_prop_binding(ctx, cb, q_ref, inst_ref):
11918 prop = _prop_closures.get(ctx)
11919 old_cb = prop.cb
11920 prop.cb = cb
11921 q = _to_expr_ref(to_Ast(q_ref), prop.ctx())
11922 inst = _to_expr_ref(to_Ast(inst_ref), prop.ctx())
11923 r = prop.binding(q, inst)
11924 prop.cb = old_cb
11925 return r
11926
11927
11928_user_prop_push = Z3_push_eh(user_prop_push)
11929_user_prop_pop = Z3_pop_eh(user_prop_pop)
11930_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11931_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11932_user_prop_created = Z3_created_eh(user_prop_created)
11933_user_prop_final = Z3_final_eh(user_prop_final)
11934_user_prop_eq = Z3_eq_eh(user_prop_eq)
11935_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11936_user_prop_decide = Z3_decide_eh(user_prop_decide)
11937_user_prop_binding = Z3_on_binding_eh(user_prop_binding)
11938
11939
11940def PropagateFunction(name, *sig):
11941 """Create a function that gets tracked by user propagator.
11942 Every term headed by this function symbol is tracked.
11943 If a term is fixed and the fixed callback is registered a
11944 callback is invoked that the term headed by this function is fixed.
11945 """
11946 sig = _get_args(sig)
11947 if z3_debug():
11948 _z3_assert(len(sig) > 0, "At least two arguments expected")
11949 arity = len(sig) - 1
11950 rng = sig[arity]
11951 if z3_debug():
11952 _z3_assert(is_sort(rng), "Z3 sort expected")
11953 dom = (Sort * arity)()
11954 for i in range(arity):
11955 if z3_debug():
11956 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11957 dom[i] = sig[i].ast
11958 ctx = rng.ctx
11959 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11960
11961
11962
11963class UserPropagateBase:
11964
11965 #
11966 # Either solver is set or ctx is set.
11967 # Propagators that are created through callbacks
11968 # to "fresh" inherit the context of that is supplied
11969 # as argument to the callback.
11970 # This context should not be deleted. It is owned by the solver.
11971 #
11972 def __init__(self, s, ctx=None):
11973 assert s is None or ctx is None
11974 ensure_prop_closures()
11975 self.solver = s
11976 self._ctx = None
11977 self.fresh_ctx = None
11978 self.cb = None
11979 self.id = _prop_closures.insert(self)
11980 self.fixed = None
11981 self.final = None
11982 self.eq = None
11983 self.diseq = None
11984 self.decide = None
11985 self.created = None
11986 self.binding = None
11987 if ctx:
11988 self.fresh_ctx = ctx
11989 if s:
11990 Z3_solver_propagate_init(self.ctx_ref(),
11991 s.solver,
11992 ctypes.c_void_p(self.id),
11993 _user_prop_push,
11994 _user_prop_pop,
11995 _user_prop_fresh)
11996
11997 def __del__(self):
11998 if self._ctx:
11999 self._ctx.ctx = None
12000
12001 def ctx(self):
12002 if self.fresh_ctx:
12003 return self.fresh_ctx
12004 else:
12005 return self.solver.ctx
12006
12007 def ctx_ref(self):
12008 return self.ctx().ref()
12009
12010 def add_fixed(self, fixed):
12011 assert not self.fixed
12012 assert not self._ctx
12013 if self.solver:
12014 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
12015 self.fixed = fixed
12016
12017 def add_created(self, created):
12018 assert not self.created
12019 assert not self._ctx
12020 if self.solver:
12021 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
12022 self.created = created
12023
12024 def add_final(self, final):
12025 assert not self.final
12026 assert not self._ctx
12027 if self.solver:
12028 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
12029 self.final = final
12030
12031 def add_eq(self, eq):
12032 assert not self.eq
12033 assert not self._ctx
12034 if self.solver:
12035 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
12036 self.eq = eq
12037
12038 def add_diseq(self, diseq):
12039 assert not self.diseq
12040 assert not self._ctx
12041 if self.solver:
12042 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
12043 self.diseq = diseq
12044
12045 def add_decide(self, decide):
12046 assert not self.decide
12047 assert not self._ctx
12048 if self.solver:
12049 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
12050 self.decide = decide
12051
12052 def add_on_binding(self, binding):
12053 assert not self.binding
12054 assert not self._ctx
12055 if self.solver:
12056 Z3_solver_propagate_on_binding(self.ctx_ref(), self.solver.solver, _user_prop_binding)
12057 self.binding = binding
12058
12059 def push(self):
12060 raise Z3Exception("push needs to be overwritten")
12061
12062 def pop(self, num_scopes):
12063 raise Z3Exception("pop needs to be overwritten")
12064
12065 def fresh(self, new_ctx):
12066 raise Z3Exception("fresh needs to be overwritten")
12067
12068 def add(self, e):
12069 assert not self._ctx
12070 if self.solver:
12071 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
12072 else:
12073 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
12074
12075 #
12076 # Tell the solver to perform the next split on a given term
12077 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
12078 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
12079 #
12080 def next_split(self, t, idx, phase):
12081 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
12082
12083 #
12084 # Propagation can only be invoked as during a fixed or final callback.
12085 #
12086 def propagate(self, e, ids, eqs=[]):
12087 _ids, num_fixed = _to_ast_array(ids)
12088 num_eqs = len(eqs)
12089 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
12090 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
12091 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
12092 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
12093
12094 def conflict(self, deps = [], eqs = []):
12095 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3241
as_decimal(self, prec)
Definition z3py.py:3253
__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
__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:4735
domain_n(self, i)
Definition z3py.py:4744
__getitem__(self, arg)
Definition z3py.py:4757
range(self)
Definition z3py.py:4748
sort(self)
Definition z3py.py:4726
default(self)
Definition z3py.py:4769
domain_n(self, i)
Definition z3py.py:4708
erase(self, k)
Definition z3py.py:6306
__deepcopy__(self, memo={})
Definition z3py.py:6243
__init__(self, m=None, ctx=None)
Definition z3py.py:6232
__repr__(self)
Definition z3py.py:6303
__len__(self)
Definition z3py.py:6250
keys(self)
Definition z3py.py:6335
__setitem__(self, k, v)
Definition z3py.py:6287
__contains__(self, key)
Definition z3py.py:6263
__del__(self)
Definition z3py.py:6246
__getitem__(self, key)
Definition z3py.py:6276
reset(self)
Definition z3py.py:6320
__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:6212
translate(self, other_ctx)
Definition z3py.py:6193
__repr__(self)
Definition z3py.py:6215
__len__(self)
Definition z3py.py:6087
__init__(self, v=None, ctx=None)
Definition z3py.py:6072
push(self, v)
Definition z3py.py:6145
__getitem__(self, i)
Definition z3py.py:6100
sexpr(self)
Definition z3py.py:6218
__del__(self)
Definition z3py.py:6083
__setitem__(self, i, v)
Definition z3py.py:6129
__contains__(self, item)
Definition z3py.py:6170
__copy__(self)
Definition z3py.py:6209
resize(self, sz)
Definition z3py.py:6157
as_binary_string(self)
Definition z3py.py:4087
as_signed_long(self)
Definition z3py.py:4061
as_string(self)
Definition z3py.py:4084
__and__(self, other)
Definition z3py.py:3751
__rmod__(self, other)
Definition z3py.py:3892
__rrshift__(self, other)
Definition z3py.py:4018
__mod__(self, other)
Definition z3py.py:3871
__or__(self, other)
Definition z3py.py:3728
__rlshift__(self, other)
Definition z3py.py:4032
__gt__(self, other)
Definition z3py.py:3942
__lt__(self, other)
Definition z3py.py:3926
__invert__(self)
Definition z3py.py:3817
__rtruediv__(self, other)
Definition z3py.py:3867
__rmul__(self, other)
Definition z3py.py:3695
__rxor__(self, other)
Definition z3py.py:3787
__ror__(self, other)
Definition z3py.py:3741
__rsub__(self, other)
Definition z3py.py:3718
__add__(self, other)
Definition z3py.py:3659
__sub__(self, other)
Definition z3py.py:3705
__radd__(self, other)
Definition z3py.py:3672
size(self)
Definition z3py.py:3648
__rand__(self, other)
Definition z3py.py:3764
__truediv__(self, other)
Definition z3py.py:3847
__le__(self, other)
Definition z3py.py:3910
__xor__(self, other)
Definition z3py.py:3774
__lshift__(self, other)
Definition z3py.py:4004
__pos__(self)
Definition z3py.py:3797
sort(self)
Definition z3py.py:3637
__mul__(self, other)
Definition z3py.py:3682
__rdiv__(self, other)
Definition z3py.py:3851
__ge__(self, other)
Definition z3py.py:3958
__neg__(self)
Definition z3py.py:3806
__rshift__(self, other)
Definition z3py.py:3974
__div__(self, other)
Definition z3py.py:3828
Bit-Vectors.
Definition z3py.py:3590
subsort(self, other)
Definition z3py.py:3602
cast(self, val)
Definition z3py.py:3605
__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:7100
__eq__(self, other)
Definition z3py.py:7103
__ne__(self, other)
Definition z3py.py:7106
__init__(self, r)
Definition z3py.py:7097
param_descrs(self)
Definition z3py.py:240
set_ast_print_mode(self, mode)
Definition z3py.py:244
__init__(self, *args, **kws)
Definition z3py.py:202
interrupt(self)
Definition z3py.py:232
__del__(self)
Definition z3py.py:222
ref(self)
Definition z3py.py:228
bool owner
Definition z3py.py:217
__deepcopy__(self, memo={})
Definition z3py.py:5246
create(self)
Definition z3py.py:5285
__init__(self, name, ctx=None)
Definition z3py.py:5241
__repr__(self)
Definition z3py.py:5282
list constructors
Definition z3py.py:5244
declare(self, name, *args)
Definition z3py.py:5261
declare_core(self, name, rec_name, *args)
Definition z3py.py:5251
update_field(self, field_accessor, new_value)
Definition z3py.py:5526
constructor(self, idx)
Definition z3py.py:5438
accessor(self, i, j)
Definition z3py.py:5485
num_constructors(self)
Definition z3py.py:5425
recognizer(self, idx)
Definition z3py.py:5457
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:6354
__deepcopy__(self, memo={})
Definition z3py.py:6362
ctx
Definition z3py.py:6359
__repr__(self)
Definition z3py.py:6459
num_args(self)
Definition z3py.py:6369
entry
Definition z3py.py:6358
value(self)
Definition z3py.py:6418
__init__(self, entry, ctx)
Definition z3py.py:6357
__del__(self)
Definition z3py.py:6365
as_list(self)
Definition z3py.py:6440
arg_value(self, idx)
Definition z3py.py:6387
__deepcopy__(self, memo={})
Definition z3py.py:6557
translate(self, other_ctx)
Definition z3py.py:6549
arity(self)
Definition z3py.py:6515
__repr__(self)
Definition z3py.py:6577
num_entries(self)
Definition z3py.py:6499
__init__(self, f, ctx)
Definition z3py.py:6466
__del__(self)
Definition z3py.py:6472
as_list(self)
Definition z3py.py:6560
else_value(self)
Definition z3py.py:6476
entry(self, idx)
Definition z3py.py:6529
__copy__(self)
Definition z3py.py:6554
__deepcopy__(self, memo={})
Definition z3py.py:6017
get(self, i)
Definition z3py.py:5875
prec(self)
Definition z3py.py:5819
translate(self, target)
Definition z3py.py:5991
append(self, *args)
Definition z3py.py:5918
as_expr(self)
Definition z3py.py:6040
assert_exprs(self, *args)
Definition z3py.py:5903
__repr__(self)
Definition z3py.py:5980
__len__(self)
Definition z3py.py:5862
inconsistent(self)
Definition z3py.py:5801
dimacs(self, include_names=True)
Definition z3py.py:5987
__getitem__(self, arg)
Definition z3py.py:5888
size(self)
Definition z3py.py:5849
precision(self)
Definition z3py.py:5840
simplify(self, *arguments, **keywords)
Definition z3py.py:6020
sexpr(self)
Definition z3py.py:5983
add(self, *args)
Definition z3py.py:5940
__del__(self)
Definition z3py.py:5779
convert_model(self, model)
Definition z3py.py:5951
insert(self, *args)
Definition z3py.py:5929
depth(self)
Definition z3py.py:5783
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5769
__copy__(self)
Definition z3py.py:6014
as_binary_string(self)
Definition z3py.py:3126
py_value(self)
Definition z3py.py:3134
as_long(self)
Definition z3py.py:3105
as_string(self)
Definition z3py.py:3118
__deepcopy__(self, memo={})
Definition z3py.py:6923
eval(self, t, model_completion=False)
Definition z3py.py:6601
translate(self, target)
Definition z3py.py:6888
__getitem__(self, idx)
Definition z3py.py:6802
num_sorts(self)
Definition z3py.py:6727
get_universe(self, s)
Definition z3py.py:6782
get_sort(self, idx)
Definition z3py.py:6742
project(self, vars, fml)
Definition z3py.py:6896
__repr__(self)
Definition z3py.py:6594
__len__(self)
Definition z3py.py:6658
get_interp(self, decl)
Definition z3py.py:6675
__init__(self, m, ctx)
Definition z3py.py:6584
sexpr(self)
Definition z3py.py:6597
sorts(self)
Definition z3py.py:6765
__del__(self)
Definition z3py.py:6590
decls(self)
Definition z3py.py:6847
project_with_witness(self, vars, fml)
Definition z3py.py:6908
update_value(self, x, value)
Definition z3py.py:6866
evaluate(self, t, model_completion=False)
Definition z3py.py:6632
__copy__(self)
Definition z3py.py:6920
__deepcopy__(self, memo={})
Definition z3py.py:5713
__init__(self, descr, ctx=None)
Definition z3py.py:5707
get_kind(self, n)
Definition z3py.py:5735
get_documentation(self, n)
Definition z3py.py:5740
__getitem__(self, arg)
Definition z3py.py:5745
get_name(self, i)
Definition z3py.py:5730
Parameter Sets.
Definition z3py.py:5634
__deepcopy__(self, memo={})
Definition z3py.py:5648
validate(self, ds)
Definition z3py.py:5675
__repr__(self)
Definition z3py.py:5672
__init__(self, ctx=None, params=None)
Definition z3py.py:5640
set(self, name, val)
Definition z3py.py:5655
__del__(self)
Definition z3py.py:5651
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:3167
is_int_value(self)
Definition z3py.py:3197
as_fraction(self)
Definition z3py.py:3225
py_value(self)
Definition z3py.py:3234
numerator(self)
Definition z3py.py:3141
is_real(self)
Definition z3py.py:3194
as_long(self)
Definition z3py.py:3200
is_int(self)
Definition z3py.py:3191
denominator_as_long(self)
Definition z3py.py:3180
as_string(self)
Definition z3py.py:3216
denominator(self)
Definition z3py.py:3156
as_decimal(self, prec)
Definition z3py.py:3204
__init__(self, c, ctx)
Definition z3py.py:5305
__init__(self, c, ctx)
Definition z3py.py:5317
Strings, Sequences and Regular expressions.
Definition z3py.py:11089
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7144
assert_and_track(self, a, p)
Definition z3py.py:7313
num_scopes(self)
Definition z3py.py:7225
append(self, *args)
Definition z3py.py:7291
__iadd__(self, fml)
Definition z3py.py:7287
pop(self, num=1)
Definition z3py.py:7203
import_model_converter(self, other)
Definition z3py.py:7391
assert_exprs(self, *args)
Definition z3py.py:7257
model(self)
Definition z3py.py:7372
set(self, *args, **keys)
Definition z3py.py:7168
__enter__(self)
Definition z3py.py:7161
add(self, *args)
Definition z3py.py:7276
__del__(self)
Definition z3py.py:7157
int backtrack_level
Definition z3py.py:7147
insert(self, *args)
Definition z3py.py:7302
check(self, *assumptions)
Definition z3py.py:7343
push(self)
Definition z3py.py:7181
__exit__(self, *exc_info)
Definition z3py.py:7165
reset(self)
Definition z3py.py:7243
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:6953
__deepcopy__(self, memo={})
Definition z3py.py:6961
__getattr__(self, name)
Definition z3py.py:7056
__getitem__(self, idx)
Definition z3py.py:7000
__init__(self, stats, ctx)
Definition z3py.py:6956
__repr__(self)
Definition z3py.py:6968
__len__(self)
Definition z3py.py:6986
__del__(self)
Definition z3py.py:6964
get_key_value(self, key)
Definition z3py.py:7036
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:3272
RotateRight(a, b)
Definition z3py.py:4522
_symbol2py(ctx, s)
Definition z3py.py:140
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4172
BVSNegNoOverflow(a)
Definition z3py.py:4669
SetAdd(s, e)
Definition z3py.py:5134
SetSort(s)
Sets.
Definition z3py.py:5085
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1302
UGT(a, b)
Definition z3py.py:4393
is_probe(p)
Definition z3py.py:8991
SetDel(s, e)
Definition z3py.py:5145
bool is_le(Any a)
Definition z3py.py:3012
BoolSort(ctx=None)
Definition z3py.py:1824
is_bv_sort(s)
Definition z3py.py:3623
_ctx_from_ast_args(*args)
Definition z3py.py:542
RatVal(a, b, ctx=None)
Definition z3py.py:3364
_to_func_decl_ref(a, ctx)
Definition z3py.py:962
SetUnion(*args)
Definition z3py.py:5108
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5205
BitVec(name, bv, ctx=None)
Definition z3py.py:4189
EmptySet(s)
Definition z3py.py:5090
BVMulNoUnderflow(a, b)
Definition z3py.py:4683
CreateDatatypes(*ds)
Definition z3py.py:5326
is_func_decl(a)
Definition z3py.py:907
get_as_array_func(n)
Definition z3py.py:6940
Distinct(*args)
Definition z3py.py:1507
RecAddDefinition(f, args, body)
Definition z3py.py:984
ToInt(a)
Definition z3py.py:3523
Implies(a, b, ctx=None)
Definition z3py.py:1918
UGE(a, b)
Definition z3py.py:4375
Ext(a, b)
Definition z3py.py:5043
_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:4334
RealSort(ctx=None)
Definition z3py.py:3304
IsSubset(a, b)
Definition z3py.py:5188
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:3072
_to_ref_array(ref, args)
Definition z3py.py:562
get_map_func(a)
Definition z3py.py:4851
_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:5577
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1333
is_select(a)
Definition z3py.py:5054
SignExt(n, a)
Definition z3py.py:4538
Int(name, ctx=None)
Definition z3py.py:3393
Bools(names, ctx=None)
Definition z3py.py:1873
_probe_and(args, ctx)
Definition z3py.py:9058
Int2BV(a, num_bits)
Definition z3py.py:4148
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:3474
BVRedOr(a)
Definition z3py.py:4627
SRem(a, b)
Definition z3py.py:4453
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:2959
is_bv(a)
Definition z3py.py:4096
SetDifference(a, b)
Definition z3py.py:5166
bool is_arith_sort(Any s)
Definition z3py.py:2507
BitVecs(names, bv, ctx=None)
Definition z3py.py:4213
_check_same_sort(a, b, ctx=None)
Definition z3py.py:1289
bool is_mod(Any a)
Definition z3py.py:3000
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1889
_has_probe(args)
Definition z3py.py:1974
IsMember(e, s)
Definition z3py.py:5177
get_param(name)
Definition z3py.py:334
BVAddNoUnderflow(a, b)
Definition z3py.py:4641
deserialize(st)
Definition z3py.py:1207
bool is_not(Any a)
Definition z3py.py:1790
Extract(high, low, a)
Definition z3py.py:4280
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:4357
EnumSort(name, values, ctx=None)
Definition z3py.py:5601
bool is_is_int(Any a)
Definition z3py.py:3060
_to_int_str(val)
Definition z3py.py:3321
is_algebraic_value(a)
Definition z3py.py:2921
is_bv_value(a)
Definition z3py.py:4110
BVSDivNoOverflow(a, b)
Definition z3py.py:4662
bool is_eq(Any a)
Definition z3py.py:1802
Context main_ctx()
Definition z3py.py:266
SetIntersect(*args)
Definition z3py.py:5121
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9125
BV2Int(a, is_signed=False)
Definition z3py.py:4125
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3432
_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:3087
is_map(a)
Definition z3py.py:4826
Context _get_ctx(ctx)
Definition z3py.py:287
Or(*args)
Definition z3py.py:2015
is_re(s)
Definition z3py.py:11579
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5680
bool is_idiv(Any a)
Definition z3py.py:2988
Consts(names, sort)
Definition z3py.py:1552
Cond(p, t1, t2, ctx=None)
Definition z3py.py:9108
_to_pattern(arg)
Definition z3py.py:2108
RealVarVector(int n, ctx=None)
Definition z3py.py:1600
is_arith(a)
Definition z3py.py:2808
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:2829
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:2935
z3_error_handler(c, e)
Definition z3py.py:184
None reset_params()
Definition z3py.py:322
Reals(names, ctx=None)
Definition z3py.py:3459
is_int_value(a)
Definition z3py.py:2875
set_param(*args, **kws)
Definition z3py.py:298
is_pattern(a)
Definition z3py.py:2066
_coerce_seq(s, ctx=None)
Definition z3py.py:11240
bool is_distinct(Any a)
Definition z3py.py:1812
bool is_lt(Any a)
Definition z3py.py:3024
ULE(a, b)
Definition z3py.py:4339
is_real(a)
Definition z3py.py:2848
FullSet(s)
Definition z3py.py:5099
to_symbol(s, ctx=None)
Definition z3py.py:132
bool is_mul(Any a)
Definition z3py.py:2947
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:4596
get_version_string()
Definition z3py.py:91
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3489
Array(name, *sorts)
Definition z3py.py:4908
Concat(*args)
Definition z3py.py:4234
_reduce(func, sequence, initial)
Definition z3py.py:1326
_is_algebraic(ctx, a)
Definition z3py.py:2871
Ints(names, ctx=None)
Definition z3py.py:3406
Select(a, *args)
Definition z3py.py:4982
Const(name, sort)
Definition z3py.py:1540
is_array_sort(a)
Definition z3py.py:4782
bool is_div(Any a)
Definition z3py.py:2971
ExprRef Var(int idx, SortRef s)
Definition z3py.py:1575
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4634
Real(name, ctx=None)
Definition z3py.py:3446
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1904
BitVecSort(sz, ctx=None)
Definition z3py.py:4157
open_log(fname)
Definition z3py.py:122
RecFunction(name, *sig)
Definition z3py.py:966
bool is_ge(Any a)
Definition z3py.py:3036
Model(ctx=None, eval={})
Definition z3py.py:6927
BVSubNoOverflow(a, b)
Definition z3py.py:4648
bool is_gt(Any a)
Definition z3py.py:3048
is_default(a)
Definition z3py.py:4842
is_K(a)
Definition z3py.py:4813
Bool(name, ctx=None)
Definition z3py.py:1861
_is_int(v)
Definition z3py.py:76
is_const_array(a)
Definition z3py.py:4800
Sqrt(a, ctx=None)
Definition z3py.py:3558
Default(a)
Definition z3py.py:4954
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:528
SetComplement(s)
Definition z3py.py:5156
is_as_array(n)
Definition z3py.py:6935
is_store(a)
Definition z3py.py:5067
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:5021
Xor(a, b, ctx=None)
Definition z3py.py:1932
Store(a, *args)
Definition z3py.py:4965
bool is_array(Any a)
Definition z3py.py:4786
mk_not(a)
Definition z3py.py:1967
is_expr(a)
Definition z3py.py:1345
_array_select(ar, arg)
Definition z3py.py:4773
is_const(a)
Definition z3py.py:1394
BoolVal(val, ctx=None)
Definition z3py.py:1842
RealVal(val, ctx=None)
Definition z3py.py:3345
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:3419
_coerce_expr_merge(s, a)
Definition z3py.py:1271
Context get_ctx(ctx)
Definition z3py.py:294
LShR(a, b)
Definition z3py.py:4474
ArraySort(*sig)
Definition z3py.py:4875
Map(f, *args)
Definition z3py.py:4998
is_rational_value(a)
Definition z3py.py:2899
_probe_or(args, ctx)
Definition z3py.py:9062
BVRedAnd(a)
Definition z3py.py:4620
Cbrt(a, ctx=None)
Definition z3py.py:3571
_to_expr_ref(a, ctx)
Definition z3py.py:1221
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5589
IntSort(ctx=None)
Definition z3py.py:3287
is_seq(a)
Definition z3py.py:11261
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:3503
URem(a, b)
Definition z3py.py:4432
bool is_bool(Any a)
Definition z3py.py:1704
StringVal(s, ctx=None)
Definition z3py.py:11288
IsInt(a)
Definition z3py.py:3541
_is_numeral(ctx, a)
Definition z3py.py:2867
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:4568
_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:5552
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4655
UDiv(a, b)
Definition z3py.py:4411
Q(a, b, ctx=None)
Definition z3py.py:3380
Update(a, *args)
Definition z3py.py:4922
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:3333
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4676
RotateLeft(a, b)
Definition z3py.py:4506
_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