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
245# Global Z3 context
246_main_ctx = None
247
248
249def main_ctx() -> Context:
250 """Return a reference to the global Z3 context.
251
252 >>> x = Real('x')
253 >>> x.ctx == main_ctx()
254 True
255 >>> c = Context()
256 >>> c == main_ctx()
257 False
258 >>> x2 = Real('x', c)
259 >>> x2.ctx == c
260 True
261 >>> eq(x, x2)
262 False
263 """
264 global _main_ctx
265 if _main_ctx is None:
266 _main_ctx = Context()
267 return _main_ctx
268
269
270def _get_ctx(ctx) -> Context:
271 if ctx is None:
272 return main_ctx()
273 else:
274 return ctx
275
276
277def get_ctx(ctx) -> Context:
278 return _get_ctx(ctx)
279
280
281def set_param(*args, **kws):
282 """Set Z3 global (or module) parameters.
283
284 >>> set_param(precision=10)
285 """
286 if z3_debug():
287 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
288 new_kws = {}
289 for k in kws:
290 v = kws[k]
291 if not set_pp_option(k, v):
292 new_kws[k] = v
293 for key in new_kws:
294 value = new_kws[key]
295 Z3_global_param_set(str(key).upper(), _to_param_value(value))
296 prev = None
297 for a in args:
298 if prev is None:
299 prev = a
300 else:
302 prev = None
303
304
305def reset_params() -> None:
306 """Reset all global (or module) parameters.
307 """
309
310
311def set_option(*args, **kws):
312 """Alias for 'set_param' for backward compatibility.
313 """
314 return set_param(*args, **kws)
315
316
317def get_param(name):
318 """Return the value of a Z3 global (or module) parameter
319
320 >>> get_param('nlsat.reorder')
321 'true'
322 """
323 ptr = (ctypes.c_char_p * 1)()
324 if Z3_global_param_get(str(name), ptr):
325 r = z3core._to_pystr(ptr[0])
326 return r
327 raise Z3Exception("failed to retrieve value for '%s'" % name)
328
329
334
335# Mark objects that use pretty printer
336
337
339 """Superclass for all Z3 objects that have support for pretty printing."""
340
341 def use_pp(self):
342 return True
343
344 def _repr_html_(self):
345 in_html = in_html_mode()
346 set_html_mode(True)
347 res = repr(self)
348 set_html_mode(in_html)
349 return res
350
351
353 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
354
355 def __init__(self, ast, ctx=None):
356 self.ast = ast
357 self.ctx = _get_ctx(ctx)
358 Z3_inc_ref(self.ctx.ref(), self.as_ast())
359
360 def __del__(self):
361 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
362 Z3_dec_ref(self.ctx.ref(), self.as_ast())
363 self.ast = None
364
365 def __deepcopy__(self, memo={}):
366 return _to_ast_ref(self.ast, self.ctx)
367
368 def __str__(self):
369 return obj_to_string(self)
370
371 def __repr__(self):
372 return obj_to_string(self)
373
374 def __eq__(self, other):
375 return self.eq(other)
376
377 def __hash__(self):
378 return self.hash()
379
380 def __nonzero__(self):
381 return self.__bool__()
382
383 def __bool__(self):
384 if is_true(self):
385 return True
386 elif is_false(self):
387 return False
388 elif is_eq(self) and self.num_args() == 2:
389 return self.arg(0).eq(self.arg(1))
390 else:
391 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
392
393 def sexpr(self):
394 """Return a string representing the AST node in s-expression notation.
395
396 >>> x = Int('x')
397 >>> ((x + 1)*x).sexpr()
398 '(* (+ x 1) x)'
399 """
400 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
401
402 def as_ast(self):
403 """Return a pointer to the corresponding C Z3_ast object."""
404 return self.ast
405
406 def get_id(self):
407 """Return unique identifier for object. It can be used for hash-tables and maps."""
408 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
409
410 def ctx_ref(self):
411 """Return a reference to the C context where this AST node is stored."""
412 return self.ctx.ref()
413
414 def eq(self, other):
415 """Return `True` if `self` and `other` are structurally identical.
416
417 >>> x = Int('x')
418 >>> n1 = x + 1
419 >>> n2 = 1 + x
420 >>> n1.eq(n2)
421 False
422 >>> n1 = simplify(n1)
423 >>> n2 = simplify(n2)
424 >>> n1.eq(n2)
425 True
426 """
427 if z3_debug():
428 _z3_assert(is_ast(other), "Z3 AST expected")
429 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
430
431 def translate(self, target):
432 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
433
434 >>> c1 = Context()
435 >>> c2 = Context()
436 >>> x = Int('x', c1)
437 >>> y = Int('y', c2)
438 >>> # Nodes in different contexts can't be mixed.
439 >>> # However, we can translate nodes from one context to another.
440 >>> x.translate(c2) + y
441 x + y
442 """
443 if z3_debug():
444 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
445 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
446
447 def __copy__(self):
448 return self.translate(self.ctx)
449
450 def hash(self):
451 """Return a hashcode for the `self`.
452
453 >>> n1 = simplify(Int('x') + 1)
454 >>> n2 = simplify(2 + Int('x') - 1)
455 >>> n1.hash() == n2.hash()
456 True
457 """
458 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
459
460 def py_value(self):
461 """Return a Python value that is equivalent to `self`."""
462 return None
463
464
465def is_ast(a : Any) -> bool:
466 """Return `True` if `a` is an AST node.
467
468 >>> is_ast(10)
469 False
470 >>> is_ast(IntVal(10))
471 True
472 >>> is_ast(Int('x'))
473 True
474 >>> is_ast(BoolSort())
475 True
476 >>> is_ast(Function('f', IntSort(), IntSort()))
477 True
478 >>> is_ast("x")
479 False
480 >>> is_ast(Solver())
481 False
482 """
483 return isinstance(a, AstRef)
484
485
486def eq(a : AstRef, b : AstRef) -> bool:
487 """Return `True` if `a` and `b` are structurally identical AST nodes.
488
489 >>> x = Int('x')
490 >>> y = Int('y')
491 >>> eq(x, y)
492 False
493 >>> eq(x + 1, x + 1)
494 True
495 >>> eq(x + 1, 1 + x)
496 False
497 >>> eq(simplify(x + 1), simplify(1 + x))
498 True
499 """
500 if z3_debug():
501 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
502 return a.eq(b)
503
504
505def _ast_kind(ctx : Context, a : Any) -> int:
506 if is_ast(a):
507 a = a.as_ast()
508 return Z3_get_ast_kind(ctx.ref(), a)
509
510
511def _ctx_from_ast_arg_list(args, default_ctx=None):
512 ctx = None
513 for a in args:
514 if is_ast(a) or is_probe(a):
515 if ctx is None:
516 ctx = a.ctx
517 else:
518 if z3_debug():
519 _z3_assert(ctx == a.ctx, "Context mismatch")
520 if ctx is None:
521 ctx = default_ctx
522 return ctx
523
524
526 return _ctx_from_ast_arg_list(args)
527
528
530 sz = len(args)
531 _args = (FuncDecl * sz)()
532 for i in range(sz):
533 _args[i] = args[i].as_func_decl()
534 return _args, sz
535
536
538 sz = len(args)
539 _args = (Ast * sz)()
540 for i in range(sz):
541 _args[i] = args[i].as_ast()
542 return _args, sz
543
544
545def _to_ref_array(ref, args):
546 sz = len(args)
547 _args = (ref * sz)()
548 for i in range(sz):
549 _args[i] = args[i].as_ast()
550 return _args, sz
551
552
553def _to_ast_ref(a, ctx):
554 k = _ast_kind(ctx, a)
555 if k == Z3_SORT_AST:
556 return _to_sort_ref(a, ctx)
557 elif k == Z3_FUNC_DECL_AST:
558 return _to_func_decl_ref(a, ctx)
559 else:
560 return _to_expr_ref(a, ctx)
561
562
563
568
569def _sort_kind(ctx, s):
570 return Z3_get_sort_kind(ctx.ref(), s)
571
572
574 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
575
576 def as_ast(self):
577 return Z3_sort_to_ast(self.ctx_ref(), self.astast)
578
579 def get_id(self):
580 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
581
582 def kind(self):
583 """Return the Z3 internal kind of a sort.
584 This method can be used to test if `self` is one of the Z3 builtin sorts.
585
586 >>> b = BoolSort()
587 >>> b.kind() == Z3_BOOL_SORT
588 True
589 >>> b.kind() == Z3_INT_SORT
590 False
591 >>> A = ArraySort(IntSort(), IntSort())
592 >>> A.kind() == Z3_ARRAY_SORT
593 True
594 >>> A.kind() == Z3_INT_SORT
595 False
596 """
597 return _sort_kind(self.ctxctx, self.astast)
598
599 def subsort(self, other):
600 """Return `True` if `self` is a subsort of `other`.
601
602 >>> IntSort().subsort(RealSort())
603 True
604 """
605 return False
606
607 def cast(self, val):
608 """Try to cast `val` as an element of sort `self`.
609
610 This method is used in Z3Py to convert Python objects such as integers,
611 floats, longs and strings into Z3 expressions.
612
613 >>> x = Int('x')
614 >>> RealSort().cast(x)
615 ToReal(x)
616 """
617 if z3_debug():
618 _z3_assert(is_expr(val), "Z3 expression expected")
619 _z3_assert(self.eq(val.sort()), "Sort mismatch")
620 return val
621
622 def name(self):
623 """Return the name (string) of sort `self`.
624
625 >>> BoolSort().name()
626 'Bool'
627 >>> ArraySort(IntSort(), IntSort()).name()
628 'Array'
629 """
630 return _symbol2py(self.ctxctx, Z3_get_sort_name(self.ctx_ref(), self.astast))
631
632 def __eq__(self, other):
633 """Return `True` if `self` and `other` are the same Z3 sort.
634
635 >>> p = Bool('p')
636 >>> p.sort() == BoolSort()
637 True
638 >>> p.sort() == IntSort()
639 False
640 """
641 if other is None:
642 return False
643 return Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
644
645 def __ne__(self, other):
646 """Return `True` if `self` and `other` are not the same Z3 sort.
647
648 >>> p = Bool('p')
649 >>> p.sort() != BoolSort()
650 False
651 >>> p.sort() != IntSort()
652 True
653 """
654 return not Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
655
656 def __gt__(self, other):
657 """Create the function space Array(self, other)"""
658 return ArraySort(self, other)
659
660 def __hash__(self):
661 """ Hash code. """
662 return AstRef.__hash__(self)
663
664
665def is_sort(s : Any) -> bool:
666 """Return `True` if `s` is a Z3 sort.
667
668 >>> is_sort(IntSort())
669 True
670 >>> is_sort(Int('x'))
671 False
672 >>> is_expr(Int('x'))
673 True
674 """
675 return isinstance(s, SortRef)
676
677
678def _to_sort_ref(s, ctx):
679 if z3_debug():
680 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
681 k = _sort_kind(ctx, s)
682 if k == Z3_BOOL_SORT:
683 return BoolSortRef(s, ctx)
684 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
685 return ArithSortRef(s, ctx)
686 elif k == Z3_BV_SORT:
687 return BitVecSortRef(s, ctx)
688 elif k == Z3_ARRAY_SORT:
689 return ArraySortRef(s, ctx)
690 elif k == Z3_DATATYPE_SORT:
691 return DatatypeSortRef(s, ctx)
692 elif k == Z3_FINITE_DOMAIN_SORT:
693 return FiniteDomainSortRef(s, ctx)
694 elif k == Z3_FLOATING_POINT_SORT:
695 return FPSortRef(s, ctx)
696 elif k == Z3_ROUNDING_MODE_SORT:
697 return FPRMSortRef(s, ctx)
698 elif k == Z3_RE_SORT:
699 return ReSortRef(s, ctx)
700 elif k == Z3_SEQ_SORT:
701 return SeqSortRef(s, ctx)
702 elif k == Z3_CHAR_SORT:
703 return CharSortRef(s, ctx)
704 elif k == Z3_TYPE_VAR:
705 return TypeVarRef(s, ctx)
706 return SortRef(s, ctx)
707
708
709def _sort(ctx : Context, a : Any) -> SortRef:
710 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
711
712
713def DeclareSort(name, ctx= None) -> SortRef:
714 """Create a new uninterpreted sort named `name`.
715
716 If `ctx=None`, then the new sort is declared in the global Z3Py context.
717
718 >>> A = DeclareSort('A')
719 >>> a = Const('a', A)
720 >>> b = Const('b', A)
721 >>> a.sort() == A
722 True
723 >>> b.sort() == A
724 True
725 >>> a == b
726 a == b
727 """
728 ctx = _get_ctx(ctx)
729 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
730
732 """Type variable reference"""
733
734 def subsort(self, other):
735 return True
736
737 def cast(self, val):
738 return val
739
740
741def DeclareTypeVar(name, ctx=None):
742 """Create a new type variable named `name`.
743
744 If `ctx=None`, then the new sort is declared in the global Z3Py context.
745
746 """
747 ctx = _get_ctx(ctx)
748 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
749
750
751
756
757
759 """Function declaration. Every constant and function have an associated declaration.
760
761 The declaration assigns a name, a sort (i.e., type), and for function
762 the sort (i.e., type) of each of its arguments. Note that, in Z3,
763 a constant is a function with 0 arguments.
764 """
765
766 def as_ast(self):
767 return Z3_func_decl_to_ast(self.ctx_ref(), self.astast)
768
769 def get_id(self):
770 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
771
772 def as_func_decl(self):
773 return self.astast
774
775 def name(self):
776 """Return the name of the function declaration `self`.
777
778 >>> f = Function('f', IntSort(), IntSort())
779 >>> f.name()
780 'f'
781 >>> isinstance(f.name(), str)
782 True
783 """
784 return _symbol2py(self.ctxctx, Z3_get_decl_name(self.ctx_ref(), self.astast))
785
786 def arity(self):
787 """Return the number of arguments of a function declaration.
788 If `self` is a constant, then `self.arity()` is 0.
789
790 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
791 >>> f.arity()
792 2
793 """
794 return int(Z3_get_arity(self.ctx_ref(), self.astast))
795
796 def domain(self, i):
797 """Return the sort of the argument `i` of a function declaration.
798 This method assumes that `0 <= i < self.arity()`.
799
800 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
801 >>> f.domain(0)
802 Int
803 >>> f.domain(1)
804 Real
805 """
806 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.astast, i), self.ctxctx)
807
808 def range(self):
809 """Return the sort of the range of a function declaration.
810 For constants, this is the sort of the constant.
811
812 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
813 >>> f.range()
814 Bool
815 """
816 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.astast), self.ctxctx)
817
818 def kind(self):
819 """Return the internal kind of a function declaration.
820 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
821
822 >>> x = Int('x')
823 >>> d = (x + 1).decl()
824 >>> d.kind() == Z3_OP_ADD
825 True
826 >>> d.kind() == Z3_OP_MUL
827 False
828 """
829 return Z3_get_decl_kind(self.ctx_ref(), self.astast)
830
831 def params(self):
832 ctx = self.ctxctx
834 result = [None for i in range(n)]
835 for i in range(n):
836 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.astast, i)
837 if k == Z3_PARAMETER_INT:
838 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.astast, i)
839 elif k == Z3_PARAMETER_DOUBLE:
840 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.astast, i)
841 elif k == Z3_PARAMETER_RATIONAL:
842 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.astast, i)
843 elif k == Z3_PARAMETER_SYMBOL:
844 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.astast, i)
845 elif k == Z3_PARAMETER_SORT:
846 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.astast, i), ctx)
847 elif k == Z3_PARAMETER_AST:
848 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.astast, i), ctx)
849 elif k == Z3_PARAMETER_FUNC_DECL:
850 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.astast, i), ctx)
851 elif k == Z3_PARAMETER_INTERNAL:
852 result[i] = "internal parameter"
853 elif k == Z3_PARAMETER_ZSTRING:
854 result[i] = "internal string"
855 else:
856 assert(False)
857 return result
858
859 def __call__(self, *args):
860 """Create a Z3 application expression using the function `self`, and the given arguments.
861
862 The arguments must be Z3 expressions. This method assumes that
863 the sorts of the elements in `args` match the sorts of the
864 domain. Limited coercion is supported. For example, if
865 args[0] is a Python integer, and the function expects a Z3
866 integer, then the argument is automatically converted into a
867 Z3 integer.
868
869 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
870 >>> x = Int('x')
871 >>> y = Real('y')
872 >>> f(x, y)
873 f(x, y)
874 >>> f(x, x)
875 f(x, ToReal(x))
876 """
877 args = _get_args(args)
878 num = len(args)
879 _args = (Ast * num)()
880 saved = []
881 for i in range(num):
882 # self.domain(i).cast(args[i]) may create a new Z3 expression,
883 # then we must save in 'saved' to prevent it from being garbage collected.
884 tmp = self.domain(i).cast(args[i])
885 saved.append(tmp)
886 _args[i] = tmp.as_ast()
887 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.astast, len(args), _args), self.ctxctx)
888
889
891 """Return `True` if `a` is a Z3 function declaration.
892
893 >>> f = Function('f', IntSort(), IntSort())
894 >>> is_func_decl(f)
895 True
896 >>> x = Real('x')
897 >>> is_func_decl(x)
898 False
899 """
900 return isinstance(a, FuncDeclRef)
901
902
903def Function(name, *sig):
904 """Create a new Z3 uninterpreted function with the given sorts.
905
906 >>> f = Function('f', IntSort(), IntSort())
907 >>> f(f(0))
908 f(f(0))
909 """
910 sig = _get_args(sig)
911 if z3_debug():
912 _z3_assert(len(sig) > 0, "At least two arguments expected")
913 arity = len(sig) - 1
914 rng = sig[arity]
915 if z3_debug():
916 _z3_assert(is_sort(rng), "Z3 sort expected")
917 dom = (Sort * arity)()
918 for i in range(arity):
919 if z3_debug():
920 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
921 dom[i] = sig[i].ast
922 ctx = rng.ctx
923 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
924
925
927 """Create a new fresh Z3 uninterpreted function with the given sorts.
928 """
929 sig = _get_args(sig)
930 if z3_debug():
931 _z3_assert(len(sig) > 0, "At least two arguments expected")
932 arity = len(sig) - 1
933 rng = sig[arity]
934 if z3_debug():
935 _z3_assert(is_sort(rng), "Z3 sort expected")
936 dom = (z3.Sort * arity)()
937 for i in range(arity):
938 if z3_debug():
939 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
940 dom[i] = sig[i].ast
941 ctx = rng.ctx
942 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
943
944
946 return FuncDeclRef(a, ctx)
947
948
949def RecFunction(name, *sig):
950 """Create a new Z3 recursive with the given sorts."""
951 sig = _get_args(sig)
952 if z3_debug():
953 _z3_assert(len(sig) > 0, "At least two arguments expected")
954 arity = len(sig) - 1
955 rng = sig[arity]
956 if z3_debug():
957 _z3_assert(is_sort(rng), "Z3 sort expected")
958 dom = (Sort * arity)()
959 for i in range(arity):
960 if z3_debug():
961 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
962 dom[i] = sig[i].ast
963 ctx = rng.ctx
964 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
965
966
967def RecAddDefinition(f, args, body):
968 """Set the body of a recursive function.
969 Recursive definitions can be simplified if they are applied to ground
970 arguments.
971 >>> ctx = Context()
972 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
973 >>> n = Int('n', ctx)
974 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
975 >>> simplify(fac(5))
976 120
977 >>> s = Solver(ctx=ctx)
978 >>> s.add(fac(n) < 3)
979 >>> s.check()
980 sat
981 >>> s.model().eval(fac(5))
982 120
983 """
984 if is_app(args):
985 args = [args]
986 ctx = body.ctx
987 args = _get_args(args)
988 n = len(args)
989 _args = (Ast * n)()
990 for i in range(n):
991 _args[i] = args[i].ast
992 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
993
994
999
1000
1002 """Constraints, formulas and terms are expressions in Z3.
1003
1004 Expressions are ASTs. Every expression has a sort.
1005 There are three main kinds of expressions:
1006 function applications, quantifiers and bounded variables.
1007 A constant is a function application with 0 arguments.
1008 For quantifier free problems, all expressions are
1009 function applications.
1010 """
1011
1012 def as_ast(self):
1013 return self.astast
1014
1015 def get_id(self):
1016 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
1017
1018 def sort(self):
1019 """Return the sort of expression `self`.
1020
1021 >>> x = Int('x')
1022 >>> (x + 1).sort()
1023 Int
1024 >>> y = Real('y')
1025 >>> (x + y).sort()
1026 Real
1027 """
1028 return _sort(self.ctxctx, self.as_astas_ast())
1029
1030 def sort_kind(self):
1031 """Shorthand for `self.sort().kind()`.
1032
1033 >>> a = Array('a', IntSort(), IntSort())
1034 >>> a.sort_kind() == Z3_ARRAY_SORT
1035 True
1036 >>> a.sort_kind() == Z3_INT_SORT
1037 False
1038 """
1039 return self.sort().kind()
1040
1041 def __eq__(self, other):
1042 """Return a Z3 expression that represents the constraint `self == other`.
1043
1044 If `other` is `None`, then this method simply returns `False`.
1045
1046 >>> a = Int('a')
1047 >>> b = Int('b')
1048 >>> a == b
1049 a == b
1050 >>> a is None
1051 False
1052 """
1053 if other is None:
1054 return False
1055 a, b = _coerce_exprs(self, other)
1056 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctx)
1057
1058 def __hash__(self):
1059 """ Hash code. """
1060 return AstRef.__hash__(self)
1061
1062 def __ne__(self, other):
1063 """Return a Z3 expression that represents the constraint `self != other`.
1064
1065 If `other` is `None`, then this method simply returns `True`.
1066
1067 >>> a = Int('a')
1068 >>> b = Int('b')
1069 >>> a != b
1070 a != b
1071 >>> a is not None
1072 True
1073 """
1074 if other is None:
1075 return True
1076 a, b = _coerce_exprs(self, other)
1077 _args, sz = _to_ast_array((a, b))
1078 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctxctx)
1079
1080 def params(self):
1081 return self.decl().params()
1082
1083 def decl(self):
1084 """Return the Z3 function declaration associated with a Z3 application.
1085
1086 >>> f = Function('f', IntSort(), IntSort())
1087 >>> a = Int('a')
1088 >>> t = f(a)
1089 >>> eq(t.decl(), f)
1090 True
1091 >>> (a + 1).decl()
1092 +
1093 """
1094 if z3_debug():
1095 _z3_assert(is_app(self), "Z3 application expected")
1096 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_astas_ast()), self.ctxctx)
1097
1098 def kind(self):
1099 """Return the Z3 internal kind of a function application."""
1100 if z3_debug():
1101 _z3_assert(is_app(self), "Z3 application expected")
1103
1104
1105 def num_args(self):
1106 """Return the number of arguments of a Z3 application.
1107
1108 >>> a = Int('a')
1109 >>> b = Int('b')
1110 >>> (a + b).num_args()
1111 2
1112 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1113 >>> t = f(a, b, 0)
1114 >>> t.num_args()
1115 3
1116 """
1117 if z3_debug():
1118 _z3_assert(is_app(self), "Z3 application expected")
1119 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_astas_ast()))
1120
1121 def arg(self, idx):
1122 """Return argument `idx` of the application `self`.
1123
1124 This method assumes that `self` is a function application with at least `idx+1` arguments.
1125
1126 >>> a = Int('a')
1127 >>> b = Int('b')
1128 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1129 >>> t = f(a, b, 0)
1130 >>> t.arg(0)
1131 a
1132 >>> t.arg(1)
1133 b
1134 >>> t.arg(2)
1135 0
1136 """
1137 if z3_debug():
1138 _z3_assert(is_app(self), "Z3 application expected")
1139 _z3_assert(idx < self.num_args(), "Invalid argument index")
1140 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_astas_ast(), idx), self.ctxctx)
1141
1142 def children(self):
1143 """Return a list containing the children of the given expression
1144
1145 >>> a = Int('a')
1146 >>> b = Int('b')
1147 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1148 >>> t = f(a, b, 0)
1149 >>> t.children()
1150 [a, b, 0]
1151 """
1152 if is_app(self):
1153 return [self.arg(i) for i in range(self.num_args())]
1154 else:
1155 return []
1156
1157 def from_string(self, s):
1158 pass
1159
1160 def serialize(self):
1161 s = Solver()
1162 f = Function('F', self.sort(), BoolSort(self.ctx))
1163 s.add(f(self))
1164 return s.sexpr()
1165
1167 """inverse function to the serialize method on ExprRef.
1168 It is made available to make it easier for users to serialize expressions back and forth between
1169 strings. Solvers can be serialized using the 'sexpr()' method.
1170 """
1171 s = Solver()
1172 s.from_string(st)
1173 if len(s.assertions()) != 1:
1174 raise Z3Exception("single assertion expected")
1175 fml = s.assertions()[0]
1176 if fml.num_args() != 1:
1177 raise Z3Exception("dummy function 'F' expected")
1178 return fml.arg(0)
1179
1180def _to_expr_ref(a, ctx):
1181 if isinstance(a, Pattern):
1182 return PatternRef(a, ctx)
1183 ctx_ref = ctx.ref()
1184 k = Z3_get_ast_kind(ctx_ref, a)
1185 if k == Z3_QUANTIFIER_AST:
1186 return QuantifierRef(a, ctx)
1187 sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1188 if sk == Z3_BOOL_SORT:
1189 return BoolRef(a, ctx)
1190 if sk == Z3_INT_SORT:
1191 if k == Z3_NUMERAL_AST:
1192 return IntNumRef(a, ctx)
1193 return ArithRef(a, ctx)
1194 if sk == Z3_REAL_SORT:
1195 if k == Z3_NUMERAL_AST:
1196 return RatNumRef(a, ctx)
1197 if _is_algebraic(ctx, a):
1198 return AlgebraicNumRef(a, ctx)
1199 return ArithRef(a, ctx)
1200 if sk == Z3_BV_SORT:
1201 if k == Z3_NUMERAL_AST:
1202 return BitVecNumRef(a, ctx)
1203 else:
1204 return BitVecRef(a, ctx)
1205 if sk == Z3_ARRAY_SORT:
1206 return ArrayRef(a, ctx)
1207 if sk == Z3_DATATYPE_SORT:
1208 return DatatypeRef(a, ctx)
1209 if sk == Z3_FLOATING_POINT_SORT:
1210 if k == Z3_APP_AST and _is_numeral(ctx, a):
1211 return FPNumRef(a, ctx)
1212 else:
1213 return FPRef(a, ctx)
1214 if sk == Z3_FINITE_DOMAIN_SORT:
1215 if k == Z3_NUMERAL_AST:
1216 return FiniteDomainNumRef(a, ctx)
1217 else:
1218 return FiniteDomainRef(a, ctx)
1219 if sk == Z3_ROUNDING_MODE_SORT:
1220 return FPRMRef(a, ctx)
1221 if sk == Z3_SEQ_SORT:
1222 return SeqRef(a, ctx)
1223 if sk == Z3_CHAR_SORT:
1224 return CharRef(a, ctx)
1225 if sk == Z3_RE_SORT:
1226 return ReRef(a, ctx)
1227 return ExprRef(a, ctx)
1228
1229
1231 if is_expr(a):
1232 s1 = a.sort()
1233 if s is None:
1234 return s1
1235 if s1.eq(s):
1236 return s
1237 elif s.subsort(s1):
1238 return s1
1239 elif s1.subsort(s):
1240 return s
1241 else:
1242 if z3_debug():
1243 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1244 _z3_assert(False, "sort mismatch")
1245 else:
1246 return s
1247
1248def _check_same_sort(a, b, ctx=None):
1249 if not isinstance(a, ExprRef):
1250 return False
1251 if not isinstance(b, ExprRef):
1252 return False
1253 if ctx is None:
1254 ctx = a.ctx
1255
1256 a_sort = Z3_get_sort(ctx.ctx, a.ast)
1257 b_sort = Z3_get_sort(ctx.ctx, b.ast)
1258 return Z3_is_eq_sort(ctx.ctx, a_sort, b_sort)
1259
1260
1261def _coerce_exprs(a, b, ctx=None):
1262 if not is_expr(a) and not is_expr(b):
1263 a = _py2expr(a, ctx)
1264 b = _py2expr(b, ctx)
1265 if isinstance(a, str) and isinstance(b, SeqRef):
1266 a = StringVal(a, b.ctx)
1267 if isinstance(b, str) and isinstance(a, SeqRef):
1268 b = StringVal(b, a.ctx)
1269 if isinstance(a, float) and isinstance(b, ArithRef):
1270 a = RealVal(a, b.ctx)
1271 if isinstance(b, float) and isinstance(a, ArithRef):
1272 b = RealVal(b, a.ctx)
1273
1274 if _check_same_sort(a, b, ctx):
1275 return (a, b)
1276
1277 s = None
1278 s = _coerce_expr_merge(s, a)
1279 s = _coerce_expr_merge(s, b)
1280 a = s.cast(a)
1281 b = s.cast(b)
1282 return (a, b)
1283
1284
1285def _reduce(func, sequence, initial):
1286 result = initial
1287 for element in sequence:
1288 result = func(result, element)
1289 return result
1290
1291
1292def _coerce_expr_list(alist, ctx=None):
1293 has_expr = False
1294 for a in alist:
1295 if is_expr(a):
1296 has_expr = True
1297 break
1298 if not has_expr:
1299 alist = [_py2expr(a, ctx) for a in alist]
1300 s = _reduce(_coerce_expr_merge, alist, None)
1301 return [s.cast(a) for a in alist]
1302
1303
1304def is_expr(a):
1305 """Return `True` if `a` is a Z3 expression.
1306
1307 >>> a = Int('a')
1308 >>> is_expr(a)
1309 True
1310 >>> is_expr(a + 1)
1311 True
1312 >>> is_expr(IntSort())
1313 False
1314 >>> is_expr(1)
1315 False
1316 >>> is_expr(IntVal(1))
1317 True
1318 >>> x = Int('x')
1319 >>> is_expr(ForAll(x, x >= 0))
1320 True
1321 >>> is_expr(FPVal(1.0))
1322 True
1323 """
1324 return isinstance(a, ExprRef)
1325
1326
1327def is_app(a):
1328 """Return `True` if `a` is a Z3 function application.
1329
1330 Note that, constants are function applications with 0 arguments.
1331
1332 >>> a = Int('a')
1333 >>> is_app(a)
1334 True
1335 >>> is_app(a + 1)
1336 True
1337 >>> is_app(IntSort())
1338 False
1339 >>> is_app(1)
1340 False
1341 >>> is_app(IntVal(1))
1342 True
1343 >>> x = Int('x')
1344 >>> is_app(ForAll(x, x >= 0))
1345 False
1346 """
1347 if not isinstance(a, ExprRef):
1348 return False
1349 k = _ast_kind(a.ctx, a)
1350 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1351
1352
1354 """Return `True` if `a` is Z3 constant/variable expression.
1355
1356 >>> a = Int('a')
1357 >>> is_const(a)
1358 True
1359 >>> is_const(a + 1)
1360 False
1361 >>> is_const(1)
1362 False
1363 >>> is_const(IntVal(1))
1364 True
1365 >>> x = Int('x')
1366 >>> is_const(ForAll(x, x >= 0))
1367 False
1368 """
1369 return is_app(a) and a.num_args() == 0
1370
1371
1372def is_var(a):
1373 """Return `True` if `a` is variable.
1374
1375 Z3 uses de-Bruijn indices for representing bound variables in
1376 quantifiers.
1377
1378 >>> x = Int('x')
1379 >>> is_var(x)
1380 False
1381 >>> is_const(x)
1382 True
1383 >>> f = Function('f', IntSort(), IntSort())
1384 >>> # Z3 replaces x with bound variables when ForAll is executed.
1385 >>> q = ForAll(x, f(x) == x)
1386 >>> b = q.body()
1387 >>> b
1388 f(Var(0)) == Var(0)
1389 >>> b.arg(1)
1390 Var(0)
1391 >>> is_var(b.arg(1))
1392 True
1393 """
1394 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1395
1396
1398 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1399
1400 >>> x = Int('x')
1401 >>> y = Int('y')
1402 >>> is_var(x)
1403 False
1404 >>> is_const(x)
1405 True
1406 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1407 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1408 >>> q = ForAll([x, y], f(x, y) == x + y)
1409 >>> q.body()
1410 f(Var(1), Var(0)) == Var(1) + Var(0)
1411 >>> b = q.body()
1412 >>> b.arg(0)
1413 f(Var(1), Var(0))
1414 >>> v1 = b.arg(0).arg(0)
1415 >>> v2 = b.arg(0).arg(1)
1416 >>> v1
1417 Var(1)
1418 >>> v2
1419 Var(0)
1420 >>> get_var_index(v1)
1421 1
1422 >>> get_var_index(v2)
1423 0
1424 """
1425 if z3_debug():
1426 _z3_assert(is_var(a), "Z3 bound variable expected")
1427 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1428
1429
1430def is_app_of(a, k):
1431 """Return `True` if `a` is an application of the given kind `k`.
1432
1433 >>> x = Int('x')
1434 >>> n = x + 1
1435 >>> is_app_of(n, Z3_OP_ADD)
1436 True
1437 >>> is_app_of(n, Z3_OP_MUL)
1438 False
1439 """
1440 return is_app(a) and a.kind() == k
1441
1442
1443def If(a, b, c, ctx=None):
1444 """Create a Z3 if-then-else expression.
1445
1446 >>> x = Int('x')
1447 >>> y = Int('y')
1448 >>> max = If(x > y, x, y)
1449 >>> max
1450 If(x > y, x, y)
1451 >>> simplify(max)
1452 If(x <= y, y, x)
1453 """
1454 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1455 return Cond(a, b, c, ctx)
1456 else:
1457 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1458 s = BoolSort(ctx)
1459 a = s.cast(a)
1460 b, c = _coerce_exprs(b, c, ctx)
1461 if z3_debug():
1462 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1463 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1464
1465
1466def Distinct(*args):
1467 """Create a Z3 distinct expression.
1468
1469 >>> x = Int('x')
1470 >>> y = Int('y')
1471 >>> Distinct(x, y)
1472 x != y
1473 >>> z = Int('z')
1474 >>> Distinct(x, y, z)
1475 Distinct(x, y, z)
1476 >>> simplify(Distinct(x, y, z))
1477 Distinct(x, y, z)
1478 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1479 And(Not(x == y), Not(x == z), Not(y == z))
1480 """
1481 args = _get_args(args)
1482 ctx = _ctx_from_ast_arg_list(args)
1483 if z3_debug():
1484 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1485 args = _coerce_expr_list(args, ctx)
1486 _args, sz = _to_ast_array(args)
1487 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1488
1489
1490def _mk_bin(f, a, b):
1491 args = (Ast * 2)()
1492 if z3_debug():
1493 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1494 args[0] = a.as_ast()
1495 args[1] = b.as_ast()
1496 return f(a.ctx.ref(), 2, args)
1497
1498
1499def Const(name, sort):
1500 """Create a constant of the given sort.
1501
1502 >>> Const('x', IntSort())
1503 x
1504 """
1505 if z3_debug():
1506 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1507 ctx = sort.ctx
1508 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1509
1510
1511def Consts(names, sort):
1512 """Create several constants of the given sort.
1513
1514 `names` is a string containing the names of all constants to be created.
1515 Blank spaces separate the names of different constants.
1516
1517 >>> x, y, z = Consts('x y z', IntSort())
1518 >>> x + y + z
1519 x + y + z
1520 """
1521 if isinstance(names, str):
1522 names = names.split(" ")
1523 return [Const(name, sort) for name in names]
1524
1525
1526def FreshConst(sort, prefix="c"):
1527 """Create a fresh constant of a specified sort"""
1528 if z3_debug():
1529 _z3_assert(is_sort(sort), f"Z3 sort expected, got {type(sort)}")
1530 ctx = _get_ctx(sort.ctx)
1531 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1532
1533
1534def Var(idx : int, s : SortRef) -> ExprRef:
1535 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1536 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1537 declarations.
1538
1539 >>> Var(0, IntSort())
1540 Var(0)
1541 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1542 False
1543 """
1544 if z3_debug():
1545 _z3_assert(is_sort(s), "Z3 sort expected")
1546 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1547
1548
1549def RealVar(idx: int, ctx=None) -> ExprRef:
1550 """
1551 Create a real free variable. Free variables are used to create quantified formulas.
1552 They are also used to create polynomials.
1553
1554 >>> RealVar(0)
1555 Var(0)
1556 """
1557 return Var(idx, RealSort(ctx))
1558
1559def RealVarVector(n: int, ctx= None):
1560 """
1561 Create a list of Real free variables.
1562 The variables have ids: 0, 1, ..., n-1
1563
1564 >>> x0, x1, x2, x3 = RealVarVector(4)
1565 >>> x2
1566 Var(2)
1567 """
1568 return [RealVar(i, ctx) for i in range(n)]
1569
1570
1575
1576
1578 """Boolean sort."""
1579
1580 def cast(self, val):
1581 """Try to cast `val` as a Boolean.
1582
1583 >>> x = BoolSort().cast(True)
1584 >>> x
1585 True
1586 >>> is_expr(x)
1587 True
1588 >>> is_expr(True)
1589 False
1590 >>> x.sort()
1591 Bool
1592 """
1593 if isinstance(val, bool):
1594 return BoolVal(val, self.ctxctxctx)
1595 if z3_debug():
1596 if not is_expr(val):
1597 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1598 _z3_assert(is_expr(val), msg % (val, type(val)))
1599 if not self.eq(val.sort()):
1600 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1601 return val
1602
1603 def subsort(self, other):
1604 return isinstance(other, ArithSortRef)
1605
1606 def is_int(self):
1607 return True
1608
1609 def is_bool(self):
1610 return True
1611
1612
1614 """All Boolean expressions are instances of this class."""
1615
1616 def sort(self):
1618
1619 def __add__(self, other):
1620 if isinstance(other, BoolRef):
1621 other = If(other, 1, 0)
1622 return If(self, 1, 0) + other
1623
1624 def __radd__(self, other):
1625 return self + other
1626
1627 def __rmul__(self, other):
1628 return self * other
1629
1630 def __mul__(self, other):
1631 """Create the Z3 expression `self * other`.
1632 """
1633 if isinstance(other, int) and other == 1:
1634 return If(self, 1, 0)
1635 if isinstance(other, int) and other == 0:
1636 return IntVal(0, self.ctxctxctx)
1637 if isinstance(other, BoolRef):
1638 other = If(other, 1, 0)
1639 return If(self, other, 0)
1640
1641 def __and__(self, other):
1642 return And(self, other)
1643
1644 def __or__(self, other):
1645 return Or(self, other)
1646
1647 def __xor__(self, other):
1648 return Xor(self, other)
1649
1650 def __invert__(self):
1651 return Not(self)
1652
1653 def py_value(self):
1654 if is_true(self):
1655 return True
1656 if is_false(self):
1657 return False
1658 return None
1659
1660
1661
1662
1663def is_bool(a : Any) -> bool:
1664 """Return `True` if `a` is a Z3 Boolean expression.
1665
1666 >>> p = Bool('p')
1667 >>> is_bool(p)
1668 True
1669 >>> q = Bool('q')
1670 >>> is_bool(And(p, q))
1671 True
1672 >>> x = Real('x')
1673 >>> is_bool(x)
1674 False
1675 >>> is_bool(x == 0)
1676 True
1677 """
1678 return isinstance(a, BoolRef)
1679
1680
1681def is_true(a : Any) -> bool:
1682 """Return `True` if `a` is the Z3 true expression.
1683
1684 >>> p = Bool('p')
1685 >>> is_true(p)
1686 False
1687 >>> is_true(simplify(p == p))
1688 True
1689 >>> x = Real('x')
1690 >>> is_true(x == 0)
1691 False
1692 >>> # True is a Python Boolean expression
1693 >>> is_true(True)
1694 False
1695 """
1696 return is_app_of(a, Z3_OP_TRUE)
1697
1698
1699def is_false(a : Any) -> bool:
1700 """Return `True` if `a` is the Z3 false expression.
1701
1702 >>> p = Bool('p')
1703 >>> is_false(p)
1704 False
1705 >>> is_false(False)
1706 False
1707 >>> is_false(BoolVal(False))
1708 True
1709 """
1710 return is_app_of(a, Z3_OP_FALSE)
1711
1712
1713def is_and(a : Any) -> bool:
1714 """Return `True` if `a` is a Z3 and expression.
1715
1716 >>> p, q = Bools('p q')
1717 >>> is_and(And(p, q))
1718 True
1719 >>> is_and(Or(p, q))
1720 False
1721 """
1722 return is_app_of(a, Z3_OP_AND)
1723
1724
1725def is_or(a : Any) -> bool:
1726 """Return `True` if `a` is a Z3 or expression.
1727
1728 >>> p, q = Bools('p q')
1729 >>> is_or(Or(p, q))
1730 True
1731 >>> is_or(And(p, q))
1732 False
1733 """
1734 return is_app_of(a, Z3_OP_OR)
1735
1736
1737def is_implies(a : Any) -> bool:
1738 """Return `True` if `a` is a Z3 implication expression.
1739
1740 >>> p, q = Bools('p q')
1741 >>> is_implies(Implies(p, q))
1742 True
1743 >>> is_implies(And(p, q))
1744 False
1745 """
1746 return is_app_of(a, Z3_OP_IMPLIES)
1747
1748
1749def is_not(a : Any) -> bool:
1750 """Return `True` if `a` is a Z3 not expression.
1751
1752 >>> p = Bool('p')
1753 >>> is_not(p)
1754 False
1755 >>> is_not(Not(p))
1756 True
1757 """
1758 return is_app_of(a, Z3_OP_NOT)
1759
1760
1761def is_eq(a : Any) -> bool:
1762 """Return `True` if `a` is a Z3 equality expression.
1763
1764 >>> x, y = Ints('x y')
1765 >>> is_eq(x == y)
1766 True
1767 """
1768 return is_app_of(a, Z3_OP_EQ)
1769
1770
1771def is_distinct(a : Any) -> bool:
1772 """Return `True` if `a` is a Z3 distinct expression.
1773
1774 >>> x, y, z = Ints('x y z')
1775 >>> is_distinct(x == y)
1776 False
1777 >>> is_distinct(Distinct(x, y, z))
1778 True
1779 """
1780 return is_app_of(a, Z3_OP_DISTINCT)
1781
1782
1783def BoolSort(ctx=None):
1784 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1785
1786 >>> BoolSort()
1787 Bool
1788 >>> p = Const('p', BoolSort())
1789 >>> is_bool(p)
1790 True
1791 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1792 >>> r(0, 1)
1793 r(0, 1)
1794 >>> is_bool(r(0, 1))
1795 True
1796 """
1797 ctx = _get_ctx(ctx)
1798 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1799
1800
1801def BoolVal(val, ctx=None):
1802 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1803
1804 >>> BoolVal(True)
1805 True
1806 >>> is_true(BoolVal(True))
1807 True
1808 >>> is_true(True)
1809 False
1810 >>> is_false(BoolVal(False))
1811 True
1812 """
1813 ctx = _get_ctx(ctx)
1814 if val:
1815 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1816 else:
1817 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1818
1819
1820def Bool(name, ctx=None):
1821 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1822
1823 >>> p = Bool('p')
1824 >>> q = Bool('q')
1825 >>> And(p, q)
1826 And(p, q)
1827 """
1828 ctx = _get_ctx(ctx)
1829 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1830
1831
1832def Bools(names, ctx=None):
1833 """Return a tuple of Boolean constants.
1834
1835 `names` is a single string containing all names separated by blank spaces.
1836 If `ctx=None`, then the global context is used.
1837
1838 >>> p, q, r = Bools('p q r')
1839 >>> And(p, Or(q, r))
1840 And(p, Or(q, r))
1841 """
1842 ctx = _get_ctx(ctx)
1843 if isinstance(names, str):
1844 names = names.split(" ")
1845 return [Bool(name, ctx) for name in names]
1846
1847
1848def BoolVector(prefix, sz, ctx=None):
1849 """Return a list of Boolean constants of size `sz`.
1850
1851 The constants are named using the given prefix.
1852 If `ctx=None`, then the global context is used.
1853
1854 >>> P = BoolVector('p', 3)
1855 >>> P
1856 [p__0, p__1, p__2]
1857 >>> And(P)
1858 And(p__0, p__1, p__2)
1859 """
1860 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1861
1862
1863def FreshBool(prefix="b", ctx=None):
1864 """Return a fresh Boolean constant in the given context using the given prefix.
1865
1866 If `ctx=None`, then the global context is used.
1867
1868 >>> b1 = FreshBool()
1869 >>> b2 = FreshBool()
1870 >>> eq(b1, b2)
1871 False
1872 """
1873 ctx = _get_ctx(ctx)
1874 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1875
1876
1877def Implies(a, b, ctx=None):
1878 """Create a Z3 implies expression.
1879
1880 >>> p, q = Bools('p q')
1881 >>> Implies(p, q)
1882 Implies(p, q)
1883 """
1884 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1885 s = BoolSort(ctx)
1886 a = s.cast(a)
1887 b = s.cast(b)
1888 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1889
1890
1891def Xor(a, b, ctx=None):
1892 """Create a Z3 Xor expression.
1893
1894 >>> p, q = Bools('p q')
1895 >>> Xor(p, q)
1896 Xor(p, q)
1897 >>> simplify(Xor(p, q))
1898 Not(p == q)
1899 """
1900 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1901 s = BoolSort(ctx)
1902 a = s.cast(a)
1903 b = s.cast(b)
1904 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1905
1906
1907def Not(a, ctx=None):
1908 """Create a Z3 not expression or probe.
1909
1910 >>> p = Bool('p')
1911 >>> Not(Not(p))
1912 Not(Not(p))
1913 >>> simplify(Not(Not(p)))
1914 p
1915 """
1916 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1917 if is_probe(a):
1918 # Not is also used to build probes
1919 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1920 else:
1921 s = BoolSort(ctx)
1922 a = s.cast(a)
1923 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1924
1925
1926def mk_not(a):
1927 if is_not(a):
1928 return a.arg(0)
1929 else:
1930 return Not(a)
1931
1932
1933def _has_probe(args):
1934 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1935 for arg in args:
1936 if is_probe(arg):
1937 return True
1938 return False
1939
1940
1941def And(*args):
1942 """Create a Z3 and-expression or and-probe.
1943
1944 >>> p, q, r = Bools('p q r')
1945 >>> And(p, q, r)
1946 And(p, q, r)
1947 >>> P = BoolVector('p', 5)
1948 >>> And(P)
1949 And(p__0, p__1, p__2, p__3, p__4)
1950 """
1951 last_arg = None
1952 if len(args) > 0:
1953 last_arg = args[len(args) - 1]
1954 if isinstance(last_arg, Context):
1955 ctx = args[len(args) - 1]
1956 args = args[:len(args) - 1]
1957 elif len(args) == 1 and isinstance(args[0], AstVector):
1958 ctx = args[0].ctx
1959 args = [a for a in args[0]]
1960 else:
1961 ctx = None
1962 args = _get_args(args)
1963 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1964 if z3_debug():
1965 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1966 if _has_probe(args):
1967 return _probe_and(args, ctx)
1968 else:
1969 args = _coerce_expr_list(args, ctx)
1970 _args, sz = _to_ast_array(args)
1971 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
1972
1973
1974def Or(*args):
1975 """Create a Z3 or-expression or or-probe.
1976
1977 >>> p, q, r = Bools('p q r')
1978 >>> Or(p, q, r)
1979 Or(p, q, r)
1980 >>> P = BoolVector('p', 5)
1981 >>> Or(P)
1982 Or(p__0, p__1, p__2, p__3, p__4)
1983 """
1984 last_arg = None
1985 if len(args) > 0:
1986 last_arg = args[len(args) - 1]
1987 if isinstance(last_arg, Context):
1988 ctx = args[len(args) - 1]
1989 args = args[:len(args) - 1]
1990 elif len(args) == 1 and isinstance(args[0], AstVector):
1991 ctx = args[0].ctx
1992 args = [a for a in args[0]]
1993 else:
1994 ctx = None
1995 args = _get_args(args)
1996 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
1997 if z3_debug():
1998 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
1999 if _has_probe(args):
2000 return _probe_or(args, ctx)
2001 else:
2002 args = _coerce_expr_list(args, ctx)
2003 _args, sz = _to_ast_array(args)
2004 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
2005
2006
2011
2012
2014 """Patterns are hints for quantifier instantiation.
2015
2016 """
2017
2018 def as_ast(self):
2020
2021 def get_id(self):
2022 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2023
2024
2026 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
2027
2028 >>> f = Function('f', IntSort(), IntSort())
2029 >>> x = Int('x')
2030 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
2031 >>> q
2032 ForAll(x, f(x) == 0)
2033 >>> q.num_patterns()
2034 1
2035 >>> is_pattern(q.pattern(0))
2036 True
2037 >>> q.pattern(0)
2038 f(Var(0))
2039 """
2040 return isinstance(a, PatternRef)
2041
2042
2043def MultiPattern(*args):
2044 """Create a Z3 multi-pattern using the given expressions `*args`
2045
2046 >>> f = Function('f', IntSort(), IntSort())
2047 >>> g = Function('g', IntSort(), IntSort())
2048 >>> x = Int('x')
2049 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2050 >>> q
2051 ForAll(x, f(x) != g(x))
2052 >>> q.num_patterns()
2053 1
2054 >>> is_pattern(q.pattern(0))
2055 True
2056 >>> q.pattern(0)
2057 MultiPattern(f(Var(0)), g(Var(0)))
2058 """
2059 if z3_debug():
2060 _z3_assert(len(args) > 0, "At least one argument expected")
2061 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2062 ctx = args[0].ctx
2063 args, sz = _to_ast_array(args)
2064 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2065
2066
2068 if is_pattern(arg):
2069 return arg
2070 else:
2071 return MultiPattern(arg)
2072
2073
2078
2079
2081 """Universally and Existentially quantified formulas."""
2082
2083 def as_ast(self):
2084 return self.astastast
2085
2086 def get_id(self):
2087 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2088
2089 def sort(self):
2090 """Return the Boolean sort or sort of Lambda."""
2091 if self.is_lambda():
2093 return BoolSort(self.ctxctxctxctx)
2094
2095 def is_forall(self):
2096 """Return `True` if `self` is a universal quantifier.
2097
2098 >>> f = Function('f', IntSort(), IntSort())
2099 >>> x = Int('x')
2100 >>> q = ForAll(x, f(x) == 0)
2101 >>> q.is_forall()
2102 True
2103 >>> q = Exists(x, f(x) != 0)
2104 >>> q.is_forall()
2105 False
2106 """
2108
2109 def is_exists(self):
2110 """Return `True` if `self` is an existential quantifier.
2111
2112 >>> f = Function('f', IntSort(), IntSort())
2113 >>> x = Int('x')
2114 >>> q = ForAll(x, f(x) == 0)
2115 >>> q.is_exists()
2116 False
2117 >>> q = Exists(x, f(x) != 0)
2118 >>> q.is_exists()
2119 True
2120 """
2121 return Z3_is_quantifier_exists(self.ctx_ref(), self.astastast)
2122
2123 def is_lambda(self):
2124 """Return `True` if `self` is a lambda expression.
2125
2126 >>> f = Function('f', IntSort(), IntSort())
2127 >>> x = Int('x')
2128 >>> q = Lambda(x, f(x))
2129 >>> q.is_lambda()
2130 True
2131 >>> q = Exists(x, f(x) != 0)
2132 >>> q.is_lambda()
2133 False
2134 """
2135 return Z3_is_lambda(self.ctx_ref(), self.astastast)
2136
2137 def __getitem__(self, arg):
2138 """Return the Z3 expression `self[arg]`.
2139 """
2140 if z3_debug():
2141 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2142 return _array_select(self, arg)
2143
2144 def weight(self):
2145 """Return the weight annotation of `self`.
2146
2147 >>> f = Function('f', IntSort(), IntSort())
2148 >>> x = Int('x')
2149 >>> q = ForAll(x, f(x) == 0)
2150 >>> q.weight()
2151 1
2152 >>> q = ForAll(x, f(x) == 0, weight=10)
2153 >>> q.weight()
2154 10
2155 """
2156 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.astastast))
2157
2158 def skolem_id(self):
2159 """Return the skolem id of `self`.
2160 """
2162
2163 def qid(self):
2164 """Return the quantifier id of `self`.
2165 """
2167
2168 def num_patterns(self):
2169 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2170
2171 >>> f = Function('f', IntSort(), IntSort())
2172 >>> g = Function('g', IntSort(), IntSort())
2173 >>> x = Int('x')
2174 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2175 >>> q.num_patterns()
2176 2
2177 """
2178 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.astastast))
2179
2180 def pattern(self, idx):
2181 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2182
2183 >>> f = Function('f', IntSort(), IntSort())
2184 >>> g = Function('g', IntSort(), IntSort())
2185 >>> x = Int('x')
2186 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2187 >>> q.num_patterns()
2188 2
2189 >>> q.pattern(0)
2190 f(Var(0))
2191 >>> q.pattern(1)
2192 g(Var(0))
2193 """
2194 if z3_debug():
2195 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2197
2199 """Return the number of no-patterns."""
2201
2202 def no_pattern(self, idx):
2203 """Return a no-pattern."""
2204 if z3_debug():
2205 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2207
2208 def body(self):
2209 """Return the expression being quantified.
2210
2211 >>> f = Function('f', IntSort(), IntSort())
2212 >>> x = Int('x')
2213 >>> q = ForAll(x, f(x) == 0)
2214 >>> q.body()
2215 f(Var(0)) == 0
2216 """
2218
2219 def num_vars(self):
2220 """Return the number of variables bounded by this quantifier.
2221
2222 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2223 >>> x = Int('x')
2224 >>> y = Int('y')
2225 >>> q = ForAll([x, y], f(x, y) >= x)
2226 >>> q.num_vars()
2227 2
2228 """
2229 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.astastast))
2230
2231 def var_name(self, idx):
2232 """Return a string representing a name used when displaying the quantifier.
2233
2234 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2235 >>> x = Int('x')
2236 >>> y = Int('y')
2237 >>> q = ForAll([x, y], f(x, y) >= x)
2238 >>> q.var_name(0)
2239 'x'
2240 >>> q.var_name(1)
2241 'y'
2242 """
2243 if z3_debug():
2244 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2246
2247 def var_sort(self, idx):
2248 """Return the sort of a bound variable.
2249
2250 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2251 >>> x = Int('x')
2252 >>> y = Real('y')
2253 >>> q = ForAll([x, y], f(x, y) >= x)
2254 >>> q.var_sort(0)
2255 Int
2256 >>> q.var_sort(1)
2257 Real
2258 """
2259 if z3_debug():
2260 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2262
2263 def children(self):
2264 """Return a list containing a single element self.body()
2265
2266 >>> f = Function('f', IntSort(), IntSort())
2267 >>> x = Int('x')
2268 >>> q = ForAll(x, f(x) == 0)
2269 >>> q.children()
2270 [f(Var(0)) == 0]
2271 """
2272 return [self.body()]
2273
2274
2276 """Return `True` if `a` is a Z3 quantifier.
2277
2278 >>> f = Function('f', IntSort(), IntSort())
2279 >>> x = Int('x')
2280 >>> q = ForAll(x, f(x) == 0)
2281 >>> is_quantifier(q)
2282 True
2283 >>> is_quantifier(f(x))
2284 False
2285 """
2286 return isinstance(a, QuantifierRef)
2287
2288
2289def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2290 if z3_debug():
2291 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2292 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2293 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2294 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2295 if is_app(vs):
2296 ctx = vs.ctx
2297 vs = [vs]
2298 else:
2299 ctx = vs[0].ctx
2300 if not is_expr(body):
2301 body = BoolVal(body, ctx)
2302 num_vars = len(vs)
2303 if num_vars == 0:
2304 return body
2305 _vs = (Ast * num_vars)()
2306 for i in range(num_vars):
2307 # TODO: Check if is constant
2308 _vs[i] = vs[i].as_ast()
2309 patterns = [_to_pattern(p) for p in patterns]
2310 num_pats = len(patterns)
2311 _pats = (Pattern * num_pats)()
2312 for i in range(num_pats):
2313 _pats[i] = patterns[i].ast
2314 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2315 qid = to_symbol(qid, ctx)
2316 skid = to_symbol(skid, ctx)
2317 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2318 num_vars, _vs,
2319 num_pats, _pats,
2320 num_no_pats, _no_pats,
2321 body.as_ast()), ctx)
2322
2323
2324def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2325 """Create a Z3 forall formula.
2326
2327 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2328
2329 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2330 >>> x = Int('x')
2331 >>> y = Int('y')
2332 >>> ForAll([x, y], f(x, y) >= x)
2333 ForAll([x, y], f(x, y) >= x)
2334 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2335 ForAll([x, y], f(x, y) >= x)
2336 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2337 ForAll([x, y], f(x, y) >= x)
2338 """
2339 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2340
2341
2342def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2343 """Create a Z3 exists formula.
2344
2345 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2346
2347
2348 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2349 >>> x = Int('x')
2350 >>> y = Int('y')
2351 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2352 >>> q
2353 Exists([x, y], f(x, y) >= x)
2354 >>> is_quantifier(q)
2355 True
2356 >>> r = Tactic('nnf')(q).as_expr()
2357 >>> is_quantifier(r)
2358 False
2359 """
2360 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2361
2362
2363def Lambda(vs, body):
2364 """Create a Z3 lambda expression.
2365
2366 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2367 >>> mem0 = Array('mem0', IntSort(), IntSort())
2368 >>> lo, hi, e, i = Ints('lo hi e i')
2369 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2370 >>> mem1
2371 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2372 """
2373 ctx = body.ctx
2374 if is_app(vs):
2375 vs = [vs]
2376 num_vars = len(vs)
2377 _vs = (Ast * num_vars)()
2378 for i in range(num_vars):
2379 # TODO: Check if is constant
2380 _vs[i] = vs[i].as_ast()
2381 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2382
2383
2388
2389
2391 """Real and Integer sorts."""
2392
2393 def is_real(self):
2394 """Return `True` if `self` is of the sort Real.
2395
2396 >>> x = Real('x')
2397 >>> x.is_real()
2398 True
2399 >>> (x + 1).is_real()
2400 True
2401 >>> x = Int('x')
2402 >>> x.is_real()
2403 False
2404 """
2405 return self.kind() == Z3_REAL_SORT
2406
2407 def is_int(self):
2408 """Return `True` if `self` is of the sort Integer.
2409
2410 >>> x = Int('x')
2411 >>> x.is_int()
2412 True
2413 >>> (x + 1).is_int()
2414 True
2415 >>> x = Real('x')
2416 >>> x.is_int()
2417 False
2418 """
2419 return self.kind() == Z3_INT_SORT
2420
2421 def is_bool(self):
2422 return False
2423
2424 def subsort(self, other):
2425 """Return `True` if `self` is a subsort of `other`."""
2426 return self.is_int() and is_arith_sort(other) and other.is_real()
2427
2428 def cast(self, val):
2429 """Try to cast `val` as an Integer or Real.
2430
2431 >>> IntSort().cast(10)
2432 10
2433 >>> is_int(IntSort().cast(10))
2434 True
2435 >>> is_int(10)
2436 False
2437 >>> RealSort().cast(10)
2438 10
2439 >>> is_real(RealSort().cast(10))
2440 True
2441 """
2442 if is_expr(val):
2443 if z3_debug():
2444 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
2445 val_s = val.sort()
2446 if self.eq(val_s):
2447 return val
2448 if val_s.is_int() and self.is_real():
2449 return ToReal(val)
2450 if val_s.is_bool() and self.is_int():
2451 return If(val, 1, 0)
2452 if val_s.is_bool() and self.is_real():
2453 return ToReal(If(val, 1, 0))
2454 if z3_debug():
2455 _z3_assert(False, "Z3 Integer/Real expression expected")
2456 else:
2457 if self.is_int():
2458 return IntVal(val, self.ctxctxctx)
2459 if self.is_real():
2460 return RealVal(val, self.ctxctxctx)
2461 if z3_debug():
2462 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2463 _z3_assert(False, msg % self)
2464
2465
2466def is_arith_sort(s : Any) -> bool:
2467 """Return `True` if s is an arithmetical sort (type).
2468
2469 >>> is_arith_sort(IntSort())
2470 True
2471 >>> is_arith_sort(RealSort())
2472 True
2473 >>> is_arith_sort(BoolSort())
2474 False
2475 >>> n = Int('x') + 1
2476 >>> is_arith_sort(n.sort())
2477 True
2478 """
2479 return isinstance(s, ArithSortRef)
2480
2481
2483 """Integer and Real expressions."""
2484
2485 def sort(self):
2486 """Return the sort (type) of the arithmetical expression `self`.
2487
2488 >>> Int('x').sort()
2489 Int
2490 >>> (Real('x') + 1).sort()
2491 Real
2492 """
2494
2495 def is_int(self):
2496 """Return `True` if `self` is an integer expression.
2497
2498 >>> x = Int('x')
2499 >>> x.is_int()
2500 True
2501 >>> (x + 1).is_int()
2502 True
2503 >>> y = Real('y')
2504 >>> (x + y).is_int()
2505 False
2506 """
2507 return self.sortsort().is_int()
2508
2509 def is_real(self):
2510 """Return `True` if `self` is an real expression.
2511
2512 >>> x = Real('x')
2513 >>> x.is_real()
2514 True
2515 >>> (x + 1).is_real()
2516 True
2517 """
2518 return self.sortsort().is_real()
2519
2520 def __add__(self, other):
2521 """Create the Z3 expression `self + other`.
2522
2523 >>> x = Int('x')
2524 >>> y = Int('y')
2525 >>> x + y
2526 x + y
2527 >>> (x + y).sort()
2528 Int
2529 """
2530 a, b = _coerce_exprs(self, other)
2531 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctxctxctx)
2532
2533 def __radd__(self, other):
2534 """Create the Z3 expression `other + self`.
2535
2536 >>> x = Int('x')
2537 >>> 10 + x
2538 10 + x
2539 """
2540 a, b = _coerce_exprs(self, other)
2541 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctxctxctx)
2542
2543 def __mul__(self, other):
2544 """Create the Z3 expression `self * other`.
2545
2546 >>> x = Real('x')
2547 >>> y = Real('y')
2548 >>> x * y
2549 x*y
2550 >>> (x * y).sort()
2551 Real
2552 """
2553 if isinstance(other, BoolRef):
2554 return If(other, self, 0)
2555 a, b = _coerce_exprs(self, other)
2556 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctxctxctx)
2557
2558 def __rmul__(self, other):
2559 """Create the Z3 expression `other * self`.
2560
2561 >>> x = Real('x')
2562 >>> 10 * x
2563 10*x
2564 """
2565 a, b = _coerce_exprs(self, other)
2566 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctxctxctx)
2567
2568 def __sub__(self, other):
2569 """Create the Z3 expression `self - other`.
2570
2571 >>> x = Int('x')
2572 >>> y = Int('y')
2573 >>> x - y
2574 x - y
2575 >>> (x - y).sort()
2576 Int
2577 """
2578 a, b = _coerce_exprs(self, other)
2579 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctxctxctx)
2580
2581 def __rsub__(self, other):
2582 """Create the Z3 expression `other - self`.
2583
2584 >>> x = Int('x')
2585 >>> 10 - x
2586 10 - x
2587 """
2588 a, b = _coerce_exprs(self, other)
2589 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctxctxctx)
2590
2591 def __pow__(self, other):
2592 """Create the Z3 expression `self**other` (** is the power operator).
2593
2594 >>> x = Real('x')
2595 >>> x**3
2596 x**3
2597 >>> (x**3).sort()
2598 Real
2599 >>> simplify(IntVal(2)**8)
2600 256
2601 """
2602 a, b = _coerce_exprs(self, other)
2603 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2604
2605 def __rpow__(self, other):
2606 """Create the Z3 expression `other**self` (** is the power operator).
2607
2608 >>> x = Real('x')
2609 >>> 2**x
2610 2**x
2611 >>> (2**x).sort()
2612 Real
2613 >>> simplify(2**IntVal(8))
2614 256
2615 """
2616 a, b = _coerce_exprs(self, other)
2617 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2618
2619 def __div__(self, other):
2620 """Create the Z3 expression `other/self`.
2621
2622 >>> x = Int('x')
2623 >>> y = Int('y')
2624 >>> x/y
2625 x/y
2626 >>> (x/y).sort()
2627 Int
2628 >>> (x/y).sexpr()
2629 '(div x y)'
2630 >>> x = Real('x')
2631 >>> y = Real('y')
2632 >>> x/y
2633 x/y
2634 >>> (x/y).sort()
2635 Real
2636 >>> (x/y).sexpr()
2637 '(/ x y)'
2638 """
2639 a, b = _coerce_exprs(self, other)
2640 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2641
2642 def __truediv__(self, other):
2643 """Create the Z3 expression `other/self`."""
2644 return self.__div__(other)
2645
2646 def __rdiv__(self, other):
2647 """Create the Z3 expression `other/self`.
2648
2649 >>> x = Int('x')
2650 >>> 10/x
2651 10/x
2652 >>> (10/x).sexpr()
2653 '(div 10 x)'
2654 >>> x = Real('x')
2655 >>> 10/x
2656 10/x
2657 >>> (10/x).sexpr()
2658 '(/ 10.0 x)'
2659 """
2660 a, b = _coerce_exprs(self, other)
2661 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2662
2663 def __rtruediv__(self, other):
2664 """Create the Z3 expression `other/self`."""
2665 return self.__rdiv__(other)
2666
2667 def __mod__(self, other):
2668 """Create the Z3 expression `other%self`.
2669
2670 >>> x = Int('x')
2671 >>> y = Int('y')
2672 >>> x % y
2673 x%y
2674 >>> simplify(IntVal(10) % IntVal(3))
2675 1
2676 """
2677 a, b = _coerce_exprs(self, other)
2678 if z3_debug():
2679 _z3_assert(a.is_int(), "Z3 integer expression expected")
2680 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2681
2682 def __rmod__(self, other):
2683 """Create the Z3 expression `other%self`.
2684
2685 >>> x = Int('x')
2686 >>> 10 % x
2687 10%x
2688 """
2689 a, b = _coerce_exprs(self, other)
2690 if z3_debug():
2691 _z3_assert(a.is_int(), "Z3 integer expression expected")
2692 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2693
2694 def __neg__(self):
2695 """Return an expression representing `-self`.
2696
2697 >>> x = Int('x')
2698 >>> -x
2699 -x
2700 >>> simplify(-(-x))
2701 x
2702 """
2703 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
2704
2705 def __pos__(self):
2706 """Return `self`.
2707
2708 >>> x = Int('x')
2709 >>> +x
2710 x
2711 """
2712 return self
2713
2714 def __le__(self, other):
2715 """Create the Z3 expression `other <= self`.
2716
2717 >>> x, y = Ints('x y')
2718 >>> x <= y
2719 x <= y
2720 >>> y = Real('y')
2721 >>> x <= y
2722 ToReal(x) <= y
2723 """
2724 a, b = _coerce_exprs(self, other)
2725 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2726
2727 def __lt__(self, other):
2728 """Create the Z3 expression `other < self`.
2729
2730 >>> x, y = Ints('x y')
2731 >>> x < y
2732 x < y
2733 >>> y = Real('y')
2734 >>> x < y
2735 ToReal(x) < y
2736 """
2737 a, b = _coerce_exprs(self, other)
2738 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2739
2740 def __gt__(self, other):
2741 """Create the Z3 expression `other > self`.
2742
2743 >>> x, y = Ints('x y')
2744 >>> x > y
2745 x > y
2746 >>> y = Real('y')
2747 >>> x > y
2748 ToReal(x) > y
2749 """
2750 a, b = _coerce_exprs(self, other)
2751 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2752
2753 def __ge__(self, other):
2754 """Create the Z3 expression `other >= self`.
2755
2756 >>> x, y = Ints('x y')
2757 >>> x >= y
2758 x >= y
2759 >>> y = Real('y')
2760 >>> x >= y
2761 ToReal(x) >= y
2762 """
2763 a, b = _coerce_exprs(self, other)
2764 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2765
2766
2768 """Return `True` if `a` is an arithmetical expression.
2769
2770 >>> x = Int('x')
2771 >>> is_arith(x)
2772 True
2773 >>> is_arith(x + 1)
2774 True
2775 >>> is_arith(1)
2776 False
2777 >>> is_arith(IntVal(1))
2778 True
2779 >>> y = Real('y')
2780 >>> is_arith(y)
2781 True
2782 >>> is_arith(y + 1)
2783 True
2784 """
2785 return isinstance(a, ArithRef)
2786
2787
2788def is_int(a) -> bool:
2789 """Return `True` if `a` is an integer expression.
2790
2791 >>> x = Int('x')
2792 >>> is_int(x + 1)
2793 True
2794 >>> is_int(1)
2795 False
2796 >>> is_int(IntVal(1))
2797 True
2798 >>> y = Real('y')
2799 >>> is_int(y)
2800 False
2801 >>> is_int(y + 1)
2802 False
2803 """
2804 return is_arith(a) and a.is_int()
2805
2806
2807def is_real(a):
2808 """Return `True` if `a` is a real expression.
2809
2810 >>> x = Int('x')
2811 >>> is_real(x + 1)
2812 False
2813 >>> y = Real('y')
2814 >>> is_real(y)
2815 True
2816 >>> is_real(y + 1)
2817 True
2818 >>> is_real(1)
2819 False
2820 >>> is_real(RealVal(1))
2821 True
2822 """
2823 return is_arith(a) and a.is_real()
2824
2825
2826def _is_numeral(ctx, a):
2827 return Z3_is_numeral_ast(ctx.ref(), a)
2828
2829
2830def _is_algebraic(ctx, a):
2831 return Z3_is_algebraic_number(ctx.ref(), a)
2832
2833
2835 """Return `True` if `a` is an integer value of sort Int.
2836
2837 >>> is_int_value(IntVal(1))
2838 True
2839 >>> is_int_value(1)
2840 False
2841 >>> is_int_value(Int('x'))
2842 False
2843 >>> n = Int('x') + 1
2844 >>> n
2845 x + 1
2846 >>> n.arg(1)
2847 1
2848 >>> is_int_value(n.arg(1))
2849 True
2850 >>> is_int_value(RealVal("1/3"))
2851 False
2852 >>> is_int_value(RealVal(1))
2853 False
2854 """
2855 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2856
2857
2859 """Return `True` if `a` is rational value of sort Real.
2860
2861 >>> is_rational_value(RealVal(1))
2862 True
2863 >>> is_rational_value(RealVal("3/5"))
2864 True
2865 >>> is_rational_value(IntVal(1))
2866 False
2867 >>> is_rational_value(1)
2868 False
2869 >>> n = Real('x') + 1
2870 >>> n.arg(1)
2871 1
2872 >>> is_rational_value(n.arg(1))
2873 True
2874 >>> is_rational_value(Real('x'))
2875 False
2876 """
2877 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2878
2879
2881 """Return `True` if `a` is an algebraic value of sort Real.
2882
2883 >>> is_algebraic_value(RealVal("3/5"))
2884 False
2885 >>> n = simplify(Sqrt(2))
2886 >>> n
2887 1.4142135623?
2888 >>> is_algebraic_value(n)
2889 True
2890 """
2891 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2892
2893
2894def is_add(a : Any) -> bool:
2895 """Return `True` if `a` is an expression of the form b + c.
2896
2897 >>> x, y = Ints('x y')
2898 >>> is_add(x + y)
2899 True
2900 >>> is_add(x - y)
2901 False
2902 """
2903 return is_app_of(a, Z3_OP_ADD)
2904
2905
2906def is_mul(a : Any) -> bool:
2907 """Return `True` if `a` is an expression of the form b * c.
2908
2909 >>> x, y = Ints('x y')
2910 >>> is_mul(x * y)
2911 True
2912 >>> is_mul(x - y)
2913 False
2914 """
2915 return is_app_of(a, Z3_OP_MUL)
2916
2917
2918def is_sub(a : Any) -> bool:
2919 """Return `True` if `a` is an expression of the form b - c.
2920
2921 >>> x, y = Ints('x y')
2922 >>> is_sub(x - y)
2923 True
2924 >>> is_sub(x + y)
2925 False
2926 """
2927 return is_app_of(a, Z3_OP_SUB)
2928
2929
2930def is_div(a : Any) -> bool:
2931 """Return `True` if `a` is an expression of the form b / c.
2932
2933 >>> x, y = Reals('x y')
2934 >>> is_div(x / y)
2935 True
2936 >>> is_div(x + y)
2937 False
2938 >>> x, y = Ints('x y')
2939 >>> is_div(x / y)
2940 False
2941 >>> is_idiv(x / y)
2942 True
2943 """
2944 return is_app_of(a, Z3_OP_DIV)
2945
2946
2947def is_idiv(a : Any) -> bool:
2948 """Return `True` if `a` is an expression of the form b div c.
2949
2950 >>> x, y = Ints('x y')
2951 >>> is_idiv(x / y)
2952 True
2953 >>> is_idiv(x + y)
2954 False
2955 """
2956 return is_app_of(a, Z3_OP_IDIV)
2957
2958
2959def is_mod(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_mod(x % y)
2964 True
2965 >>> is_mod(x + y)
2966 False
2967 """
2968 return is_app_of(a, Z3_OP_MOD)
2969
2970
2971def is_le(a : Any) -> bool:
2972 """Return `True` if `a` is an expression of the form b <= c.
2973
2974 >>> x, y = Ints('x y')
2975 >>> is_le(x <= y)
2976 True
2977 >>> is_le(x < y)
2978 False
2979 """
2980 return is_app_of(a, Z3_OP_LE)
2981
2982
2983def is_lt(a : Any) -> bool:
2984 """Return `True` if `a` is an expression of the form b < c.
2985
2986 >>> x, y = Ints('x y')
2987 >>> is_lt(x < y)
2988 True
2989 >>> is_lt(x == y)
2990 False
2991 """
2992 return is_app_of(a, Z3_OP_LT)
2993
2994
2995def is_ge(a : Any) -> bool:
2996 """Return `True` if `a` is an expression of the form b >= c.
2997
2998 >>> x, y = Ints('x y')
2999 >>> is_ge(x >= y)
3000 True
3001 >>> is_ge(x == y)
3002 False
3003 """
3004 return is_app_of(a, Z3_OP_GE)
3005
3006
3007def is_gt(a : Any) -> bool:
3008 """Return `True` if `a` is an expression of the form b > c.
3009
3010 >>> x, y = Ints('x y')
3011 >>> is_gt(x > y)
3012 True
3013 >>> is_gt(x == y)
3014 False
3015 """
3016 return is_app_of(a, Z3_OP_GT)
3017
3018
3019def is_is_int(a : Any) -> bool:
3020 """Return `True` if `a` is an expression of the form IsInt(b).
3021
3022 >>> x = Real('x')
3023 >>> is_is_int(IsInt(x))
3024 True
3025 >>> is_is_int(x)
3026 False
3027 """
3028 return is_app_of(a, Z3_OP_IS_INT)
3029
3030
3031def is_to_real(a : Any) -> bool:
3032 """Return `True` if `a` is an expression of the form ToReal(b).
3033
3034 >>> x = Int('x')
3035 >>> n = ToReal(x)
3036 >>> n
3037 ToReal(x)
3038 >>> is_to_real(n)
3039 True
3040 >>> is_to_real(x)
3041 False
3042 """
3043 return is_app_of(a, Z3_OP_TO_REAL)
3044
3045
3046def is_to_int(a : Any) -> bool:
3047 """Return `True` if `a` is an expression of the form ToInt(b).
3048
3049 >>> x = Real('x')
3050 >>> n = ToInt(x)
3051 >>> n
3052 ToInt(x)
3053 >>> is_to_int(n)
3054 True
3055 >>> is_to_int(x)
3056 False
3057 """
3058 return is_app_of(a, Z3_OP_TO_INT)
3059
3060
3062 """Integer values."""
3063
3064 def as_long(self):
3065 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3066
3067 >>> v = IntVal(1)
3068 >>> v + 1
3069 1 + 1
3070 >>> v.as_long() + 1
3071 2
3072 """
3073 if z3_debug():
3074 _z3_assert(self.is_int(), "Integer value expected")
3075 return int(self.as_string())
3076
3077 def as_string(self):
3078 """Return a Z3 integer numeral as a Python string.
3079 >>> v = IntVal(100)
3080 >>> v.as_string()
3081 '100'
3082 """
3083 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3084
3086 """Return a Z3 integer numeral as a Python binary string.
3087 >>> v = IntVal(10)
3088 >>> v.as_binary_string()
3089 '1010'
3090 """
3092
3093 def py_value(self):
3094 return self.as_long()
3095
3096
3098 """Rational values."""
3099
3100 def numerator(self):
3101 """ Return the numerator of a Z3 rational numeral.
3102
3103 >>> is_rational_value(RealVal("3/5"))
3104 True
3105 >>> n = RealVal("3/5")
3106 >>> n.numerator()
3107 3
3108 >>> is_rational_value(Q(3,5))
3109 True
3110 >>> Q(3,5).numerator()
3111 3
3112 """
3114
3115 def denominator(self):
3116 """ Return the denominator of a Z3 rational numeral.
3117
3118 >>> is_rational_value(Q(3,5))
3119 True
3120 >>> n = Q(3,5)
3121 >>> n.denominator()
3122 5
3123 """
3124 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctxctx)
3125
3127 """ Return the numerator as a Python long.
3128
3129 >>> v = RealVal(10000000000)
3130 >>> v
3131 10000000000
3132 >>> v + 1
3133 10000000000 + 1
3134 >>> v.numerator_as_long() + 1 == 10000000001
3135 True
3136 """
3137 return self.numerator().as_long()
3138
3140 """ Return the denominator as a Python long.
3141
3142 >>> v = RealVal("1/3")
3143 >>> v
3144 1/3
3145 >>> v.denominator_as_long()
3146 3
3147 """
3148 return self.denominator().as_long()
3149
3150 def is_int(self):
3151 return False
3152
3153 def is_real(self):
3154 return True
3155
3156 def is_int_value(self):
3157 return self.denominator().is_int() and self.denominator_as_long() == 1
3158
3159 def as_long(self):
3160 _z3_assert(self.is_int_value(), "Expected integer fraction")
3161 return self.numerator_as_long()
3162
3163 def as_decimal(self, prec):
3164 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3165
3166 >>> v = RealVal("1/5")
3167 >>> v.as_decimal(3)
3168 '0.2'
3169 >>> v = RealVal("1/3")
3170 >>> v.as_decimal(3)
3171 '0.333?'
3172 """
3173 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3174
3175 def as_string(self):
3176 """Return a Z3 rational numeral as a Python string.
3177
3178 >>> v = Q(3,6)
3179 >>> v.as_string()
3180 '1/2'
3181 """
3182 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3183
3184 def as_fraction(self):
3185 """Return a Z3 rational as a Python Fraction object.
3186
3187 >>> v = RealVal("1/5")
3188 >>> v.as_fraction()
3189 Fraction(1, 5)
3190 """
3191 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3192
3193 def py_value(self):
3194 return Z3_get_numeral_double(self.ctx_ref(), self.as_astas_ast())
3195
3196
3198 """Algebraic irrational values."""
3199
3200 def approx(self, precision=10):
3201 """Return a Z3 rational number that approximates the algebraic number `self`.
3202 The result `r` is such that |r - self| <= 1/10^precision
3203
3204 >>> x = simplify(Sqrt(2))
3205 >>> x.approx(20)
3206 6838717160008073720548335/4835703278458516698824704
3207 >>> x.approx(5)
3208 2965821/2097152
3209 """
3211
3212 def as_decimal(self, prec):
3213 """Return a string representation of the algebraic number `self` in decimal notation
3214 using `prec` decimal places.
3215
3216 >>> x = simplify(Sqrt(2))
3217 >>> x.as_decimal(10)
3218 '1.4142135623?'
3219 >>> x.as_decimal(20)
3220 '1.41421356237309504880?'
3221 """
3222 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3223
3224 def poly(self):
3226
3227 def index(self):
3228 return Z3_algebraic_get_i(self.ctx_ref(), self.as_astas_ast())
3229
3230
3231def _py2expr(a, ctx=None):
3232 if isinstance(a, bool):
3233 return BoolVal(a, ctx)
3234 if _is_int(a):
3235 return IntVal(a, ctx)
3236 if isinstance(a, float):
3237 return RealVal(a, ctx)
3238 if isinstance(a, str):
3239 return StringVal(a, ctx)
3240 if is_expr(a):
3241 return a
3242 if z3_debug():
3243 _z3_assert(False, "Python bool, int, long or float expected")
3244
3245
3246def IntSort(ctx=None):
3247 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3248
3249 >>> IntSort()
3250 Int
3251 >>> x = Const('x', IntSort())
3252 >>> is_int(x)
3253 True
3254 >>> x.sort() == IntSort()
3255 True
3256 >>> x.sort() == BoolSort()
3257 False
3258 """
3259 ctx = _get_ctx(ctx)
3260 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3261
3262
3263def RealSort(ctx=None):
3264 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3265
3266 >>> RealSort()
3267 Real
3268 >>> x = Const('x', RealSort())
3269 >>> is_real(x)
3270 True
3271 >>> is_int(x)
3272 False
3273 >>> x.sort() == RealSort()
3274 True
3275 """
3276 ctx = _get_ctx(ctx)
3277 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3278
3279
3281 if isinstance(val, float):
3282 return str(int(val))
3283 elif isinstance(val, bool):
3284 if val:
3285 return "1"
3286 else:
3287 return "0"
3288 else:
3289 return str(val)
3290
3291
3292def IntVal(val, ctx=None):
3293 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3294
3295 >>> IntVal(1)
3296 1
3297 >>> IntVal("100")
3298 100
3299 """
3300 ctx = _get_ctx(ctx)
3301 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3302
3303
3304def RealVal(val, ctx=None):
3305 """Return a Z3 real value.
3306
3307 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3308 If `ctx=None`, then the global context is used.
3309
3310 >>> RealVal(1)
3311 1
3312 >>> RealVal(1).sort()
3313 Real
3314 >>> RealVal("3/5")
3315 3/5
3316 >>> RealVal("1.5")
3317 3/2
3318 """
3319 ctx = _get_ctx(ctx)
3320 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3321
3322
3323def RatVal(a, b, ctx=None):
3324 """Return a Z3 rational a/b.
3325
3326 If `ctx=None`, then the global context is used.
3327
3328 >>> RatVal(3,5)
3329 3/5
3330 >>> RatVal(3,5).sort()
3331 Real
3332 """
3333 if z3_debug():
3334 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3335 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3336 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3337
3338
3339def Q(a, b, ctx=None):
3340 """Return a Z3 rational a/b.
3341
3342 If `ctx=None`, then the global context is used.
3343
3344 >>> Q(3,5)
3345 3/5
3346 >>> Q(3,5).sort()
3347 Real
3348 """
3349 return simplify(RatVal(a, b, ctx=ctx))
3350
3351
3352def Int(name, ctx=None):
3353 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3354
3355 >>> x = Int('x')
3356 >>> is_int(x)
3357 True
3358 >>> is_int(x + 1)
3359 True
3360 """
3361 ctx = _get_ctx(ctx)
3362 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3363
3364
3365def Ints(names, ctx=None):
3366 """Return a tuple of Integer constants.
3367
3368 >>> x, y, z = Ints('x y z')
3369 >>> Sum(x, y, z)
3370 x + y + z
3371 """
3372 ctx = _get_ctx(ctx)
3373 if isinstance(names, str):
3374 names = names.split(" ")
3375 return [Int(name, ctx) for name in names]
3376
3377
3378def IntVector(prefix, sz, ctx=None):
3379 """Return a list of integer constants of size `sz`.
3380
3381 >>> X = IntVector('x', 3)
3382 >>> X
3383 [x__0, x__1, x__2]
3384 >>> Sum(X)
3385 x__0 + x__1 + x__2
3386 """
3387 ctx = _get_ctx(ctx)
3388 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3389
3390
3391def FreshInt(prefix="x", ctx=None):
3392 """Return a fresh integer constant in the given context using the given prefix.
3393
3394 >>> x = FreshInt()
3395 >>> y = FreshInt()
3396 >>> eq(x, y)
3397 False
3398 >>> x.sort()
3399 Int
3400 """
3401 ctx = _get_ctx(ctx)
3402 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3403
3404
3405def Real(name, ctx=None):
3406 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3407
3408 >>> x = Real('x')
3409 >>> is_real(x)
3410 True
3411 >>> is_real(x + 1)
3412 True
3413 """
3414 ctx = _get_ctx(ctx)
3415 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3416
3417
3418def Reals(names, ctx=None):
3419 """Return a tuple of real constants.
3420
3421 >>> x, y, z = Reals('x y z')
3422 >>> Sum(x, y, z)
3423 x + y + z
3424 >>> Sum(x, y, z).sort()
3425 Real
3426 """
3427 ctx = _get_ctx(ctx)
3428 if isinstance(names, str):
3429 names = names.split(" ")
3430 return [Real(name, ctx) for name in names]
3431
3432
3433def RealVector(prefix, sz, ctx=None):
3434 """Return a list of real constants of size `sz`.
3435
3436 >>> X = RealVector('x', 3)
3437 >>> X
3438 [x__0, x__1, x__2]
3439 >>> Sum(X)
3440 x__0 + x__1 + x__2
3441 >>> Sum(X).sort()
3442 Real
3443 """
3444 ctx = _get_ctx(ctx)
3445 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3446
3447
3448def FreshReal(prefix="b", ctx=None):
3449 """Return a fresh real constant in the given context using the given prefix.
3450
3451 >>> x = FreshReal()
3452 >>> y = FreshReal()
3453 >>> eq(x, y)
3454 False
3455 >>> x.sort()
3456 Real
3457 """
3458 ctx = _get_ctx(ctx)
3459 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3460
3461
3462def ToReal(a):
3463 """ Return the Z3 expression ToReal(a).
3464
3465 >>> x = Int('x')
3466 >>> x.sort()
3467 Int
3468 >>> n = ToReal(x)
3469 >>> n
3470 ToReal(x)
3471 >>> n.sort()
3472 Real
3473 """
3474 ctx = a.ctx
3475 if isinstance(a, BoolRef):
3476 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3477 if z3_debug():
3478 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3479 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3480
3481
3482def ToInt(a):
3483 """ Return the Z3 expression ToInt(a).
3484
3485 >>> x = Real('x')
3486 >>> x.sort()
3487 Real
3488 >>> n = ToInt(x)
3489 >>> n
3490 ToInt(x)
3491 >>> n.sort()
3492 Int
3493 """
3494 if z3_debug():
3495 _z3_assert(a.is_real(), "Z3 real expression expected.")
3496 ctx = a.ctx
3497 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3498
3499
3500def IsInt(a):
3501 """ Return the Z3 predicate IsInt(a).
3502
3503 >>> x = Real('x')
3504 >>> IsInt(x + "1/2")
3505 IsInt(x + 1/2)
3506 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3507 [x = 1/2]
3508 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3509 no solution
3510 """
3511 if z3_debug():
3512 _z3_assert(a.is_real(), "Z3 real expression expected.")
3513 ctx = a.ctx
3514 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3515
3516
3517def Sqrt(a, ctx=None):
3518 """ Return a Z3 expression which represents the square root of a.
3519
3520 >>> x = Real('x')
3521 >>> Sqrt(x)
3522 x**(1/2)
3523 """
3524 if not is_expr(a):
3525 ctx = _get_ctx(ctx)
3526 a = RealVal(a, ctx)
3527 return a ** "1/2"
3528
3529
3530def Cbrt(a, ctx=None):
3531 """ Return a Z3 expression which represents the cubic root of a.
3532
3533 >>> x = Real('x')
3534 >>> Cbrt(x)
3535 x**(1/3)
3536 """
3537 if not is_expr(a):
3538 ctx = _get_ctx(ctx)
3539 a = RealVal(a, ctx)
3540 return a ** "1/3"
3541
3542
3547
3548
3550 """Bit-vector sort."""
3551
3552 def size(self):
3553 """Return the size (number of bits) of the bit-vector sort `self`.
3554
3555 >>> b = BitVecSort(32)
3556 >>> b.size()
3557 32
3558 """
3559 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.astastast))
3560
3561 def subsort(self, other):
3562 return is_bv_sort(other) and self.size() < other.size()
3563
3564 def cast(self, val):
3565 """Try to cast `val` as a Bit-Vector.
3566
3567 >>> b = BitVecSort(32)
3568 >>> b.cast(10)
3569 10
3570 >>> b.cast(10).sexpr()
3571 '#x0000000a'
3572 """
3573 if is_expr(val):
3574 if z3_debug():
3575 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
3576 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3577 return val
3578 else:
3579 return BitVecVal(val, self)
3580
3581
3583 """Return True if `s` is a Z3 bit-vector sort.
3584
3585 >>> is_bv_sort(BitVecSort(32))
3586 True
3587 >>> is_bv_sort(IntSort())
3588 False
3589 """
3590 return isinstance(s, BitVecSortRef)
3591
3592
3594 """Bit-vector expressions."""
3595
3596 def sort(self):
3597 """Return the sort of the bit-vector expression `self`.
3598
3599 >>> x = BitVec('x', 32)
3600 >>> x.sort()
3601 BitVec(32)
3602 >>> x.sort() == BitVecSort(32)
3603 True
3604 """
3606
3607 def size(self):
3608 """Return the number of bits of the bit-vector expression `self`.
3609
3610 >>> x = BitVec('x', 32)
3611 >>> (x + 1).size()
3612 32
3613 >>> Concat(x, x).size()
3614 64
3615 """
3616 return self.sortsort().size()
3617
3618 def __add__(self, other):
3619 """Create the Z3 expression `self + other`.
3620
3621 >>> x = BitVec('x', 32)
3622 >>> y = BitVec('y', 32)
3623 >>> x + y
3624 x + y
3625 >>> (x + y).sort()
3626 BitVec(32)
3627 """
3628 a, b = _coerce_exprs(self, other)
3629 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3630
3631 def __radd__(self, other):
3632 """Create the Z3 expression `other + self`.
3633
3634 >>> x = BitVec('x', 32)
3635 >>> 10 + x
3636 10 + x
3637 """
3638 a, b = _coerce_exprs(self, other)
3639 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3640
3641 def __mul__(self, other):
3642 """Create the Z3 expression `self * other`.
3643
3644 >>> x = BitVec('x', 32)
3645 >>> y = BitVec('y', 32)
3646 >>> x * y
3647 x*y
3648 >>> (x * y).sort()
3649 BitVec(32)
3650 """
3651 a, b = _coerce_exprs(self, other)
3652 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3653
3654 def __rmul__(self, other):
3655 """Create the Z3 expression `other * self`.
3656
3657 >>> x = BitVec('x', 32)
3658 >>> 10 * x
3659 10*x
3660 """
3661 a, b = _coerce_exprs(self, other)
3662 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3663
3664 def __sub__(self, other):
3665 """Create the Z3 expression `self - other`.
3666
3667 >>> x = BitVec('x', 32)
3668 >>> y = BitVec('y', 32)
3669 >>> x - y
3670 x - y
3671 >>> (x - y).sort()
3672 BitVec(32)
3673 """
3674 a, b = _coerce_exprs(self, other)
3675 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3676
3677 def __rsub__(self, other):
3678 """Create the Z3 expression `other - self`.
3679
3680 >>> x = BitVec('x', 32)
3681 >>> 10 - x
3682 10 - x
3683 """
3684 a, b = _coerce_exprs(self, other)
3685 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3686
3687 def __or__(self, other):
3688 """Create the Z3 expression bitwise-or `self | other`.
3689
3690 >>> x = BitVec('x', 32)
3691 >>> y = BitVec('y', 32)
3692 >>> x | y
3693 x | y
3694 >>> (x | y).sort()
3695 BitVec(32)
3696 """
3697 a, b = _coerce_exprs(self, other)
3698 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3699
3700 def __ror__(self, other):
3701 """Create the Z3 expression bitwise-or `other | self`.
3702
3703 >>> x = BitVec('x', 32)
3704 >>> 10 | x
3705 10 | x
3706 """
3707 a, b = _coerce_exprs(self, other)
3708 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3709
3710 def __and__(self, other):
3711 """Create the Z3 expression bitwise-and `self & other`.
3712
3713 >>> x = BitVec('x', 32)
3714 >>> y = BitVec('y', 32)
3715 >>> x & y
3716 x & y
3717 >>> (x & y).sort()
3718 BitVec(32)
3719 """
3720 a, b = _coerce_exprs(self, other)
3721 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3722
3723 def __rand__(self, other):
3724 """Create the Z3 expression bitwise-or `other & self`.
3725
3726 >>> x = BitVec('x', 32)
3727 >>> 10 & x
3728 10 & x
3729 """
3730 a, b = _coerce_exprs(self, other)
3731 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3732
3733 def __xor__(self, other):
3734 """Create the Z3 expression bitwise-xor `self ^ other`.
3735
3736 >>> x = BitVec('x', 32)
3737 >>> y = BitVec('y', 32)
3738 >>> x ^ y
3739 x ^ y
3740 >>> (x ^ y).sort()
3741 BitVec(32)
3742 """
3743 a, b = _coerce_exprs(self, other)
3744 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3745
3746 def __rxor__(self, other):
3747 """Create the Z3 expression bitwise-xor `other ^ self`.
3748
3749 >>> x = BitVec('x', 32)
3750 >>> 10 ^ x
3751 10 ^ x
3752 """
3753 a, b = _coerce_exprs(self, other)
3754 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3755
3756 def __pos__(self):
3757 """Return `self`.
3758
3759 >>> x = BitVec('x', 32)
3760 >>> +x
3761 x
3762 """
3763 return self
3764
3765 def __neg__(self):
3766 """Return an expression representing `-self`.
3767
3768 >>> x = BitVec('x', 32)
3769 >>> -x
3770 -x
3771 >>> simplify(-(-x))
3772 x
3773 """
3774 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3775
3776 def __invert__(self):
3777 """Create the Z3 expression bitwise-not `~self`.
3778
3779 >>> x = BitVec('x', 32)
3780 >>> ~x
3781 ~x
3782 >>> simplify(~(~x))
3783 x
3784 """
3785 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3786
3787 def __div__(self, other):
3788 """Create the Z3 expression (signed) division `self / other`.
3789
3790 Use the function UDiv() for unsigned division.
3791
3792 >>> x = BitVec('x', 32)
3793 >>> y = BitVec('y', 32)
3794 >>> x / y
3795 x/y
3796 >>> (x / y).sort()
3797 BitVec(32)
3798 >>> (x / y).sexpr()
3799 '(bvsdiv x y)'
3800 >>> UDiv(x, y).sexpr()
3801 '(bvudiv x y)'
3802 """
3803 a, b = _coerce_exprs(self, other)
3804 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3805
3806 def __truediv__(self, other):
3807 """Create the Z3 expression (signed) division `self / other`."""
3808 return self.__div__(other)
3809
3810 def __rdiv__(self, other):
3811 """Create the Z3 expression (signed) division `other / self`.
3812
3813 Use the function UDiv() for unsigned division.
3814
3815 >>> x = BitVec('x', 32)
3816 >>> 10 / x
3817 10/x
3818 >>> (10 / x).sexpr()
3819 '(bvsdiv #x0000000a x)'
3820 >>> UDiv(10, x).sexpr()
3821 '(bvudiv #x0000000a x)'
3822 """
3823 a, b = _coerce_exprs(self, other)
3824 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3825
3826 def __rtruediv__(self, other):
3827 """Create the Z3 expression (signed) division `other / self`."""
3828 return self.__rdiv__(other)
3829
3830 def __mod__(self, other):
3831 """Create the Z3 expression (signed) mod `self % other`.
3832
3833 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3834
3835 >>> x = BitVec('x', 32)
3836 >>> y = BitVec('y', 32)
3837 >>> x % y
3838 x%y
3839 >>> (x % y).sort()
3840 BitVec(32)
3841 >>> (x % y).sexpr()
3842 '(bvsmod x y)'
3843 >>> URem(x, y).sexpr()
3844 '(bvurem x y)'
3845 >>> SRem(x, y).sexpr()
3846 '(bvsrem x y)'
3847 """
3848 a, b = _coerce_exprs(self, other)
3849 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3850
3851 def __rmod__(self, other):
3852 """Create the Z3 expression (signed) mod `other % self`.
3853
3854 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3855
3856 >>> x = BitVec('x', 32)
3857 >>> 10 % x
3858 10%x
3859 >>> (10 % x).sexpr()
3860 '(bvsmod #x0000000a x)'
3861 >>> URem(10, x).sexpr()
3862 '(bvurem #x0000000a x)'
3863 >>> SRem(10, x).sexpr()
3864 '(bvsrem #x0000000a x)'
3865 """
3866 a, b = _coerce_exprs(self, other)
3867 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3868
3869 def __le__(self, other):
3870 """Create the Z3 expression (signed) `other <= self`.
3871
3872 Use the function ULE() for unsigned less than or equal to.
3873
3874 >>> x, y = BitVecs('x y', 32)
3875 >>> x <= y
3876 x <= y
3877 >>> (x <= y).sexpr()
3878 '(bvsle x y)'
3879 >>> ULE(x, y).sexpr()
3880 '(bvule x y)'
3881 """
3882 a, b = _coerce_exprs(self, other)
3883 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3884
3885 def __lt__(self, other):
3886 """Create the Z3 expression (signed) `other < self`.
3887
3888 Use the function ULT() for unsigned less than.
3889
3890 >>> x, y = BitVecs('x y', 32)
3891 >>> x < y
3892 x < y
3893 >>> (x < y).sexpr()
3894 '(bvslt x y)'
3895 >>> ULT(x, y).sexpr()
3896 '(bvult x y)'
3897 """
3898 a, b = _coerce_exprs(self, other)
3899 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3900
3901 def __gt__(self, other):
3902 """Create the Z3 expression (signed) `other > self`.
3903
3904 Use the function UGT() for unsigned greater than.
3905
3906 >>> x, y = BitVecs('x y', 32)
3907 >>> x > y
3908 x > y
3909 >>> (x > y).sexpr()
3910 '(bvsgt x y)'
3911 >>> UGT(x, y).sexpr()
3912 '(bvugt x y)'
3913 """
3914 a, b = _coerce_exprs(self, other)
3915 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3916
3917 def __ge__(self, other):
3918 """Create the Z3 expression (signed) `other >= self`.
3919
3920 Use the function UGE() for unsigned greater than or equal to.
3921
3922 >>> x, y = BitVecs('x y', 32)
3923 >>> x >= y
3924 x >= y
3925 >>> (x >= y).sexpr()
3926 '(bvsge x y)'
3927 >>> UGE(x, y).sexpr()
3928 '(bvuge x y)'
3929 """
3930 a, b = _coerce_exprs(self, other)
3931 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3932
3933 def __rshift__(self, other):
3934 """Create the Z3 expression (arithmetical) right shift `self >> other`
3935
3936 Use the function LShR() for the right logical shift
3937
3938 >>> x, y = BitVecs('x y', 32)
3939 >>> x >> y
3940 x >> y
3941 >>> (x >> y).sexpr()
3942 '(bvashr x y)'
3943 >>> LShR(x, y).sexpr()
3944 '(bvlshr x y)'
3945 >>> BitVecVal(4, 3)
3946 4
3947 >>> BitVecVal(4, 3).as_signed_long()
3948 -4
3949 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3950 -2
3951 >>> simplify(BitVecVal(4, 3) >> 1)
3952 6
3953 >>> simplify(LShR(BitVecVal(4, 3), 1))
3954 2
3955 >>> simplify(BitVecVal(2, 3) >> 1)
3956 1
3957 >>> simplify(LShR(BitVecVal(2, 3), 1))
3958 1
3959 """
3960 a, b = _coerce_exprs(self, other)
3961 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3962
3963 def __lshift__(self, other):
3964 """Create the Z3 expression left shift `self << other`
3965
3966 >>> x, y = BitVecs('x y', 32)
3967 >>> x << y
3968 x << y
3969 >>> (x << y).sexpr()
3970 '(bvshl x y)'
3971 >>> simplify(BitVecVal(2, 3) << 1)
3972 4
3973 """
3974 a, b = _coerce_exprs(self, other)
3975 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3976
3977 def __rrshift__(self, other):
3978 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
3979
3980 Use the function LShR() for the right logical shift
3981
3982 >>> x = BitVec('x', 32)
3983 >>> 10 >> x
3984 10 >> x
3985 >>> (10 >> x).sexpr()
3986 '(bvashr #x0000000a x)'
3987 """
3988 a, b = _coerce_exprs(self, other)
3989 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3990
3991 def __rlshift__(self, other):
3992 """Create the Z3 expression left shift `other << self`.
3993
3994 Use the function LShR() for the right logical shift
3995
3996 >>> x = BitVec('x', 32)
3997 >>> 10 << x
3998 10 << x
3999 >>> (10 << x).sexpr()
4000 '(bvshl #x0000000a x)'
4001 """
4002 a, b = _coerce_exprs(self, other)
4003 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
4004
4005
4007 """Bit-vector values."""
4008
4009 def as_long(self):
4010 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4011
4012 >>> v = BitVecVal(0xbadc0de, 32)
4013 >>> v
4014 195936478
4015 >>> print("0x%.8x" % v.as_long())
4016 0x0badc0de
4017 """
4018 return int(self.as_string())
4019
4021 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4022 The most significant bit is assumed to be the sign.
4023
4024 >>> BitVecVal(4, 3).as_signed_long()
4025 -4
4026 >>> BitVecVal(7, 3).as_signed_long()
4027 -1
4028 >>> BitVecVal(3, 3).as_signed_long()
4029 3
4030 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4031 -1
4032 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4033 -1
4034 """
4035 sz = self.size()
4036 val = self.as_long()
4037 if val >= 2**(sz - 1):
4038 val = val - 2**sz
4039 if val < -2**(sz - 1):
4040 val = val + 2**sz
4041 return int(val)
4042
4043 def as_string(self):
4044 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
4045
4048
4049 def py_value(self):
4050 """Return the Python value of a Z3 bit-vector numeral."""
4051 return self.as_long()
4052
4053
4054
4055def is_bv(a):
4056 """Return `True` if `a` is a Z3 bit-vector expression.
4057
4058 >>> b = BitVec('b', 32)
4059 >>> is_bv(b)
4060 True
4061 >>> is_bv(b + 10)
4062 True
4063 >>> is_bv(Int('x'))
4064 False
4065 """
4066 return isinstance(a, BitVecRef)
4067
4068
4070 """Return `True` if `a` is a Z3 bit-vector numeral value.
4071
4072 >>> b = BitVec('b', 32)
4073 >>> is_bv_value(b)
4074 False
4075 >>> b = BitVecVal(10, 32)
4076 >>> b
4077 10
4078 >>> is_bv_value(b)
4079 True
4080 """
4081 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4082
4083
4084def BV2Int(a, is_signed=False):
4085 """Return the Z3 expression BV2Int(a).
4086
4087 >>> b = BitVec('b', 3)
4088 >>> BV2Int(b).sort()
4089 Int
4090 >>> x = Int('x')
4091 >>> x > BV2Int(b)
4092 x > BV2Int(b)
4093 >>> x > BV2Int(b, is_signed=False)
4094 x > BV2Int(b)
4095 >>> x > BV2Int(b, is_signed=True)
4096 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4097 >>> solve(x > BV2Int(b), b == 1, x < 3)
4098 [x = 2, b = 1]
4099 """
4100 if z3_debug():
4101 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4102 ctx = a.ctx
4103 # investigate problem with bv2int
4104 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4105
4106
4107def Int2BV(a, num_bits):
4108 """Return the z3 expression Int2BV(a, num_bits).
4109 It is a bit-vector of width num_bits and represents the
4110 modulo of a by 2^num_bits
4111 """
4112 ctx = a.ctx
4113 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4114
4115
4116def BitVecSort(sz, ctx=None):
4117 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4118
4119 >>> Byte = BitVecSort(8)
4120 >>> Word = BitVecSort(16)
4121 >>> Byte
4122 BitVec(8)
4123 >>> x = Const('x', Byte)
4124 >>> eq(x, BitVec('x', 8))
4125 True
4126 """
4127 ctx = _get_ctx(ctx)
4128 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4129
4130
4131def BitVecVal(val, bv, ctx=None):
4132 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4133
4134 >>> v = BitVecVal(10, 32)
4135 >>> v
4136 10
4137 >>> print("0x%.8x" % v.as_long())
4138 0x0000000a
4139 """
4140 if is_bv_sort(bv):
4141 ctx = bv.ctx
4142 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4143 else:
4144 ctx = _get_ctx(ctx)
4145 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4146
4147
4148def BitVec(name, bv, ctx=None):
4149 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4150 If `ctx=None`, then the global context is used.
4151
4152 >>> x = BitVec('x', 16)
4153 >>> is_bv(x)
4154 True
4155 >>> x.size()
4156 16
4157 >>> x.sort()
4158 BitVec(16)
4159 >>> word = BitVecSort(16)
4160 >>> x2 = BitVec('x', word)
4161 >>> eq(x, x2)
4162 True
4163 """
4164 if isinstance(bv, BitVecSortRef):
4165 ctx = bv.ctx
4166 else:
4167 ctx = _get_ctx(ctx)
4168 bv = BitVecSort(bv, ctx)
4169 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4170
4171
4172def BitVecs(names, bv, ctx=None):
4173 """Return a tuple of bit-vector constants of size bv.
4174
4175 >>> x, y, z = BitVecs('x y z', 16)
4176 >>> x.size()
4177 16
4178 >>> x.sort()
4179 BitVec(16)
4180 >>> Sum(x, y, z)
4181 0 + x + y + z
4182 >>> Product(x, y, z)
4183 1*x*y*z
4184 >>> simplify(Product(x, y, z))
4185 x*y*z
4186 """
4187 ctx = _get_ctx(ctx)
4188 if isinstance(names, str):
4189 names = names.split(" ")
4190 return [BitVec(name, bv, ctx) for name in names]
4191
4192
4193def Concat(*args):
4194 """Create a Z3 bit-vector concatenation expression.
4195
4196 >>> v = BitVecVal(1, 4)
4197 >>> Concat(v, v+1, v)
4198 Concat(Concat(1, 1 + 1), 1)
4199 >>> simplify(Concat(v, v+1, v))
4200 289
4201 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4202 121
4203 """
4204 args = _get_args(args)
4205 sz = len(args)
4206 if z3_debug():
4207 _z3_assert(sz >= 2, "At least two arguments expected.")
4208
4209 ctx = None
4210 for a in args:
4211 if is_expr(a):
4212 ctx = a.ctx
4213 break
4214 if is_seq(args[0]) or isinstance(args[0], str):
4215 args = [_coerce_seq(s, ctx) for s in args]
4216 if z3_debug():
4217 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4218 v = (Ast * sz)()
4219 for i in range(sz):
4220 v[i] = args[i].as_ast()
4221 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4222
4223 if is_re(args[0]):
4224 if z3_debug():
4225 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4226 v = (Ast * sz)()
4227 for i in range(sz):
4228 v[i] = args[i].as_ast()
4229 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4230
4231 if z3_debug():
4232 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4233 r = args[0]
4234 for i in range(sz - 1):
4235 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4236 return r
4237
4238
4239def Extract(high, low, a):
4240 """Create a Z3 bit-vector extraction expression or sequence extraction expression.
4241
4242 Extract is overloaded to work with both bit-vectors and sequences:
4243
4244 **Bit-vector extraction**: Extract(high, low, bitvector)
4245 Extracts bits from position `high` down to position `low` (both inclusive).
4246 - high: int - the highest bit position to extract (0-indexed from right)
4247 - low: int - the lowest bit position to extract (0-indexed from right)
4248 - bitvector: BitVecRef - the bit-vector to extract from
4249 Returns a new bit-vector containing bits [high:low]
4250
4251 **Sequence extraction**: Extract(sequence, offset, length)
4252 Extracts a subsequence starting at the given offset with the specified length.
4253 The functions SubString and SubSeq are redirected to this form of Extract.
4254 - sequence: SeqRef or str - the sequence to extract from
4255 - offset: int - the starting position (0-indexed)
4256 - length: int - the number of elements to extract
4257 Returns a new sequence containing the extracted subsequence
4258
4259 >>> # Bit-vector extraction examples
4260 >>> x = BitVec('x', 8)
4261 >>> Extract(6, 2, x) # Extract bits 6 down to 2 (5 bits total)
4262 Extract(6, 2, x)
4263 >>> Extract(6, 2, x).sort() # Result is a 5-bit vector
4264 BitVec(5)
4265 >>> Extract(7, 0, x) # Extract all 8 bits
4266 Extract(7, 0, x)
4267 >>> Extract(3, 3, x) # Extract single bit at position 3
4268 Extract(3, 3, x)
4269
4270 >>> # Sequence extraction examples
4271 >>> s = StringVal("hello")
4272 >>> Extract(s, 1, 3) # Extract 3 characters starting at position 1
4273 str.substr("hello", 1, 3)
4274 >>> simplify(Extract(StringVal("abcd"), 2, 1)) # Extract 1 character at position 2
4275 "c"
4276 >>> simplify(Extract(StringVal("abcd"), 0, 2)) # Extract first 2 characters
4277 "ab"
4278 """
4279 if isinstance(high, str):
4280 high = StringVal(high)
4281 if is_seq(high):
4282 s = high
4283 offset, length = _coerce_exprs(low, a, s.ctx)
4284 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4285 if z3_debug():
4286 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4287 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4288 "First and second arguments must be non negative integers")
4289 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4290 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4291
4292
4294 if z3_debug():
4295 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4296
4297
4298def ULE(a, b):
4299 """Create the Z3 expression (unsigned) `other <= self`.
4300
4301 Use the operator <= for signed less than or equal to.
4302
4303 >>> x, y = BitVecs('x y', 32)
4304 >>> ULE(x, y)
4305 ULE(x, y)
4306 >>> (x <= y).sexpr()
4307 '(bvsle x y)'
4308 >>> ULE(x, y).sexpr()
4309 '(bvule x y)'
4310 """
4311 _check_bv_args(a, b)
4312 a, b = _coerce_exprs(a, b)
4313 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4314
4315
4316def ULT(a, b):
4317 """Create the Z3 expression (unsigned) `other < self`.
4318
4319 Use the operator < for signed less than.
4320
4321 >>> x, y = BitVecs('x y', 32)
4322 >>> ULT(x, y)
4323 ULT(x, y)
4324 >>> (x < y).sexpr()
4325 '(bvslt x y)'
4326 >>> ULT(x, y).sexpr()
4327 '(bvult x y)'
4328 """
4329 _check_bv_args(a, b)
4330 a, b = _coerce_exprs(a, b)
4331 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4332
4333
4334def UGE(a, b):
4335 """Create the Z3 expression (unsigned) `other >= self`.
4336
4337 Use the operator >= for signed greater than or equal to.
4338
4339 >>> x, y = BitVecs('x y', 32)
4340 >>> UGE(x, y)
4341 UGE(x, y)
4342 >>> (x >= y).sexpr()
4343 '(bvsge x y)'
4344 >>> UGE(x, y).sexpr()
4345 '(bvuge x y)'
4346 """
4347 _check_bv_args(a, b)
4348 a, b = _coerce_exprs(a, b)
4349 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4350
4351
4352def UGT(a, b):
4353 """Create the Z3 expression (unsigned) `other > self`.
4354
4355 Use the operator > for signed greater than.
4356
4357 >>> x, y = BitVecs('x y', 32)
4358 >>> UGT(x, y)
4359 UGT(x, y)
4360 >>> (x > y).sexpr()
4361 '(bvsgt x y)'
4362 >>> UGT(x, y).sexpr()
4363 '(bvugt x y)'
4364 """
4365 _check_bv_args(a, b)
4366 a, b = _coerce_exprs(a, b)
4367 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4368
4369
4370def UDiv(a, b):
4371 """Create the Z3 expression (unsigned) division `self / other`.
4372
4373 Use the operator / for signed division.
4374
4375 >>> x = BitVec('x', 32)
4376 >>> y = BitVec('y', 32)
4377 >>> UDiv(x, y)
4378 UDiv(x, y)
4379 >>> UDiv(x, y).sort()
4380 BitVec(32)
4381 >>> (x / y).sexpr()
4382 '(bvsdiv x y)'
4383 >>> UDiv(x, y).sexpr()
4384 '(bvudiv x y)'
4385 """
4386 _check_bv_args(a, b)
4387 a, b = _coerce_exprs(a, b)
4388 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4389
4390
4391def URem(a, b):
4392 """Create the Z3 expression (unsigned) remainder `self % other`.
4393
4394 Use the operator % for signed modulus, and SRem() for signed remainder.
4395
4396 >>> x = BitVec('x', 32)
4397 >>> y = BitVec('y', 32)
4398 >>> URem(x, y)
4399 URem(x, y)
4400 >>> URem(x, y).sort()
4401 BitVec(32)
4402 >>> (x % y).sexpr()
4403 '(bvsmod x y)'
4404 >>> URem(x, y).sexpr()
4405 '(bvurem x y)'
4406 """
4407 _check_bv_args(a, b)
4408 a, b = _coerce_exprs(a, b)
4409 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4410
4411
4412def SRem(a, b):
4413 """Create the Z3 expression signed remainder.
4414
4415 Use the operator % for signed modulus, and URem() for unsigned remainder.
4416
4417 >>> x = BitVec('x', 32)
4418 >>> y = BitVec('y', 32)
4419 >>> SRem(x, y)
4420 SRem(x, y)
4421 >>> SRem(x, y).sort()
4422 BitVec(32)
4423 >>> (x % y).sexpr()
4424 '(bvsmod x y)'
4425 >>> SRem(x, y).sexpr()
4426 '(bvsrem x y)'
4427 """
4428 _check_bv_args(a, b)
4429 a, b = _coerce_exprs(a, b)
4430 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4431
4432
4433def LShR(a, b):
4434 """Create the Z3 expression logical right shift.
4435
4436 Use the operator >> for the arithmetical right shift.
4437
4438 >>> x, y = BitVecs('x y', 32)
4439 >>> LShR(x, y)
4440 LShR(x, y)
4441 >>> (x >> y).sexpr()
4442 '(bvashr x y)'
4443 >>> LShR(x, y).sexpr()
4444 '(bvlshr x y)'
4445 >>> BitVecVal(4, 3)
4446 4
4447 >>> BitVecVal(4, 3).as_signed_long()
4448 -4
4449 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4450 -2
4451 >>> simplify(BitVecVal(4, 3) >> 1)
4452 6
4453 >>> simplify(LShR(BitVecVal(4, 3), 1))
4454 2
4455 >>> simplify(BitVecVal(2, 3) >> 1)
4456 1
4457 >>> simplify(LShR(BitVecVal(2, 3), 1))
4458 1
4459 """
4460 _check_bv_args(a, b)
4461 a, b = _coerce_exprs(a, b)
4462 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4463
4464
4465def RotateLeft(a, b):
4466 """Return an expression representing `a` rotated to the left `b` times.
4467
4468 >>> a, b = BitVecs('a b', 16)
4469 >>> RotateLeft(a, b)
4470 RotateLeft(a, b)
4471 >>> simplify(RotateLeft(a, 0))
4472 a
4473 >>> simplify(RotateLeft(a, 16))
4474 a
4475 """
4476 _check_bv_args(a, b)
4477 a, b = _coerce_exprs(a, b)
4478 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4479
4480
4481def RotateRight(a, b):
4482 """Return an expression representing `a` rotated to the right `b` times.
4483
4484 >>> a, b = BitVecs('a b', 16)
4485 >>> RotateRight(a, b)
4486 RotateRight(a, b)
4487 >>> simplify(RotateRight(a, 0))
4488 a
4489 >>> simplify(RotateRight(a, 16))
4490 a
4491 """
4492 _check_bv_args(a, b)
4493 a, b = _coerce_exprs(a, b)
4494 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4495
4496
4497def SignExt(n, a):
4498 """Return a bit-vector expression with `n` extra sign-bits.
4499
4500 >>> x = BitVec('x', 16)
4501 >>> n = SignExt(8, x)
4502 >>> n.size()
4503 24
4504 >>> n
4505 SignExt(8, x)
4506 >>> n.sort()
4507 BitVec(24)
4508 >>> v0 = BitVecVal(2, 2)
4509 >>> v0
4510 2
4511 >>> v0.size()
4512 2
4513 >>> v = simplify(SignExt(6, v0))
4514 >>> v
4515 254
4516 >>> v.size()
4517 8
4518 >>> print("%.x" % v.as_long())
4519 fe
4520 """
4521 if z3_debug():
4522 _z3_assert(_is_int(n), "First argument must be an integer")
4523 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4524 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4525
4526
4527def ZeroExt(n, a):
4528 """Return a bit-vector expression with `n` extra zero-bits.
4529
4530 >>> x = BitVec('x', 16)
4531 >>> n = ZeroExt(8, x)
4532 >>> n.size()
4533 24
4534 >>> n
4535 ZeroExt(8, x)
4536 >>> n.sort()
4537 BitVec(24)
4538 >>> v0 = BitVecVal(2, 2)
4539 >>> v0
4540 2
4541 >>> v0.size()
4542 2
4543 >>> v = simplify(ZeroExt(6, v0))
4544 >>> v
4545 2
4546 >>> v.size()
4547 8
4548 """
4549 if z3_debug():
4550 _z3_assert(_is_int(n), "First argument must be an integer")
4551 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4552 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4553
4554
4556 """Return an expression representing `n` copies of `a`.
4557
4558 >>> x = BitVec('x', 8)
4559 >>> n = RepeatBitVec(4, x)
4560 >>> n
4561 RepeatBitVec(4, x)
4562 >>> n.size()
4563 32
4564 >>> v0 = BitVecVal(10, 4)
4565 >>> print("%.x" % v0.as_long())
4566 a
4567 >>> v = simplify(RepeatBitVec(4, v0))
4568 >>> v.size()
4569 16
4570 >>> print("%.x" % v.as_long())
4571 aaaa
4572 """
4573 if z3_debug():
4574 _z3_assert(_is_int(n), "First argument must be an integer")
4575 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4576 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4577
4578
4580 """Return the reduction-and expression of `a`."""
4581 if z3_debug():
4582 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4583 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4584
4585
4586def BVRedOr(a):
4587 """Return the reduction-or expression of `a`."""
4588 if z3_debug():
4589 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4590 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4591
4592
4593def BVAddNoOverflow(a, b, signed):
4594 """A predicate the determines that bit-vector addition does not overflow"""
4595 _check_bv_args(a, b)
4596 a, b = _coerce_exprs(a, b)
4597 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4598
4599
4601 """A predicate the determines that signed bit-vector addition does not underflow"""
4602 _check_bv_args(a, b)
4603 a, b = _coerce_exprs(a, b)
4604 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4605
4606
4608 """A predicate the determines that bit-vector subtraction does not overflow"""
4609 _check_bv_args(a, b)
4610 a, b = _coerce_exprs(a, b)
4611 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4612
4613
4614def BVSubNoUnderflow(a, b, signed):
4615 """A predicate the determines that bit-vector subtraction does not underflow"""
4616 _check_bv_args(a, b)
4617 a, b = _coerce_exprs(a, b)
4618 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4619
4620
4622 """A predicate the determines that bit-vector signed division does not overflow"""
4623 _check_bv_args(a, b)
4624 a, b = _coerce_exprs(a, b)
4625 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4626
4627
4629 """A predicate the determines that bit-vector unary negation does not overflow"""
4630 if z3_debug():
4631 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4632 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4633
4634
4635def BVMulNoOverflow(a, b, signed):
4636 """A predicate the determines that bit-vector multiplication does not overflow"""
4637 _check_bv_args(a, b)
4638 a, b = _coerce_exprs(a, b)
4639 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4640
4641
4643 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4644 _check_bv_args(a, b)
4645 a, b = _coerce_exprs(a, b)
4646 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4647
4648
4649
4654
4656 """Array sorts."""
4657
4658 def domain(self):
4659 """Return the domain of the array sort `self`.
4660
4661 >>> A = ArraySort(IntSort(), BoolSort())
4662 >>> A.domain()
4663 Int
4664 """
4666
4667 def domain_n(self, i):
4668 """Return the domain of the array sort `self`.
4669 """
4671
4672 def range(self):
4673 """Return the range of the array sort `self`.
4674
4675 >>> A = ArraySort(IntSort(), BoolSort())
4676 >>> A.range()
4677 Bool
4678 """
4680
4681
4683 """Array expressions. """
4684
4685 def sort(self):
4686 """Return the array sort of the array expression `self`.
4687
4688 >>> a = Array('a', IntSort(), BoolSort())
4689 >>> a.sort()
4690 Array(Int, Bool)
4691 """
4693
4694 def domain(self):
4695 """Shorthand for `self.sort().domain()`.
4696
4697 >>> a = Array('a', IntSort(), BoolSort())
4698 >>> a.domain()
4699 Int
4700 """
4701 return self.sortsort().domain()
4702
4703 def domain_n(self, i):
4704 """Shorthand for self.sort().domain_n(i)`."""
4705 return self.sortsort().domain_n(i)
4706
4707 def range(self):
4708 """Shorthand for `self.sort().range()`.
4709
4710 >>> a = Array('a', IntSort(), BoolSort())
4711 >>> a.range()
4712 Bool
4713 """
4714 return self.sortsort().range()
4715
4716 def __getitem__(self, arg):
4717 """Return the Z3 expression `self[arg]`.
4718
4719 >>> a = Array('a', IntSort(), BoolSort())
4720 >>> i = Int('i')
4721 >>> a[i]
4722 a[i]
4723 >>> a[i].sexpr()
4724 '(select a i)'
4725 """
4726 return _array_select(self, arg)
4727
4728 def default(self):
4729 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
4730
4731
4732def _array_select(ar, arg):
4733 if isinstance(arg, tuple):
4734 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4735 _args, sz = _to_ast_array(args)
4736 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4737 arg = ar.sort().domain().cast(arg)
4738 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4739
4740
4742 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4743
4744
4745def is_array(a : Any) -> bool:
4746 """Return `True` if `a` is a Z3 array expression.
4747
4748 >>> a = Array('a', IntSort(), IntSort())
4749 >>> is_array(a)
4750 True
4751 >>> is_array(Store(a, 0, 1))
4752 True
4753 >>> is_array(a[0])
4754 False
4755 """
4756 return isinstance(a, ArrayRef)
4757
4758
4760 """Return `True` if `a` is a Z3 constant array.
4761
4762 >>> a = K(IntSort(), 10)
4763 >>> is_const_array(a)
4764 True
4765 >>> a = Array('a', IntSort(), IntSort())
4766 >>> is_const_array(a)
4767 False
4768 """
4769 return is_app_of(a, Z3_OP_CONST_ARRAY)
4770
4771
4772def is_K(a):
4773 """Return `True` if `a` is a Z3 constant array.
4774
4775 >>> a = K(IntSort(), 10)
4776 >>> is_K(a)
4777 True
4778 >>> a = Array('a', IntSort(), IntSort())
4779 >>> is_K(a)
4780 False
4781 """
4782 return is_app_of(a, Z3_OP_CONST_ARRAY)
4783
4784
4785def is_map(a):
4786 """Return `True` if `a` is a Z3 map array expression.
4787
4788 >>> f = Function('f', IntSort(), IntSort())
4789 >>> b = Array('b', IntSort(), IntSort())
4790 >>> a = Map(f, b)
4791 >>> a
4792 Map(f, b)
4793 >>> is_map(a)
4794 True
4795 >>> is_map(b)
4796 False
4797 """
4798 return is_app_of(a, Z3_OP_ARRAY_MAP)
4799
4800
4802 """Return `True` if `a` is a Z3 default array expression.
4803 >>> d = Default(K(IntSort(), 10))
4804 >>> is_default(d)
4805 True
4806 """
4807 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4808
4809
4811 """Return the function declaration associated with a Z3 map array expression.
4812
4813 >>> f = Function('f', IntSort(), IntSort())
4814 >>> b = Array('b', IntSort(), IntSort())
4815 >>> a = Map(f, b)
4816 >>> eq(f, get_map_func(a))
4817 True
4818 >>> get_map_func(a)
4819 f
4820 >>> get_map_func(a)(0)
4821 f(0)
4822 """
4823 if z3_debug():
4824 _z3_assert(is_map(a), "Z3 array map expression expected.")
4825 return FuncDeclRef(
4827 a.ctx_ref(),
4828 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4829 ),
4830 ctx=a.ctx,
4831 )
4832
4833
4834def ArraySort(*sig):
4835 """Return the Z3 array sort with the given domain and range sorts.
4836
4837 >>> A = ArraySort(IntSort(), BoolSort())
4838 >>> A
4839 Array(Int, Bool)
4840 >>> A.domain()
4841 Int
4842 >>> A.range()
4843 Bool
4844 >>> AA = ArraySort(IntSort(), A)
4845 >>> AA
4846 Array(Int, Array(Int, Bool))
4847 """
4848 sig = _get_args(sig)
4849 if z3_debug():
4850 _z3_assert(len(sig) > 1, "At least two arguments expected")
4851 arity = len(sig) - 1
4852 r = sig[arity]
4853 d = sig[0]
4854 if z3_debug():
4855 for s in sig:
4856 _z3_assert(is_sort(s), "Z3 sort expected")
4857 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4858 ctx = d.ctx
4859 if len(sig) == 2:
4860 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4861 dom = (Sort * arity)()
4862 for i in range(arity):
4863 dom[i] = sig[i].ast
4864 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4865
4866
4867def Array(name, *sorts):
4868 """Return an array constant named `name` with the given domain and range sorts.
4869
4870 >>> a = Array('a', IntSort(), IntSort())
4871 >>> a.sort()
4872 Array(Int, Int)
4873 >>> a[0]
4874 a[0]
4875 """
4876 s = ArraySort(sorts)
4877 ctx = s.ctx
4878 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4879
4880
4881def Update(a, *args):
4882 """Return a Z3 store array expression.
4883
4884 >>> a = Array('a', IntSort(), IntSort())
4885 >>> i, v = Ints('i v')
4886 >>> s = Update(a, i, v)
4887 >>> s.sort()
4888 Array(Int, Int)
4889 >>> prove(s[i] == v)
4890 proved
4891 >>> j = Int('j')
4892 >>> prove(Implies(i != j, s[j] == a[j]))
4893 proved
4894 """
4895 if z3_debug():
4896 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4897 args = _get_args(args)
4898 ctx = a.ctx
4899 if len(args) <= 1:
4900 raise Z3Exception("array update requires index and value arguments")
4901 if len(args) == 2:
4902 i = args[0]
4903 v = args[1]
4904 i = a.sort().domain().cast(i)
4905 v = a.sort().range().cast(v)
4906 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4907 v = a.sort().range().cast(args[-1])
4908 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4909 _args, sz = _to_ast_array(idxs)
4910 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4911
4912
4913def Default(a):
4914 """ Return a default value for array expression.
4915 >>> b = K(IntSort(), 1)
4916 >>> prove(Default(b) == 1)
4917 proved
4918 """
4919 if z3_debug():
4920 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4921 return a.default()
4922
4923
4924def Store(a, *args):
4925 """Return a Z3 store array expression.
4926
4927 >>> a = Array('a', IntSort(), IntSort())
4928 >>> i, v = Ints('i v')
4929 >>> s = Store(a, i, v)
4930 >>> s.sort()
4931 Array(Int, Int)
4932 >>> prove(s[i] == v)
4933 proved
4934 >>> j = Int('j')
4935 >>> prove(Implies(i != j, s[j] == a[j]))
4936 proved
4937 """
4938 return Update(a, args)
4939
4940
4941def Select(a, *args):
4942 """Return a Z3 select array expression.
4943
4944 >>> a = Array('a', IntSort(), IntSort())
4945 >>> i = Int('i')
4946 >>> Select(a, i)
4947 a[i]
4948 >>> eq(Select(a, i), a[i])
4949 True
4950 """
4951 args = _get_args(args)
4952 if z3_debug():
4953 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4954 return a[args]
4955
4956
4957def Map(f, *args):
4958 """Return a Z3 map array expression.
4959
4960 >>> f = Function('f', IntSort(), IntSort(), IntSort())
4961 >>> a1 = Array('a1', IntSort(), IntSort())
4962 >>> a2 = Array('a2', IntSort(), IntSort())
4963 >>> b = Map(f, a1, a2)
4964 >>> b
4965 Map(f, a1, a2)
4966 >>> prove(b[0] == f(a1[0], a2[0]))
4967 proved
4968 """
4969 args = _get_args(args)
4970 if z3_debug():
4971 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
4972 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
4973 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
4974 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
4975 _args, sz = _to_ast_array(args)
4976 ctx = f.ctx
4977 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
4978
4979
4980def K(dom, v):
4981 """Return a Z3 constant array expression.
4982
4983 >>> a = K(IntSort(), 10)
4984 >>> a
4985 K(Int, 10)
4986 >>> a.sort()
4987 Array(Int, Int)
4988 >>> i = Int('i')
4989 >>> a[i]
4990 K(Int, 10)[i]
4991 >>> simplify(a[i])
4992 10
4993 """
4994 if z3_debug():
4995 _z3_assert(is_sort(dom), "Z3 sort expected")
4996 ctx = dom.ctx
4997 if not is_expr(v):
4998 v = _py2expr(v, ctx)
4999 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
5000
5001
5002def Ext(a, b):
5003 """Return extensionality index for one-dimensional arrays.
5004 >> a, b = Consts('a b', SetSort(IntSort()))
5005 >> Ext(a, b)
5006 Ext(a, b)
5007 """
5008 ctx = a.ctx
5009 if z3_debug():
5010 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
5011 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5012
5013
5014def SetHasSize(a, k):
5015 ctx = a.ctx
5016 k = _py2expr(k, ctx)
5017 return _to_expr_ref(Z3_mk_set_has_size(ctx.ref(), a.as_ast(), k.as_ast()), ctx)
5018
5019
5021 """Return `True` if `a` is a Z3 array select application.
5022
5023 >>> a = Array('a', IntSort(), IntSort())
5024 >>> is_select(a)
5025 False
5026 >>> i = Int('i')
5027 >>> is_select(a[i])
5028 True
5029 """
5030 return is_app_of(a, Z3_OP_SELECT)
5031
5032
5034 """Return `True` if `a` is a Z3 array store application.
5035
5036 >>> a = Array('a', IntSort(), IntSort())
5037 >>> is_store(a)
5038 False
5039 >>> is_store(Store(a, 0, 1))
5040 True
5041 """
5042 return is_app_of(a, Z3_OP_STORE)
5043
5044
5049
5050
5051def SetSort(s):
5052 """ Create a set sort over element sort s"""
5053 return ArraySort(s, BoolSort())
5054
5055
5057 """Create the empty set
5058 >>> EmptySet(IntSort())
5059 K(Int, False)
5060 """
5061 ctx = s.ctx
5062 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5063
5064
5065def FullSet(s):
5066 """Create the full set
5067 >>> FullSet(IntSort())
5068 K(Int, True)
5069 """
5070 ctx = s.ctx
5071 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5072
5073
5074def SetUnion(*args):
5075 """ Take the union of sets
5076 >>> a = Const('a', SetSort(IntSort()))
5077 >>> b = Const('b', SetSort(IntSort()))
5078 >>> SetUnion(a, b)
5079 union(a, b)
5080 """
5081 args = _get_args(args)
5082 ctx = _ctx_from_ast_arg_list(args)
5083 _args, sz = _to_ast_array(args)
5084 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5085
5086
5087def SetIntersect(*args):
5088 """ Take the union of sets
5089 >>> a = Const('a', SetSort(IntSort()))
5090 >>> b = Const('b', SetSort(IntSort()))
5091 >>> SetIntersect(a, b)
5092 intersection(a, b)
5093 """
5094 args = _get_args(args)
5095 ctx = _ctx_from_ast_arg_list(args)
5096 _args, sz = _to_ast_array(args)
5097 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5098
5099
5100def SetAdd(s, e):
5101 """ Add element e to set s
5102 >>> a = Const('a', SetSort(IntSort()))
5103 >>> SetAdd(a, 1)
5104 Store(a, 1, True)
5105 """
5106 ctx = _ctx_from_ast_arg_list([s, e])
5107 e = _py2expr(e, ctx)
5108 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5109
5110
5111def SetDel(s, e):
5112 """ Remove element e to set s
5113 >>> a = Const('a', SetSort(IntSort()))
5114 >>> SetDel(a, 1)
5115 Store(a, 1, False)
5116 """
5117 ctx = _ctx_from_ast_arg_list([s, e])
5118 e = _py2expr(e, ctx)
5119 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5120
5121
5123 """ The complement of set s
5124 >>> a = Const('a', SetSort(IntSort()))
5125 >>> SetComplement(a)
5126 complement(a)
5127 """
5128 ctx = s.ctx
5129 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5130
5131
5133 """ The set difference of a and b
5134 >>> a = Const('a', SetSort(IntSort()))
5135 >>> b = Const('b', SetSort(IntSort()))
5136 >>> SetDifference(a, b)
5137 setminus(a, b)
5138 """
5139 ctx = _ctx_from_ast_arg_list([a, b])
5140 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5141
5142
5143def IsMember(e, s):
5144 """ Check if e is a member of set s
5145 >>> a = Const('a', SetSort(IntSort()))
5146 >>> IsMember(1, a)
5147 a[1]
5148 """
5149 ctx = _ctx_from_ast_arg_list([s, e])
5150 e = _py2expr(e, ctx)
5151 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5152
5153
5154def IsSubset(a, b):
5155 """ Check if a is a subset of b
5156 >>> a = Const('a', SetSort(IntSort()))
5157 >>> b = Const('b', SetSort(IntSort()))
5158 >>> IsSubset(a, b)
5159 subset(a, b)
5160 """
5161 ctx = _ctx_from_ast_arg_list([a, b])
5162 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5163
5164
5165
5170
5172 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5173 if not isinstance(acc, tuple):
5174 return False
5175 if len(acc) != 2:
5176 return False
5177 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5178
5179
5181 """Helper class for declaring Z3 datatypes.
5182
5183 >>> List = Datatype('List')
5184 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5185 >>> List.declare('nil')
5186 >>> List = List.create()
5187 >>> # List is now a Z3 declaration
5188 >>> List.nil
5189 nil
5190 >>> List.cons(10, List.nil)
5191 cons(10, nil)
5192 >>> List.cons(10, List.nil).sort()
5193 List
5194 >>> cons = List.cons
5195 >>> nil = List.nil
5196 >>> car = List.car
5197 >>> cdr = List.cdr
5198 >>> n = cons(1, cons(0, nil))
5199 >>> n
5200 cons(1, cons(0, nil))
5201 >>> simplify(cdr(n))
5202 cons(0, nil)
5203 >>> simplify(car(n))
5204 1
5205 """
5206
5207 def __init__(self, name, ctx=None):
5208 self.ctx = _get_ctx(ctx)
5209 self.name = name
5211
5212 def __deepcopy__(self, memo={}):
5213 r = Datatype(self.name, self.ctx)
5214 r.constructors = copy.deepcopy(self.constructors)
5215 return r
5216
5217 def declare_core(self, name, rec_name, *args):
5218 if z3_debug():
5219 _z3_assert(isinstance(name, str), "String expected")
5220 _z3_assert(isinstance(rec_name, str), "String expected")
5221 _z3_assert(
5222 all([_valid_accessor(a) for a in args]),
5223 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5224 )
5225 self.constructors.append((name, rec_name, args))
5226
5227 def declare(self, name, *args):
5228 """Declare constructor named `name` with the given accessors `args`.
5229 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5230 or a reference to the datatypes being declared.
5231
5232 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5233 declares the constructor named `cons` that builds a new List using an integer and a List.
5234 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5235 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5236 we use the method create() to create the actual datatype in Z3.
5237
5238 >>> List = Datatype('List')
5239 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5240 >>> List.declare('nil')
5241 >>> List = List.create()
5242 """
5243 if z3_debug():
5244 _z3_assert(isinstance(name, str), "String expected")
5245 _z3_assert(name != "", "Constructor name cannot be empty")
5246 return self.declare_core(name, "is-" + name, *args)
5247
5248 def __repr__(self):
5249 return "Datatype(%s, %s)" % (self.name, self.constructors)
5250
5251 def create(self):
5252 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5253
5254 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5255
5256 >>> List = Datatype('List')
5257 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5258 >>> List.declare('nil')
5259 >>> List = List.create()
5260 >>> List.nil
5261 nil
5262 >>> List.cons(10, List.nil)
5263 cons(10, nil)
5264 """
5265 return CreateDatatypes([self])[0]
5266
5267
5269 """Auxiliary object used to create Z3 datatypes."""
5270
5271 def __init__(self, c, ctx):
5272 self.c = c
5273 self.ctx = ctx
5274
5275 def __del__(self):
5276 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5277 Z3_del_constructor(self.ctx.ref(), self.c)
5278
5279
5281 """Auxiliary object used to create Z3 datatypes."""
5282
5283 def __init__(self, c, ctx):
5284 self.c = c
5285 self.ctx = ctx
5286
5287 def __del__(self):
5288 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5289 Z3_del_constructor_list(self.ctx.ref(), self.c)
5290
5291
5293 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5294
5295 In the following example we define a Tree-List using two mutually recursive datatypes.
5296
5297 >>> TreeList = Datatype('TreeList')
5298 >>> Tree = Datatype('Tree')
5299 >>> # Tree has two constructors: leaf and node
5300 >>> Tree.declare('leaf', ('val', IntSort()))
5301 >>> # a node contains a list of trees
5302 >>> Tree.declare('node', ('children', TreeList))
5303 >>> TreeList.declare('nil')
5304 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5305 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5306 >>> Tree.val(Tree.leaf(10))
5307 val(leaf(10))
5308 >>> simplify(Tree.val(Tree.leaf(10)))
5309 10
5310 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5311 >>> n1
5312 node(cons(leaf(10), cons(leaf(20), nil)))
5313 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5314 >>> simplify(n2 == n1)
5315 False
5316 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5317 True
5318 """
5319 ds = _get_args(ds)
5320 if z3_debug():
5321 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5322 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5323 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5324 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5325 ctx = ds[0].ctx
5326 num = len(ds)
5327 names = (Symbol * num)()
5328 out = (Sort * num)()
5329 clists = (ConstructorList * num)()
5330 to_delete = []
5331 for i in range(num):
5332 d = ds[i]
5333 names[i] = to_symbol(d.name, ctx)
5334 num_cs = len(d.constructors)
5335 cs = (Constructor * num_cs)()
5336 for j in range(num_cs):
5337 c = d.constructors[j]
5338 cname = to_symbol(c[0], ctx)
5339 rname = to_symbol(c[1], ctx)
5340 fs = c[2]
5341 num_fs = len(fs)
5342 fnames = (Symbol * num_fs)()
5343 sorts = (Sort * num_fs)()
5344 refs = (ctypes.c_uint * num_fs)()
5345 for k in range(num_fs):
5346 fname = fs[k][0]
5347 ftype = fs[k][1]
5348 fnames[k] = to_symbol(fname, ctx)
5349 if isinstance(ftype, Datatype):
5350 if z3_debug():
5351 _z3_assert(
5352 ds.count(ftype) == 1,
5353 "One and only one occurrence of each datatype is expected",
5354 )
5355 sorts[k] = None
5356 refs[k] = ds.index(ftype)
5357 else:
5358 if z3_debug():
5359 _z3_assert(is_sort(ftype), "Z3 sort expected")
5360 sorts[k] = ftype.ast
5361 refs[k] = 0
5362 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5363 to_delete.append(ScopedConstructor(cs[j], ctx))
5364 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5365 to_delete.append(ScopedConstructorList(clists[i], ctx))
5366 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5367 result = []
5368 # Create a field for every constructor, recognizer and accessor
5369 for i in range(num):
5370 dref = DatatypeSortRef(out[i], ctx)
5371 num_cs = dref.num_constructors()
5372 for j in range(num_cs):
5373 cref = dref.constructor(j)
5374 cref_name = cref.name()
5375 cref_arity = cref.arity()
5376 if cref.arity() == 0:
5377 cref = cref()
5378 setattr(dref, cref_name, cref)
5379 rref = dref.recognizer(j)
5380 setattr(dref, "is_" + cref_name, rref)
5381 for k in range(cref_arity):
5382 aref = dref.accessor(j, k)
5383 setattr(dref, aref.name(), aref)
5384 result.append(dref)
5385 return tuple(result)
5386
5387
5389 """Datatype sorts."""
5390
5392 """Return the number of constructors in the given Z3 datatype.
5393
5394 >>> List = Datatype('List')
5395 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5396 >>> List.declare('nil')
5397 >>> List = List.create()
5398 >>> # List is now a Z3 declaration
5399 >>> List.num_constructors()
5400 2
5401 """
5403
5404 def constructor(self, idx):
5405 """Return a constructor of the datatype `self`.
5406
5407 >>> List = Datatype('List')
5408 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5409 >>> List.declare('nil')
5410 >>> List = List.create()
5411 >>> # List is now a Z3 declaration
5412 >>> List.num_constructors()
5413 2
5414 >>> List.constructor(0)
5415 cons
5416 >>> List.constructor(1)
5417 nil
5418 """
5419 if z3_debug():
5420 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5422
5423 def recognizer(self, idx):
5424 """In Z3, each constructor has an associated recognizer predicate.
5425
5426 If the constructor is named `name`, then the recognizer `is_name`.
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 >>> List.recognizer(0)
5436 is(cons)
5437 >>> List.recognizer(1)
5438 is(nil)
5439 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5440 False
5441 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5442 True
5443 >>> l = Const('l', List)
5444 >>> simplify(List.is_cons(l))
5445 is(cons, l)
5446 """
5447 if z3_debug():
5448 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5450
5451 def accessor(self, i, j):
5452 """In Z3, each constructor has 0 or more accessor.
5453 The number of accessors is equal to the arity of the constructor.
5454
5455 >>> List = Datatype('List')
5456 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5457 >>> List.declare('nil')
5458 >>> List = List.create()
5459 >>> List.num_constructors()
5460 2
5461 >>> List.constructor(0)
5462 cons
5463 >>> num_accs = List.constructor(0).arity()
5464 >>> num_accs
5465 2
5466 >>> List.accessor(0, 0)
5467 car
5468 >>> List.accessor(0, 1)
5469 cdr
5470 >>> List.constructor(1)
5471 nil
5472 >>> num_accs = List.constructor(1).arity()
5473 >>> num_accs
5474 0
5475 """
5476 if z3_debug():
5477 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5478 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5479 return FuncDeclRef(
5481 ctx=self.ctxctxctx,
5482 )
5483
5484
5486 """Datatype expressions."""
5487
5488 def sort(self):
5489 """Return the datatype sort of the datatype expression `self`."""
5491
5492def DatatypeSort(name, params=None, ctx=None):
5493 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype.
5494
5495 Args:
5496 name: name of the datatype sort
5497 params: optional list/tuple of sort parameters for parametric datatypes
5498 ctx: Z3 context (optional)
5499
5500 Example:
5501 >>> # Non-parametric datatype
5502 >>> TreeRef = DatatypeSort('Tree')
5503 >>> # Parametric datatype with one parameter
5504 >>> ListIntRef = DatatypeSort('List', [IntSort()])
5505 >>> # Parametric datatype with multiple parameters
5506 >>> PairRef = DatatypeSort('Pair', [IntSort(), BoolSort()])
5507 """
5508 ctx = _get_ctx(ctx)
5509 if params is None or len(params) == 0:
5510 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), 0, (Sort * 0)()), ctx)
5511 else:
5512 _params = (Sort * len(params))()
5513 for i in range(len(params)):
5514 _params[i] = params[i].ast
5515 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), len(params), _params), ctx)
5516
5517def TupleSort(name, sorts, ctx=None):
5518 """Create a named tuple sort base on a set of underlying sorts
5519 Example:
5520 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5521 """
5522 tuple = Datatype(name, ctx)
5523 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5524 tuple.declare(name, *projects)
5525 tuple = tuple.create()
5526 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5527
5528
5529def DisjointSum(name, sorts, ctx=None):
5530 """Create a named tagged union sort base on a set of underlying sorts
5531 Example:
5532 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5533 """
5534 sum = Datatype(name, ctx)
5535 for i in range(len(sorts)):
5536 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5537 sum = sum.create()
5538 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5539
5540
5541def EnumSort(name, values, ctx=None):
5542 """Return a new enumeration sort named `name` containing the given values.
5543
5544 The result is a pair (sort, list of constants).
5545 Example:
5546 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5547 """
5548 if z3_debug():
5549 _z3_assert(isinstance(name, str), "Name must be a string")
5550 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5551 _z3_assert(len(values) > 0, "At least one value expected")
5552 ctx = _get_ctx(ctx)
5553 num = len(values)
5554 _val_names = (Symbol * num)()
5555 for i in range(num):
5556 _val_names[i] = to_symbol(values[i], ctx)
5557 _values = (FuncDecl * num)()
5558 _testers = (FuncDecl * num)()
5559 name = to_symbol(name, ctx)
5560 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5561 V = []
5562 for i in range(num):
5563 V.append(FuncDeclRef(_values[i], ctx))
5564 V = [a() for a in V]
5565 return S, V
5566
5567
5572
5573
5575 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5576
5577 Consider using the function `args2params` to create instances of this object.
5578 """
5579
5580 def __init__(self, ctx=None, params=None):
5581 self.ctx = _get_ctx(ctx)
5582 if params is None:
5583 self.params = Z3_mk_params(self.ctx.ref())
5584 else:
5585 self.params = params
5586 Z3_params_inc_ref(self.ctx.ref(), self.params)
5587
5588 def __deepcopy__(self, memo={}):
5589 return ParamsRef(self.ctx, self.params)
5590
5591 def __del__(self):
5592 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5593 Z3_params_dec_ref(self.ctx.ref(), self.params)
5594
5595 def set(self, name, val):
5596 """Set parameter name with value val."""
5597 if z3_debug():
5598 _z3_assert(isinstance(name, str), "parameter name must be a string")
5599 name_sym = to_symbol(name, self.ctx)
5600 if isinstance(val, bool):
5601 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5602 elif _is_int(val):
5603 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5604 elif isinstance(val, float):
5605 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5606 elif isinstance(val, str):
5607 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5608 else:
5609 if z3_debug():
5610 _z3_assert(False, "invalid parameter value")
5611
5612 def __repr__(self):
5613 return Z3_params_to_string(self.ctx.ref(), self.params)
5614
5615 def validate(self, ds):
5616 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5617 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5618
5619
5620def args2params(arguments, keywords, ctx=None):
5621 """Convert python arguments into a Z3_params object.
5622 A ':' is added to the keywords, and '_' is replaced with '-'
5623
5624 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5625 (params model true relevancy 2 elim_and true)
5626 """
5627 if z3_debug():
5628 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5629 prev = None
5630 r = ParamsRef(ctx)
5631 for a in arguments:
5632 if prev is None:
5633 prev = a
5634 else:
5635 r.set(prev, a)
5636 prev = None
5637 for k in keywords:
5638 v = keywords[k]
5639 r.set(k, v)
5640 return r
5641
5642
5644 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5645 """
5646
5647 def __init__(self, descr, ctx=None):
5648 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5649 self.ctx = _get_ctx(ctx)
5650 self.descr = descr
5651 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5652
5653 def __deepcopy__(self, memo={}):
5654 return ParamsDescrsRef(self.descr, self.ctx)
5655
5656 def __del__(self):
5657 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5658 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5659
5660 def size(self):
5661 """Return the size of in the parameter description `self`.
5662 """
5663 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5664
5665 def __len__(self):
5666 """Return the size of in the parameter description `self`.
5667 """
5668 return self.size()
5669
5670 def get_name(self, i):
5671 """Return the i-th parameter name in the parameter description `self`.
5672 """
5673 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5674
5675 def get_kind(self, n):
5676 """Return the kind of the parameter named `n`.
5677 """
5678 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5679
5680 def get_documentation(self, n):
5681 """Return the documentation string of the parameter named `n`.
5682 """
5683 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5684
5685 def __getitem__(self, arg):
5686 if _is_int(arg):
5687 return self.get_name(arg)
5688 else:
5689 return self.get_kind(arg)
5690
5691 def __repr__(self):
5692 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5693
5694
5699
5700
5702 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5703
5704 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5705 A goal has a solution if one of its subgoals has a solution.
5706 A goal is unsatisfiable if all subgoals are unsatisfiable.
5707 """
5708
5709 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5710 if z3_debug():
5711 _z3_assert(goal is None or ctx is not None,
5712 "If goal is different from None, then ctx must be also different from None")
5713 self.ctx = _get_ctx(ctx)
5714 self.goal = goal
5715 if self.goal is None:
5716 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5717 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5718
5719 def __del__(self):
5720 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5721 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5722
5723 def depth(self):
5724 """Return the depth of the goal `self`.
5725 The depth corresponds to the number of tactics applied to `self`.
5726
5727 >>> x, y = Ints('x y')
5728 >>> g = Goal()
5729 >>> g.add(x == 0, y >= x + 1)
5730 >>> g.depth()
5731 0
5732 >>> r = Then('simplify', 'solve-eqs')(g)
5733 >>> # r has 1 subgoal
5734 >>> len(r)
5735 1
5736 >>> r[0].depth()
5737 2
5738 """
5739 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5740
5741 def inconsistent(self):
5742 """Return `True` if `self` contains the `False` constraints.
5743
5744 >>> x, y = Ints('x y')
5745 >>> g = Goal()
5746 >>> g.inconsistent()
5747 False
5748 >>> g.add(x == 0, x == 1)
5749 >>> g
5750 [x == 0, x == 1]
5751 >>> g.inconsistent()
5752 False
5753 >>> g2 = Tactic('propagate-values')(g)[0]
5754 >>> g2.inconsistent()
5755 True
5756 """
5757 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5758
5759 def prec(self):
5760 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5761
5762 >>> g = Goal()
5763 >>> g.prec() == Z3_GOAL_PRECISE
5764 True
5765 >>> x, y = Ints('x y')
5766 >>> g.add(x == y + 1)
5767 >>> g.prec() == Z3_GOAL_PRECISE
5768 True
5769 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5770 >>> g2 = t(g)[0]
5771 >>> g2
5772 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5773 >>> g2.prec() == Z3_GOAL_PRECISE
5774 False
5775 >>> g2.prec() == Z3_GOAL_UNDER
5776 True
5777 """
5778 return Z3_goal_precision(self.ctx.ref(), self.goal)
5779
5780 def precision(self):
5781 """Alias for `prec()`.
5782
5783 >>> g = Goal()
5784 >>> g.precision() == Z3_GOAL_PRECISE
5785 True
5786 """
5787 return self.prec()
5788
5789 def size(self):
5790 """Return the number of constraints in the goal `self`.
5791
5792 >>> g = Goal()
5793 >>> g.size()
5794 0
5795 >>> x, y = Ints('x y')
5796 >>> g.add(x == 0, y > x)
5797 >>> g.size()
5798 2
5799 """
5800 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5801
5802 def __len__(self):
5803 """Return the number of constraints in the goal `self`.
5804
5805 >>> g = Goal()
5806 >>> len(g)
5807 0
5808 >>> x, y = Ints('x y')
5809 >>> g.add(x == 0, y > x)
5810 >>> len(g)
5811 2
5812 """
5813 return self.size()
5814
5815 def get(self, i):
5816 """Return a constraint in the goal `self`.
5817
5818 >>> g = Goal()
5819 >>> x, y = Ints('x y')
5820 >>> g.add(x == 0, y > x)
5821 >>> g.get(0)
5822 x == 0
5823 >>> g.get(1)
5824 y > x
5825 """
5826 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5827
5828 def __getitem__(self, arg):
5829 """Return a constraint in the goal `self`.
5830
5831 >>> g = Goal()
5832 >>> x, y = Ints('x y')
5833 >>> g.add(x == 0, y > x)
5834 >>> g[0]
5835 x == 0
5836 >>> g[1]
5837 y > x
5838 """
5839 if arg >= len(self):
5840 raise IndexError
5841 return self.get(arg)
5842
5843 def assert_exprs(self, *args):
5844 """Assert constraints into the goal.
5845
5846 >>> x = Int('x')
5847 >>> g = Goal()
5848 >>> g.assert_exprs(x > 0, x < 2)
5849 >>> g
5850 [x > 0, x < 2]
5851 """
5852 args = _get_args(args)
5853 s = BoolSort(self.ctx)
5854 for arg in args:
5855 arg = s.cast(arg)
5856 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5857
5858 def append(self, *args):
5859 """Add constraints.
5860
5861 >>> x = Int('x')
5862 >>> g = Goal()
5863 >>> g.append(x > 0, x < 2)
5864 >>> g
5865 [x > 0, x < 2]
5866 """
5867 self.assert_exprs(*args)
5868
5869 def insert(self, *args):
5870 """Add constraints.
5871
5872 >>> x = Int('x')
5873 >>> g = Goal()
5874 >>> g.insert(x > 0, x < 2)
5875 >>> g
5876 [x > 0, x < 2]
5877 """
5878 self.assert_exprs(*args)
5879
5880 def add(self, *args):
5881 """Add constraints.
5882
5883 >>> x = Int('x')
5884 >>> g = Goal()
5885 >>> g.add(x > 0, x < 2)
5886 >>> g
5887 [x > 0, x < 2]
5888 """
5889 self.assert_exprs(*args)
5890
5891 def convert_model(self, model):
5892 """Retrieve model from a satisfiable goal
5893 >>> a, b = Ints('a b')
5894 >>> g = Goal()
5895 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5896 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5897 >>> r = t(g)
5898 >>> r[0]
5899 [Or(b == 0, b == 1), Not(0 <= b)]
5900 >>> r[1]
5901 [Or(b == 0, b == 1), Not(1 <= b)]
5902 >>> # Remark: the subgoal r[0] is unsatisfiable
5903 >>> # Creating a solver for solving the second subgoal
5904 >>> s = Solver()
5905 >>> s.add(r[1])
5906 >>> s.check()
5907 sat
5908 >>> s.model()
5909 [b = 0]
5910 >>> # Model s.model() does not assign a value to `a`
5911 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5912 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5913 >>> r[1].convert_model(s.model())
5914 [b = 0, a = 1]
5915 """
5916 if z3_debug():
5917 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5918 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5919
5920 def __repr__(self):
5921 return obj_to_string(self)
5922
5923 def sexpr(self):
5924 """Return a textual representation of the s-expression representing the goal."""
5925 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5926
5927 def dimacs(self, include_names=True):
5928 """Return a textual representation of the goal in DIMACS format."""
5929 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5930
5931 def translate(self, target):
5932 """Copy goal `self` to context `target`.
5933
5934 >>> x = Int('x')
5935 >>> g = Goal()
5936 >>> g.add(x > 10)
5937 >>> g
5938 [x > 10]
5939 >>> c2 = Context()
5940 >>> g2 = g.translate(c2)
5941 >>> g2
5942 [x > 10]
5943 >>> g.ctx == main_ctx()
5944 True
5945 >>> g2.ctx == c2
5946 True
5947 >>> g2.ctx == main_ctx()
5948 False
5949 """
5950 if z3_debug():
5951 _z3_assert(isinstance(target, Context), "target must be a context")
5952 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5953
5954 def __copy__(self):
5955 return self.translate(self.ctx)
5956
5957 def __deepcopy__(self, memo={}):
5958 return self.translate(self.ctx)
5959
5960 def simplify(self, *arguments, **keywords):
5961 """Return a new simplified goal.
5962
5963 This method is essentially invoking the simplify tactic.
5964
5965 >>> g = Goal()
5966 >>> x = Int('x')
5967 >>> g.add(x + 1 >= 2)
5968 >>> g
5969 [x + 1 >= 2]
5970 >>> g2 = g.simplify()
5971 >>> g2
5972 [x >= 1]
5973 >>> # g was not modified
5974 >>> g
5975 [x + 1 >= 2]
5976 """
5977 t = Tactic("simplify")
5978 return t.apply(self, *arguments, **keywords)[0]
5979
5980 def as_expr(self):
5981 """Return goal `self` as a single Z3 expression.
5982
5983 >>> x = Int('x')
5984 >>> g = Goal()
5985 >>> g.as_expr()
5986 True
5987 >>> g.add(x > 1)
5988 >>> g.as_expr()
5989 x > 1
5990 >>> g.add(x < 10)
5991 >>> g.as_expr()
5992 And(x > 1, x < 10)
5993 """
5994 sz = len(self)
5995 if sz == 0:
5996 return BoolVal(True, self.ctx)
5997 elif sz == 1:
5998 return self.get(0)
5999 else:
6000 return And([self.get(i) for i in range(len(self))], self.ctx)
6001
6002
6007
6008
6010 """A collection (vector) of ASTs."""
6011
6012 def __init__(self, v=None, ctx=None):
6013 self.vector = None
6014 if v is None:
6015 self.ctx = _get_ctx(ctx)
6016 self.vector = Z3_mk_ast_vector(self.ctx.ref())
6017 else:
6018 self.vector = v
6019 assert ctx is not None
6020 self.ctx = ctx
6021 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
6022
6023 def __del__(self):
6024 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
6025 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
6026
6027 def __len__(self):
6028 """Return the size of the vector `self`.
6029
6030 >>> A = AstVector()
6031 >>> len(A)
6032 0
6033 >>> A.push(Int('x'))
6034 >>> A.push(Int('x'))
6035 >>> len(A)
6036 2
6037 """
6038 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
6039
6040 def __getitem__(self, i):
6041 """Return the AST at position `i`.
6042
6043 >>> A = AstVector()
6044 >>> A.push(Int('x') + 1)
6045 >>> A.push(Int('y'))
6046 >>> A[0]
6047 x + 1
6048 >>> A[1]
6049 y
6050 """
6051
6052 if isinstance(i, int):
6053 if i < 0:
6054 i += self.__len__()
6055
6056 if i >= self.__len__():
6057 raise IndexError
6058 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
6059
6060 elif isinstance(i, slice):
6061 result = []
6062 for ii in range(*i.indices(self.__len__())):
6063 result.append(_to_ast_ref(
6064 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6065 self.ctx,
6066 ))
6067 return result
6068
6069 def __setitem__(self, i, v):
6070 """Update AST at position `i`.
6071
6072 >>> A = AstVector()
6073 >>> A.push(Int('x') + 1)
6074 >>> A.push(Int('y'))
6075 >>> A[0]
6076 x + 1
6077 >>> A[0] = Int('x')
6078 >>> A[0]
6079 x
6080 """
6081 if i >= self.__len__():
6082 raise IndexError
6083 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6084
6085 def push(self, v):
6086 """Add `v` in the end of the vector.
6087
6088 >>> A = AstVector()
6089 >>> len(A)
6090 0
6091 >>> A.push(Int('x'))
6092 >>> len(A)
6093 1
6094 """
6095 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6096
6097 def resize(self, sz):
6098 """Resize the vector to `sz` elements.
6099
6100 >>> A = AstVector()
6101 >>> A.resize(10)
6102 >>> len(A)
6103 10
6104 >>> for i in range(10): A[i] = Int('x')
6105 >>> A[5]
6106 x
6107 """
6108 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6109
6110 def __contains__(self, item):
6111 """Return `True` if the vector contains `item`.
6112
6113 >>> x = Int('x')
6114 >>> A = AstVector()
6115 >>> x in A
6116 False
6117 >>> A.push(x)
6118 >>> x in A
6119 True
6120 >>> (x+1) in A
6121 False
6122 >>> A.push(x+1)
6123 >>> (x+1) in A
6124 True
6125 >>> A
6126 [x, x + 1]
6127 """
6128 for elem in self:
6129 if elem.eq(item):
6130 return True
6131 return False
6132
6133 def translate(self, other_ctx):
6134 """Copy vector `self` to context `other_ctx`.
6135
6136 >>> x = Int('x')
6137 >>> A = AstVector()
6138 >>> A.push(x)
6139 >>> c2 = Context()
6140 >>> B = A.translate(c2)
6141 >>> B
6142 [x]
6143 """
6144 return AstVector(
6145 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6146 ctx=other_ctx,
6147 )
6148
6149 def __copy__(self):
6150 return self.translate(self.ctx)
6151
6152 def __deepcopy__(self, memo={}):
6153 return self.translate(self.ctx)
6154
6155 def __repr__(self):
6156 return obj_to_string(self)
6157
6158 def sexpr(self):
6159 """Return a textual representation of the s-expression representing the vector."""
6160 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6161
6162
6167
6168
6170 """A mapping from ASTs to ASTs."""
6171
6172 def __init__(self, m=None, ctx=None):
6173 self.map = None
6174 if m is None:
6175 self.ctx = _get_ctx(ctx)
6176 self.map = Z3_mk_ast_map(self.ctx.ref())
6177 else:
6178 self.map = m
6179 assert ctx is not None
6180 self.ctx = ctx
6181 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6182
6183 def __deepcopy__(self, memo={}):
6184 return AstMap(self.map, self.ctx)
6185
6186 def __del__(self):
6187 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6188 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6189
6190 def __len__(self):
6191 """Return the size of the map.
6192
6193 >>> M = AstMap()
6194 >>> len(M)
6195 0
6196 >>> x = Int('x')
6197 >>> M[x] = IntVal(1)
6198 >>> len(M)
6199 1
6200 """
6201 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6202
6203 def __contains__(self, key):
6204 """Return `True` if the map contains key `key`.
6205
6206 >>> M = AstMap()
6207 >>> x = Int('x')
6208 >>> M[x] = x + 1
6209 >>> x in M
6210 True
6211 >>> x+1 in M
6212 False
6213 """
6214 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6215
6216 def __getitem__(self, key):
6217 """Retrieve the value associated with key `key`.
6218
6219 >>> M = AstMap()
6220 >>> x = Int('x')
6221 >>> M[x] = x + 1
6222 >>> M[x]
6223 x + 1
6224 """
6225 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6226
6227 def __setitem__(self, k, v):
6228 """Add/Update key `k` with value `v`.
6229
6230 >>> M = AstMap()
6231 >>> x = Int('x')
6232 >>> M[x] = x + 1
6233 >>> len(M)
6234 1
6235 >>> M[x]
6236 x + 1
6237 >>> M[x] = IntVal(1)
6238 >>> M[x]
6239 1
6240 """
6241 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6242
6243 def __repr__(self):
6244 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6245
6246 def erase(self, k):
6247 """Remove the entry associated with key `k`.
6248
6249 >>> M = AstMap()
6250 >>> x = Int('x')
6251 >>> M[x] = x + 1
6252 >>> len(M)
6253 1
6254 >>> M.erase(x)
6255 >>> len(M)
6256 0
6257 """
6258 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6259
6260 def reset(self):
6261 """Remove all entries from the map.
6262
6263 >>> M = AstMap()
6264 >>> x = Int('x')
6265 >>> M[x] = x + 1
6266 >>> M[x+x] = IntVal(1)
6267 >>> len(M)
6268 2
6269 >>> M.reset()
6270 >>> len(M)
6271 0
6272 """
6273 Z3_ast_map_reset(self.ctx.ref(), self.map)
6274
6275 def keys(self):
6276 """Return an AstVector containing all keys in the map.
6277
6278 >>> M = AstMap()
6279 >>> x = Int('x')
6280 >>> M[x] = x + 1
6281 >>> M[x+x] = IntVal(1)
6282 >>> M.keys()
6283 [x, x + x]
6284 """
6285 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6286
6287
6292
6293
6295 """Store the value of the interpretation of a function in a particular point."""
6296
6297 def __init__(self, entry, ctx):
6298 self.entry = entry
6299 self.ctx = ctx
6300 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6301
6302 def __deepcopy__(self, memo={}):
6303 return FuncEntry(self.entry, self.ctx)
6304
6305 def __del__(self):
6306 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6307 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6308
6309 def num_args(self):
6310 """Return the number of arguments in the given entry.
6311
6312 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6313 >>> s = Solver()
6314 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6315 >>> s.check()
6316 sat
6317 >>> m = s.model()
6318 >>> f_i = m[f]
6319 >>> f_i.num_entries()
6320 1
6321 >>> e = f_i.entry(0)
6322 >>> e.num_args()
6323 2
6324 """
6325 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6326
6327 def arg_value(self, idx):
6328 """Return the value of argument `idx`.
6329
6330 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6331 >>> s = Solver()
6332 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6333 >>> s.check()
6334 sat
6335 >>> m = s.model()
6336 >>> f_i = m[f]
6337 >>> f_i.num_entries()
6338 1
6339 >>> e = f_i.entry(0)
6340 >>> e
6341 [1, 2, 20]
6342 >>> e.num_args()
6343 2
6344 >>> e.arg_value(0)
6345 1
6346 >>> e.arg_value(1)
6347 2
6348 >>> try:
6349 ... e.arg_value(2)
6350 ... except IndexError:
6351 ... print("index error")
6352 index error
6353 """
6354 if idx >= self.num_args():
6355 raise IndexError
6356 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6357
6358 def value(self):
6359 """Return the value of the function at point `self`.
6360
6361 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6362 >>> s = Solver()
6363 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6364 >>> s.check()
6365 sat
6366 >>> m = s.model()
6367 >>> f_i = m[f]
6368 >>> f_i.num_entries()
6369 1
6370 >>> e = f_i.entry(0)
6371 >>> e
6372 [1, 2, 20]
6373 >>> e.num_args()
6374 2
6375 >>> e.value()
6376 20
6377 """
6378 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6379
6380 def as_list(self):
6381 """Return entry `self` as a Python list.
6382 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6383 >>> s = Solver()
6384 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6385 >>> s.check()
6386 sat
6387 >>> m = s.model()
6388 >>> f_i = m[f]
6389 >>> f_i.num_entries()
6390 1
6391 >>> e = f_i.entry(0)
6392 >>> e.as_list()
6393 [1, 2, 20]
6394 """
6395 args = [self.arg_value(i) for i in range(self.num_args())]
6396 args.append(self.value())
6397 return args
6398
6399 def __repr__(self):
6400 return repr(self.as_list())
6401
6402
6404 """Stores the interpretation of a function in a Z3 model."""
6405
6406 def __init__(self, f, ctx):
6407 self.f = f
6408 self.ctx = ctx
6409 if self.f is not None:
6410 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6411
6412 def __del__(self):
6413 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6414 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6415
6416 def else_value(self):
6417 """
6418 Return the `else` value for a function interpretation.
6419 Return None if Z3 did not specify the `else` value for
6420 this object.
6421
6422 >>> f = Function('f', IntSort(), IntSort())
6423 >>> s = Solver()
6424 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6425 >>> s.check()
6426 sat
6427 >>> m = s.model()
6428 >>> m[f]
6429 [2 -> 0, else -> 1]
6430 >>> m[f].else_value()
6431 1
6432 """
6433 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6434 if r:
6435 return _to_expr_ref(r, self.ctx)
6436 else:
6437 return None
6438
6439 def num_entries(self):
6440 """Return the number of entries/points in the function interpretation `self`.
6441
6442 >>> f = Function('f', IntSort(), IntSort())
6443 >>> s = Solver()
6444 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6445 >>> s.check()
6446 sat
6447 >>> m = s.model()
6448 >>> m[f]
6449 [2 -> 0, else -> 1]
6450 >>> m[f].num_entries()
6451 1
6452 """
6453 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6454
6455 def arity(self):
6456 """Return the number of arguments for each entry in the function interpretation `self`.
6457
6458 >>> f = Function('f', IntSort(), IntSort())
6459 >>> s = Solver()
6460 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6461 >>> s.check()
6462 sat
6463 >>> m = s.model()
6464 >>> m[f].arity()
6465 1
6466 """
6467 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6468
6469 def entry(self, idx):
6470 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6471
6472 >>> f = Function('f', IntSort(), IntSort())
6473 >>> s = Solver()
6474 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6475 >>> s.check()
6476 sat
6477 >>> m = s.model()
6478 >>> m[f]
6479 [2 -> 0, else -> 1]
6480 >>> m[f].num_entries()
6481 1
6482 >>> m[f].entry(0)
6483 [2, 0]
6484 """
6485 if idx >= self.num_entries():
6486 raise IndexError
6487 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6488
6489 def translate(self, other_ctx):
6490 """Copy model 'self' to context 'other_ctx'.
6491 """
6492 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6493
6494 def __copy__(self):
6495 return self.translate(self.ctx)
6496
6497 def __deepcopy__(self, memo={}):
6498 return self.translate(self.ctx)
6499
6500 def as_list(self):
6501 """Return the function interpretation as a Python list.
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].as_list()
6511 [[2, 0], 1]
6512 """
6513 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6514 r.append(self.else_value())
6515 return r
6516
6517 def __repr__(self):
6518 return obj_to_string(self)
6519
6520
6522 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6523
6524 def __init__(self, m, ctx):
6525 assert ctx is not None
6526 self.model = m
6527 self.ctx = ctx
6528 Z3_model_inc_ref(self.ctx.ref(), self.model)
6529
6530 def __del__(self):
6531 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6532 Z3_model_dec_ref(self.ctx.ref(), self.model)
6533
6534 def __repr__(self):
6535 return obj_to_string(self)
6536
6537 def sexpr(self):
6538 """Return a textual representation of the s-expression representing the model."""
6539 return Z3_model_to_string(self.ctx.ref(), self.model)
6540
6541 def eval(self, t, model_completion=False):
6542 """Evaluate the expression `t` in the model `self`.
6543 If `model_completion` is enabled, then a default interpretation is automatically added
6544 for symbols that do not have an interpretation in the model `self`.
6545
6546 >>> x = Int('x')
6547 >>> s = Solver()
6548 >>> s.add(x > 0, x < 2)
6549 >>> s.check()
6550 sat
6551 >>> m = s.model()
6552 >>> m.eval(x + 1)
6553 2
6554 >>> m.eval(x == 1)
6555 True
6556 >>> y = Int('y')
6557 >>> m.eval(y + x)
6558 1 + y
6559 >>> m.eval(y)
6560 y
6561 >>> m.eval(y, model_completion=True)
6562 0
6563 >>> # Now, m contains an interpretation for y
6564 >>> m.eval(y + x)
6565 1
6566 """
6567 r = (Ast * 1)()
6568 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6569 return _to_expr_ref(r[0], self.ctx)
6570 raise Z3Exception("failed to evaluate expression in the model")
6571
6572 def evaluate(self, t, model_completion=False):
6573 """Alias for `eval`.
6574
6575 >>> x = Int('x')
6576 >>> s = Solver()
6577 >>> s.add(x > 0, x < 2)
6578 >>> s.check()
6579 sat
6580 >>> m = s.model()
6581 >>> m.evaluate(x + 1)
6582 2
6583 >>> m.evaluate(x == 1)
6584 True
6585 >>> y = Int('y')
6586 >>> m.evaluate(y + x)
6587 1 + y
6588 >>> m.evaluate(y)
6589 y
6590 >>> m.evaluate(y, model_completion=True)
6591 0
6592 >>> # Now, m contains an interpretation for y
6593 >>> m.evaluate(y + x)
6594 1
6595 """
6596 return self.eval(t, model_completion)
6597
6598 def __len__(self):
6599 """Return the number of constant and function declarations in the model `self`.
6600
6601 >>> f = Function('f', IntSort(), IntSort())
6602 >>> x = Int('x')
6603 >>> s = Solver()
6604 >>> s.add(x > 0, f(x) != x)
6605 >>> s.check()
6606 sat
6607 >>> m = s.model()
6608 >>> len(m)
6609 2
6610 """
6611 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6612 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6613 return num_consts + num_funcs
6614
6615 def get_interp(self, decl):
6616 """Return the interpretation for a given declaration or constant.
6617
6618 >>> f = Function('f', IntSort(), IntSort())
6619 >>> x = Int('x')
6620 >>> s = Solver()
6621 >>> s.add(x > 0, x < 2, f(x) == 0)
6622 >>> s.check()
6623 sat
6624 >>> m = s.model()
6625 >>> m[x]
6626 1
6627 >>> m[f]
6628 [else -> 0]
6629 """
6630 if z3_debug():
6631 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6632 if is_const(decl):
6633 decl = decl.decl()
6634 try:
6635 if decl.arity() == 0:
6636 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6637 if _r.value is None:
6638 return None
6639 r = _to_expr_ref(_r, self.ctx)
6640 if is_as_array(r):
6641 fi = self.get_interp(get_as_array_func(r))
6642 if fi is None:
6643 return fi
6644 e = fi.else_value()
6645 if e is None:
6646 return fi
6647 if fi.arity() != 1:
6648 return fi
6649 srt = decl.range()
6650 dom = srt.domain()
6651 e = K(dom, e)
6652 i = 0
6653 sz = fi.num_entries()
6654 n = fi.arity()
6655 while i < sz:
6656 fe = fi.entry(i)
6657 e = Store(e, fe.arg_value(0), fe.value())
6658 i += 1
6659 return e
6660 else:
6661 return r
6662 else:
6663 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6664 except Z3Exception:
6665 return None
6666
6667 def num_sorts(self):
6668 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6669
6670 >>> A = DeclareSort('A')
6671 >>> a, b = Consts('a b', A)
6672 >>> s = Solver()
6673 >>> s.add(a != b)
6674 >>> s.check()
6675 sat
6676 >>> m = s.model()
6677 >>> m.num_sorts()
6678 1
6679 """
6680 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6681
6682 def get_sort(self, idx):
6683 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6684
6685 >>> A = DeclareSort('A')
6686 >>> B = DeclareSort('B')
6687 >>> a1, a2 = Consts('a1 a2', A)
6688 >>> b1, b2 = Consts('b1 b2', B)
6689 >>> s = Solver()
6690 >>> s.add(a1 != a2, b1 != b2)
6691 >>> s.check()
6692 sat
6693 >>> m = s.model()
6694 >>> m.num_sorts()
6695 2
6696 >>> m.get_sort(0)
6697 A
6698 >>> m.get_sort(1)
6699 B
6700 """
6701 if idx >= self.num_sorts():
6702 raise IndexError
6703 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6704
6705 def sorts(self):
6706 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6707
6708 >>> A = DeclareSort('A')
6709 >>> B = DeclareSort('B')
6710 >>> a1, a2 = Consts('a1 a2', A)
6711 >>> b1, b2 = Consts('b1 b2', B)
6712 >>> s = Solver()
6713 >>> s.add(a1 != a2, b1 != b2)
6714 >>> s.check()
6715 sat
6716 >>> m = s.model()
6717 >>> m.sorts()
6718 [A, B]
6719 """
6720 return [self.get_sort(i) for i in range(self.num_sorts())]
6721
6722 def get_universe(self, s):
6723 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6724
6725 >>> A = DeclareSort('A')
6726 >>> a, b = Consts('a b', A)
6727 >>> s = Solver()
6728 >>> s.add(a != b)
6729 >>> s.check()
6730 sat
6731 >>> m = s.model()
6732 >>> m.get_universe(A)
6733 [A!val!1, A!val!0]
6734 """
6735 if z3_debug():
6736 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6737 try:
6738 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6739 except Z3Exception:
6740 return None
6741
6742 def __getitem__(self, idx):
6743 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6744 If `idx` is a declaration, then the actual interpretation is returned.
6745
6746 The elements can be retrieved using position or the actual declaration.
6747
6748 >>> f = Function('f', IntSort(), IntSort())
6749 >>> x = Int('x')
6750 >>> s = Solver()
6751 >>> s.add(x > 0, x < 2, f(x) == 0)
6752 >>> s.check()
6753 sat
6754 >>> m = s.model()
6755 >>> len(m)
6756 2
6757 >>> m[0]
6758 x
6759 >>> m[1]
6760 f
6761 >>> m[x]
6762 1
6763 >>> m[f]
6764 [else -> 0]
6765 >>> for d in m: print("%s -> %s" % (d, m[d]))
6766 x -> 1
6767 f -> [else -> 0]
6768 """
6769 if _is_int(idx):
6770 if idx >= len(self):
6771 raise IndexError
6772 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6773 if (idx < num_consts):
6774 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6775 else:
6776 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6777 if isinstance(idx, FuncDeclRef):
6778 return self.get_interp(idx)
6779 if is_const(idx):
6780 return self.get_interp(idx.decl())
6781 if isinstance(idx, SortRef):
6782 return self.get_universe(idx)
6783 if z3_debug():
6784 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6785 return None
6786
6787 def decls(self):
6788 """Return a list with all symbols that have an interpretation in the model `self`.
6789 >>> f = Function('f', IntSort(), IntSort())
6790 >>> x = Int('x')
6791 >>> s = Solver()
6792 >>> s.add(x > 0, x < 2, f(x) == 0)
6793 >>> s.check()
6794 sat
6795 >>> m = s.model()
6796 >>> m.decls()
6797 [x, f]
6798 """
6799 r = []
6800 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6801 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6802 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6803 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6804 return r
6805
6806 def update_value(self, x, value):
6807 """Update the interpretation of a constant"""
6808 if is_expr(x):
6809 x = x.decl()
6810 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6811 fi1 = value.f
6812 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6813 fi2 = FuncInterp(fi2, x.ctx)
6814 for i in range(value.num_entries()):
6815 e = value.entry(i)
6816 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6817 v = AstVector()
6818 for j in range(n):
6819 v.push(e.arg_value(j))
6820 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6821 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6822 return
6823 if not is_func_decl(x) or x.arity() != 0:
6824 raise Z3Exception("Expecting 0-ary function or constant expression")
6825 value = _py2expr(value)
6826 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6827
6828 def translate(self, target):
6829 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6830 """
6831 if z3_debug():
6832 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6833 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6834 return ModelRef(model, target)
6835
6836 def project(self, vars, fml):
6837 """Perform model-based projection on fml with respect to vars.
6838 Assume that the model satisfies fml. Then compute a projection fml_p, such
6839 that vars do not occur free in fml_p, fml_p is true in the model and
6840 fml_p => exists vars . fml
6841 """
6842 ctx = self.ctx.ref()
6843 _vars = (Ast * len(vars))()
6844 for i in range(len(vars)):
6845 _vars[i] = vars[i].as_ast()
6846 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6847
6848 def project_with_witness(self, vars, fml):
6849 """Perform model-based projection, but also include realizer terms for the projected variables"""
6850 ctx = self.ctx.ref()
6851 _vars = (Ast * len(vars))()
6852 for i in range(len(vars)):
6853 _vars[i] = vars[i].as_ast()
6854 defs = AstMap()
6855 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6856 result = _to_expr_ref(result, self.ctx)
6857 return result, defs
6858
6859
6860 def __copy__(self):
6861 return self.translate(self.ctx)
6862
6863 def __deepcopy__(self, memo={}):
6864 return self.translate(self.ctx)
6865
6866
6867def Model(ctx=None, eval = {}):
6868 ctx = _get_ctx(ctx)
6869 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6870 for k, v in eval.items():
6871 mdl.update_value(k, v)
6872 return mdl
6873
6874
6876 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6877 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6878
6879
6881 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6882 if z3_debug():
6883 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6884 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6885
6886
6891
6892
6894 """Statistics for `Solver.check()`."""
6895
6896 def __init__(self, stats, ctx):
6897 self.stats = stats
6898 self.ctx = ctx
6899 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6900
6901 def __deepcopy__(self, memo={}):
6902 return Statistics(self.stats, self.ctx)
6903
6904 def __del__(self):
6905 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6906 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6907
6908 def __repr__(self):
6909 if in_html_mode():
6910 out = io.StringIO()
6911 even = True
6912 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6913 for k, v in self:
6914 if even:
6915 out.write(u('<tr style="background-color:#CFCFCF">'))
6916 even = False
6917 else:
6918 out.write(u("<tr>"))
6919 even = True
6920 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6921 out.write(u("</table>"))
6922 return out.getvalue()
6923 else:
6924 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6925
6926 def __len__(self):
6927 """Return the number of statistical counters.
6928
6929 >>> x = Int('x')
6930 >>> s = Then('simplify', 'nlsat').solver()
6931 >>> s.add(x > 0)
6932 >>> s.check()
6933 sat
6934 >>> st = s.statistics()
6935 >>> len(st)
6936 7
6937 """
6938 return int(Z3_stats_size(self.ctx.ref(), self.stats))
6939
6940 def __getitem__(self, idx):
6941 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6942
6943 >>> x = Int('x')
6944 >>> s = Then('simplify', 'nlsat').solver()
6945 >>> s.add(x > 0)
6946 >>> s.check()
6947 sat
6948 >>> st = s.statistics()
6949 >>> len(st)
6950 7
6951 >>> st[0]
6952 ('nlsat propagations', 2)
6953 >>> st[1]
6954 ('nlsat restarts', 1)
6955 """
6956 if idx >= len(self):
6957 raise IndexError
6958 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6959 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6960 else:
6961 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6962 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
6963
6964 def keys(self):
6965 """Return the list of statistical counters.
6966
6967 >>> x = Int('x')
6968 >>> s = Then('simplify', 'nlsat').solver()
6969 >>> s.add(x > 0)
6970 >>> s.check()
6971 sat
6972 >>> st = s.statistics()
6973 """
6974 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
6975
6976 def get_key_value(self, key):
6977 """Return the value of a particular statistical counter.
6978
6979 >>> x = Int('x')
6980 >>> s = Then('simplify', 'nlsat').solver()
6981 >>> s.add(x > 0)
6982 >>> s.check()
6983 sat
6984 >>> st = s.statistics()
6985 >>> st.get_key_value('nlsat propagations')
6986 2
6987 """
6988 for idx in range(len(self)):
6989 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
6990 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6991 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6992 else:
6993 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6994 raise Z3Exception("unknown key")
6995
6996 def __getattr__(self, name):
6997 """Access the value of statistical using attributes.
6998
6999 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
7000 we should use '_' (e.g., 'nlsat_propagations').
7001
7002 >>> x = Int('x')
7003 >>> s = Then('simplify', 'nlsat').solver()
7004 >>> s.add(x > 0)
7005 >>> s.check()
7006 sat
7007 >>> st = s.statistics()
7008 >>> st.nlsat_propagations
7009 2
7010 >>> st.nlsat_stages
7011 2
7012 """
7013 key = name.replace("_", " ")
7014 try:
7015 return self.get_key_value(key)
7016 except Z3Exception:
7017 raise AttributeError
7018
7019
7024
7025
7027 """Represents the result of a satisfiability check: sat, unsat, unknown.
7028
7029 >>> s = Solver()
7030 >>> s.check()
7031 sat
7032 >>> r = s.check()
7033 >>> isinstance(r, CheckSatResult)
7034 True
7035 """
7036
7037 def __init__(self, r):
7038 self.r = r
7039
7040 def __deepcopy__(self, memo={}):
7041 return CheckSatResult(self.r)
7042
7043 def __eq__(self, other):
7044 return isinstance(other, CheckSatResult) and self.r == other.r
7045
7046 def __ne__(self, other):
7047 return not self.__eq__(other)
7048
7049 def __repr__(self):
7050 if in_html_mode():
7051 if self.r == Z3_L_TRUE:
7052 return "<b>sat</b>"
7053 elif self.r == Z3_L_FALSE:
7054 return "<b>unsat</b>"
7055 else:
7056 return "<b>unknown</b>"
7057 else:
7058 if self.r == Z3_L_TRUE:
7059 return "sat"
7060 elif self.r == Z3_L_FALSE:
7061 return "unsat"
7062 else:
7063 return "unknown"
7064
7065 def _repr_html_(self):
7066 in_html = in_html_mode()
7067 set_html_mode(True)
7068 res = repr(self)
7069 set_html_mode(in_html)
7070 return res
7071
7072
7073sat = CheckSatResult(Z3_L_TRUE)
7074unsat = CheckSatResult(Z3_L_FALSE)
7075unknown = CheckSatResult(Z3_L_UNDEF)
7076
7077
7079 """
7080 Solver API provides methods for implementing the main SMT 2.0 commands:
7081 push, pop, check, get-model, etc.
7082 """
7083
7084 def __init__(self, solver=None, ctx=None, logFile=None):
7085 assert solver is None or ctx is not None
7086 self.ctx = _get_ctx(ctx)
7087 self.backtrack_level = 4000000000
7088 self.solver = None
7089 if solver is None:
7090 self.solver = Z3_mk_solver(self.ctx.ref())
7091 else:
7092 self.solver = solver
7093 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7094 if logFile is not None:
7095 self.set("smtlib2_log", logFile)
7096
7097 def __del__(self):
7098 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7099 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7100
7101 def __enter__(self):
7102 self.push()
7103 return self
7104
7105 def __exit__(self, *exc_info):
7106 self.pop()
7107
7108 def set(self, *args, **keys):
7109 """Set a configuration option.
7110 The method `help()` return a string containing all available options.
7111
7112 >>> s = Solver()
7113 >>> # The option MBQI can be set using three different approaches.
7114 >>> s.set(mbqi=True)
7115 >>> s.set('MBQI', True)
7116 >>> s.set(':mbqi', True)
7117 """
7118 p = args2params(args, keys, self.ctx)
7119 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7120
7121 def push(self):
7122 """Create a backtracking point.
7123
7124 >>> x = Int('x')
7125 >>> s = Solver()
7126 >>> s.add(x > 0)
7127 >>> s
7128 [x > 0]
7129 >>> s.push()
7130 >>> s.add(x < 1)
7131 >>> s
7132 [x > 0, x < 1]
7133 >>> s.check()
7134 unsat
7135 >>> s.pop()
7136 >>> s.check()
7137 sat
7138 >>> s
7139 [x > 0]
7140 """
7141 Z3_solver_push(self.ctx.ref(), self.solver)
7142
7143 def pop(self, num=1):
7144 """Backtrack \\c num backtracking points.
7145
7146 >>> x = Int('x')
7147 >>> s = Solver()
7148 >>> s.add(x > 0)
7149 >>> s
7150 [x > 0]
7151 >>> s.push()
7152 >>> s.add(x < 1)
7153 >>> s
7154 [x > 0, x < 1]
7155 >>> s.check()
7156 unsat
7157 >>> s.pop()
7158 >>> s.check()
7159 sat
7160 >>> s
7161 [x > 0]
7162 """
7163 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7164
7165 def num_scopes(self):
7166 """Return the current number of backtracking points.
7167
7168 >>> s = Solver()
7169 >>> s.num_scopes()
7170 0
7171 >>> s.push()
7172 >>> s.num_scopes()
7173 1
7174 >>> s.push()
7175 >>> s.num_scopes()
7176 2
7177 >>> s.pop()
7178 >>> s.num_scopes()
7179 1
7180 """
7181 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7182
7183 def reset(self):
7184 """Remove all asserted constraints and backtracking points created using `push()`.
7185
7186 >>> x = Int('x')
7187 >>> s = Solver()
7188 >>> s.add(x > 0)
7189 >>> s
7190 [x > 0]
7191 >>> s.reset()
7192 >>> s
7193 []
7194 """
7195 Z3_solver_reset(self.ctx.ref(), self.solver)
7196
7197 def assert_exprs(self, *args):
7198 """Assert constraints into the solver.
7199
7200 >>> x = Int('x')
7201 >>> s = Solver()
7202 >>> s.assert_exprs(x > 0, x < 2)
7203 >>> s
7204 [x > 0, x < 2]
7205 """
7206 args = _get_args(args)
7207 s = BoolSort(self.ctx)
7208 for arg in args:
7209 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7210 for f in arg:
7211 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7212 else:
7213 arg = s.cast(arg)
7214 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7215
7216 def add(self, *args):
7217 """Assert constraints into the solver.
7218
7219 >>> x = Int('x')
7220 >>> s = Solver()
7221 >>> s.add(x > 0, x < 2)
7222 >>> s
7223 [x > 0, x < 2]
7224 """
7225 self.assert_exprs(*args)
7226
7227 def __iadd__(self, fml):
7228 self.add(fml)
7229 return self
7230
7231 def append(self, *args):
7232 """Assert constraints into the solver.
7233
7234 >>> x = Int('x')
7235 >>> s = Solver()
7236 >>> s.append(x > 0, x < 2)
7237 >>> s
7238 [x > 0, x < 2]
7239 """
7240 self.assert_exprs(*args)
7241
7242 def insert(self, *args):
7243 """Assert constraints into the solver.
7244
7245 >>> x = Int('x')
7246 >>> s = Solver()
7247 >>> s.insert(x > 0, x < 2)
7248 >>> s
7249 [x > 0, x < 2]
7250 """
7251 self.assert_exprs(*args)
7252
7253 def assert_and_track(self, a, p):
7254 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7255
7256 If `p` is a string, it will be automatically converted into a Boolean constant.
7257
7258 >>> x = Int('x')
7259 >>> p3 = Bool('p3')
7260 >>> s = Solver()
7261 >>> s.set(unsat_core=True)
7262 >>> s.assert_and_track(x > 0, 'p1')
7263 >>> s.assert_and_track(x != 1, 'p2')
7264 >>> s.assert_and_track(x < 0, p3)
7265 >>> print(s.check())
7266 unsat
7267 >>> c = s.unsat_core()
7268 >>> len(c)
7269 2
7270 >>> Bool('p1') in c
7271 True
7272 >>> Bool('p2') in c
7273 False
7274 >>> p3 in c
7275 True
7276 """
7277 if isinstance(p, str):
7278 p = Bool(p, self.ctx)
7279 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7280 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7281 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7282
7283 def check(self, *assumptions):
7284 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7285
7286 >>> x = Int('x')
7287 >>> s = Solver()
7288 >>> s.check()
7289 sat
7290 >>> s.add(x > 0, x < 2)
7291 >>> s.check()
7292 sat
7293 >>> s.model().eval(x)
7294 1
7295 >>> s.add(x < 1)
7296 >>> s.check()
7297 unsat
7298 >>> s.reset()
7299 >>> s.add(2**x == 4)
7300 >>> s.check()
7301 sat
7302 """
7303 s = BoolSort(self.ctx)
7304 assumptions = _get_args(assumptions)
7305 num = len(assumptions)
7306 _assumptions = (Ast * num)()
7307 for i in range(num):
7308 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7309 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7310 return CheckSatResult(r)
7311
7312 def model(self):
7313 """Return a model for the last `check()`.
7314
7315 This function raises an exception if
7316 a model is not available (e.g., last `check()` returned unsat).
7317
7318 >>> s = Solver()
7319 >>> a = Int('a')
7320 >>> s.add(a + 2 == 0)
7321 >>> s.check()
7322 sat
7323 >>> s.model()
7324 [a = -2]
7325 """
7326 try:
7327 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7328 except Z3Exception:
7329 raise Z3Exception("model is not available")
7330
7331 def import_model_converter(self, other):
7332 """Import model converter from other into the current solver"""
7333 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7334
7335 def interrupt(self):
7336 """Interrupt the execution of the solver object.
7337 Remarks: This ensures that the interrupt applies only
7338 to the given solver object and it applies only if it is running.
7339 """
7340 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7341
7342 def unsat_core(self):
7343 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7344
7345 These are the assumptions Z3 used in the unsatisfiability proof.
7346 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7347 They may be also used to "retract" assumptions. Note that, assumptions are not really
7348 "soft constraints", but they can be used to implement them.
7349
7350 >>> p1, p2, p3 = Bools('p1 p2 p3')
7351 >>> x, y = Ints('x y')
7352 >>> s = Solver()
7353 >>> s.add(Implies(p1, x > 0))
7354 >>> s.add(Implies(p2, y > x))
7355 >>> s.add(Implies(p2, y < 1))
7356 >>> s.add(Implies(p3, y > -3))
7357 >>> s.check(p1, p2, p3)
7358 unsat
7359 >>> core = s.unsat_core()
7360 >>> len(core)
7361 2
7362 >>> p1 in core
7363 True
7364 >>> p2 in core
7365 True
7366 >>> p3 in core
7367 False
7368 >>> # "Retracting" p2
7369 >>> s.check(p1, p3)
7370 sat
7371 """
7372 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7373
7374 def consequences(self, assumptions, variables):
7375 """Determine fixed values for the variables based on the solver state and assumptions.
7376 >>> s = Solver()
7377 >>> a, b, c, d = Bools('a b c d')
7378 >>> s.add(Implies(a,b), Implies(b, c))
7379 >>> s.consequences([a],[b,c,d])
7380 (sat, [Implies(a, b), Implies(a, c)])
7381 >>> s.consequences([Not(c),d],[a,b,c,d])
7382 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7383 """
7384 if isinstance(assumptions, list):
7385 _asms = AstVector(None, self.ctx)
7386 for a in assumptions:
7387 _asms.push(a)
7388 assumptions = _asms
7389 if isinstance(variables, list):
7390 _vars = AstVector(None, self.ctx)
7391 for a in variables:
7392 _vars.push(a)
7393 variables = _vars
7394 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7395 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7396 consequences = AstVector(None, self.ctx)
7397 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7398 variables.vector, consequences.vector)
7399 sz = len(consequences)
7400 consequences = [consequences[i] for i in range(sz)]
7401 return CheckSatResult(r), consequences
7402
7403 def from_file(self, filename):
7404 """Parse assertions from a file"""
7405 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7406
7407 def from_string(self, s):
7408 """Parse assertions from a string"""
7409 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7410
7411 def cube(self, vars=None):
7412 """Get set of cubes
7413 The method takes an optional set of variables that restrict which
7414 variables may be used as a starting point for cubing.
7415 If vars is not None, then the first case split is based on a variable in
7416 this set.
7417 """
7418 self.cube_vs = AstVector(None, self.ctx)
7419 if vars is not None:
7420 for v in vars:
7421 self.cube_vs.push(v)
7422 while True:
7423 lvl = self.backtrack_level
7424 self.backtrack_level = 4000000000
7425 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7426 if (len(r) == 1 and is_false(r[0])):
7427 return
7428 yield r
7429 if (len(r) == 0):
7430 return
7431
7432 def cube_vars(self):
7433 """Access the set of variables that were touched by the most recently generated cube.
7434 This set of variables can be used as a starting point for additional cubes.
7435 The idea is that variables that appear in clauses that are reduced by the most recent
7436 cube are likely more useful to cube on."""
7437 return self.cube_vs
7438
7439 def root(self, t):
7440 """Retrieve congruence closure root of the term t relative to the current search state
7441 The function primarily works for SimpleSolver. Terms and variables that are
7442 eliminated during pre-processing are not visible to the congruence closure.
7443 """
7444 t = _py2expr(t, self.ctx)
7445 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7446
7447 def next(self, t):
7448 """Retrieve congruence closure sibling of the term t relative to the current search state
7449 The function primarily works for SimpleSolver. Terms and variables that are
7450 eliminated during pre-processing are not visible to the congruence closure.
7451 """
7452 t = _py2expr(t, self.ctx)
7453 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7454
7455 def explain_congruent(self, a, b):
7456 """Explain congruence of a and b relative to the current search state"""
7457 a = _py2expr(a, self.ctx)
7458 b = _py2expr(b, self.ctx)
7459 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7460
7461
7462 def solve_for(self, ts):
7463 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7464 vars = AstVector(ctx=self.ctx);
7465 terms = AstVector(ctx=self.ctx);
7466 guards = AstVector(ctx=self.ctx);
7467 for t in ts:
7468 t = _py2expr(t, self.ctx)
7469 vars.push(t)
7470 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7471 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7472
7473
7474 def proof(self):
7475 """Return a proof for the last `check()`. Proof construction must be enabled."""
7476 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7477
7478 def assertions(self):
7479 """Return an AST vector containing all added constraints.
7480
7481 >>> s = Solver()
7482 >>> s.assertions()
7483 []
7484 >>> a = Int('a')
7485 >>> s.add(a > 0)
7486 >>> s.add(a < 10)
7487 >>> s.assertions()
7488 [a > 0, a < 10]
7489 """
7490 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7491
7492 def units(self):
7493 """Return an AST vector containing all currently inferred units.
7494 """
7495 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7496
7497 def non_units(self):
7498 """Return an AST vector containing all atomic formulas in solver state that are not units.
7499 """
7500 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7501
7502 def trail_levels(self):
7503 """Return trail and decision levels of the solver state after a check() call.
7504 """
7505 trail = self.trail()
7506 levels = (ctypes.c_uint * len(trail))()
7507 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7508 return trail, levels
7509
7510 def set_initial_value(self, var, value):
7511 """initialize the solver's state by setting the initial value of var to value
7512 """
7513 s = var.sort()
7514 value = s.cast(value)
7515 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7516
7517 def trail(self):
7518 """Return trail of the solver state after a check() call.
7519 """
7520 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7521
7522 def statistics(self):
7523 """Return statistics for the last `check()`.
7524
7525 >>> s = SimpleSolver()
7526 >>> x = Int('x')
7527 >>> s.add(x > 0)
7528 >>> s.check()
7529 sat
7530 >>> st = s.statistics()
7531 >>> st.get_key_value('final checks')
7532 1
7533 >>> len(st) > 0
7534 True
7535 >>> st[0] != 0
7536 True
7537 """
7538 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7539
7540 def reason_unknown(self):
7541 """Return a string describing why the last `check()` returned `unknown`.
7542
7543 >>> x = Int('x')
7544 >>> s = SimpleSolver()
7545 >>> s.add(x == 2**x)
7546 >>> s.check()
7547 unknown
7548 >>> s.reason_unknown()
7549 '(incomplete (theory arithmetic))'
7550 """
7551 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7552
7553 def help(self):
7554 """Display a string describing all available options."""
7555 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7556
7557 def param_descrs(self):
7558 """Return the parameter description set."""
7559 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7560
7561 def __repr__(self):
7562 """Return a formatted string with all added constraints."""
7563 return obj_to_string(self)
7564
7565 def translate(self, target):
7566 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7567
7568 >>> c1 = Context()
7569 >>> c2 = Context()
7570 >>> s1 = Solver(ctx=c1)
7571 >>> s2 = s1.translate(c2)
7572 """
7573 if z3_debug():
7574 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7575 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7576 return Solver(solver, target)
7577
7578 def __copy__(self):
7579 return self.translate(self.ctx)
7580
7581 def __deepcopy__(self, memo={}):
7582 return self.translate(self.ctx)
7583
7584 def sexpr(self):
7585 """Return a formatted string (in Lisp-like format) with all added constraints.
7586 We say the string is in s-expression format.
7587
7588 >>> x = Int('x')
7589 >>> s = Solver()
7590 >>> s.add(x > 0)
7591 >>> s.add(x < 2)
7592 >>> r = s.sexpr()
7593 """
7594 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7595
7596 def dimacs(self, include_names=True):
7597 """Return a textual representation of the solver in DIMACS format."""
7598 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7599
7600 def to_smt2(self):
7601 """return SMTLIB2 formatted benchmark for solver's assertions"""
7602 es = self.assertions()
7603 sz = len(es)
7604 sz1 = sz
7605 if sz1 > 0:
7606 sz1 -= 1
7607 v = (Ast * sz1)()
7608 for i in range(sz1):
7609 v[i] = es[i].as_ast()
7610 if sz > 0:
7611 e = es[sz1].as_ast()
7612 else:
7613 e = BoolVal(True, self.ctx).as_ast()
7614 return Z3_benchmark_to_smtlib_string(
7615 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7616 )
7617
7618
7619def SolverFor(logic, ctx=None, logFile=None):
7620 """Create a solver customized for the given logic.
7621
7622 The parameter `logic` is a string. It should be contains
7623 the name of a SMT-LIB logic.
7624 See http://www.smtlib.org/ for the name of all available logics.
7625
7626 >>> s = SolverFor("QF_LIA")
7627 >>> x = Int('x')
7628 >>> s.add(x > 0)
7629 >>> s.add(x < 2)
7630 >>> s.check()
7631 sat
7632 >>> s.model()
7633 [x = 1]
7634 """
7635 ctx = _get_ctx(ctx)
7636 logic = to_symbol(logic)
7637 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7638
7639
7640def SimpleSolver(ctx=None, logFile=None):
7641 """Return a simple general purpose solver with limited amount of preprocessing.
7642
7643 >>> s = SimpleSolver()
7644 >>> x = Int('x')
7645 >>> s.add(x > 0)
7646 >>> s.check()
7647 sat
7648 """
7649 ctx = _get_ctx(ctx)
7650 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7651
7652#########################################
7653#
7654# Fixedpoint
7655#
7656#########################################
7657
7658
7659class Fixedpoint(Z3PPObject):
7660 """Fixedpoint API provides methods for solving with recursive predicates"""
7661
7662 def __init__(self, fixedpoint=None, ctx=None):
7663 assert fixedpoint is None or ctx is not None
7664 self.ctx = _get_ctx(ctx)
7665 self.fixedpoint = None
7666 if fixedpoint is None:
7667 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7668 else:
7669 self.fixedpoint = fixedpoint
7670 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7671 self.vars = []
7672
7673 def __deepcopy__(self, memo={}):
7674 return FixedPoint(self.fixedpoint, self.ctx)
7675
7676 def __del__(self):
7677 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7678 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7679
7680 def set(self, *args, **keys):
7681 """Set a configuration option. The method `help()` return a string containing all available options.
7682 """
7683 p = args2params(args, keys, self.ctx)
7684 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7685
7686 def help(self):
7687 """Display a string describing all available options."""
7688 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7689
7690 def param_descrs(self):
7691 """Return the parameter description set."""
7692 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7693
7694 def assert_exprs(self, *args):
7695 """Assert constraints as background axioms for the fixedpoint solver."""
7696 args = _get_args(args)
7697 s = BoolSort(self.ctx)
7698 for arg in args:
7699 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7700 for f in arg:
7701 f = self.abstract(f)
7702 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7703 else:
7704 arg = s.cast(arg)
7705 arg = self.abstract(arg)
7706 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7707
7708 def add(self, *args):
7709 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7710 self.assert_exprs(*args)
7711
7712 def __iadd__(self, fml):
7713 self.add(fml)
7714 return self
7715
7716 def append(self, *args):
7717 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7718 self.assert_exprs(*args)
7719
7720 def insert(self, *args):
7721 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7722 self.assert_exprs(*args)
7723
7724 def add_rule(self, head, body=None, name=None):
7725 """Assert rules defining recursive predicates to the fixedpoint solver.
7726 >>> a = Bool('a')
7727 >>> b = Bool('b')
7728 >>> s = Fixedpoint()
7729 >>> s.register_relation(a.decl())
7730 >>> s.register_relation(b.decl())
7731 >>> s.fact(a)
7732 >>> s.rule(b, a)
7733 >>> s.query(b)
7734 sat
7735 """
7736 if name is None:
7737 name = ""
7738 name = to_symbol(name, self.ctx)
7739 if body is None:
7740 head = self.abstract(head)
7741 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7742 else:
7743 body = _get_args(body)
7744 f = self.abstract(Implies(And(body, self.ctx), head))
7745 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7746
7747 def rule(self, head, body=None, name=None):
7748 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7749 self.add_rule(head, body, name)
7750
7751 def fact(self, head, name=None):
7752 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7753 self.add_rule(head, None, name)
7754
7755 def query(self, *query):
7756 """Query the fixedpoint engine whether formula is derivable.
7757 You can also pass an tuple or list of recursive predicates.
7758 """
7759 query = _get_args(query)
7760 sz = len(query)
7761 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7762 _decls = (FuncDecl * sz)()
7763 i = 0
7764 for q in query:
7765 _decls[i] = q.ast
7766 i = i + 1
7767 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7768 else:
7769 if sz == 1:
7770 query = query[0]
7771 else:
7772 query = And(query, self.ctx)
7773 query = self.abstract(query, False)
7774 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7775 return CheckSatResult(r)
7776
7777 def query_from_lvl(self, lvl, *query):
7778 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7779 """
7780 query = _get_args(query)
7781 sz = len(query)
7782 if sz >= 1 and isinstance(query[0], FuncDecl):
7783 _z3_assert(False, "unsupported")
7784 else:
7785 if sz == 1:
7786 query = query[0]
7787 else:
7788 query = And(query)
7789 query = self.abstract(query, False)
7790 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7791 return CheckSatResult(r)
7792
7793 def update_rule(self, head, body, name):
7794 """update rule"""
7795 if name is None:
7796 name = ""
7797 name = to_symbol(name, self.ctx)
7798 body = _get_args(body)
7799 f = self.abstract(Implies(And(body, self.ctx), head))
7800 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7801
7802 def get_answer(self):
7803 """Retrieve answer from last query call."""
7804 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7805 return _to_expr_ref(r, self.ctx)
7806
7807 def get_ground_sat_answer(self):
7808 """Retrieve a ground cex from last query call."""
7809 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7810 return _to_expr_ref(r, self.ctx)
7811
7812 def get_rules_along_trace(self):
7813 """retrieve rules along the counterexample trace"""
7814 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7815
7816 def get_rule_names_along_trace(self):
7817 """retrieve rule names along the counterexample trace"""
7818 # this is a hack as I don't know how to return a list of symbols from C++;
7819 # obtain names as a single string separated by semicolons
7820 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7821 # split into individual names
7822 return names.split(";")
7823
7824 def get_num_levels(self, predicate):
7825 """Retrieve number of levels used for predicate in PDR engine"""
7826 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7827
7828 def get_cover_delta(self, level, predicate):
7829 """Retrieve properties known about predicate for the level'th unfolding.
7830 -1 is treated as the limit (infinity)
7831 """
7832 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7833 return _to_expr_ref(r, self.ctx)
7834
7835 def add_cover(self, level, predicate, property):
7836 """Add property to predicate for the level'th unfolding.
7837 -1 is treated as infinity (infinity)
7838 """
7839 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7840
7841 def register_relation(self, *relations):
7842 """Register relation as recursive"""
7843 relations = _get_args(relations)
7844 for f in relations:
7845 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7846
7847 def set_predicate_representation(self, f, *representations):
7848 """Control how relation is represented"""
7849 representations = _get_args(representations)
7850 representations = [to_symbol(s) for s in representations]
7851 sz = len(representations)
7852 args = (Symbol * sz)()
7853 for i in range(sz):
7854 args[i] = representations[i]
7855 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7856
7857 def parse_string(self, s):
7858 """Parse rules and queries from a string"""
7859 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7860
7861 def parse_file(self, f):
7862 """Parse rules and queries from a file"""
7863 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7864
7865 def get_rules(self):
7866 """retrieve rules that have been added to fixedpoint context"""
7867 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7868
7869 def get_assertions(self):
7870 """retrieve assertions that have been added to fixedpoint context"""
7871 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7872
7873 def __repr__(self):
7874 """Return a formatted string with all added rules and constraints."""
7875 return self.sexpr()
7876
7877 def sexpr(self):
7878 """Return a formatted string (in Lisp-like format) with all added constraints.
7879 We say the string is in s-expression format.
7880 """
7881 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7882
7883 def to_string(self, queries):
7884 """Return a formatted string (in Lisp-like format) with all added constraints.
7885 We say the string is in s-expression format.
7886 Include also queries.
7887 """
7888 args, len = _to_ast_array(queries)
7889 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7890
7891 def statistics(self):
7892 """Return statistics for the last `query()`.
7893 """
7894 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7895
7896 def reason_unknown(self):
7897 """Return a string describing why the last `query()` returned `unknown`.
7898 """
7899 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7900
7901 def declare_var(self, *vars):
7902 """Add variable or several variables.
7903 The added variable or variables will be bound in the rules
7904 and queries
7905 """
7906 vars = _get_args(vars)
7907 for v in vars:
7908 self.vars += [v]
7909
7910 def abstract(self, fml, is_forall=True):
7911 if self.vars == []:
7912 return fml
7913 if is_forall:
7914 return ForAll(self.vars, fml)
7915 else:
7916 return Exists(self.vars, fml)
7917
7918
7919#########################################
7920#
7921# Finite domains
7922#
7923#########################################
7924
7925class FiniteDomainSortRef(SortRef):
7926 """Finite domain sort."""
7927
7928 def size(self):
7929 """Return the size of the finite domain sort"""
7930 r = (ctypes.c_ulonglong * 1)()
7931 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7932 return r[0]
7933 else:
7934 raise Z3Exception("Failed to retrieve finite domain sort size")
7935
7936
7937def FiniteDomainSort(name, sz, ctx=None):
7938 """Create a named finite domain sort of a given size sz"""
7939 if not isinstance(name, Symbol):
7940 name = to_symbol(name)
7941 ctx = _get_ctx(ctx)
7942 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7943
7944
7945def is_finite_domain_sort(s):
7946 """Return True if `s` is a Z3 finite-domain sort.
7947
7948 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7949 True
7950 >>> is_finite_domain_sort(IntSort())
7951 False
7952 """
7953 return isinstance(s, FiniteDomainSortRef)
7954
7955
7956class FiniteDomainRef(ExprRef):
7957 """Finite-domain expressions."""
7958
7959 def sort(self):
7960 """Return the sort of the finite-domain expression `self`."""
7961 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7962
7963 def as_string(self):
7964 """Return a Z3 floating point expression as a Python string."""
7965 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7966
7967
7968def is_finite_domain(a):
7969 """Return `True` if `a` is a Z3 finite-domain expression.
7970
7971 >>> s = FiniteDomainSort('S', 100)
7972 >>> b = Const('b', s)
7973 >>> is_finite_domain(b)
7974 True
7975 >>> is_finite_domain(Int('x'))
7976 False
7977 """
7978 return isinstance(a, FiniteDomainRef)
7979
7980
7981class FiniteDomainNumRef(FiniteDomainRef):
7982 """Integer values."""
7983
7984 def as_long(self):
7985 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7986
7987 >>> s = FiniteDomainSort('S', 100)
7988 >>> v = FiniteDomainVal(3, s)
7989 >>> v
7990 3
7991 >>> v.as_long() + 1
7992 4
7993 """
7994 return int(self.as_string())
7995
7996 def as_string(self):
7997 """Return a Z3 finite-domain numeral as a Python string.
7998
7999 >>> s = FiniteDomainSort('S', 100)
8000 >>> v = FiniteDomainVal(42, s)
8001 >>> v.as_string()
8002 '42'
8003 """
8004 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
8005
8006
8007def FiniteDomainVal(val, sort, ctx=None):
8008 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
8009
8010 >>> s = FiniteDomainSort('S', 256)
8011 >>> FiniteDomainVal(255, s)
8012 255
8013 >>> FiniteDomainVal('100', s)
8014 100
8015 """
8016 if z3_debug():
8017 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
8018 ctx = sort.ctx
8019 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
8020
8021
8022def is_finite_domain_value(a):
8023 """Return `True` if `a` is a Z3 finite-domain value.
8024
8025 >>> s = FiniteDomainSort('S', 100)
8026 >>> b = Const('b', s)
8027 >>> is_finite_domain_value(b)
8028 False
8029 >>> b = FiniteDomainVal(10, s)
8030 >>> b
8031 10
8032 >>> is_finite_domain_value(b)
8033 True
8034 """
8035 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
8036
8037
8038#########################################
8039#
8040# Optimize
8041#
8042#########################################
8043
8044class OptimizeObjective:
8045 def __init__(self, opt, value, is_max):
8046 self._opt = opt
8047 self._value = value
8048 self._is_max = is_max
8049
8050 def lower(self):
8051 opt = self._opt
8052 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8053
8054 def upper(self):
8055 opt = self._opt
8056 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8057
8058 def lower_values(self):
8059 opt = self._opt
8060 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8061
8062 def upper_values(self):
8063 opt = self._opt
8064 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8065
8066 def value(self):
8067 if self._is_max:
8068 return self.upper()
8069 else:
8070 return self.lower()
8071
8072 def __str__(self):
8073 return "%s:%s" % (self._value, self._is_max)
8074
8075
8076_on_models = {}
8077
8078
8079def _global_on_model(ctx):
8080 (fn, mdl) = _on_models[ctx]
8081 fn(mdl)
8082
8083
8084_on_model_eh = on_model_eh_type(_global_on_model)
8085
8086
8087class Optimize(Z3PPObject):
8088 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8089
8090 def __init__(self, optimize=None, ctx=None):
8091 self.ctx = _get_ctx(ctx)
8092 if optimize is None:
8093 self.optimize = Z3_mk_optimize(self.ctx.ref())
8094 else:
8095 self.optimize = optimize
8096 self._on_models_id = None
8097 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8098
8099 def __deepcopy__(self, memo={}):
8100 return Optimize(self.optimize, self.ctx)
8101
8102 def __del__(self):
8103 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8104 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8105 if self._on_models_id is not None:
8106 del _on_models[self._on_models_id]
8107
8108 def __enter__(self):
8109 self.push()
8110 return self
8111
8112 def __exit__(self, *exc_info):
8113 self.pop()
8114
8115 def set(self, *args, **keys):
8116 """Set a configuration option.
8117 The method `help()` return a string containing all available options.
8118 """
8119 p = args2params(args, keys, self.ctx)
8120 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8121
8122 def help(self):
8123 """Display a string describing all available options."""
8124 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8125
8126 def param_descrs(self):
8127 """Return the parameter description set."""
8128 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8129
8130 def assert_exprs(self, *args):
8131 """Assert constraints as background axioms for the optimize solver."""
8132 args = _get_args(args)
8133 s = BoolSort(self.ctx)
8134 for arg in args:
8135 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8136 for f in arg:
8137 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8138 else:
8139 arg = s.cast(arg)
8140 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8141
8142 def add(self, *args):
8143 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8144 self.assert_exprs(*args)
8145
8146 def __iadd__(self, fml):
8147 self.add(fml)
8148 return self
8149
8150 def assert_and_track(self, a, p):
8151 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8152
8153 If `p` is a string, it will be automatically converted into a Boolean constant.
8154
8155 >>> x = Int('x')
8156 >>> p3 = Bool('p3')
8157 >>> s = Optimize()
8158 >>> s.assert_and_track(x > 0, 'p1')
8159 >>> s.assert_and_track(x != 1, 'p2')
8160 >>> s.assert_and_track(x < 0, p3)
8161 >>> print(s.check())
8162 unsat
8163 >>> c = s.unsat_core()
8164 >>> len(c)
8165 2
8166 >>> Bool('p1') in c
8167 True
8168 >>> Bool('p2') in c
8169 False
8170 >>> p3 in c
8171 True
8172 """
8173 if isinstance(p, str):
8174 p = Bool(p, self.ctx)
8175 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8176 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8177 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8178
8179 def add_soft(self, arg, weight="1", id=None):
8180 """Add soft constraint with optional weight and optional identifier.
8181 If no weight is supplied, then the penalty for violating the soft constraint
8182 is 1.
8183 Soft constraints are grouped by identifiers. Soft constraints that are
8184 added without identifiers are grouped by default.
8185 """
8186 if _is_int(weight):
8187 weight = "%d" % weight
8188 elif isinstance(weight, float):
8189 weight = "%f" % weight
8190 if not isinstance(weight, str):
8191 raise Z3Exception("weight should be a string or an integer")
8192 if id is None:
8193 id = ""
8194 id = to_symbol(id, self.ctx)
8195
8196 def asoft(a):
8197 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8198 return OptimizeObjective(self, v, False)
8199 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8200 return [asoft(a) for a in arg]
8201 return asoft(arg)
8202
8203 def set_initial_value(self, var, value):
8204 """initialize the solver's state by setting the initial value of var to value
8205 """
8206 s = var.sort()
8207 value = s.cast(value)
8208 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8209
8210 def maximize(self, arg):
8211 """Add objective function to maximize."""
8212 return OptimizeObjective(
8213 self,
8214 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8215 is_max=True,
8216 )
8217
8218 def minimize(self, arg):
8219 """Add objective function to minimize."""
8220 return OptimizeObjective(
8221 self,
8222 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8223 is_max=False,
8224 )
8225
8226 def push(self):
8227 """create a backtracking point for added rules, facts and assertions"""
8228 Z3_optimize_push(self.ctx.ref(), self.optimize)
8229
8230 def pop(self):
8231 """restore to previously created backtracking point"""
8232 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8233
8234 def check(self, *assumptions):
8235 """Check consistency and produce optimal values."""
8236 assumptions = _get_args(assumptions)
8237 num = len(assumptions)
8238 _assumptions = (Ast * num)()
8239 for i in range(num):
8240 _assumptions[i] = assumptions[i].as_ast()
8241 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8242
8243 def reason_unknown(self):
8244 """Return a string that describes why the last `check()` returned `unknown`."""
8245 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8246
8247 def model(self):
8248 """Return a model for the last check()."""
8249 try:
8250 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8251 except Z3Exception:
8252 raise Z3Exception("model is not available")
8253
8254 def unsat_core(self):
8255 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8256
8257 def lower(self, obj):
8258 if not isinstance(obj, OptimizeObjective):
8259 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8260 return obj.lower()
8261
8262 def upper(self, obj):
8263 if not isinstance(obj, OptimizeObjective):
8264 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8265 return obj.upper()
8266
8267 def lower_values(self, obj):
8268 if not isinstance(obj, OptimizeObjective):
8269 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8270 return obj.lower_values()
8271
8272 def upper_values(self, obj):
8273 if not isinstance(obj, OptimizeObjective):
8274 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8275 return obj.upper_values()
8276
8277 def from_file(self, filename):
8278 """Parse assertions and objectives from a file"""
8279 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8280
8281 def from_string(self, s):
8282 """Parse assertions and objectives from a string"""
8283 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8284
8285 def assertions(self):
8286 """Return an AST vector containing all added constraints."""
8287 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8288
8289 def objectives(self):
8290 """returns set of objective functions"""
8291 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8292
8293 def __repr__(self):
8294 """Return a formatted string with all added rules and constraints."""
8295 return self.sexpr()
8296
8297 def sexpr(self):
8298 """Return a formatted string (in Lisp-like format) with all added constraints.
8299 We say the string is in s-expression format.
8300 """
8301 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8302
8303 def statistics(self):
8304 """Return statistics for the last check`.
8305 """
8306 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8307
8308 def set_on_model(self, on_model):
8309 """Register a callback that is invoked with every incremental improvement to
8310 objective values. The callback takes a model as argument.
8311 The life-time of the model is limited to the callback so the
8312 model has to be (deep) copied if it is to be used after the callback
8313 """
8314 id = len(_on_models) + 41
8315 mdl = Model(self.ctx)
8316 _on_models[id] = (on_model, mdl)
8317 self._on_models_id = id
8318 Z3_optimize_register_model_eh(
8319 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8320 )
8321
8322
8323#########################################
8324#
8325# ApplyResult
8326#
8327#########################################
8328class ApplyResult(Z3PPObject):
8329 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8330 It also contains model and proof converters.
8331 """
8332
8333 def __init__(self, result, ctx):
8334 self.result = result
8335 self.ctx = ctx
8336 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8337
8338 def __deepcopy__(self, memo={}):
8339 return ApplyResult(self.result, self.ctx)
8340
8341 def __del__(self):
8342 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8343 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8344
8345 def __len__(self):
8346 """Return the number of subgoals in `self`.
8347
8348 >>> a, b = Ints('a b')
8349 >>> g = Goal()
8350 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8351 >>> t = Tactic('split-clause')
8352 >>> r = t(g)
8353 >>> len(r)
8354 2
8355 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8356 >>> len(t(g))
8357 4
8358 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8359 >>> len(t(g))
8360 1
8361 """
8362 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8363
8364 def __getitem__(self, idx):
8365 """Return one of the subgoals stored in ApplyResult object `self`.
8366
8367 >>> a, b = Ints('a b')
8368 >>> g = Goal()
8369 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8370 >>> t = Tactic('split-clause')
8371 >>> r = t(g)
8372 >>> r[0]
8373 [a == 0, Or(b == 0, b == 1), a > b]
8374 >>> r[1]
8375 [a == 1, Or(b == 0, b == 1), a > b]
8376 """
8377 if idx >= len(self):
8378 raise IndexError
8379 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8380
8381 def __repr__(self):
8382 return obj_to_string(self)
8383
8384 def sexpr(self):
8385 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8386 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8387
8388 def as_expr(self):
8389 """Return a Z3 expression consisting of all subgoals.
8390
8391 >>> x = Int('x')
8392 >>> g = Goal()
8393 >>> g.add(x > 1)
8394 >>> g.add(Or(x == 2, x == 3))
8395 >>> r = Tactic('simplify')(g)
8396 >>> r
8397 [[Not(x <= 1), Or(x == 2, x == 3)]]
8398 >>> r.as_expr()
8399 And(Not(x <= 1), Or(x == 2, x == 3))
8400 >>> r = Tactic('split-clause')(g)
8401 >>> r
8402 [[x > 1, x == 2], [x > 1, x == 3]]
8403 >>> r.as_expr()
8404 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8405 """
8406 sz = len(self)
8407 if sz == 0:
8408 return BoolVal(False, self.ctx)
8409 elif sz == 1:
8410 return self[0].as_expr()
8411 else:
8412 return Or([self[i].as_expr() for i in range(len(self))])
8413
8414#########################################
8415#
8416# Simplifiers
8417#
8418#########################################
8419
8420class Simplifier:
8421 """Simplifiers act as pre-processing utilities for solvers.
8422 Build a custom simplifier and add it to a solver"""
8423
8424 def __init__(self, simplifier, ctx=None):
8425 self.ctx = _get_ctx(ctx)
8426 self.simplifier = None
8427 if isinstance(simplifier, SimplifierObj):
8428 self.simplifier = simplifier
8429 elif isinstance(simplifier, list):
8430 simps = [Simplifier(s, ctx) for s in simplifier]
8431 self.simplifier = simps[0].simplifier
8432 for i in range(1, len(simps)):
8433 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8434 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8435 return
8436 else:
8437 if z3_debug():
8438 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8439 try:
8440 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8441 except Z3Exception:
8442 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8443 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8444
8445 def __deepcopy__(self, memo={}):
8446 return Simplifier(self.simplifier, self.ctx)
8447
8448 def __del__(self):
8449 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8450 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8451
8452 def using_params(self, *args, **keys):
8453 """Return a simplifier that uses the given configuration options"""
8454 p = args2params(args, keys, self.ctx)
8455 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8456
8457 def add(self, solver):
8458 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8459 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8460
8461 def help(self):
8462 """Display a string containing a description of the available options for the `self` simplifier."""
8463 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8464
8465 def param_descrs(self):
8466 """Return the parameter description set."""
8467 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8468
8469
8470#########################################
8471#
8472# Tactics
8473#
8474#########################################
8475
8476
8477class Tactic:
8478 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8479 A Tactic can be converted into a Solver using the method solver().
8480
8481 Several combinators are available for creating new tactics using the built-in ones:
8482 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8483 """
8484
8485 def __init__(self, tactic, ctx=None):
8486 self.ctx = _get_ctx(ctx)
8487 self.tactic = None
8488 if isinstance(tactic, TacticObj):
8489 self.tactic = tactic
8490 else:
8491 if z3_debug():
8492 _z3_assert(isinstance(tactic, str), "tactic name expected")
8493 try:
8494 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8495 except Z3Exception:
8496 raise Z3Exception("unknown tactic '%s'" % tactic)
8497 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8498
8499 def __deepcopy__(self, memo={}):
8500 return Tactic(self.tactic, self.ctx)
8501
8502 def __del__(self):
8503 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8504 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8505
8506 def solver(self, logFile=None):
8507 """Create a solver using the tactic `self`.
8508
8509 The solver supports the methods `push()` and `pop()`, but it
8510 will always solve each `check()` from scratch.
8511
8512 >>> t = Then('simplify', 'nlsat')
8513 >>> s = t.solver()
8514 >>> x = Real('x')
8515 >>> s.add(x**2 == 2, x > 0)
8516 >>> s.check()
8517 sat
8518 >>> s.model()
8519 [x = 1.4142135623?]
8520 """
8521 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8522
8523 def apply(self, goal, *arguments, **keywords):
8524 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8525
8526 >>> x, y = Ints('x y')
8527 >>> t = Tactic('solve-eqs')
8528 >>> t.apply(And(x == 0, y >= x + 1))
8529 [[y >= 1]]
8530 """
8531 if z3_debug():
8532 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8533 goal = _to_goal(goal)
8534 if len(arguments) > 0 or len(keywords) > 0:
8535 p = args2params(arguments, keywords, self.ctx)
8536 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8537 else:
8538 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8539
8540 def __call__(self, goal, *arguments, **keywords):
8541 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8542
8543 >>> x, y = Ints('x y')
8544 >>> t = Tactic('solve-eqs')
8545 >>> t(And(x == 0, y >= x + 1))
8546 [[y >= 1]]
8547 """
8548 return self.apply(goal, *arguments, **keywords)
8549
8550 def help(self):
8551 """Display a string containing a description of the available options for the `self` tactic."""
8552 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8553
8554 def param_descrs(self):
8555 """Return the parameter description set."""
8556 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8557
8558
8559def _to_goal(a):
8560 if isinstance(a, BoolRef):
8561 goal = Goal(ctx=a.ctx)
8562 goal.add(a)
8563 return goal
8564 else:
8565 return a
8566
8567
8568def _to_tactic(t, ctx=None):
8569 if isinstance(t, Tactic):
8570 return t
8571 else:
8572 return Tactic(t, ctx)
8573
8574
8575def _and_then(t1, t2, ctx=None):
8576 t1 = _to_tactic(t1, ctx)
8577 t2 = _to_tactic(t2, ctx)
8578 if z3_debug():
8579 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8580 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8581
8582
8583def _or_else(t1, t2, ctx=None):
8584 t1 = _to_tactic(t1, ctx)
8585 t2 = _to_tactic(t2, ctx)
8586 if z3_debug():
8587 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8588 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8589
8590
8591def AndThen(*ts, **ks):
8592 """Return a tactic that applies the tactics in `*ts` in sequence.
8593
8594 >>> x, y = Ints('x y')
8595 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8596 >>> t(And(x == 0, y > x + 1))
8597 [[Not(y <= 1)]]
8598 >>> t(And(x == 0, y > x + 1)).as_expr()
8599 Not(y <= 1)
8600 """
8601 if z3_debug():
8602 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8603 ctx = ks.get("ctx", None)
8604 num = len(ts)
8605 r = ts[0]
8606 for i in range(num - 1):
8607 r = _and_then(r, ts[i + 1], ctx)
8608 return r
8609
8610
8611def Then(*ts, **ks):
8612 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8613
8614 >>> x, y = Ints('x y')
8615 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8616 >>> t(And(x == 0, y > x + 1))
8617 [[Not(y <= 1)]]
8618 >>> t(And(x == 0, y > x + 1)).as_expr()
8619 Not(y <= 1)
8620 """
8621 return AndThen(*ts, **ks)
8622
8623
8624def OrElse(*ts, **ks):
8625 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8626
8627 >>> x = Int('x')
8628 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8629 >>> # Tactic split-clause fails if there is no clause in the given goal.
8630 >>> t(x == 0)
8631 [[x == 0]]
8632 >>> t(Or(x == 0, x == 1))
8633 [[x == 0], [x == 1]]
8634 """
8635 if z3_debug():
8636 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8637 ctx = ks.get("ctx", None)
8638 num = len(ts)
8639 r = ts[0]
8640 for i in range(num - 1):
8641 r = _or_else(r, ts[i + 1], ctx)
8642 return r
8643
8644
8645def ParOr(*ts, **ks):
8646 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8647
8648 >>> x = Int('x')
8649 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8650 >>> t(x + 1 == 2)
8651 [[x == 1]]
8652 """
8653 if z3_debug():
8654 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8655 ctx = _get_ctx(ks.get("ctx", None))
8656 ts = [_to_tactic(t, ctx) for t in ts]
8657 sz = len(ts)
8658 _args = (TacticObj * sz)()
8659 for i in range(sz):
8660 _args[i] = ts[i].tactic
8661 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8662
8663
8664def ParThen(t1, t2, ctx=None):
8665 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8666 The subgoals are processed in parallel.
8667
8668 >>> x, y = Ints('x y')
8669 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8670 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8671 [[x == 1, y == 2], [x == 2, y == 3]]
8672 """
8673 t1 = _to_tactic(t1, ctx)
8674 t2 = _to_tactic(t2, ctx)
8675 if z3_debug():
8676 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8677 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8678
8679
8680def ParAndThen(t1, t2, ctx=None):
8681 """Alias for ParThen(t1, t2, ctx)."""
8682 return ParThen(t1, t2, ctx)
8683
8684
8685def With(t, *args, **keys):
8686 """Return a tactic that applies tactic `t` using the given configuration options.
8687
8688 >>> x, y = Ints('x y')
8689 >>> t = With(Tactic('simplify'), som=True)
8690 >>> t((x + 1)*(y + 2) == 0)
8691 [[2*x + y + x*y == -2]]
8692 """
8693 ctx = keys.pop("ctx", None)
8694 t = _to_tactic(t, ctx)
8695 p = args2params(args, keys, t.ctx)
8696 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8697
8698
8699def WithParams(t, p):
8700 """Return a tactic that applies tactic `t` using the given configuration options.
8701
8702 >>> x, y = Ints('x y')
8703 >>> p = ParamsRef()
8704 >>> p.set("som", True)
8705 >>> t = WithParams(Tactic('simplify'), p)
8706 >>> t((x + 1)*(y + 2) == 0)
8707 [[2*x + y + x*y == -2]]
8708 """
8709 t = _to_tactic(t, None)
8710 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8711
8712
8713def Repeat(t, max=4294967295, ctx=None):
8714 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8715 or the maximum number of iterations `max` is reached.
8716
8717 >>> x, y = Ints('x y')
8718 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8719 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8720 >>> r = t(c)
8721 >>> for subgoal in r: print(subgoal)
8722 [x == 0, y == 0, x > y]
8723 [x == 0, y == 1, x > y]
8724 [x == 1, y == 0, x > y]
8725 [x == 1, y == 1, x > y]
8726 >>> t = Then(t, Tactic('propagate-values'))
8727 >>> t(c)
8728 [[x == 1, y == 0]]
8729 """
8730 t = _to_tactic(t, ctx)
8731 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8732
8733
8734def TryFor(t, ms, ctx=None):
8735 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8736
8737 If `t` does not terminate in `ms` milliseconds, then it fails.
8738 """
8739 t = _to_tactic(t, ctx)
8740 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8741
8742
8743def tactics(ctx=None):
8744 """Return a list of all available tactics in Z3.
8745
8746 >>> l = tactics()
8747 >>> l.count('simplify') == 1
8748 True
8749 """
8750 ctx = _get_ctx(ctx)
8751 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8752
8753
8754def tactic_description(name, ctx=None):
8755 """Return a short description for the tactic named `name`.
8756
8757 >>> d = tactic_description('simplify')
8758 """
8759 ctx = _get_ctx(ctx)
8760 return Z3_tactic_get_descr(ctx.ref(), name)
8761
8762
8763def describe_tactics():
8764 """Display a (tabular) description of all available tactics in Z3."""
8765 if in_html_mode():
8766 even = True
8767 print('<table border="1" cellpadding="2" cellspacing="0">')
8768 for t in tactics():
8769 if even:
8770 print('<tr style="background-color:#CFCFCF">')
8771 even = False
8772 else:
8773 print("<tr>")
8774 even = True
8775 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8776 print("</table>")
8777 else:
8778 for t in tactics():
8779 print("%s : %s" % (t, tactic_description(t)))
8780
8781
8782class Probe:
8783 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8784 to decide which solver and/or preprocessing step will be used.
8785 """
8786
8787 def __init__(self, probe, ctx=None):
8788 self.ctx = _get_ctx(ctx)
8789 self.probe = None
8790 if isinstance(probe, ProbeObj):
8791 self.probe = probe
8792 elif isinstance(probe, float):
8793 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8794 elif _is_int(probe):
8795 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8796 elif isinstance(probe, bool):
8797 if probe:
8798 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8799 else:
8800 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8801 else:
8802 if z3_debug():
8803 _z3_assert(isinstance(probe, str), "probe name expected")
8804 try:
8805 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8806 except Z3Exception:
8807 raise Z3Exception("unknown probe '%s'" % probe)
8808 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8809
8810 def __deepcopy__(self, memo={}):
8811 return Probe(self.probe, self.ctx)
8812
8813 def __del__(self):
8814 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8815 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8816
8817 def __lt__(self, other):
8818 """Return a probe that evaluates to "true" when the value returned by `self`
8819 is less than the value returned by `other`.
8820
8821 >>> p = Probe('size') < 10
8822 >>> x = Int('x')
8823 >>> g = Goal()
8824 >>> g.add(x > 0)
8825 >>> g.add(x < 10)
8826 >>> p(g)
8827 1.0
8828 """
8829 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8830
8831 def __gt__(self, other):
8832 """Return a probe that evaluates to "true" when the value returned by `self`
8833 is greater than the value returned by `other`.
8834
8835 >>> p = Probe('size') > 10
8836 >>> x = Int('x')
8837 >>> g = Goal()
8838 >>> g.add(x > 0)
8839 >>> g.add(x < 10)
8840 >>> p(g)
8841 0.0
8842 """
8843 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8844
8845 def __le__(self, other):
8846 """Return a probe that evaluates to "true" when the value returned by `self`
8847 is less than or equal to the value returned by `other`.
8848
8849 >>> p = Probe('size') <= 2
8850 >>> x = Int('x')
8851 >>> g = Goal()
8852 >>> g.add(x > 0)
8853 >>> g.add(x < 10)
8854 >>> p(g)
8855 1.0
8856 """
8857 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8858
8859 def __ge__(self, other):
8860 """Return a probe that evaluates to "true" when the value returned by `self`
8861 is greater than or equal to the value returned by `other`.
8862
8863 >>> p = Probe('size') >= 2
8864 >>> x = Int('x')
8865 >>> g = Goal()
8866 >>> g.add(x > 0)
8867 >>> g.add(x < 10)
8868 >>> p(g)
8869 1.0
8870 """
8871 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8872
8873 def __eq__(self, other):
8874 """Return a probe that evaluates to "true" when the value returned by `self`
8875 is equal to the value returned by `other`.
8876
8877 >>> p = Probe('size') == 2
8878 >>> x = Int('x')
8879 >>> g = Goal()
8880 >>> g.add(x > 0)
8881 >>> g.add(x < 10)
8882 >>> p(g)
8883 1.0
8884 """
8885 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8886
8887 def __ne__(self, other):
8888 """Return a probe that evaluates to "true" when the value returned by `self`
8889 is not equal to the value returned by `other`.
8890
8891 >>> p = Probe('size') != 2
8892 >>> x = Int('x')
8893 >>> g = Goal()
8894 >>> g.add(x > 0)
8895 >>> g.add(x < 10)
8896 >>> p(g)
8897 0.0
8898 """
8899 p = self.__eq__(other)
8900 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8901
8902 def __call__(self, goal):
8903 """Evaluate the probe `self` in the given goal.
8904
8905 >>> p = Probe('size')
8906 >>> x = Int('x')
8907 >>> g = Goal()
8908 >>> g.add(x > 0)
8909 >>> g.add(x < 10)
8910 >>> p(g)
8911 2.0
8912 >>> g.add(x < 20)
8913 >>> p(g)
8914 3.0
8915 >>> p = Probe('num-consts')
8916 >>> p(g)
8917 1.0
8918 >>> p = Probe('is-propositional')
8919 >>> p(g)
8920 0.0
8921 >>> p = Probe('is-qflia')
8922 >>> p(g)
8923 1.0
8924 """
8925 if z3_debug():
8926 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8927 goal = _to_goal(goal)
8928 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8929
8930
8931def is_probe(p):
8932 """Return `True` if `p` is a Z3 probe.
8933
8934 >>> is_probe(Int('x'))
8935 False
8936 >>> is_probe(Probe('memory'))
8937 True
8938 """
8939 return isinstance(p, Probe)
8940
8941
8942def _to_probe(p, ctx=None):
8943 if is_probe(p):
8944 return p
8945 else:
8946 return Probe(p, ctx)
8947
8948
8949def probes(ctx=None):
8950 """Return a list of all available probes in Z3.
8951
8952 >>> l = probes()
8953 >>> l.count('memory') == 1
8954 True
8955 """
8956 ctx = _get_ctx(ctx)
8957 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8958
8959
8960def probe_description(name, ctx=None):
8961 """Return a short description for the probe named `name`.
8962
8963 >>> d = probe_description('memory')
8964 """
8965 ctx = _get_ctx(ctx)
8966 return Z3_probe_get_descr(ctx.ref(), name)
8967
8968
8969def describe_probes():
8970 """Display a (tabular) description of all available probes in Z3."""
8971 if in_html_mode():
8972 even = True
8973 print('<table border="1" cellpadding="2" cellspacing="0">')
8974 for p in probes():
8975 if even:
8976 print('<tr style="background-color:#CFCFCF">')
8977 even = False
8978 else:
8979 print("<tr>")
8980 even = True
8981 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
8982 print("</table>")
8983 else:
8984 for p in probes():
8985 print("%s : %s" % (p, probe_description(p)))
8986
8987
8988def _probe_nary(f, args, ctx):
8989 if z3_debug():
8990 _z3_assert(len(args) > 0, "At least one argument expected")
8991 num = len(args)
8992 r = _to_probe(args[0], ctx)
8993 for i in range(num - 1):
8994 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
8995 return r
8996
8997
8998def _probe_and(args, ctx):
8999 return _probe_nary(Z3_probe_and, args, ctx)
9000
9001
9002def _probe_or(args, ctx):
9003 return _probe_nary(Z3_probe_or, args, ctx)
9004
9005
9006def FailIf(p, ctx=None):
9007 """Return a tactic that fails if the probe `p` evaluates to true.
9008 Otherwise, it returns the input goal unmodified.
9009
9010 In the following example, the tactic applies 'simplify' if and only if there are
9011 more than 2 constraints in the goal.
9012
9013 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
9014 >>> x, y = Ints('x y')
9015 >>> g = Goal()
9016 >>> g.add(x > 0)
9017 >>> g.add(y > 0)
9018 >>> t(g)
9019 [[x > 0, y > 0]]
9020 >>> g.add(x == y + 1)
9021 >>> t(g)
9022 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9023 """
9024 p = _to_probe(p, ctx)
9025 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
9026
9027
9028def When(p, t, ctx=None):
9029 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
9030 Otherwise, it returns the input goal unmodified.
9031
9032 >>> t = When(Probe('size') > 2, Tactic('simplify'))
9033 >>> x, y = Ints('x y')
9034 >>> g = Goal()
9035 >>> g.add(x > 0)
9036 >>> g.add(y > 0)
9037 >>> t(g)
9038 [[x > 0, y > 0]]
9039 >>> g.add(x == y + 1)
9040 >>> t(g)
9041 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9042 """
9043 p = _to_probe(p, ctx)
9044 t = _to_tactic(t, ctx)
9045 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
9046
9047
9048def Cond(p, t1, t2, ctx=None):
9049 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
9050
9051 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
9052 """
9053 p = _to_probe(p, ctx)
9054 t1 = _to_tactic(t1, ctx)
9055 t2 = _to_tactic(t2, ctx)
9056 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
9057
9058#########################################
9059#
9060# Utils
9061#
9062#########################################
9063
9064
9065def simplify(a, *arguments, **keywords):
9066 """Simplify the expression `a` using the given options.
9067
9068 This function has many options. Use `help_simplify` to obtain the complete list.
9069
9070 >>> x = Int('x')
9071 >>> y = Int('y')
9072 >>> simplify(x + 1 + y + x + 1)
9073 2 + 2*x + y
9074 >>> simplify((x + 1)*(y + 1), som=True)
9075 1 + x + y + x*y
9076 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9077 And(Not(x == y), Not(x == 1), Not(y == 1))
9078 >>> simplify(And(x == 0, y == 1), elim_and=True)
9079 Not(Or(Not(x == 0), Not(y == 1)))
9080 """
9081 if z3_debug():
9082 _z3_assert(is_expr(a), "Z3 expression expected")
9083 if len(arguments) > 0 or len(keywords) > 0:
9084 p = args2params(arguments, keywords, a.ctx)
9085 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9086 else:
9087 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9088
9089
9090def help_simplify():
9091 """Return a string describing all options available for Z3 `simplify` procedure."""
9092 print(Z3_simplify_get_help(main_ctx().ref()))
9093
9094
9095def simplify_param_descrs():
9096 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9097 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9098
9099
9100def substitute(t, *m):
9101 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9102 Every occurrence in t of from is replaced with to.
9103
9104 >>> x = Int('x')
9105 >>> y = Int('y')
9106 >>> substitute(x + 1, (x, y + 1))
9107 y + 1 + 1
9108 >>> f = Function('f', IntSort(), IntSort())
9109 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9110 1 + 1
9111 """
9112 if isinstance(m, tuple):
9113 m1 = _get_args(m)
9114 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9115 m = m1
9116 if z3_debug():
9117 _z3_assert(is_expr(t), "Z3 expression expected")
9118 _z3_assert(
9119 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9120 "Z3 invalid substitution, expression pairs expected.")
9121 _z3_assert(
9122 all([p[0].sort().eq(p[1].sort()) for p in m]),
9123 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9124 num = len(m)
9125 _from = (Ast * num)()
9126 _to = (Ast * num)()
9127 for i in range(num):
9128 _from[i] = m[i][0].as_ast()
9129 _to[i] = m[i][1].as_ast()
9130 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9131
9132
9133def substitute_vars(t, *m):
9134 """Substitute the free variables in t with the expression in m.
9135
9136 >>> v0 = Var(0, IntSort())
9137 >>> v1 = Var(1, IntSort())
9138 >>> x = Int('x')
9139 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9140 >>> # replace v0 with x+1 and v1 with x
9141 >>> substitute_vars(f(v0, v1), x + 1, x)
9142 f(x + 1, x)
9143 """
9144 if z3_debug():
9145 _z3_assert(is_expr(t), "Z3 expression expected")
9146 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9147 num = len(m)
9148 _to = (Ast * num)()
9149 for i in range(num):
9150 _to[i] = m[i].as_ast()
9151 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9152
9153def substitute_funs(t, *m):
9154 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9155 Every occurrence in to of the function from is replaced with the expression to.
9156 The expression to can have free variables, that refer to the arguments of from.
9157 For examples, see
9158 """
9159 if isinstance(m, tuple):
9160 m1 = _get_args(m)
9161 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9162 m = m1
9163 if z3_debug():
9164 _z3_assert(is_expr(t), "Z3 expression expected")
9165 _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.")
9166 num = len(m)
9167 _from = (FuncDecl * num)()
9168 _to = (Ast * num)()
9169 for i in range(num):
9170 _from[i] = m[i][0].as_func_decl()
9171 _to[i] = m[i][1].as_ast()
9172 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9173
9174
9175def Sum(*args):
9176 """Create the sum of the Z3 expressions.
9177
9178 >>> a, b, c = Ints('a b c')
9179 >>> Sum(a, b, c)
9180 a + b + c
9181 >>> Sum([a, b, c])
9182 a + b + c
9183 >>> A = IntVector('a', 5)
9184 >>> Sum(A)
9185 a__0 + a__1 + a__2 + a__3 + a__4
9186 """
9187 args = _get_args(args)
9188 if len(args) == 0:
9189 return 0
9190 ctx = _ctx_from_ast_arg_list(args)
9191 if ctx is None:
9192 return _reduce(lambda a, b: a + b, args, 0)
9193 args = _coerce_expr_list(args, ctx)
9194 if is_bv(args[0]):
9195 return _reduce(lambda a, b: a + b, args, 0)
9196 else:
9197 _args, sz = _to_ast_array(args)
9198 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9199
9200
9201def Product(*args):
9202 """Create the product of the Z3 expressions.
9203
9204 >>> a, b, c = Ints('a b c')
9205 >>> Product(a, b, c)
9206 a*b*c
9207 >>> Product([a, b, c])
9208 a*b*c
9209 >>> A = IntVector('a', 5)
9210 >>> Product(A)
9211 a__0*a__1*a__2*a__3*a__4
9212 """
9213 args = _get_args(args)
9214 if len(args) == 0:
9215 return 1
9216 ctx = _ctx_from_ast_arg_list(args)
9217 if ctx is None:
9218 return _reduce(lambda a, b: a * b, args, 1)
9219 args = _coerce_expr_list(args, ctx)
9220 if is_bv(args[0]):
9221 return _reduce(lambda a, b: a * b, args, 1)
9222 else:
9223 _args, sz = _to_ast_array(args)
9224 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9225
9226def Abs(arg):
9227 """Create the absolute value of an arithmetic expression"""
9228 return If(arg > 0, arg, -arg)
9229
9230
9231def AtMost(*args):
9232 """Create an at-most Pseudo-Boolean k constraint.
9233
9234 >>> a, b, c = Bools('a b c')
9235 >>> f = AtMost(a, b, c, 2)
9236 """
9237 args = _get_args(args)
9238 if z3_debug():
9239 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9240 ctx = _ctx_from_ast_arg_list(args)
9241 if z3_debug():
9242 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9243 args1 = _coerce_expr_list(args[:-1], ctx)
9244 k = args[-1]
9245 _args, sz = _to_ast_array(args1)
9246 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9247
9248
9249def AtLeast(*args):
9250 """Create an at-least Pseudo-Boolean k constraint.
9251
9252 >>> a, b, c = Bools('a b c')
9253 >>> f = AtLeast(a, b, c, 2)
9254 """
9255 args = _get_args(args)
9256 if z3_debug():
9257 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9258 ctx = _ctx_from_ast_arg_list(args)
9259 if z3_debug():
9260 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9261 args1 = _coerce_expr_list(args[:-1], ctx)
9262 k = args[-1]
9263 _args, sz = _to_ast_array(args1)
9264 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9265
9266
9267def _reorder_pb_arg(arg):
9268 a, b = arg
9269 if not _is_int(b) and _is_int(a):
9270 return b, a
9271 return arg
9272
9273
9274def _pb_args_coeffs(args, default_ctx=None):
9275 args = _get_args_ast_list(args)
9276 if len(args) == 0:
9277 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9278 args = [_reorder_pb_arg(arg) for arg in args]
9279 args, coeffs = zip(*args)
9280 if z3_debug():
9281 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9282 ctx = _ctx_from_ast_arg_list(args)
9283 if z3_debug():
9284 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9285 args = _coerce_expr_list(args, ctx)
9286 _args, sz = _to_ast_array(args)
9287 _coeffs = (ctypes.c_int * len(coeffs))()
9288 for i in range(len(coeffs)):
9289 _z3_check_cint_overflow(coeffs[i], "coefficient")
9290 _coeffs[i] = coeffs[i]
9291 return ctx, sz, _args, _coeffs, args
9292
9293
9294def PbLe(args, k):
9295 """Create a Pseudo-Boolean inequality k constraint.
9296
9297 >>> a, b, c = Bools('a b c')
9298 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9299 """
9300 _z3_check_cint_overflow(k, "k")
9301 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9302 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9303
9304
9305def PbGe(args, k):
9306 """Create a Pseudo-Boolean inequality k constraint.
9307
9308 >>> a, b, c = Bools('a b c')
9309 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9310 """
9311 _z3_check_cint_overflow(k, "k")
9312 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9313 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9314
9315
9316def PbEq(args, k, ctx=None):
9317 """Create a Pseudo-Boolean equality k constraint.
9318
9319 >>> a, b, c = Bools('a b c')
9320 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9321 """
9322 _z3_check_cint_overflow(k, "k")
9323 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9324 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9325
9326
9327def solve(*args, **keywords):
9328 """Solve the constraints `*args`.
9329
9330 This is a simple function for creating demonstrations. It creates a solver,
9331 configure it using the options in `keywords`, adds the constraints
9332 in `args`, and invokes check.
9333
9334 >>> a = Int('a')
9335 >>> solve(a > 0, a < 2)
9336 [a = 1]
9337 """
9338 show = keywords.pop("show", False)
9339 s = Solver()
9340 s.set(**keywords)
9341 s.add(*args)
9342 if show:
9343 print(s)
9344 r = s.check()
9345 if r == unsat:
9346 print("no solution")
9347 elif r == unknown:
9348 print("failed to solve")
9349 try:
9350 print(s.model())
9351 except Z3Exception:
9352 return
9353 else:
9354 print(s.model())
9355
9356
9357def solve_using(s, *args, **keywords):
9358 """Solve the constraints `*args` using solver `s`.
9359
9360 This is a simple function for creating demonstrations. It is similar to `solve`,
9361 but it uses the given solver `s`.
9362 It configures solver `s` using the options in `keywords`, adds the constraints
9363 in `args`, and invokes check.
9364 """
9365 show = keywords.pop("show", False)
9366 if z3_debug():
9367 _z3_assert(isinstance(s, Solver), "Solver object expected")
9368 s.set(**keywords)
9369 s.add(*args)
9370 if show:
9371 print("Problem:")
9372 print(s)
9373 r = s.check()
9374 if r == unsat:
9375 print("no solution")
9376 elif r == unknown:
9377 print("failed to solve")
9378 try:
9379 print(s.model())
9380 except Z3Exception:
9381 return
9382 else:
9383 if show:
9384 print("Solution:")
9385 print(s.model())
9386
9387
9388def prove(claim, show=False, **keywords):
9389 """Try to prove the given claim.
9390
9391 This is a simple function for creating demonstrations. It tries to prove
9392 `claim` by showing the negation is unsatisfiable.
9393
9394 >>> p, q = Bools('p q')
9395 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9396 proved
9397 """
9398 if z3_debug():
9399 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9400 s = Solver()
9401 s.set(**keywords)
9402 s.add(Not(claim))
9403 if show:
9404 print(s)
9405 r = s.check()
9406 if r == unsat:
9407 print("proved")
9408 elif r == unknown:
9409 print("failed to prove")
9410 print(s.model())
9411 else:
9412 print("counterexample")
9413 print(s.model())
9414
9415
9416def _solve_html(*args, **keywords):
9417 """Version of function `solve` that renders HTML output."""
9418 show = keywords.pop("show", False)
9419 s = Solver()
9420 s.set(**keywords)
9421 s.add(*args)
9422 if show:
9423 print("<b>Problem:</b>")
9424 print(s)
9425 r = s.check()
9426 if r == unsat:
9427 print("<b>no solution</b>")
9428 elif r == unknown:
9429 print("<b>failed to solve</b>")
9430 try:
9431 print(s.model())
9432 except Z3Exception:
9433 return
9434 else:
9435 if show:
9436 print("<b>Solution:</b>")
9437 print(s.model())
9438
9439
9440def _solve_using_html(s, *args, **keywords):
9441 """Version of function `solve_using` that renders HTML."""
9442 show = keywords.pop("show", False)
9443 if z3_debug():
9444 _z3_assert(isinstance(s, Solver), "Solver object expected")
9445 s.set(**keywords)
9446 s.add(*args)
9447 if show:
9448 print("<b>Problem:</b>")
9449 print(s)
9450 r = s.check()
9451 if r == unsat:
9452 print("<b>no solution</b>")
9453 elif r == unknown:
9454 print("<b>failed to solve</b>")
9455 try:
9456 print(s.model())
9457 except Z3Exception:
9458 return
9459 else:
9460 if show:
9461 print("<b>Solution:</b>")
9462 print(s.model())
9463
9464
9465def _prove_html(claim, show=False, **keywords):
9466 """Version of function `prove` that renders HTML."""
9467 if z3_debug():
9468 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9469 s = Solver()
9470 s.set(**keywords)
9471 s.add(Not(claim))
9472 if show:
9473 print(s)
9474 r = s.check()
9475 if r == unsat:
9476 print("<b>proved</b>")
9477 elif r == unknown:
9478 print("<b>failed to prove</b>")
9479 print(s.model())
9480 else:
9481 print("<b>counterexample</b>")
9482 print(s.model())
9483
9484
9485def _dict2sarray(sorts, ctx):
9486 sz = len(sorts)
9487 _names = (Symbol * sz)()
9488 _sorts = (Sort * sz)()
9489 i = 0
9490 for k in sorts:
9491 v = sorts[k]
9492 if z3_debug():
9493 _z3_assert(isinstance(k, str), "String expected")
9494 _z3_assert(is_sort(v), "Z3 sort expected")
9495 _names[i] = to_symbol(k, ctx)
9496 _sorts[i] = v.ast
9497 i = i + 1
9498 return sz, _names, _sorts
9499
9500
9501def _dict2darray(decls, ctx):
9502 sz = len(decls)
9503 _names = (Symbol * sz)()
9504 _decls = (FuncDecl * sz)()
9505 i = 0
9506 for k in decls:
9507 v = decls[k]
9508 if z3_debug():
9509 _z3_assert(isinstance(k, str), "String expected")
9510 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9511 _names[i] = to_symbol(k, ctx)
9512 if is_const(v):
9513 _decls[i] = v.decl().ast
9514 else:
9515 _decls[i] = v.ast
9516 i = i + 1
9517 return sz, _names, _decls
9518
9519class ParserContext:
9520 def __init__(self, ctx= None):
9521 self.ctx = _get_ctx(ctx)
9522 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9523 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9524
9525 def __del__(self):
9526 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9527 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9528 self.pctx = None
9529
9530 def add_sort(self, sort):
9531 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9532
9533 def add_decl(self, decl):
9534 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9535
9536 def from_string(self, s):
9537 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9538
9539def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9540 """Parse a string in SMT 2.0 format using the given sorts and decls.
9541
9542 The arguments sorts and decls are Python dictionaries used to initialize
9543 the symbol table used for the SMT 2.0 parser.
9544
9545 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9546 [x > 0, x < 10]
9547 >>> x, y = Ints('x y')
9548 >>> f = Function('f', IntSort(), IntSort())
9549 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9550 [x + f(y) > 0]
9551 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9552 [a > 0]
9553 """
9554 ctx = _get_ctx(ctx)
9555 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9556 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9557 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9558
9559
9560def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9561 """Parse a file in SMT 2.0 format using the given sorts and decls.
9562
9563 This function is similar to parse_smt2_string().
9564 """
9565 ctx = _get_ctx(ctx)
9566 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9567 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9568 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9569
9570
9571#########################################
9572#
9573# Floating-Point Arithmetic
9574#
9575#########################################
9576
9577
9578# Global default rounding mode
9579_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9580_dflt_fpsort_ebits = 11
9581_dflt_fpsort_sbits = 53
9582
9583
9584def get_default_rounding_mode(ctx=None):
9585 """Retrieves the global default rounding mode."""
9586 global _dflt_rounding_mode
9587 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9588 return RTZ(ctx)
9589 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9590 return RTN(ctx)
9591 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9592 return RTP(ctx)
9593 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9594 return RNE(ctx)
9595 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9596 return RNA(ctx)
9597
9598
9599_ROUNDING_MODES = frozenset({
9600 Z3_OP_FPA_RM_TOWARD_ZERO,
9601 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9602 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9603 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9604 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9605})
9606
9607
9608def set_default_rounding_mode(rm, ctx=None):
9609 global _dflt_rounding_mode
9610 if is_fprm_value(rm):
9611 _dflt_rounding_mode = rm.kind()
9612 else:
9613 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9614 _dflt_rounding_mode = rm
9615
9616
9617def get_default_fp_sort(ctx=None):
9618 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9619
9620
9621def set_default_fp_sort(ebits, sbits, ctx=None):
9622 global _dflt_fpsort_ebits
9623 global _dflt_fpsort_sbits
9624 _dflt_fpsort_ebits = ebits
9625 _dflt_fpsort_sbits = sbits
9626
9627
9628def _dflt_rm(ctx=None):
9629 return get_default_rounding_mode(ctx)
9630
9631
9632def _dflt_fps(ctx=None):
9633 return get_default_fp_sort(ctx)
9634
9635
9636def _coerce_fp_expr_list(alist, ctx):
9637 first_fp_sort = None
9638 for a in alist:
9639 if is_fp(a):
9640 if first_fp_sort is None:
9641 first_fp_sort = a.sort()
9642 elif first_fp_sort == a.sort():
9643 pass # OK, same as before
9644 else:
9645 # we saw at least 2 different float sorts; something will
9646 # throw a sort mismatch later, for now assume None.
9647 first_fp_sort = None
9648 break
9649
9650 r = []
9651 for i in range(len(alist)):
9652 a = alist[i]
9653 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9654 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9655 r.append(FPVal(a, None, first_fp_sort, ctx))
9656 else:
9657 r.append(a)
9658 return _coerce_expr_list(r, ctx)
9659
9660
9661# FP Sorts
9662
9663class FPSortRef(SortRef):
9664 """Floating-point sort."""
9665
9666 def ebits(self):
9667 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9668 >>> b = FPSort(8, 24)
9669 >>> b.ebits()
9670 8
9671 """
9672 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9673
9674 def sbits(self):
9675 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9676 >>> b = FPSort(8, 24)
9677 >>> b.sbits()
9678 24
9679 """
9680 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9681
9682 def cast(self, val):
9683 """Try to cast `val` as a floating-point expression.
9684 >>> b = FPSort(8, 24)
9685 >>> b.cast(1.0)
9686 1
9687 >>> b.cast(1.0).sexpr()
9688 '(fp #b0 #x7f #b00000000000000000000000)'
9689 """
9690 if is_expr(val):
9691 if z3_debug():
9692 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9693 return val
9694 else:
9695 return FPVal(val, None, self, self.ctx)
9696
9697
9698def Float16(ctx=None):
9699 """Floating-point 16-bit (half) sort."""
9700 ctx = _get_ctx(ctx)
9701 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9702
9703
9704def FloatHalf(ctx=None):
9705 """Floating-point 16-bit (half) sort."""
9706 ctx = _get_ctx(ctx)
9707 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9708
9709
9710def Float32(ctx=None):
9711 """Floating-point 32-bit (single) sort."""
9712 ctx = _get_ctx(ctx)
9713 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9714
9715
9716def FloatSingle(ctx=None):
9717 """Floating-point 32-bit (single) sort."""
9718 ctx = _get_ctx(ctx)
9719 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9720
9721
9722def Float64(ctx=None):
9723 """Floating-point 64-bit (double) sort."""
9724 ctx = _get_ctx(ctx)
9725 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9726
9727
9728def FloatDouble(ctx=None):
9729 """Floating-point 64-bit (double) sort."""
9730 ctx = _get_ctx(ctx)
9731 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9732
9733
9734def Float128(ctx=None):
9735 """Floating-point 128-bit (quadruple) sort."""
9736 ctx = _get_ctx(ctx)
9737 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9738
9739
9740def FloatQuadruple(ctx=None):
9741 """Floating-point 128-bit (quadruple) sort."""
9742 ctx = _get_ctx(ctx)
9743 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9744
9745
9746class FPRMSortRef(SortRef):
9747 """"Floating-point rounding mode sort."""
9748
9749
9750def is_fp_sort(s):
9751 """Return True if `s` is a Z3 floating-point sort.
9752
9753 >>> is_fp_sort(FPSort(8, 24))
9754 True
9755 >>> is_fp_sort(IntSort())
9756 False
9757 """
9758 return isinstance(s, FPSortRef)
9759
9760
9761def is_fprm_sort(s):
9762 """Return True if `s` is a Z3 floating-point rounding mode sort.
9763
9764 >>> is_fprm_sort(FPSort(8, 24))
9765 False
9766 >>> is_fprm_sort(RNE().sort())
9767 True
9768 """
9769 return isinstance(s, FPRMSortRef)
9770
9771# FP Expressions
9772
9773
9774class FPRef(ExprRef):
9775 """Floating-point expressions."""
9776
9777 def sort(self):
9778 """Return the sort of the floating-point expression `self`.
9779
9780 >>> x = FP('1.0', FPSort(8, 24))
9781 >>> x.sort()
9782 FPSort(8, 24)
9783 >>> x.sort() == FPSort(8, 24)
9784 True
9785 """
9786 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9787
9788 def ebits(self):
9789 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9790 >>> b = FPSort(8, 24)
9791 >>> b.ebits()
9792 8
9793 """
9794 return self.sort().ebits()
9795
9796 def sbits(self):
9797 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9798 >>> b = FPSort(8, 24)
9799 >>> b.sbits()
9800 24
9801 """
9802 return self.sort().sbits()
9803
9804 def as_string(self):
9805 """Return a Z3 floating point expression as a Python string."""
9806 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9807
9808 def __le__(self, other):
9809 return fpLEQ(self, other, self.ctx)
9810
9811 def __lt__(self, other):
9812 return fpLT(self, other, self.ctx)
9813
9814 def __ge__(self, other):
9815 return fpGEQ(self, other, self.ctx)
9816
9817 def __gt__(self, other):
9818 return fpGT(self, other, self.ctx)
9819
9820 def __add__(self, other):
9821 """Create the Z3 expression `self + other`.
9822
9823 >>> x = FP('x', FPSort(8, 24))
9824 >>> y = FP('y', FPSort(8, 24))
9825 >>> x + y
9826 x + y
9827 >>> (x + y).sort()
9828 FPSort(8, 24)
9829 """
9830 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9831 return fpAdd(_dflt_rm(), a, b, self.ctx)
9832
9833 def __radd__(self, other):
9834 """Create the Z3 expression `other + self`.
9835
9836 >>> x = FP('x', FPSort(8, 24))
9837 >>> 10 + x
9838 1.25*(2**3) + x
9839 """
9840 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9841 return fpAdd(_dflt_rm(), a, b, self.ctx)
9842
9843 def __sub__(self, other):
9844 """Create the Z3 expression `self - other`.
9845
9846 >>> x = FP('x', FPSort(8, 24))
9847 >>> y = FP('y', FPSort(8, 24))
9848 >>> x - y
9849 x - y
9850 >>> (x - y).sort()
9851 FPSort(8, 24)
9852 """
9853 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9854 return fpSub(_dflt_rm(), a, b, self.ctx)
9855
9856 def __rsub__(self, other):
9857 """Create the Z3 expression `other - self`.
9858
9859 >>> x = FP('x', FPSort(8, 24))
9860 >>> 10 - x
9861 1.25*(2**3) - x
9862 """
9863 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9864 return fpSub(_dflt_rm(), a, b, self.ctx)
9865
9866 def __mul__(self, other):
9867 """Create the Z3 expression `self * other`.
9868
9869 >>> x = FP('x', FPSort(8, 24))
9870 >>> y = FP('y', FPSort(8, 24))
9871 >>> x * y
9872 x * y
9873 >>> (x * y).sort()
9874 FPSort(8, 24)
9875 >>> 10 * y
9876 1.25*(2**3) * y
9877 """
9878 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9879 return fpMul(_dflt_rm(), a, b, self.ctx)
9880
9881 def __rmul__(self, other):
9882 """Create the Z3 expression `other * self`.
9883
9884 >>> x = FP('x', FPSort(8, 24))
9885 >>> y = FP('y', FPSort(8, 24))
9886 >>> x * y
9887 x * y
9888 >>> x * 10
9889 x * 1.25*(2**3)
9890 """
9891 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9892 return fpMul(_dflt_rm(), a, b, self.ctx)
9893
9894 def __pos__(self):
9895 """Create the Z3 expression `+self`."""
9896 return self
9897
9898 def __neg__(self):
9899 """Create the Z3 expression `-self`.
9900
9901 >>> x = FP('x', Float32())
9902 >>> -x
9903 -x
9904 """
9905 return fpNeg(self)
9906
9907 def __div__(self, other):
9908 """Create the Z3 expression `self / other`.
9909
9910 >>> x = FP('x', FPSort(8, 24))
9911 >>> y = FP('y', FPSort(8, 24))
9912 >>> x / y
9913 x / y
9914 >>> (x / y).sort()
9915 FPSort(8, 24)
9916 >>> 10 / y
9917 1.25*(2**3) / y
9918 """
9919 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9920 return fpDiv(_dflt_rm(), a, b, self.ctx)
9921
9922 def __rdiv__(self, other):
9923 """Create the Z3 expression `other / self`.
9924
9925 >>> x = FP('x', FPSort(8, 24))
9926 >>> y = FP('y', FPSort(8, 24))
9927 >>> x / y
9928 x / y
9929 >>> x / 10
9930 x / 1.25*(2**3)
9931 """
9932 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9933 return fpDiv(_dflt_rm(), a, b, self.ctx)
9934
9935 def __truediv__(self, other):
9936 """Create the Z3 expression division `self / other`."""
9937 return self.__div__(other)
9938
9939 def __rtruediv__(self, other):
9940 """Create the Z3 expression division `other / self`."""
9941 return self.__rdiv__(other)
9942
9943 def __mod__(self, other):
9944 """Create the Z3 expression mod `self % other`."""
9945 return fpRem(self, other)
9946
9947 def __rmod__(self, other):
9948 """Create the Z3 expression mod `other % self`."""
9949 return fpRem(other, self)
9950
9951
9952class FPRMRef(ExprRef):
9953 """Floating-point rounding mode expressions"""
9954
9955 def as_string(self):
9956 """Return a Z3 floating point expression as a Python string."""
9957 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9958
9959
9960def RoundNearestTiesToEven(ctx=None):
9961 ctx = _get_ctx(ctx)
9962 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9963
9964
9965def RNE(ctx=None):
9966 ctx = _get_ctx(ctx)
9967 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9968
9969
9970def RoundNearestTiesToAway(ctx=None):
9971 ctx = _get_ctx(ctx)
9972 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9973
9974
9975def RNA(ctx=None):
9976 ctx = _get_ctx(ctx)
9977 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9978
9979
9980def RoundTowardPositive(ctx=None):
9981 ctx = _get_ctx(ctx)
9982 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9983
9984
9985def RTP(ctx=None):
9986 ctx = _get_ctx(ctx)
9987 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9988
9989
9990def RoundTowardNegative(ctx=None):
9991 ctx = _get_ctx(ctx)
9992 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9993
9994
9995def RTN(ctx=None):
9996 ctx = _get_ctx(ctx)
9997 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9998
9999
10000def RoundTowardZero(ctx=None):
10001 ctx = _get_ctx(ctx)
10002 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10003
10004
10005def RTZ(ctx=None):
10006 ctx = _get_ctx(ctx)
10007 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10008
10009
10010def is_fprm(a):
10011 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
10012
10013 >>> rm = RNE()
10014 >>> is_fprm(rm)
10015 True
10016 >>> rm = 1.0
10017 >>> is_fprm(rm)
10018 False
10019 """
10020 return isinstance(a, FPRMRef)
10021
10022
10023def is_fprm_value(a):
10024 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
10025 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
10026
10027# FP Numerals
10028
10029
10030class FPNumRef(FPRef):
10031 """The sign of the numeral.
10032
10033 >>> x = FPVal(+1.0, FPSort(8, 24))
10034 >>> x.sign()
10035 False
10036 >>> x = FPVal(-1.0, FPSort(8, 24))
10037 >>> x.sign()
10038 True
10039 """
10040
10041 def sign(self):
10042 num = (ctypes.c_int)()
10043 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
10044 if nsign is False:
10045 raise Z3Exception("error retrieving the sign of a numeral.")
10046 return num.value != 0
10047
10048 """The sign of a floating-point numeral as a bit-vector expression.
10049
10050 Remark: NaN's are invalid arguments.
10051 """
10052
10053 def sign_as_bv(self):
10054 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10055
10056 """The significand of the numeral.
10057
10058 >>> x = FPVal(2.5, FPSort(8, 24))
10059 >>> x.significand()
10060 1.25
10061 """
10062
10063 def significand(self):
10064 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10065
10066 """The significand of the numeral as a long.
10067
10068 >>> x = FPVal(2.5, FPSort(8, 24))
10069 >>> x.significand_as_long()
10070 1.25
10071 """
10072
10073 def significand_as_long(self):
10074 ptr = (ctypes.c_ulonglong * 1)()
10075 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10076 raise Z3Exception("error retrieving the significand of a numeral.")
10077 return ptr[0]
10078
10079 """The significand of the numeral as a bit-vector expression.
10080
10081 Remark: NaN are invalid arguments.
10082 """
10083
10084 def significand_as_bv(self):
10085 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10086
10087 """The exponent of the numeral.
10088
10089 >>> x = FPVal(2.5, FPSort(8, 24))
10090 >>> x.exponent()
10091 1
10092 """
10093
10094 def exponent(self, biased=True):
10095 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10096
10097 """The exponent of the numeral as a long.
10098
10099 >>> x = FPVal(2.5, FPSort(8, 24))
10100 >>> x.exponent_as_long()
10101 1
10102 """
10103
10104 def exponent_as_long(self, biased=True):
10105 ptr = (ctypes.c_longlong * 1)()
10106 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10107 raise Z3Exception("error retrieving the exponent of a numeral.")
10108 return ptr[0]
10109
10110 """The exponent of the numeral as a bit-vector expression.
10111
10112 Remark: NaNs are invalid arguments.
10113 """
10114
10115 def exponent_as_bv(self, biased=True):
10116 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10117
10118 """Indicates whether the numeral is a NaN."""
10119
10120 def isNaN(self):
10121 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10122
10123 """Indicates whether the numeral is +oo or -oo."""
10124
10125 def isInf(self):
10126 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10127
10128 """Indicates whether the numeral is +zero or -zero."""
10129
10130 def isZero(self):
10131 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10132
10133 """Indicates whether the numeral is normal."""
10134
10135 def isNormal(self):
10136 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10137
10138 """Indicates whether the numeral is subnormal."""
10139
10140 def isSubnormal(self):
10141 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10142
10143 """Indicates whether the numeral is positive."""
10144
10145 def isPositive(self):
10146 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10147
10148 """Indicates whether the numeral is negative."""
10149
10150 def isNegative(self):
10151 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10152
10153 """
10154 The string representation of the numeral.
10155
10156 >>> x = FPVal(20, FPSort(8, 24))
10157 >>> x.as_string()
10158 1.25*(2**4)
10159 """
10160
10161 def as_string(self):
10162 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10163 return ("FPVal(%s, %s)" % (s, self.sort()))
10164
10165 def py_value(self):
10166 bv = simplify(fpToIEEEBV(self))
10167 binary = bv.py_value()
10168 if not isinstance(binary, int):
10169 return None
10170 # Decode the IEEE 754 binary representation
10171 import struct
10172 bytes_rep = binary.to_bytes(8, byteorder='big')
10173 return struct.unpack('>d', bytes_rep)[0]
10174
10175
10176def is_fp(a):
10177 """Return `True` if `a` is a Z3 floating-point expression.
10178
10179 >>> b = FP('b', FPSort(8, 24))
10180 >>> is_fp(b)
10181 True
10182 >>> is_fp(b + 1.0)
10183 True
10184 >>> is_fp(Int('x'))
10185 False
10186 """
10187 return isinstance(a, FPRef)
10188
10189
10190def is_fp_value(a):
10191 """Return `True` if `a` is a Z3 floating-point numeral value.
10192
10193 >>> b = FP('b', FPSort(8, 24))
10194 >>> is_fp_value(b)
10195 False
10196 >>> b = FPVal(1.0, FPSort(8, 24))
10197 >>> b
10198 1
10199 >>> is_fp_value(b)
10200 True
10201 """
10202 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10203
10204
10205def FPSort(ebits, sbits, ctx=None):
10206 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10207
10208 >>> Single = FPSort(8, 24)
10209 >>> Double = FPSort(11, 53)
10210 >>> Single
10211 FPSort(8, 24)
10212 >>> x = Const('x', Single)
10213 >>> eq(x, FP('x', FPSort(8, 24)))
10214 True
10215 """
10216 ctx = _get_ctx(ctx)
10217 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10218
10219
10220def _to_float_str(val, exp=0):
10221 if isinstance(val, float):
10222 if math.isnan(val):
10223 res = "NaN"
10224 elif val == 0.0:
10225 sone = math.copysign(1.0, val)
10226 if sone < 0.0:
10227 return "-0.0"
10228 else:
10229 return "+0.0"
10230 elif val == float("+inf"):
10231 res = "+oo"
10232 elif val == float("-inf"):
10233 res = "-oo"
10234 else:
10235 v = val.as_integer_ratio()
10236 num = v[0]
10237 den = v[1]
10238 rvs = str(num) + "/" + str(den)
10239 res = rvs + "p" + _to_int_str(exp)
10240 elif isinstance(val, bool):
10241 if val:
10242 res = "1.0"
10243 else:
10244 res = "0.0"
10245 elif _is_int(val):
10246 res = str(val)
10247 elif isinstance(val, str):
10248 inx = val.find("*(2**")
10249 if inx == -1:
10250 res = val
10251 elif val[-1] == ")":
10252 res = val[0:inx]
10253 exp = str(int(val[inx + 5:-1]) + int(exp))
10254 else:
10255 _z3_assert(False, "String does not have floating-point numeral form.")
10256 elif z3_debug():
10257 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10258 if exp == 0:
10259 return res
10260 else:
10261 return res + "p" + exp
10262
10263
10264def fpNaN(s):
10265 """Create a Z3 floating-point NaN term.
10266
10267 >>> s = FPSort(8, 24)
10268 >>> set_fpa_pretty(True)
10269 >>> fpNaN(s)
10270 NaN
10271 >>> pb = get_fpa_pretty()
10272 >>> set_fpa_pretty(False)
10273 >>> fpNaN(s)
10274 fpNaN(FPSort(8, 24))
10275 >>> set_fpa_pretty(pb)
10276 """
10277 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10278 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10279
10280
10281def fpPlusInfinity(s):
10282 """Create a Z3 floating-point +oo term.
10283
10284 >>> s = FPSort(8, 24)
10285 >>> pb = get_fpa_pretty()
10286 >>> set_fpa_pretty(True)
10287 >>> fpPlusInfinity(s)
10288 +oo
10289 >>> set_fpa_pretty(False)
10290 >>> fpPlusInfinity(s)
10291 fpPlusInfinity(FPSort(8, 24))
10292 >>> set_fpa_pretty(pb)
10293 """
10294 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10295 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10296
10297
10298def fpMinusInfinity(s):
10299 """Create a Z3 floating-point -oo term."""
10300 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10301 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10302
10303
10304def fpInfinity(s, negative):
10305 """Create a Z3 floating-point +oo or -oo term."""
10306 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10307 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10308 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10309
10310
10311def fpPlusZero(s):
10312 """Create a Z3 floating-point +0.0 term."""
10313 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10314 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10315
10316
10317def fpMinusZero(s):
10318 """Create a Z3 floating-point -0.0 term."""
10319 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10320 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10321
10322
10323def fpZero(s, negative):
10324 """Create a Z3 floating-point +0.0 or -0.0 term."""
10325 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10326 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10327 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10328
10329
10330def FPVal(sig, exp=None, fps=None, ctx=None):
10331 """Return a floating-point value of value `val` and sort `fps`.
10332 If `ctx=None`, then the global context is used.
10333
10334 >>> v = FPVal(20.0, FPSort(8, 24))
10335 >>> v
10336 1.25*(2**4)
10337 >>> print("0x%.8x" % v.exponent_as_long(False))
10338 0x00000004
10339 >>> v = FPVal(2.25, FPSort(8, 24))
10340 >>> v
10341 1.125*(2**1)
10342 >>> v = FPVal(-2.25, FPSort(8, 24))
10343 >>> v
10344 -1.125*(2**1)
10345 >>> FPVal(-0.0, FPSort(8, 24))
10346 -0.0
10347 >>> FPVal(0.0, FPSort(8, 24))
10348 +0.0
10349 >>> FPVal(+0.0, FPSort(8, 24))
10350 +0.0
10351 """
10352 ctx = _get_ctx(ctx)
10353 if is_fp_sort(exp):
10354 fps = exp
10355 exp = None
10356 elif fps is None:
10357 fps = _dflt_fps(ctx)
10358 _z3_assert(is_fp_sort(fps), "sort mismatch")
10359 if exp is None:
10360 exp = 0
10361 val = _to_float_str(sig)
10362 if val == "NaN" or val == "nan":
10363 return fpNaN(fps)
10364 elif val == "-0.0":
10365 return fpMinusZero(fps)
10366 elif val == "0.0" or val == "+0.0":
10367 return fpPlusZero(fps)
10368 elif val == "+oo" or val == "+inf" or val == "+Inf":
10369 return fpPlusInfinity(fps)
10370 elif val == "-oo" or val == "-inf" or val == "-Inf":
10371 return fpMinusInfinity(fps)
10372 else:
10373 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10374
10375
10376def FP(name, fpsort, ctx=None):
10377 """Return a floating-point constant named `name`.
10378 `fpsort` is the floating-point sort.
10379 If `ctx=None`, then the global context is used.
10380
10381 >>> x = FP('x', FPSort(8, 24))
10382 >>> is_fp(x)
10383 True
10384 >>> x.ebits()
10385 8
10386 >>> x.sort()
10387 FPSort(8, 24)
10388 >>> word = FPSort(8, 24)
10389 >>> x2 = FP('x', word)
10390 >>> eq(x, x2)
10391 True
10392 """
10393 if isinstance(fpsort, FPSortRef) and ctx is None:
10394 ctx = fpsort.ctx
10395 else:
10396 ctx = _get_ctx(ctx)
10397 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10398
10399
10400def FPs(names, fpsort, ctx=None):
10401 """Return an array of floating-point constants.
10402
10403 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10404 >>> x.sort()
10405 FPSort(8, 24)
10406 >>> x.sbits()
10407 24
10408 >>> x.ebits()
10409 8
10410 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10411 (x + y) * z
10412 """
10413 ctx = _get_ctx(ctx)
10414 if isinstance(names, str):
10415 names = names.split(" ")
10416 return [FP(name, fpsort, ctx) for name in names]
10417
10418
10419def fpAbs(a, ctx=None):
10420 """Create a Z3 floating-point absolute value expression.
10421
10422 >>> s = FPSort(8, 24)
10423 >>> rm = RNE()
10424 >>> x = FPVal(1.0, s)
10425 >>> fpAbs(x)
10426 fpAbs(1)
10427 >>> y = FPVal(-20.0, s)
10428 >>> y
10429 -1.25*(2**4)
10430 >>> fpAbs(y)
10431 fpAbs(-1.25*(2**4))
10432 >>> fpAbs(-1.25*(2**4))
10433 fpAbs(-1.25*(2**4))
10434 >>> fpAbs(x).sort()
10435 FPSort(8, 24)
10436 """
10437 ctx = _get_ctx(ctx)
10438 [a] = _coerce_fp_expr_list([a], ctx)
10439 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10440
10441
10442def fpNeg(a, ctx=None):
10443 """Create a Z3 floating-point addition expression.
10444
10445 >>> s = FPSort(8, 24)
10446 >>> rm = RNE()
10447 >>> x = FP('x', s)
10448 >>> fpNeg(x)
10449 -x
10450 >>> fpNeg(x).sort()
10451 FPSort(8, 24)
10452 """
10453 ctx = _get_ctx(ctx)
10454 [a] = _coerce_fp_expr_list([a], ctx)
10455 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10456
10457
10458def _mk_fp_unary(f, rm, a, ctx):
10459 ctx = _get_ctx(ctx)
10460 [a] = _coerce_fp_expr_list([a], ctx)
10461 if z3_debug():
10462 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10463 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10464 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10465
10466
10467def _mk_fp_unary_pred(f, a, ctx):
10468 ctx = _get_ctx(ctx)
10469 [a] = _coerce_fp_expr_list([a], ctx)
10470 if z3_debug():
10471 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10472 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10473
10474
10475def _mk_fp_bin(f, rm, a, b, ctx):
10476 ctx = _get_ctx(ctx)
10477 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10478 if z3_debug():
10479 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10480 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10481 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10482
10483
10484def _mk_fp_bin_norm(f, a, b, ctx):
10485 ctx = _get_ctx(ctx)
10486 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10487 if z3_debug():
10488 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10489 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10490
10491
10492def _mk_fp_bin_pred(f, a, b, ctx):
10493 ctx = _get_ctx(ctx)
10494 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10495 if z3_debug():
10496 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10497 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10498
10499
10500def _mk_fp_tern(f, rm, a, b, c, ctx):
10501 ctx = _get_ctx(ctx)
10502 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10503 if z3_debug():
10504 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10505 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10506 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10507 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10508
10509
10510def fpAdd(rm, a, b, ctx=None):
10511 """Create a Z3 floating-point addition expression.
10512
10513 >>> s = FPSort(8, 24)
10514 >>> rm = RNE()
10515 >>> x = FP('x', s)
10516 >>> y = FP('y', s)
10517 >>> fpAdd(rm, x, y)
10518 x + y
10519 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10520 fpAdd(RTZ(), x, y)
10521 >>> fpAdd(rm, x, y).sort()
10522 FPSort(8, 24)
10523 """
10524 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10525
10526
10527def fpSub(rm, a, b, ctx=None):
10528 """Create a Z3 floating-point subtraction expression.
10529
10530 >>> s = FPSort(8, 24)
10531 >>> rm = RNE()
10532 >>> x = FP('x', s)
10533 >>> y = FP('y', s)
10534 >>> fpSub(rm, x, y)
10535 x - y
10536 >>> fpSub(rm, x, y).sort()
10537 FPSort(8, 24)
10538 """
10539 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10540
10541
10542def fpMul(rm, a, b, ctx=None):
10543 """Create a Z3 floating-point multiplication expression.
10544
10545 >>> s = FPSort(8, 24)
10546 >>> rm = RNE()
10547 >>> x = FP('x', s)
10548 >>> y = FP('y', s)
10549 >>> fpMul(rm, x, y)
10550 x * y
10551 >>> fpMul(rm, x, y).sort()
10552 FPSort(8, 24)
10553 """
10554 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10555
10556
10557def fpDiv(rm, a, b, ctx=None):
10558 """Create a Z3 floating-point division expression.
10559
10560 >>> s = FPSort(8, 24)
10561 >>> rm = RNE()
10562 >>> x = FP('x', s)
10563 >>> y = FP('y', s)
10564 >>> fpDiv(rm, x, y)
10565 x / y
10566 >>> fpDiv(rm, x, y).sort()
10567 FPSort(8, 24)
10568 """
10569 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10570
10571
10572def fpRem(a, b, ctx=None):
10573 """Create a Z3 floating-point remainder expression.
10574
10575 >>> s = FPSort(8, 24)
10576 >>> x = FP('x', s)
10577 >>> y = FP('y', s)
10578 >>> fpRem(x, y)
10579 fpRem(x, y)
10580 >>> fpRem(x, y).sort()
10581 FPSort(8, 24)
10582 """
10583 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10584
10585
10586def fpMin(a, b, ctx=None):
10587 """Create a Z3 floating-point minimum expression.
10588
10589 >>> s = FPSort(8, 24)
10590 >>> rm = RNE()
10591 >>> x = FP('x', s)
10592 >>> y = FP('y', s)
10593 >>> fpMin(x, y)
10594 fpMin(x, y)
10595 >>> fpMin(x, y).sort()
10596 FPSort(8, 24)
10597 """
10598 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10599
10600
10601def fpMax(a, b, ctx=None):
10602 """Create a Z3 floating-point maximum expression.
10603
10604 >>> s = FPSort(8, 24)
10605 >>> rm = RNE()
10606 >>> x = FP('x', s)
10607 >>> y = FP('y', s)
10608 >>> fpMax(x, y)
10609 fpMax(x, y)
10610 >>> fpMax(x, y).sort()
10611 FPSort(8, 24)
10612 """
10613 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10614
10615
10616def fpFMA(rm, a, b, c, ctx=None):
10617 """Create a Z3 floating-point fused multiply-add expression.
10618 """
10619 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10620
10621
10622def fpSqrt(rm, a, ctx=None):
10623 """Create a Z3 floating-point square root expression.
10624 """
10625 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10626
10627
10628def fpRoundToIntegral(rm, a, ctx=None):
10629 """Create a Z3 floating-point roundToIntegral expression.
10630 """
10631 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10632
10633
10634def fpIsNaN(a, ctx=None):
10635 """Create a Z3 floating-point isNaN expression.
10636
10637 >>> s = FPSort(8, 24)
10638 >>> x = FP('x', s)
10639 >>> y = FP('y', s)
10640 >>> fpIsNaN(x)
10641 fpIsNaN(x)
10642 """
10643 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10644
10645
10646def fpIsInf(a, ctx=None):
10647 """Create a Z3 floating-point isInfinite expression.
10648
10649 >>> s = FPSort(8, 24)
10650 >>> x = FP('x', s)
10651 >>> fpIsInf(x)
10652 fpIsInf(x)
10653 """
10654 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10655
10656
10657def fpIsZero(a, ctx=None):
10658 """Create a Z3 floating-point isZero expression.
10659 """
10660 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10661
10662
10663def fpIsNormal(a, ctx=None):
10664 """Create a Z3 floating-point isNormal expression.
10665 """
10666 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10667
10668
10669def fpIsSubnormal(a, ctx=None):
10670 """Create a Z3 floating-point isSubnormal expression.
10671 """
10672 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10673
10674
10675def fpIsNegative(a, ctx=None):
10676 """Create a Z3 floating-point isNegative expression.
10677 """
10678 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10679
10680
10681def fpIsPositive(a, ctx=None):
10682 """Create a Z3 floating-point isPositive expression.
10683 """
10684 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10685
10686
10687def _check_fp_args(a, b):
10688 if z3_debug():
10689 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10690
10691
10692def fpLT(a, b, ctx=None):
10693 """Create the Z3 floating-point expression `other < self`.
10694
10695 >>> x, y = FPs('x y', FPSort(8, 24))
10696 >>> fpLT(x, y)
10697 x < y
10698 >>> (x < y).sexpr()
10699 '(fp.lt x y)'
10700 """
10701 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10702
10703
10704def fpLEQ(a, b, ctx=None):
10705 """Create the Z3 floating-point expression `other <= self`.
10706
10707 >>> x, y = FPs('x y', FPSort(8, 24))
10708 >>> fpLEQ(x, y)
10709 x <= y
10710 >>> (x <= y).sexpr()
10711 '(fp.leq x y)'
10712 """
10713 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10714
10715
10716def fpGT(a, b, ctx=None):
10717 """Create the Z3 floating-point expression `other > self`.
10718
10719 >>> x, y = FPs('x y', FPSort(8, 24))
10720 >>> fpGT(x, y)
10721 x > y
10722 >>> (x > y).sexpr()
10723 '(fp.gt x y)'
10724 """
10725 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10726
10727
10728def fpGEQ(a, b, ctx=None):
10729 """Create the Z3 floating-point expression `other >= self`.
10730
10731 >>> x, y = FPs('x y', FPSort(8, 24))
10732 >>> fpGEQ(x, y)
10733 x >= y
10734 >>> (x >= y).sexpr()
10735 '(fp.geq x y)'
10736 """
10737 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10738
10739
10740def fpEQ(a, b, ctx=None):
10741 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10742
10743 >>> x, y = FPs('x y', FPSort(8, 24))
10744 >>> fpEQ(x, y)
10745 fpEQ(x, y)
10746 >>> fpEQ(x, y).sexpr()
10747 '(fp.eq x y)'
10748 """
10749 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10750
10751
10752def fpNEQ(a, b, ctx=None):
10753 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10754
10755 >>> x, y = FPs('x y', FPSort(8, 24))
10756 >>> fpNEQ(x, y)
10757 Not(fpEQ(x, y))
10758 >>> (x != y).sexpr()
10759 '(distinct x y)'
10760 """
10761 return Not(fpEQ(a, b, ctx))
10762
10763
10764def fpFP(sgn, exp, sig, ctx=None):
10765 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10766
10767 >>> s = FPSort(8, 24)
10768 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10769 >>> print(x)
10770 fpFP(1, 127, 4194304)
10771 >>> xv = FPVal(-1.5, s)
10772 >>> print(xv)
10773 -1.5
10774 >>> slvr = Solver()
10775 >>> slvr.add(fpEQ(x, xv))
10776 >>> slvr.check()
10777 sat
10778 >>> xv = FPVal(+1.5, s)
10779 >>> print(xv)
10780 1.5
10781 >>> slvr = Solver()
10782 >>> slvr.add(fpEQ(x, xv))
10783 >>> slvr.check()
10784 unsat
10785 """
10786 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10787 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10788 ctx = _get_ctx(ctx)
10789 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10790 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10791
10792
10793def fpToFP(a1, a2=None, a3=None, ctx=None):
10794 """Create a Z3 floating-point conversion expression from other term sorts
10795 to floating-point.
10796
10797 From a bit-vector term in IEEE 754-2008 format:
10798 >>> x = FPVal(1.0, Float32())
10799 >>> x_bv = fpToIEEEBV(x)
10800 >>> simplify(fpToFP(x_bv, Float32()))
10801 1
10802
10803 From a floating-point term with different precision:
10804 >>> x = FPVal(1.0, Float32())
10805 >>> x_db = fpToFP(RNE(), x, Float64())
10806 >>> x_db.sort()
10807 FPSort(11, 53)
10808
10809 From a real term:
10810 >>> x_r = RealVal(1.5)
10811 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10812 1.5
10813
10814 From a signed bit-vector term:
10815 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10816 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10817 -1.25*(2**2)
10818 """
10819 ctx = _get_ctx(ctx)
10820 if is_bv(a1) and is_fp_sort(a2):
10821 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10822 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10823 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10824 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10825 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10826 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10827 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10828 else:
10829 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10830
10831
10832def fpBVToFP(v, sort, ctx=None):
10833 """Create a Z3 floating-point conversion expression that represents the
10834 conversion from a bit-vector term to a floating-point term.
10835
10836 >>> x_bv = BitVecVal(0x3F800000, 32)
10837 >>> x_fp = fpBVToFP(x_bv, Float32())
10838 >>> x_fp
10839 fpToFP(1065353216)
10840 >>> simplify(x_fp)
10841 1
10842 """
10843 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10844 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10845 ctx = _get_ctx(ctx)
10846 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10847
10848
10849def fpFPToFP(rm, v, sort, ctx=None):
10850 """Create a Z3 floating-point conversion expression that represents the
10851 conversion from a floating-point term to a floating-point term of different precision.
10852
10853 >>> x_sgl = FPVal(1.0, Float32())
10854 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10855 >>> x_dbl
10856 fpToFP(RNE(), 1)
10857 >>> simplify(x_dbl)
10858 1
10859 >>> x_dbl.sort()
10860 FPSort(11, 53)
10861 """
10862 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10863 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10864 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10865 ctx = _get_ctx(ctx)
10866 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10867
10868
10869def fpRealToFP(rm, v, sort, ctx=None):
10870 """Create a Z3 floating-point conversion expression that represents the
10871 conversion from a real term to a floating-point term.
10872
10873 >>> x_r = RealVal(1.5)
10874 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10875 >>> x_fp
10876 fpToFP(RNE(), 3/2)
10877 >>> simplify(x_fp)
10878 1.5
10879 """
10880 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10881 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10882 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10883 ctx = _get_ctx(ctx)
10884 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10885
10886
10887def fpSignedToFP(rm, v, sort, ctx=None):
10888 """Create a Z3 floating-point conversion expression that represents the
10889 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10890
10891 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10892 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10893 >>> x_fp
10894 fpToFP(RNE(), 4294967291)
10895 >>> simplify(x_fp)
10896 -1.25*(2**2)
10897 """
10898 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10899 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10900 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10901 ctx = _get_ctx(ctx)
10902 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10903
10904
10905def fpUnsignedToFP(rm, v, sort, ctx=None):
10906 """Create a Z3 floating-point conversion expression that represents the
10907 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10908
10909 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10910 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10911 >>> x_fp
10912 fpToFPUnsigned(RNE(), 4294967291)
10913 >>> simplify(x_fp)
10914 1*(2**32)
10915 """
10916 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10917 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10918 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10919 ctx = _get_ctx(ctx)
10920 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10921
10922
10923def fpToFPUnsigned(rm, x, s, ctx=None):
10924 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10925 if z3_debug():
10926 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10927 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10928 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10929 ctx = _get_ctx(ctx)
10930 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10931
10932
10933def fpToSBV(rm, x, s, ctx=None):
10934 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10935
10936 >>> x = FP('x', FPSort(8, 24))
10937 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10938 >>> print(is_fp(x))
10939 True
10940 >>> print(is_bv(y))
10941 True
10942 >>> print(is_fp(y))
10943 False
10944 >>> print(is_bv(x))
10945 False
10946 """
10947 if z3_debug():
10948 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10949 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10950 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10951 ctx = _get_ctx(ctx)
10952 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10953
10954
10955def fpToUBV(rm, x, s, ctx=None):
10956 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10957
10958 >>> x = FP('x', FPSort(8, 24))
10959 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10960 >>> print(is_fp(x))
10961 True
10962 >>> print(is_bv(y))
10963 True
10964 >>> print(is_fp(y))
10965 False
10966 >>> print(is_bv(x))
10967 False
10968 """
10969 if z3_debug():
10970 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10971 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10972 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10973 ctx = _get_ctx(ctx)
10974 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10975
10976
10977def fpToReal(x, ctx=None):
10978 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
10979
10980 >>> x = FP('x', FPSort(8, 24))
10981 >>> y = fpToReal(x)
10982 >>> print(is_fp(x))
10983 True
10984 >>> print(is_real(y))
10985 True
10986 >>> print(is_fp(y))
10987 False
10988 >>> print(is_real(x))
10989 False
10990 """
10991 if z3_debug():
10992 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10993 ctx = _get_ctx(ctx)
10994 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
10995
10996
10997def fpToIEEEBV(x, ctx=None):
10998 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
10999
11000 The size of the resulting bit-vector is automatically determined.
11001
11002 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
11003 knows only one NaN and it will always produce the same bit-vector representation of
11004 that NaN.
11005
11006 >>> x = FP('x', FPSort(8, 24))
11007 >>> y = fpToIEEEBV(x)
11008 >>> print(is_fp(x))
11009 True
11010 >>> print(is_bv(y))
11011 True
11012 >>> print(is_fp(y))
11013 False
11014 >>> print(is_bv(x))
11015 False
11016 """
11017 if z3_debug():
11018 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11019 ctx = _get_ctx(ctx)
11020 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
11021
11022
11023#########################################
11024#
11025# Strings, Sequences and Regular expressions
11026#
11027#########################################
11028
11029class SeqSortRef(SortRef):
11030 """Sequence sort."""
11031
11032 def is_string(self):
11033 """Determine if sort is a string
11034 >>> s = StringSort()
11035 >>> s.is_string()
11036 True
11037 >>> s = SeqSort(IntSort())
11038 >>> s.is_string()
11039 False
11040 """
11041 return Z3_is_string_sort(self.ctx_ref(), self.ast)
11042
11043 def basis(self):
11044 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11045
11046class CharSortRef(SortRef):
11047 """Character sort."""
11048
11049
11050def StringSort(ctx=None):
11051 """Create a string sort
11052 >>> s = StringSort()
11053 >>> print(s)
11054 String
11055 """
11056 ctx = _get_ctx(ctx)
11057 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
11058
11059def CharSort(ctx=None):
11060 """Create a character sort
11061 >>> ch = CharSort()
11062 >>> print(ch)
11063 Char
11064 """
11065 ctx = _get_ctx(ctx)
11066 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11067
11068
11069def SeqSort(s):
11070 """Create a sequence sort over elements provided in the argument
11071 >>> s = SeqSort(IntSort())
11072 >>> s == Unit(IntVal(1)).sort()
11073 True
11074 """
11075 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11076
11077
11078class SeqRef(ExprRef):
11079 """Sequence expression."""
11080
11081 def sort(self):
11082 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11083
11084 def __add__(self, other):
11085 return Concat(self, other)
11086
11087 def __radd__(self, other):
11088 return Concat(other, self)
11089
11090 def __getitem__(self, i):
11091 if _is_int(i):
11092 i = IntVal(i, self.ctx)
11093 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11094
11095 def at(self, i):
11096 if _is_int(i):
11097 i = IntVal(i, self.ctx)
11098 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11099
11100 def is_string(self):
11101 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11102
11103 def is_string_value(self):
11104 return Z3_is_string(self.ctx_ref(), self.as_ast())
11105
11106 def as_string(self):
11107 """Return a string representation of sequence expression."""
11108 if self.is_string_value():
11109 string_length = ctypes.c_uint()
11110 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11111 return string_at(chars, size=string_length.value).decode("latin-1")
11112 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11113
11114 def py_value(self):
11115 return self.as_string()
11116
11117 def __le__(self, other):
11118 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11119
11120 def __lt__(self, other):
11121 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11122
11123 def __ge__(self, other):
11124 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11125
11126 def __gt__(self, other):
11127 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11128
11129
11130def _coerce_char(ch, ctx=None):
11131 if isinstance(ch, str):
11132 ctx = _get_ctx(ctx)
11133 ch = CharVal(ch, ctx)
11134 if not is_expr(ch):
11135 raise Z3Exception("Character expression expected")
11136 return ch
11137
11138class CharRef(ExprRef):
11139 """Character expression."""
11140
11141 def __le__(self, other):
11142 other = _coerce_char(other, self.ctx)
11143 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11144
11145 def to_int(self):
11146 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11147
11148 def to_bv(self):
11149 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11150
11151 def is_digit(self):
11152 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11153
11154
11155def CharVal(ch, ctx=None):
11156 ctx = _get_ctx(ctx)
11157 if isinstance(ch, str):
11158 ch = ord(ch)
11159 if not isinstance(ch, int):
11160 raise Z3Exception("character value should be an ordinal")
11161 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11162
11163def CharFromBv(bv):
11164 if not is_expr(bv):
11165 raise Z3Exception("Bit-vector expression needed")
11166 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11167
11168def CharToBv(ch, ctx=None):
11169 ch = _coerce_char(ch, ctx)
11170 return ch.to_bv()
11171
11172def CharToInt(ch, ctx=None):
11173 ch = _coerce_char(ch, ctx)
11174 return ch.to_int()
11175
11176def CharIsDigit(ch, ctx=None):
11177 ch = _coerce_char(ch, ctx)
11178 return ch.is_digit()
11179
11180def _coerce_seq(s, ctx=None):
11181 if isinstance(s, str):
11182 ctx = _get_ctx(ctx)
11183 s = StringVal(s, ctx)
11184 if not is_expr(s):
11185 raise Z3Exception("Non-expression passed as a sequence")
11186 if not is_seq(s):
11187 raise Z3Exception("Non-sequence passed as a sequence")
11188 return s
11189
11190
11191def _get_ctx2(a, b, ctx=None):
11192 if is_expr(a):
11193 return a.ctx
11194 if is_expr(b):
11195 return b.ctx
11196 if ctx is None:
11197 ctx = main_ctx()
11198 return ctx
11199
11200
11201def is_seq(a):
11202 """Return `True` if `a` is a Z3 sequence expression.
11203 >>> print (is_seq(Unit(IntVal(0))))
11204 True
11205 >>> print (is_seq(StringVal("abc")))
11206 True
11207 """
11208 return isinstance(a, SeqRef)
11209
11210
11211def is_string(a: Any) -> bool:
11212 """Return `True` if `a` is a Z3 string expression.
11213 >>> print (is_string(StringVal("ab")))
11214 True
11215 """
11216 return isinstance(a, SeqRef) and a.is_string()
11217
11218
11219def is_string_value(a: Any) -> bool:
11220 """return 'True' if 'a' is a Z3 string constant expression.
11221 >>> print (is_string_value(StringVal("a")))
11222 True
11223 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11224 False
11225 """
11226 return isinstance(a, SeqRef) and a.is_string_value()
11227
11228def StringVal(s, ctx=None):
11229 """create a string expression"""
11230 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11231 ctx = _get_ctx(ctx)
11232 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11233
11234
11235def String(name, ctx=None):
11236 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11237
11238 >>> x = String('x')
11239 """
11240 ctx = _get_ctx(ctx)
11241 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11242
11243
11244def Strings(names, ctx=None):
11245 """Return a tuple of String constants. """
11246 ctx = _get_ctx(ctx)
11247 if isinstance(names, str):
11248 names = names.split(" ")
11249 return [String(name, ctx) for name in names]
11250
11251
11252def SubString(s, offset, length):
11253 """Extract substring or subsequence starting at offset.
11254
11255 This is a convenience function that redirects to Extract(s, offset, length).
11256
11257 >>> s = StringVal("hello world")
11258 >>> SubString(s, 6, 5) # Extract "world"
11259 str.substr("hello world", 6, 5)
11260 >>> simplify(SubString(StringVal("hello"), 1, 3))
11261 "ell"
11262 """
11263 return Extract(s, offset, length)
11264
11265
11266def SubSeq(s, offset, length):
11267 """Extract substring or subsequence starting at offset.
11268
11269 This is a convenience function that redirects to Extract(s, offset, length).
11270
11271 >>> s = StringVal("hello world")
11272 >>> SubSeq(s, 0, 5) # Extract "hello"
11273 str.substr("hello world", 0, 5)
11274 >>> simplify(SubSeq(StringVal("testing"), 2, 4))
11275 "stin"
11276 """
11277 return Extract(s, offset, length)
11278
11279
11280def Empty(s):
11281 """Create the empty sequence of the given sort
11282 >>> e = Empty(StringSort())
11283 >>> e2 = StringVal("")
11284 >>> print(e.eq(e2))
11285 True
11286 >>> e3 = Empty(SeqSort(IntSort()))
11287 >>> print(e3)
11288 Empty(Seq(Int))
11289 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11290 >>> print(e4)
11291 Empty(ReSort(Seq(Int)))
11292 """
11293 if isinstance(s, SeqSortRef):
11294 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11295 if isinstance(s, ReSortRef):
11296 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11297 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11298
11299
11300def Full(s):
11301 """Create the regular expression that accepts the universal language
11302 >>> e = Full(ReSort(SeqSort(IntSort())))
11303 >>> print(e)
11304 Full(ReSort(Seq(Int)))
11305 >>> e1 = Full(ReSort(StringSort()))
11306 >>> print(e1)
11307 Full(ReSort(String))
11308 """
11309 if isinstance(s, ReSortRef):
11310 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11311 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11312
11313
11314
11315def Unit(a):
11316 """Create a singleton sequence"""
11317 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11318
11319
11320def PrefixOf(a, b):
11321 """Check if 'a' is a prefix of 'b'
11322 >>> s1 = PrefixOf("ab", "abc")
11323 >>> simplify(s1)
11324 True
11325 >>> s2 = PrefixOf("bc", "abc")
11326 >>> simplify(s2)
11327 False
11328 """
11329 ctx = _get_ctx2(a, b)
11330 a = _coerce_seq(a, ctx)
11331 b = _coerce_seq(b, ctx)
11332 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11333
11334
11335def SuffixOf(a, b):
11336 """Check if 'a' is a suffix of 'b'
11337 >>> s1 = SuffixOf("ab", "abc")
11338 >>> simplify(s1)
11339 False
11340 >>> s2 = SuffixOf("bc", "abc")
11341 >>> simplify(s2)
11342 True
11343 """
11344 ctx = _get_ctx2(a, b)
11345 a = _coerce_seq(a, ctx)
11346 b = _coerce_seq(b, ctx)
11347 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11348
11349
11350def Contains(a, b):
11351 """Check if 'a' contains 'b'
11352 >>> s1 = Contains("abc", "ab")
11353 >>> simplify(s1)
11354 True
11355 >>> s2 = Contains("abc", "bc")
11356 >>> simplify(s2)
11357 True
11358 >>> x, y, z = Strings('x y z')
11359 >>> s3 = Contains(Concat(x,y,z), y)
11360 >>> simplify(s3)
11361 True
11362 """
11363 ctx = _get_ctx2(a, b)
11364 a = _coerce_seq(a, ctx)
11365 b = _coerce_seq(b, ctx)
11366 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11367
11368
11369def Replace(s, src, dst):
11370 """Replace the first occurrence of 'src' by 'dst' in 's'
11371 >>> r = Replace("aaa", "a", "b")
11372 >>> simplify(r)
11373 "baa"
11374 """
11375 ctx = _get_ctx2(dst, s)
11376 if ctx is None and is_expr(src):
11377 ctx = src.ctx
11378 src = _coerce_seq(src, ctx)
11379 dst = _coerce_seq(dst, ctx)
11380 s = _coerce_seq(s, ctx)
11381 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11382
11383
11384def IndexOf(s, substr, offset=None):
11385 """Retrieve the index of substring within a string starting at a specified offset.
11386 >>> simplify(IndexOf("abcabc", "bc", 0))
11387 1
11388 >>> simplify(IndexOf("abcabc", "bc", 2))
11389 4
11390 """
11391 if offset is None:
11392 offset = IntVal(0)
11393 ctx = None
11394 if is_expr(offset):
11395 ctx = offset.ctx
11396 ctx = _get_ctx2(s, substr, ctx)
11397 s = _coerce_seq(s, ctx)
11398 substr = _coerce_seq(substr, ctx)
11399 if _is_int(offset):
11400 offset = IntVal(offset, ctx)
11401 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11402
11403
11404def LastIndexOf(s, substr):
11405 """Retrieve the last index of substring within a string"""
11406 ctx = None
11407 ctx = _get_ctx2(s, substr, ctx)
11408 s = _coerce_seq(s, ctx)
11409 substr = _coerce_seq(substr, ctx)
11410 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11411
11412
11413def Length(s):
11414 """Obtain the length of a sequence 's'
11415 >>> l = Length(StringVal("abc"))
11416 >>> simplify(l)
11417 3
11418 """
11419 s = _coerce_seq(s)
11420 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11421
11422def SeqMap(f, s):
11423 """Map function 'f' over sequence 's'"""
11424 ctx = _get_ctx2(f, s)
11425 s = _coerce_seq(s, ctx)
11426 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11427
11428def SeqMapI(f, i, s):
11429 """Map function 'f' over sequence 's' at index 'i'"""
11430 ctx = _get_ctx2(f, s)
11431 s = _coerce_seq(s, ctx)
11432 if not is_expr(i):
11433 i = _py2expr(i)
11434 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11435
11436def SeqFoldLeft(f, a, s):
11437 ctx = _get_ctx2(f, s)
11438 s = _coerce_seq(s, ctx)
11439 a = _py2expr(a)
11440 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11441
11442def SeqFoldLeftI(f, i, a, s):
11443 ctx = _get_ctx2(f, s)
11444 s = _coerce_seq(s, ctx)
11445 a = _py2expr(a)
11446 i = _py2expr(i)
11447 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11448
11449def StrToInt(s):
11450 """Convert string expression to integer
11451 >>> a = StrToInt("1")
11452 >>> simplify(1 == a)
11453 True
11454 >>> b = StrToInt("2")
11455 >>> simplify(1 == b)
11456 False
11457 >>> c = StrToInt(IntToStr(2))
11458 >>> simplify(1 == c)
11459 False
11460 """
11461 s = _coerce_seq(s)
11462 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11463
11464
11465def IntToStr(s):
11466 """Convert integer expression to string"""
11467 if not is_expr(s):
11468 s = _py2expr(s)
11469 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11470
11471
11472def StrToCode(s):
11473 """Convert a unit length string to integer code"""
11474 if not is_expr(s):
11475 s = _py2expr(s)
11476 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11477
11478def StrFromCode(c):
11479 """Convert code to a string"""
11480 if not is_expr(c):
11481 c = _py2expr(c)
11482 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11483
11484def Re(s, ctx=None):
11485 """The regular expression that accepts sequence 's'
11486 >>> s1 = Re("ab")
11487 >>> s2 = Re(StringVal("ab"))
11488 >>> s3 = Re(Unit(BoolVal(True)))
11489 """
11490 s = _coerce_seq(s, ctx)
11491 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11492
11493
11494# Regular expressions
11495
11496class ReSortRef(SortRef):
11497 """Regular expression sort."""
11498
11499 def basis(self):
11500 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11501
11502
11503def ReSort(s):
11504 if is_ast(s):
11505 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11506 if s is None or isinstance(s, Context):
11507 ctx = _get_ctx(s)
11508 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11509 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11510
11511
11512class ReRef(ExprRef):
11513 """Regular expressions."""
11514
11515 def __add__(self, other):
11516 return Union(self, other)
11517
11518
11519def is_re(s):
11520 return isinstance(s, ReRef)
11521
11522
11523def InRe(s, re):
11524 """Create regular expression membership test
11525 >>> re = Union(Re("a"),Re("b"))
11526 >>> print (simplify(InRe("a", re)))
11527 True
11528 >>> print (simplify(InRe("b", re)))
11529 True
11530 >>> print (simplify(InRe("c", re)))
11531 False
11532 """
11533 s = _coerce_seq(s, re.ctx)
11534 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11535
11536
11537def Union(*args):
11538 """Create union of regular expressions.
11539 >>> re = Union(Re("a"), Re("b"), Re("c"))
11540 >>> print (simplify(InRe("d", re)))
11541 False
11542 """
11543 args = _get_args(args)
11544 sz = len(args)
11545 if z3_debug():
11546 _z3_assert(sz > 0, "At least one argument expected.")
11547 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11548 if sz == 1:
11549 return args[0]
11550 ctx = args[0].ctx
11551 v = (Ast * sz)()
11552 for i in range(sz):
11553 v[i] = args[i].as_ast()
11554 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11555
11556
11557def Intersect(*args):
11558 """Create intersection of regular expressions.
11559 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11560 """
11561 args = _get_args(args)
11562 sz = len(args)
11563 if z3_debug():
11564 _z3_assert(sz > 0, "At least one argument expected.")
11565 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11566 if sz == 1:
11567 return args[0]
11568 ctx = args[0].ctx
11569 v = (Ast * sz)()
11570 for i in range(sz):
11571 v[i] = args[i].as_ast()
11572 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11573
11574
11575def Plus(re):
11576 """Create the regular expression accepting one or more repetitions of argument.
11577 >>> re = Plus(Re("a"))
11578 >>> print(simplify(InRe("aa", re)))
11579 True
11580 >>> print(simplify(InRe("ab", re)))
11581 False
11582 >>> print(simplify(InRe("", re)))
11583 False
11584 """
11585 if z3_debug():
11586 _z3_assert(is_expr(re), "expression expected")
11587 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11588
11589
11590def Option(re):
11591 """Create the regular expression that optionally accepts the argument.
11592 >>> re = Option(Re("a"))
11593 >>> print(simplify(InRe("a", re)))
11594 True
11595 >>> print(simplify(InRe("", re)))
11596 True
11597 >>> print(simplify(InRe("aa", re)))
11598 False
11599 """
11600 if z3_debug():
11601 _z3_assert(is_expr(re), "expression expected")
11602 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11603
11604
11605def Complement(re):
11606 """Create the complement regular expression."""
11607 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11608
11609
11610def Star(re):
11611 """Create the regular expression accepting zero or more repetitions of argument.
11612 >>> re = Star(Re("a"))
11613 >>> print(simplify(InRe("aa", re)))
11614 True
11615 >>> print(simplify(InRe("ab", re)))
11616 False
11617 >>> print(simplify(InRe("", re)))
11618 True
11619 """
11620 if z3_debug():
11621 _z3_assert(is_expr(re), "expression expected")
11622 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11623
11624
11625def Loop(re, lo, hi=0):
11626 """Create the regular expression accepting between a lower and upper bound repetitions
11627 >>> re = Loop(Re("a"), 1, 3)
11628 >>> print(simplify(InRe("aa", re)))
11629 True
11630 >>> print(simplify(InRe("aaaa", re)))
11631 False
11632 >>> print(simplify(InRe("", re)))
11633 False
11634 """
11635 if z3_debug():
11636 _z3_assert(is_expr(re), "expression expected")
11637 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11638
11639
11640def Range(lo, hi, ctx=None):
11641 """Create the range regular expression over two sequences of length 1
11642 >>> range = Range("a","z")
11643 >>> print(simplify(InRe("b", range)))
11644 True
11645 >>> print(simplify(InRe("bb", range)))
11646 False
11647 """
11648 lo = _coerce_seq(lo, ctx)
11649 hi = _coerce_seq(hi, ctx)
11650 if z3_debug():
11651 _z3_assert(is_expr(lo), "expression expected")
11652 _z3_assert(is_expr(hi), "expression expected")
11653 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11654
11655def Diff(a, b, ctx=None):
11656 """Create the difference regular expression
11657 """
11658 if z3_debug():
11659 _z3_assert(is_expr(a), "expression expected")
11660 _z3_assert(is_expr(b), "expression expected")
11661 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11662
11663def AllChar(regex_sort, ctx=None):
11664 """Create a regular expression that accepts all single character strings
11665 """
11666 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11667
11668# Special Relations
11669
11670
11671def PartialOrder(a, index):
11672 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11673
11674
11675def LinearOrder(a, index):
11676 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11677
11678
11679def TreeOrder(a, index):
11680 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11681
11682
11683def PiecewiseLinearOrder(a, index):
11684 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11685
11686
11687def TransitiveClosure(f):
11688 """Given a binary relation R, such that the two arguments have the same sort
11689 create the transitive closure relation R+.
11690 The transitive closure R+ is a new relation.
11691 """
11692 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11693
11694def to_Ast(ptr,):
11695 ast = Ast(ptr)
11696 super(ctypes.c_void_p, ast).__init__(ptr)
11697 return ast
11698
11699def to_ContextObj(ptr,):
11700 ctx = ContextObj(ptr)
11701 super(ctypes.c_void_p, ctx).__init__(ptr)
11702 return ctx
11703
11704def to_AstVectorObj(ptr,):
11705 v = AstVectorObj(ptr)
11706 super(ctypes.c_void_p, v).__init__(ptr)
11707 return v
11708
11709# NB. my-hacky-class only works for a single instance of OnClause
11710# it should be replaced with a proper correlation between OnClause
11711# and object references that can be passed over the FFI.
11712# for UserPropagator we use a global dictionary, which isn't great code.
11713
11714_my_hacky_class = None
11715def on_clause_eh(ctx, p, n, dep, clause):
11716 onc = _my_hacky_class
11717 p = _to_expr_ref(to_Ast(p), onc.ctx)
11718 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11719 deps = [dep[i] for i in range(n)]
11720 onc.on_clause(p, deps, clause)
11721
11722_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11723
11724class OnClause:
11725 def __init__(self, s, on_clause):
11726 self.s = s
11727 self.ctx = s.ctx
11728 self.on_clause = on_clause
11729 self.idx = 22
11730 global _my_hacky_class
11731 _my_hacky_class = self
11732 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11733
11734
11735class PropClosures:
11736 def __init__(self):
11737 self.bases = {}
11738 self.lock = None
11739
11740 def set_threaded(self):
11741 if self.lock is None:
11742 import threading
11743 self.lock = threading.Lock()
11744
11745 def get(self, ctx):
11746 if self.lock:
11747 with self.lock:
11748 r = self.bases[ctx]
11749 else:
11750 r = self.bases[ctx]
11751 return r
11752
11753 def set(self, ctx, r):
11754 if self.lock:
11755 with self.lock:
11756 self.bases[ctx] = r
11757 else:
11758 self.bases[ctx] = r
11759
11760 def insert(self, r):
11761 if self.lock:
11762 with self.lock:
11763 id = len(self.bases) + 3
11764 self.bases[id] = r
11765 else:
11766 id = len(self.bases) + 3
11767 self.bases[id] = r
11768 return id
11769
11770
11771_prop_closures = None
11772
11773
11774def ensure_prop_closures():
11775 global _prop_closures
11776 if _prop_closures is None:
11777 _prop_closures = PropClosures()
11778
11779
11780def user_prop_push(ctx, cb):
11781 prop = _prop_closures.get(ctx)
11782 prop.cb = cb
11783 prop.push()
11784
11785
11786def user_prop_pop(ctx, cb, num_scopes):
11787 prop = _prop_closures.get(ctx)
11788 prop.cb = cb
11789 prop.pop(num_scopes)
11790
11791
11792def user_prop_fresh(ctx, _new_ctx):
11793 _prop_closures.set_threaded()
11794 prop = _prop_closures.get(ctx)
11795 nctx = Context()
11796 Z3_del_context(nctx.ctx)
11797 new_ctx = to_ContextObj(_new_ctx)
11798 nctx.ctx = new_ctx
11799 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11800 nctx.owner = False
11801 new_prop = prop.fresh(nctx)
11802 _prop_closures.set(new_prop.id, new_prop)
11803 return new_prop.id
11804
11805
11806def user_prop_fixed(ctx, cb, id, value):
11807 prop = _prop_closures.get(ctx)
11808 old_cb = prop.cb
11809 prop.cb = cb
11810 id = _to_expr_ref(to_Ast(id), prop.ctx())
11811 value = _to_expr_ref(to_Ast(value), prop.ctx())
11812 prop.fixed(id, value)
11813 prop.cb = old_cb
11814
11815def user_prop_created(ctx, cb, id):
11816 prop = _prop_closures.get(ctx)
11817 old_cb = prop.cb
11818 prop.cb = cb
11819 id = _to_expr_ref(to_Ast(id), prop.ctx())
11820 prop.created(id)
11821 prop.cb = old_cb
11822
11823
11824def user_prop_final(ctx, cb):
11825 prop = _prop_closures.get(ctx)
11826 old_cb = prop.cb
11827 prop.cb = cb
11828 prop.final()
11829 prop.cb = old_cb
11830
11831def user_prop_eq(ctx, cb, x, y):
11832 prop = _prop_closures.get(ctx)
11833 old_cb = prop.cb
11834 prop.cb = cb
11835 x = _to_expr_ref(to_Ast(x), prop.ctx())
11836 y = _to_expr_ref(to_Ast(y), prop.ctx())
11837 prop.eq(x, y)
11838 prop.cb = old_cb
11839
11840def user_prop_diseq(ctx, cb, x, y):
11841 prop = _prop_closures.get(ctx)
11842 old_cb = prop.cb
11843 prop.cb = cb
11844 x = _to_expr_ref(to_Ast(x), prop.ctx())
11845 y = _to_expr_ref(to_Ast(y), prop.ctx())
11846 prop.diseq(x, y)
11847 prop.cb = old_cb
11848
11849def user_prop_decide(ctx, cb, t_ref, idx, phase):
11850 prop = _prop_closures.get(ctx)
11851 old_cb = prop.cb
11852 prop.cb = cb
11853 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11854 prop.decide(t, idx, phase)
11855 prop.cb = old_cb
11856
11857def user_prop_binding(ctx, cb, q_ref, inst_ref):
11858 prop = _prop_closures.get(ctx)
11859 old_cb = prop.cb
11860 prop.cb = cb
11861 q = _to_expr_ref(to_Ast(q_ref), prop.ctx())
11862 inst = _to_expr_ref(to_Ast(inst_ref), prop.ctx())
11863 r = prop.binding(q, inst)
11864 prop.cb = old_cb
11865 return r
11866
11867
11868_user_prop_push = Z3_push_eh(user_prop_push)
11869_user_prop_pop = Z3_pop_eh(user_prop_pop)
11870_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11871_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11872_user_prop_created = Z3_created_eh(user_prop_created)
11873_user_prop_final = Z3_final_eh(user_prop_final)
11874_user_prop_eq = Z3_eq_eh(user_prop_eq)
11875_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11876_user_prop_decide = Z3_decide_eh(user_prop_decide)
11877_user_prop_binding = Z3_on_binding_eh(user_prop_binding)
11878
11879
11880def PropagateFunction(name, *sig):
11881 """Create a function that gets tracked by user propagator.
11882 Every term headed by this function symbol is tracked.
11883 If a term is fixed and the fixed callback is registered a
11884 callback is invoked that the term headed by this function is fixed.
11885 """
11886 sig = _get_args(sig)
11887 if z3_debug():
11888 _z3_assert(len(sig) > 0, "At least two arguments expected")
11889 arity = len(sig) - 1
11890 rng = sig[arity]
11891 if z3_debug():
11892 _z3_assert(is_sort(rng), "Z3 sort expected")
11893 dom = (Sort * arity)()
11894 for i in range(arity):
11895 if z3_debug():
11896 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11897 dom[i] = sig[i].ast
11898 ctx = rng.ctx
11899 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11900
11901
11902
11903class UserPropagateBase:
11904
11905 #
11906 # Either solver is set or ctx is set.
11907 # Propagators that are created through callbacks
11908 # to "fresh" inherit the context of that is supplied
11909 # as argument to the callback.
11910 # This context should not be deleted. It is owned by the solver.
11911 #
11912 def __init__(self, s, ctx=None):
11913 assert s is None or ctx is None
11914 ensure_prop_closures()
11915 self.solver = s
11916 self._ctx = None
11917 self.fresh_ctx = None
11918 self.cb = None
11919 self.id = _prop_closures.insert(self)
11920 self.fixed = None
11921 self.final = None
11922 self.eq = None
11923 self.diseq = None
11924 self.decide = None
11925 self.created = None
11926 self.binding = None
11927 if ctx:
11928 self.fresh_ctx = ctx
11929 if s:
11930 Z3_solver_propagate_init(self.ctx_ref(),
11931 s.solver,
11932 ctypes.c_void_p(self.id),
11933 _user_prop_push,
11934 _user_prop_pop,
11935 _user_prop_fresh)
11936
11937 def __del__(self):
11938 if self._ctx:
11939 self._ctx.ctx = None
11940
11941 def ctx(self):
11942 if self.fresh_ctx:
11943 return self.fresh_ctx
11944 else:
11945 return self.solver.ctx
11946
11947 def ctx_ref(self):
11948 return self.ctx().ref()
11949
11950 def add_fixed(self, fixed):
11951 assert not self.fixed
11952 assert not self._ctx
11953 if self.solver:
11954 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11955 self.fixed = fixed
11956
11957 def add_created(self, created):
11958 assert not self.created
11959 assert not self._ctx
11960 if self.solver:
11961 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
11962 self.created = created
11963
11964 def add_final(self, final):
11965 assert not self.final
11966 assert not self._ctx
11967 if self.solver:
11968 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
11969 self.final = final
11970
11971 def add_eq(self, eq):
11972 assert not self.eq
11973 assert not self._ctx
11974 if self.solver:
11975 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
11976 self.eq = eq
11977
11978 def add_diseq(self, diseq):
11979 assert not self.diseq
11980 assert not self._ctx
11981 if self.solver:
11982 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
11983 self.diseq = diseq
11984
11985 def add_decide(self, decide):
11986 assert not self.decide
11987 assert not self._ctx
11988 if self.solver:
11989 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
11990 self.decide = decide
11991
11992 def add_on_binding(self, binding):
11993 assert not self.binding
11994 assert not self._ctx
11995 if self.solver:
11996 Z3_solver_propagate_on_binding(self.ctx_ref(), self.solver.solver, _user_prop_binding)
11997 self.binding = binding
11998
11999 def push(self):
12000 raise Z3Exception("push needs to be overwritten")
12001
12002 def pop(self, num_scopes):
12003 raise Z3Exception("pop needs to be overwritten")
12004
12005 def fresh(self, new_ctx):
12006 raise Z3Exception("fresh needs to be overwritten")
12007
12008 def add(self, e):
12009 assert not self._ctx
12010 if self.solver:
12011 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
12012 else:
12013 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
12014
12015 #
12016 # Tell the solver to perform the next split on a given term
12017 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
12018 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
12019 #
12020 def next_split(self, t, idx, phase):
12021 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
12022
12023 #
12024 # Propagation can only be invoked as during a fixed or final callback.
12025 #
12026 def propagate(self, e, ids, eqs=[]):
12027 _ids, num_fixed = _to_ast_array(ids)
12028 num_eqs = len(eqs)
12029 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
12030 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
12031 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
12032 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
12033
12034 def conflict(self, deps = [], eqs = []):
12035 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3200
as_decimal(self, prec)
Definition z3py.py:3212
__rmod__(self, other)
Definition z3py.py:2682
__mod__(self, other)
Definition z3py.py:2667
__pow__(self, other)
Definition z3py.py:2591
__gt__(self, other)
Definition z3py.py:2740
__lt__(self, other)
Definition z3py.py:2727
__rtruediv__(self, other)
Definition z3py.py:2663
__rmul__(self, other)
Definition z3py.py:2558
__rsub__(self, other)
Definition z3py.py:2581
__add__(self, other)
Definition z3py.py:2520
__sub__(self, other)
Definition z3py.py:2568
is_real(self)
Definition z3py.py:2509
is_int(self)
Definition z3py.py:2495
__radd__(self, other)
Definition z3py.py:2533
__truediv__(self, other)
Definition z3py.py:2642
__le__(self, other)
Definition z3py.py:2714
__rpow__(self, other)
Definition z3py.py:2605
__pos__(self)
Definition z3py.py:2705
sort(self)
Definition z3py.py:2485
__mul__(self, other)
Definition z3py.py:2543
__rdiv__(self, other)
Definition z3py.py:2646
__ge__(self, other)
Definition z3py.py:2753
__neg__(self)
Definition z3py.py:2694
__div__(self, other)
Definition z3py.py:2619
Arithmetic.
Definition z3py.py:2390
subsort(self, other)
Definition z3py.py:2424
cast(self, val)
Definition z3py.py:2428
domain(self)
Definition z3py.py:4694
domain_n(self, i)
Definition z3py.py:4703
__getitem__(self, arg)
Definition z3py.py:4716
range(self)
Definition z3py.py:4707
sort(self)
Definition z3py.py:4685
default(self)
Definition z3py.py:4728
domain_n(self, i)
Definition z3py.py:4667
erase(self, k)
Definition z3py.py:6246
__deepcopy__(self, memo={})
Definition z3py.py:6183
__init__(self, m=None, ctx=None)
Definition z3py.py:6172
__repr__(self)
Definition z3py.py:6243
__len__(self)
Definition z3py.py:6190
keys(self)
Definition z3py.py:6275
__setitem__(self, k, v)
Definition z3py.py:6227
__contains__(self, key)
Definition z3py.py:6203
__del__(self)
Definition z3py.py:6186
__getitem__(self, key)
Definition z3py.py:6216
reset(self)
Definition z3py.py:6260
__deepcopy__(self, memo={})
Definition z3py.py:365
__nonzero__(self)
Definition z3py.py:380
as_ast(self)
Definition z3py.py:402
translate(self, target)
Definition z3py.py:431
__hash__(self)
Definition z3py.py:377
__init__(self, ast, ctx=None)
Definition z3py.py:355
__str__(self)
Definition z3py.py:368
ctx_ref(self)
Definition z3py.py:410
py_value(self)
Definition z3py.py:460
__repr__(self)
Definition z3py.py:371
get_id(self)
Definition z3py.py:406
hash(self)
Definition z3py.py:450
__eq__(self, other)
Definition z3py.py:374
eq(self, other)
Definition z3py.py:414
sexpr(self)
Definition z3py.py:393
__del__(self)
Definition z3py.py:360
__bool__(self)
Definition z3py.py:383
__copy__(self)
Definition z3py.py:447
__deepcopy__(self, memo={})
Definition z3py.py:6152
translate(self, other_ctx)
Definition z3py.py:6133
__repr__(self)
Definition z3py.py:6155
__len__(self)
Definition z3py.py:6027
__init__(self, v=None, ctx=None)
Definition z3py.py:6012
push(self, v)
Definition z3py.py:6085
__getitem__(self, i)
Definition z3py.py:6040
sexpr(self)
Definition z3py.py:6158
__del__(self)
Definition z3py.py:6023
__setitem__(self, i, v)
Definition z3py.py:6069
__contains__(self, item)
Definition z3py.py:6110
__copy__(self)
Definition z3py.py:6149
resize(self, sz)
Definition z3py.py:6097
as_binary_string(self)
Definition z3py.py:4046
as_signed_long(self)
Definition z3py.py:4020
as_string(self)
Definition z3py.py:4043
__and__(self, other)
Definition z3py.py:3710
__rmod__(self, other)
Definition z3py.py:3851
__rrshift__(self, other)
Definition z3py.py:3977
__mod__(self, other)
Definition z3py.py:3830
__or__(self, other)
Definition z3py.py:3687
__rlshift__(self, other)
Definition z3py.py:3991
__gt__(self, other)
Definition z3py.py:3901
__lt__(self, other)
Definition z3py.py:3885
__invert__(self)
Definition z3py.py:3776
__rtruediv__(self, other)
Definition z3py.py:3826
__rmul__(self, other)
Definition z3py.py:3654
__rxor__(self, other)
Definition z3py.py:3746
__ror__(self, other)
Definition z3py.py:3700
__rsub__(self, other)
Definition z3py.py:3677
__add__(self, other)
Definition z3py.py:3618
__sub__(self, other)
Definition z3py.py:3664
__radd__(self, other)
Definition z3py.py:3631
size(self)
Definition z3py.py:3607
__rand__(self, other)
Definition z3py.py:3723
__truediv__(self, other)
Definition z3py.py:3806
__le__(self, other)
Definition z3py.py:3869
__xor__(self, other)
Definition z3py.py:3733
__lshift__(self, other)
Definition z3py.py:3963
__pos__(self)
Definition z3py.py:3756
sort(self)
Definition z3py.py:3596
__mul__(self, other)
Definition z3py.py:3641
__rdiv__(self, other)
Definition z3py.py:3810
__ge__(self, other)
Definition z3py.py:3917
__neg__(self)
Definition z3py.py:3765
__rshift__(self, other)
Definition z3py.py:3933
__div__(self, other)
Definition z3py.py:3787
Bit-Vectors.
Definition z3py.py:3549
subsort(self, other)
Definition z3py.py:3561
cast(self, val)
Definition z3py.py:3564
__and__(self, other)
Definition z3py.py:1641
__or__(self, other)
Definition z3py.py:1644
__invert__(self)
Definition z3py.py:1650
__rmul__(self, other)
Definition z3py.py:1627
__add__(self, other)
Definition z3py.py:1619
py_value(self)
Definition z3py.py:1653
__radd__(self, other)
Definition z3py.py:1624
__xor__(self, other)
Definition z3py.py:1647
sort(self)
Definition z3py.py:1616
__mul__(self, other)
Definition z3py.py:1630
Booleans.
Definition z3py.py:1577
subsort(self, other)
Definition z3py.py:1603
is_bool(self)
Definition z3py.py:1609
cast(self, val)
Definition z3py.py:1580
__deepcopy__(self, memo={})
Definition z3py.py:7040
__eq__(self, other)
Definition z3py.py:7043
__ne__(self, other)
Definition z3py.py:7046
__init__(self, r)
Definition z3py.py:7037
param_descrs(self)
Definition z3py.py:240
__init__(self, *args, **kws)
Definition z3py.py:202
interrupt(self)
Definition z3py.py:232
__del__(self)
Definition z3py.py:222
ref(self)
Definition z3py.py:228
__deepcopy__(self, memo={})
Definition z3py.py:5212
create(self)
Definition z3py.py:5251
__init__(self, name, ctx=None)
Definition z3py.py:5207
__repr__(self)
Definition z3py.py:5248
declare(self, name, *args)
Definition z3py.py:5227
declare_core(self, name, rec_name, *args)
Definition z3py.py:5217
constructor(self, idx)
Definition z3py.py:5404
accessor(self, i, j)
Definition z3py.py:5451
num_constructors(self)
Definition z3py.py:5391
recognizer(self, idx)
Definition z3py.py:5423
Expressions.
Definition z3py.py:1001
as_ast(self)
Definition z3py.py:1012
__hash__(self)
Definition z3py.py:1058
kind(self)
Definition z3py.py:1098
children(self)
Definition z3py.py:1142
serialize(self)
Definition z3py.py:1160
get_id(self)
Definition z3py.py:1015
num_args(self)
Definition z3py.py:1105
__eq__(self, other)
Definition z3py.py:1041
__ne__(self, other)
Definition z3py.py:1062
from_string(self, s)
Definition z3py.py:1157
sort_kind(self)
Definition z3py.py:1030
arg(self, idx)
Definition z3py.py:1121
sort(self)
Definition z3py.py:1018
params(self)
Definition z3py.py:1080
decl(self)
Definition z3py.py:1083
Function Declarations.
Definition z3py.py:758
as_func_decl(self)
Definition z3py.py:772
domain(self, i)
Definition z3py.py:796
as_ast(self)
Definition z3py.py:766
__call__(self, *args)
Definition z3py.py:859
arity(self)
Definition z3py.py:786
get_id(self)
Definition z3py.py:769
range(self)
Definition z3py.py:808
params(self)
Definition z3py.py:831
Definition z3py.py:6294
__deepcopy__(self, memo={})
Definition z3py.py:6302
ctx
Definition z3py.py:6299
__repr__(self)
Definition z3py.py:6399
num_args(self)
Definition z3py.py:6309
entry
Definition z3py.py:6298
value(self)
Definition z3py.py:6358
__init__(self, entry, ctx)
Definition z3py.py:6297
__del__(self)
Definition z3py.py:6305
as_list(self)
Definition z3py.py:6380
arg_value(self, idx)
Definition z3py.py:6327
__deepcopy__(self, memo={})
Definition z3py.py:6497
translate(self, other_ctx)
Definition z3py.py:6489
arity(self)
Definition z3py.py:6455
__repr__(self)
Definition z3py.py:6517
num_entries(self)
Definition z3py.py:6439
__init__(self, f, ctx)
Definition z3py.py:6406
__del__(self)
Definition z3py.py:6412
as_list(self)
Definition z3py.py:6500
else_value(self)
Definition z3py.py:6416
entry(self, idx)
Definition z3py.py:6469
__copy__(self)
Definition z3py.py:6494
__deepcopy__(self, memo={})
Definition z3py.py:5957
get(self, i)
Definition z3py.py:5815
prec(self)
Definition z3py.py:5759
translate(self, target)
Definition z3py.py:5931
append(self, *args)
Definition z3py.py:5858
as_expr(self)
Definition z3py.py:5980
assert_exprs(self, *args)
Definition z3py.py:5843
__repr__(self)
Definition z3py.py:5920
__len__(self)
Definition z3py.py:5802
inconsistent(self)
Definition z3py.py:5741
dimacs(self, include_names=True)
Definition z3py.py:5927
__getitem__(self, arg)
Definition z3py.py:5828
size(self)
Definition z3py.py:5789
precision(self)
Definition z3py.py:5780
simplify(self, *arguments, **keywords)
Definition z3py.py:5960
sexpr(self)
Definition z3py.py:5923
add(self, *args)
Definition z3py.py:5880
__del__(self)
Definition z3py.py:5719
convert_model(self, model)
Definition z3py.py:5891
insert(self, *args)
Definition z3py.py:5869
depth(self)
Definition z3py.py:5723
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5709
__copy__(self)
Definition z3py.py:5954
as_binary_string(self)
Definition z3py.py:3085
py_value(self)
Definition z3py.py:3093
as_long(self)
Definition z3py.py:3064
as_string(self)
Definition z3py.py:3077
__deepcopy__(self, memo={})
Definition z3py.py:6863
eval(self, t, model_completion=False)
Definition z3py.py:6541
translate(self, target)
Definition z3py.py:6828
__getitem__(self, idx)
Definition z3py.py:6742
num_sorts(self)
Definition z3py.py:6667
get_universe(self, s)
Definition z3py.py:6722
get_sort(self, idx)
Definition z3py.py:6682
project(self, vars, fml)
Definition z3py.py:6836
__repr__(self)
Definition z3py.py:6534
__len__(self)
Definition z3py.py:6598
get_interp(self, decl)
Definition z3py.py:6615
__init__(self, m, ctx)
Definition z3py.py:6524
sexpr(self)
Definition z3py.py:6537
sorts(self)
Definition z3py.py:6705
__del__(self)
Definition z3py.py:6530
decls(self)
Definition z3py.py:6787
project_with_witness(self, vars, fml)
Definition z3py.py:6848
update_value(self, x, value)
Definition z3py.py:6806
evaluate(self, t, model_completion=False)
Definition z3py.py:6572
__copy__(self)
Definition z3py.py:6860
__deepcopy__(self, memo={})
Definition z3py.py:5653
__init__(self, descr, ctx=None)
Definition z3py.py:5647
get_kind(self, n)
Definition z3py.py:5675
get_documentation(self, n)
Definition z3py.py:5680
__getitem__(self, arg)
Definition z3py.py:5685
get_name(self, i)
Definition z3py.py:5670
Parameter Sets.
Definition z3py.py:5574
__deepcopy__(self, memo={})
Definition z3py.py:5588
validate(self, ds)
Definition z3py.py:5615
__repr__(self)
Definition z3py.py:5612
__init__(self, ctx=None, params=None)
Definition z3py.py:5580
set(self, name, val)
Definition z3py.py:5595
__del__(self)
Definition z3py.py:5591
Patterns.
Definition z3py.py:2013
as_ast(self)
Definition z3py.py:2018
get_id(self)
Definition z3py.py:2021
Quantifiers.
Definition z3py.py:2080
num_no_patterns(self)
Definition z3py.py:2198
no_pattern(self, idx)
Definition z3py.py:2202
num_patterns(self)
Definition z3py.py:2168
var_name(self, idx)
Definition z3py.py:2231
__getitem__(self, arg)
Definition z3py.py:2137
var_sort(self, idx)
Definition z3py.py:2247
pattern(self, idx)
Definition z3py.py:2180
numerator_as_long(self)
Definition z3py.py:3126
is_int_value(self)
Definition z3py.py:3156
as_fraction(self)
Definition z3py.py:3184
py_value(self)
Definition z3py.py:3193
numerator(self)
Definition z3py.py:3100
is_real(self)
Definition z3py.py:3153
as_long(self)
Definition z3py.py:3159
is_int(self)
Definition z3py.py:3150
denominator_as_long(self)
Definition z3py.py:3139
as_string(self)
Definition z3py.py:3175
denominator(self)
Definition z3py.py:3115
as_decimal(self, prec)
Definition z3py.py:3163
__init__(self, c, ctx)
Definition z3py.py:5271
__init__(self, c, ctx)
Definition z3py.py:5283
Strings, Sequences and Regular expressions.
Definition z3py.py:11029
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7084
assert_and_track(self, a, p)
Definition z3py.py:7253
num_scopes(self)
Definition z3py.py:7165
append(self, *args)
Definition z3py.py:7231
__iadd__(self, fml)
Definition z3py.py:7227
backtrack_level
Definition z3py.py:7087
pop(self, num=1)
Definition z3py.py:7143
import_model_converter(self, other)
Definition z3py.py:7331
assert_exprs(self, *args)
Definition z3py.py:7197
model(self)
Definition z3py.py:7312
set(self, *args, **keys)
Definition z3py.py:7108
__enter__(self)
Definition z3py.py:7101
add(self, *args)
Definition z3py.py:7216
__del__(self)
Definition z3py.py:7097
insert(self, *args)
Definition z3py.py:7242
check(self, *assumptions)
Definition z3py.py:7283
push(self)
Definition z3py.py:7121
__exit__(self, *exc_info)
Definition z3py.py:7105
reset(self)
Definition z3py.py:7183
subsort(self, other)
Definition z3py.py:599
as_ast(self)
Definition z3py.py:576
__hash__(self)
Definition z3py.py:660
kind(self)
Definition z3py.py:582
__gt__(self, other)
Definition z3py.py:656
get_id(self)
Definition z3py.py:579
__eq__(self, other)
Definition z3py.py:632
__ne__(self, other)
Definition z3py.py:645
cast(self, val)
Definition z3py.py:607
name(self)
Definition z3py.py:622
Statistics.
Definition z3py.py:6893
__deepcopy__(self, memo={})
Definition z3py.py:6901
__getattr__(self, name)
Definition z3py.py:6996
__getitem__(self, idx)
Definition z3py.py:6940
__init__(self, stats, ctx)
Definition z3py.py:6896
__repr__(self)
Definition z3py.py:6908
__len__(self)
Definition z3py.py:6926
__del__(self)
Definition z3py.py:6904
get_key_value(self, key)
Definition z3py.py:6976
subsort(self, other)
Definition z3py.py:734
cast(self, val)
Definition z3py.py:737
ASTs base class.
Definition z3py.py:338
_repr_html_(self)
Definition z3py.py:344
use_pp(self)
Definition z3py.py:341
Z3_ast Z3_API Z3_model_get_const_interp(Z3_context c, Z3_model m, Z3_func_decl a)
Return the interpretation (i.e., assignment) of constant a in the model m. Return NULL,...
Z3_sort Z3_API Z3_mk_int_sort(Z3_context c)
Create the integer type.
Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const *domain, Z3_sort range)
Create an array type with N arguments.
bool Z3_API Z3_open_log(Z3_string filename)
Log interaction to a file.
Z3_parameter_kind Z3_API Z3_get_decl_parameter_kind(Z3_context c, Z3_func_decl d, unsigned idx)
Return the parameter type associated with a declaration.
Z3_ast Z3_API Z3_get_denominator(Z3_context c, Z3_ast a)
Return the denominator (as a numeral AST) of a numeral AST of sort Real.
Z3_probe Z3_API Z3_probe_not(Z3_context x, Z3_probe p)
Return a probe that evaluates to "true" when p does not evaluate to true.
Z3_decl_kind Z3_API Z3_get_decl_kind(Z3_context c, Z3_func_decl d)
Return declaration kind corresponding to declaration.
void Z3_API Z3_solver_assert_and_track(Z3_context c, Z3_solver s, Z3_ast a, Z3_ast p)
Assert a constraint a into the solver, and track it (in the unsat) core using the Boolean constant p.
Z3_ast Z3_API Z3_func_interp_get_else(Z3_context c, Z3_func_interp f)
Return the 'else' value of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsge(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than or equal to.
void Z3_API Z3_ast_map_inc_ref(Z3_context c, Z3_ast_map m)
Increment the reference counter of the given AST map.
Z3_ast Z3_API Z3_mk_const_array(Z3_context c, Z3_sort domain, Z3_ast v)
Create the constant array.
Z3_ast Z3_API Z3_mk_bvsle(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than or equal to.
Z3_func_decl Z3_API Z3_get_app_decl(Z3_context c, Z3_app a)
Return the declaration of a constant or function application.
void Z3_API Z3_del_context(Z3_context c)
Delete the given logical context.
Z3_func_decl Z3_API Z3_get_decl_func_decl_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_ast Z3_API Z3_ast_map_find(Z3_context c, Z3_ast_map m, Z3_ast k)
Return the value associated with the key k.
Z3_string Z3_API Z3_ast_map_to_string(Z3_context c, Z3_ast_map m)
Convert the given map into a string.
Z3_string Z3_API Z3_param_descrs_to_string(Z3_context c, Z3_param_descrs p)
Convert a parameter description set into a string. This function is mainly used for printing the cont...
Z3_ast Z3_API Z3_mk_zero_ext(Z3_context c, unsigned i, Z3_ast t1)
Extend the given bit-vector with zeros to the (unsigned) equivalent bit-vector of size m+i ,...
void Z3_API Z3_solver_set_params(Z3_context c, Z3_solver s, Z3_params p)
Set the given solver using the given parameters.
Z3_ast Z3_API Z3_mk_set_intersect(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the intersection of a list of sets.
Z3_params Z3_API Z3_mk_params(Z3_context c)
Create a Z3 (empty) parameter set. Starting at Z3 4.0, parameter sets are used to configure many comp...
unsigned Z3_API Z3_get_decl_num_parameters(Z3_context c, Z3_func_decl d)
Return the number of parameters associated with a declaration.
Z3_ast Z3_API Z3_mk_set_subset(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Check for subsetness of sets.
Z3_ast Z3_API Z3_mk_bvule(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than or equal to.
Z3_ast Z3_API Z3_mk_full_set(Z3_context c, Z3_sort domain)
Create the full set.
Z3_param_kind Z3_API Z3_param_descrs_get_kind(Z3_context c, Z3_param_descrs p, Z3_symbol n)
Return the kind associated with the given parameter name n.
void Z3_API Z3_add_rec_def(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast args[], Z3_ast body)
Define the body of a recursive function.
Z3_ast Z3_API Z3_mk_true(Z3_context c)
Create an AST node representing true.
Z3_ast Z3_API Z3_mk_set_union(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the union of a list of sets.
Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast default_value)
Create a fresh func_interp object, add it to a model for a specified function. It has reference count...
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed division of t1 and t2 does not overflow.
unsigned Z3_API Z3_get_arity(Z3_context c, Z3_func_decl d)
Alias for Z3_get_domain_size.
void Z3_API Z3_ast_vector_set(Z3_context c, Z3_ast_vector v, unsigned i, Z3_ast a)
Update position i of the AST vector v with the AST a.
Z3_ast Z3_API Z3_mk_bvxor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise exclusive-or.
Z3_string Z3_API Z3_stats_to_string(Z3_context c, Z3_stats s)
Convert a statistics into a string.
Z3_sort Z3_API Z3_mk_real_sort(Z3_context c)
Create the real type.
Z3_ast Z3_API Z3_mk_le(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than or equal to.
bool Z3_API Z3_global_param_get(Z3_string param_id, Z3_string_ptr param_value)
Get a global (or module) parameter.
bool Z3_API Z3_goal_inconsistent(Z3_context c, Z3_goal g)
Return true if the given goal contains the formula false.
Z3_ast Z3_API Z3_mk_lambda_const(Z3_context c, unsigned num_bound, Z3_app const bound[], Z3_ast body)
Create a lambda expression using a list of constants that form the set of bound variables.
void Z3_API Z3_solver_dec_ref(Z3_context c, Z3_solver s)
Decrement the reference counter of the given solver.
Z3_ast Z3_API Z3_mk_bvslt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than.
Z3_func_decl Z3_API Z3_model_get_func_decl(Z3_context c, Z3_model m, unsigned i)
Return the declaration of the i-th function in the given model.
bool Z3_API Z3_ast_map_contains(Z3_context c, Z3_ast_map m, Z3_ast k)
Return true if the map m contains the AST key k.
Z3_ast Z3_API Z3_mk_numeral(Z3_context c, Z3_string numeral, Z3_sort ty)
Create a numeral of a given sort.
unsigned Z3_API Z3_func_entry_get_num_args(Z3_context c, Z3_func_entry e)
Return the number of arguments in a Z3_func_entry object.
Z3_symbol Z3_API Z3_get_decl_symbol_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the double value associated with an double parameter.
Z3_symbol Z3_API Z3_get_quantifier_skolem_id(Z3_context c, Z3_ast a)
Obtain skolem id of quantifier.
Z3_ast Z3_API Z3_get_numerator(Z3_context c, Z3_ast a)
Return the numerator (as a numeral AST) of a numeral AST of sort Real.
Z3_ast Z3_API Z3_mk_unary_minus(Z3_context c, Z3_ast arg)
Create an AST node representing - arg .
Z3_ast Z3_API Z3_mk_and(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] and ... and args[num_args-1] .
void Z3_API Z3_interrupt(Z3_context c)
Interrupt the execution of a Z3 procedure. This procedure can be used to interrupt: solvers,...
void Z3_API Z3_goal_assert(Z3_context c, Z3_goal g, Z3_ast a)
Add a new formula a to the given goal. The formula is split according to the following procedure that...
Z3_symbol Z3_API Z3_param_descrs_get_name(Z3_context c, Z3_param_descrs p, unsigned i)
Return the name of the parameter at given index i.
Z3_ast Z3_API Z3_func_entry_get_value(Z3_context c, Z3_func_entry e)
Return the value of this point.
bool Z3_API Z3_is_quantifier_exists(Z3_context c, Z3_ast a)
Determine if ast is an existential quantifier.
Z3_sort Z3_API Z3_mk_uninterpreted_sort(Z3_context c, Z3_symbol s)
Create a free (uninterpreted) type using the given name (symbol).
Z3_ast Z3_API Z3_mk_false(Z3_context c)
Create an AST node representing false.
Z3_ast_vector Z3_API Z3_ast_map_keys(Z3_context c, Z3_ast_map m)
Return the keys stored in the given map.
Z3_ast Z3_API Z3_mk_bvmul(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement multiplication.
Z3_model Z3_API Z3_goal_convert_model(Z3_context c, Z3_goal g, Z3_model m)
Convert a model of the formulas of a goal to a model of an original goal. The model may be null,...
void Z3_API Z3_del_constructor(Z3_context c, Z3_constructor constr)
Reclaim memory allocated to constructor.
Z3_ast Z3_API Z3_mk_bvsgt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than.
Z3_string Z3_API Z3_ast_to_string(Z3_context c, Z3_ast a)
Convert the given AST node into a string.
Z3_context Z3_API Z3_mk_context_rc(Z3_config c)
Create a context using the given configuration. This function is similar to Z3_mk_context....
Z3_string Z3_API Z3_get_full_version(void)
Return a string that fully describes the version of Z3 in use.
void Z3_API Z3_enable_trace(Z3_string tag)
Enable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_mk_set_complement(Z3_context c, Z3_ast arg)
Take the complement of a set.
unsigned Z3_API Z3_get_quantifier_num_patterns(Z3_context c, Z3_ast a)
Return number of patterns used in quantifier.
Z3_symbol Z3_API Z3_get_quantifier_bound_name(Z3_context c, Z3_ast a, unsigned i)
Return symbol of the i'th bound variable.
bool Z3_API Z3_stats_is_uint(Z3_context c, Z3_stats s, unsigned idx)
Return true if the given statistical data is a unsigned integer.
unsigned Z3_API Z3_model_get_num_consts(Z3_context c, Z3_model m)
Return the number of constants assigned by the given model.
Z3_ast Z3_API Z3_mk_extract(Z3_context c, unsigned high, unsigned low, Z3_ast t1)
Extract the bits high down to low from a bit-vector of size m to yield a new bit-vector of size n,...
Z3_ast Z3_API Z3_mk_mod(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 mod arg2 .
Z3_ast Z3_API Z3_mk_bvredand(Z3_context c, Z3_ast t1)
Take conjunction of bits in vector, return vector of length 1.
Z3_ast Z3_API Z3_mk_set_add(Z3_context c, Z3_ast set, Z3_ast elem)
Add an element to a set.
Z3_ast Z3_API Z3_mk_ge(Z3_context c, Z3_ast t1, Z3_ast t2)
Create greater than or equal to.
Z3_ast Z3_API Z3_mk_bvadd_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed addition of t1 and t2 does not underflow.
Z3_ast Z3_API Z3_mk_bvadd_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise addition of t1 and t2 does not overflow.
void Z3_API Z3_set_ast_print_mode(Z3_context c, Z3_ast_print_mode mode)
Select mode for the format used for pretty-printing AST nodes.
Z3_ast Z3_API Z3_mk_array_default(Z3_context c, Z3_ast array)
Access the array default value. Produces the default range value, for arrays that can be represented ...
unsigned Z3_API Z3_model_get_num_sorts(Z3_context c, Z3_model m)
Return the number of uninterpreted sorts that m assigns an interpretation to.
Z3_ast_vector Z3_API Z3_ast_vector_translate(Z3_context s, Z3_ast_vector v, Z3_context t)
Translate the AST vector v from context s into an AST vector in context t.
void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e)
Increment the reference counter of the given Z3_func_entry object.
Z3_ast Z3_API Z3_mk_fresh_const(Z3_context c, Z3_string prefix, Z3_sort ty)
Declare and create a fresh constant.
Z3_ast Z3_API Z3_mk_bvsub_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed subtraction of t1 and t2 does not overflow.
void Z3_API Z3_solver_push(Z3_context c, Z3_solver s)
Create a backtracking point.
Z3_ast Z3_API Z3_mk_bvsub_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise subtraction of t1 and t2 does not underflow.
Z3_goal Z3_API Z3_goal_translate(Z3_context source, Z3_goal g, Z3_context target)
Copy a goal g from the context source to the context target.
Z3_ast Z3_API Z3_mk_bvudiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned division.
Z3_string Z3_API Z3_ast_vector_to_string(Z3_context c, Z3_ast_vector v)
Convert AST vector into a string.
Z3_ast Z3_API Z3_mk_bvshl(Z3_context c, Z3_ast t1, Z3_ast t2)
Shift left.
bool Z3_API Z3_is_numeral_ast(Z3_context c, Z3_ast a)
Z3_ast Z3_API Z3_mk_bvsrem(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed remainder (sign follows dividend).
bool Z3_API Z3_is_as_array(Z3_context c, Z3_ast a)
The (_ as-array f) AST node is a construct for assigning interpretations for arrays in Z3....
Z3_func_decl Z3_API Z3_mk_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a constant or function.
Z3_ast Z3_API Z3_mk_is_int(Z3_context c, Z3_ast t1)
Check if a real number is an integer.
void Z3_API Z3_params_set_bool(Z3_context c, Z3_params p, Z3_symbol k, bool v)
Add a Boolean parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_mk_ite(Z3_context c, Z3_ast t1, Z3_ast t2, Z3_ast t3)
Create an AST node representing an if-then-else: ite(t1, t2, t3) .
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i)
Array read. The argument a is the array and i is the index of the array that gets read.
Z3_ast Z3_API Z3_mk_sign_ext(Z3_context c, unsigned i, Z3_ast t1)
Sign-extend of the given bit-vector to the (signed) equivalent bit-vector of size m+i ,...
unsigned Z3_API Z3_goal_size(Z3_context c, Z3_goal g)
Return the number of formulas in the given goal.
void Z3_API Z3_stats_inc_ref(Z3_context c, Z3_stats s)
Increment the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs)
n-ary Array read. The argument a is the array and idxs are the indices of the array that gets read.
Z3_ast_vector Z3_API Z3_algebraic_get_poly(Z3_context c, Z3_ast a)
Return the coefficients of the defining polynomial.
Z3_ast Z3_API Z3_mk_div(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 div arg2 .
void Z3_API Z3_model_dec_ref(Z3_context c, Z3_model m)
Decrement the reference counter of the given model.
Z3_sort Z3_API Z3_mk_datatype_sort(Z3_context c, Z3_symbol name, unsigned num_params, Z3_sort const params[])
create a forward reference to a recursive datatype being declared. The forward reference can be used ...
void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f)
Increment the reference counter of the given Z3_func_interp object.
void Z3_API Z3_params_set_double(Z3_context c, Z3_params p, Z3_symbol k, double v)
Add a double parameter k with value v to the parameter set p.
Z3_string Z3_API Z3_param_descrs_get_documentation(Z3_context c, Z3_param_descrs p, Z3_symbol s)
Retrieve documentation string corresponding to parameter name s.
Z3_solver Z3_API Z3_mk_solver(Z3_context c)
Create a new solver. This solver is a "combined solver" (see combined_solver module) that internally ...
Z3_model Z3_API Z3_solver_get_model(Z3_context c, Z3_solver s)
Retrieve the model for the last Z3_solver_check or Z3_solver_check_assumptions.
int Z3_API Z3_get_symbol_int(Z3_context c, Z3_symbol s)
Return the symbol int value.
Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a)
Return the function declaration f associated with a (_ as_array f) node.
Z3_ast Z3_API Z3_mk_ext_rotate_left(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the left t2 times.
void Z3_API Z3_goal_inc_ref(Z3_context c, Z3_goal g)
Increment the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_implies(Z3_context c, Z3_ast t1, Z3_ast t2)
Create an AST node representing t1 implies t2 .
unsigned Z3_API Z3_get_datatype_sort_num_constructors(Z3_context c, Z3_sort t)
Return number of constructors for datatype.
void Z3_API Z3_params_set_uint(Z3_context c, Z3_params p, Z3_symbol k, unsigned v)
Add a unsigned parameter k with value v to the parameter set p.
Z3_lbool Z3_API Z3_solver_check_assumptions(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[])
Check whether the assertions in the given solver and optional assumptions are consistent or not.
Z3_sort Z3_API Z3_model_get_sort(Z3_context c, Z3_model m, unsigned i)
Return a uninterpreted sort that m assigns an interpretation.
Z3_ast Z3_API Z3_mk_bvashr(Z3_context c, Z3_ast t1, Z3_ast t2)
Arithmetic shift right.
Z3_ast Z3_API Z3_mk_bv2int(Z3_context c, Z3_ast t1, bool is_signed)
Create an integer from the bit-vector argument t1. If is_signed is false, then the bit-vector t1 is t...
Z3_sort Z3_API Z3_get_array_sort_domain_n(Z3_context c, Z3_sort t, unsigned idx)
Return the i'th domain sort of an n-dimensional array.
Z3_ast Z3_API Z3_mk_set_del(Z3_context c, Z3_ast set, Z3_ast elem)
Remove an element to a set.
Z3_ast Z3_API Z3_mk_bvmul_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise multiplication of t1 and t2 does not overflow.
Z3_ast Z3_API Z3_mk_bvor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise or.
int Z3_API Z3_get_decl_int_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the integer value associated with an integer parameter.
unsigned Z3_API Z3_get_quantifier_num_no_patterns(Z3_context c, Z3_ast a)
Return number of no_patterns used in quantifier.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor(Z3_context c, Z3_sort t, unsigned idx)
Return idx'th constructor.
void Z3_API Z3_ast_vector_resize(Z3_context c, Z3_ast_vector v, unsigned n)
Resize the AST vector v.
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c, bool is_forall, unsigned weight, Z3_symbol quantifier_id, Z3_symbol skolem_id, unsigned num_bound, Z3_app const bound[], unsigned num_patterns, Z3_pattern const patterns[], unsigned num_no_patterns, Z3_ast const no_patterns[], Z3_ast body)
Create a universal or existential quantifier using a list of constants that will form the set of boun...
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[])
Create a pattern for quantifier instantiation.
Z3_symbol_kind Z3_API Z3_get_symbol_kind(Z3_context c, Z3_symbol s)
Return Z3_INT_SYMBOL if the symbol was constructed using Z3_mk_int_symbol, and Z3_STRING_SYMBOL if th...
bool Z3_API Z3_is_lambda(Z3_context c, Z3_ast a)
Determine if ast is a lambda expression.
unsigned Z3_API Z3_stats_get_uint_value(Z3_context c, Z3_stats s, unsigned idx)
Return the unsigned value of the given statistical data.
Z3_sort Z3_API Z3_get_array_sort_domain(Z3_context c, Z3_sort t)
Return the domain of the given array sort. In the case of a multi-dimensional array,...
Z3_ast Z3_API Z3_mk_bvmul_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed multiplication of t1 and t2 does not underflo...
Z3_ast Z3_API Z3_func_decl_to_ast(Z3_context c, Z3_func_decl f)
Convert a Z3_func_decl into Z3_ast. This is just type casting.
void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a)
Add a constant interpretation.
Z3_ast Z3_API Z3_mk_bvadd(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement addition.
unsigned Z3_API Z3_algebraic_get_i(Z3_context c, Z3_ast a)
Return which root of the polynomial the algebraic number represents.
void Z3_API Z3_params_dec_ref(Z3_context c, Z3_params p)
Decrement the reference counter of the given parameter set.
Z3_ast Z3_API Z3_get_app_arg(Z3_context c, Z3_app a, unsigned i)
Return the i-th argument of the given application.
Z3_string Z3_API Z3_model_to_string(Z3_context c, Z3_model m)
Convert the given model into a string.
Z3_func_decl Z3_API Z3_mk_fresh_func_decl(Z3_context c, Z3_string prefix, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a fresh constant or function.
unsigned Z3_API Z3_ast_map_size(Z3_context c, Z3_ast_map m)
Return the size of the given map.
unsigned Z3_API Z3_param_descrs_size(Z3_context c, Z3_param_descrs p)
Return the number of parameters in the given parameter description set.
Z3_string Z3_API Z3_goal_to_dimacs_string(Z3_context c, Z3_goal g, bool include_names)
Convert a goal into a DIMACS formatted string. The goal must be in CNF. You can convert a goal to CNF...
Z3_ast Z3_API Z3_mk_lt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than.
Z3_ast Z3_API Z3_get_quantifier_no_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th no_pattern.
double Z3_API Z3_stats_get_double_value(Z3_context c, Z3_stats s, unsigned idx)
Return the double value of the given statistical data.
Z3_ast Z3_API Z3_mk_bvugt(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than.
unsigned Z3_API Z3_goal_depth(Z3_context c, Z3_goal g)
Return the depth of the given goal. It tracks how many transformations were applied to it.
Z3_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_set_has_size(Z3_context c, Z3_ast set, Z3_ast k)
Create predicate that holds if Boolean array set has k elements set to true.
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:3231
RotateRight(a, b)
Definition z3py.py:4481
_symbol2py(ctx, s)
Definition z3py.py:140
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4131
BVSNegNoOverflow(a)
Definition z3py.py:4628
SetAdd(s, e)
Definition z3py.py:5100
SetSort(s)
Sets.
Definition z3py.py:5051
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1261
UGT(a, b)
Definition z3py.py:4352
is_probe(p)
Definition z3py.py:8931
SetDel(s, e)
Definition z3py.py:5111
bool is_le(Any a)
Definition z3py.py:2971
BoolSort(ctx=None)
Definition z3py.py:1783
is_bv_sort(s)
Definition z3py.py:3582
_ctx_from_ast_args(*args)
Definition z3py.py:525
RatVal(a, b, ctx=None)
Definition z3py.py:3323
_to_func_decl_ref(a, ctx)
Definition z3py.py:945
SetUnion(*args)
Definition z3py.py:5074
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5171
BitVec(name, bv, ctx=None)
Definition z3py.py:4148
EmptySet(s)
Definition z3py.py:5056
BVMulNoUnderflow(a, b)
Definition z3py.py:4642
CreateDatatypes(*ds)
Definition z3py.py:5292
is_func_decl(a)
Definition z3py.py:890
get_as_array_func(n)
Definition z3py.py:6880
Distinct(*args)
Definition z3py.py:1466
RecAddDefinition(f, args, body)
Definition z3py.py:967
ToInt(a)
Definition z3py.py:3482
Implies(a, b, ctx=None)
Definition z3py.py:1877
UGE(a, b)
Definition z3py.py:4334
Ext(a, b)
Definition z3py.py:5002
_to_ast_array(args)
Definition z3py.py:537
bool is_sort(Any s)
Definition z3py.py:665
_check_bv_args(a, b)
Definition z3py.py:4293
RealSort(ctx=None)
Definition z3py.py:3263
IsSubset(a, b)
Definition z3py.py:5154
DeclareTypeVar(name, ctx=None)
Definition z3py.py:741
_get_args_ast_list(args)
Definition z3py.py:168
bool is_to_real(Any a)
Definition z3py.py:3031
_to_ref_array(ref, args)
Definition z3py.py:545
get_map_func(a)
Definition z3py.py:4810
_z3_check_cint_overflow(n, name)
Definition z3py.py:118
bool is_and(Any a)
Definition z3py.py:1713
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5517
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1292
is_select(a)
Definition z3py.py:5020
SignExt(n, a)
Definition z3py.py:4497
Int(name, ctx=None)
Definition z3py.py:3352
Bools(names, ctx=None)
Definition z3py.py:1832
_probe_and(args, ctx)
Definition z3py.py:8998
Int2BV(a, num_bits)
Definition z3py.py:4107
Lambda(vs, body)
Definition z3py.py:2363
_to_param_value(val)
Definition z3py.py:178
FreshFunction(*sig)
Definition z3py.py:926
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3433
BVRedOr(a)
Definition z3py.py:4586
SRem(a, b)
Definition z3py.py:4412
SortRef _sort(Context ctx, Any a)
Definition z3py.py:709
set_option(*args, **kws)
Definition z3py.py:311
ExprRef RealVar(int idx, ctx=None)
Definition z3py.py:1549
bool is_sub(Any a)
Definition z3py.py:2918
is_bv(a)
Definition z3py.py:4055
SetDifference(a, b)
Definition z3py.py:5132
bool is_arith_sort(Any s)
Definition z3py.py:2466
BitVecs(names, bv, ctx=None)
Definition z3py.py:4172
_check_same_sort(a, b, ctx=None)
Definition z3py.py:1248
bool is_mod(Any a)
Definition z3py.py:2959
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1848
_has_probe(args)
Definition z3py.py:1933
IsMember(e, s)
Definition z3py.py:5143
get_param(name)
Definition z3py.py:317
BVAddNoUnderflow(a, b)
Definition z3py.py:4600
deserialize(st)
Definition z3py.py:1166
bool is_not(Any a)
Definition z3py.py:1749
Extract(high, low, a)
Definition z3py.py:4239
Function(name, *sig)
Definition z3py.py:903
get_version()
Definition z3py.py:100
FreshConst(sort, prefix="c")
Definition z3py.py:1526
ULT(a, b)
Definition z3py.py:4316
EnumSort(name, values, ctx=None)
Definition z3py.py:5541
bool is_is_int(Any a)
Definition z3py.py:3019
_to_int_str(val)
Definition z3py.py:3280
is_algebraic_value(a)
Definition z3py.py:2880
is_bv_value(a)
Definition z3py.py:4069
BVSDivNoOverflow(a, b)
Definition z3py.py:4621
bool is_eq(Any a)
Definition z3py.py:1761
Context main_ctx()
Definition z3py.py:249
SetIntersect(*args)
Definition z3py.py:5087
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9065
BV2Int(a, is_signed=False)
Definition z3py.py:4084
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3391
_to_ast_ref(a, ctx)
Definition z3py.py:553
_to_func_decl_array(args)
Definition z3py.py:529
disable_trace(msg)
Definition z3py.py:87
bool is_to_int(Any a)
Definition z3py.py:3046
is_map(a)
Definition z3py.py:4785
Context _get_ctx(ctx)
Definition z3py.py:270
Or(*args)
Definition z3py.py:1974
is_re(s)
Definition z3py.py:11519
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5620
bool is_idiv(Any a)
Definition z3py.py:2947
Consts(names, sort)
Definition z3py.py:1511
Cond(p, t1, t2, ctx=None)
Definition z3py.py:9048
_to_pattern(arg)
Definition z3py.py:2067
RealVarVector(int n, ctx=None)
Definition z3py.py:1559
is_arith(a)
Definition z3py.py:2767
bool is_true(Any a)
Definition z3py.py:1681
bool is_false(Any a)
Definition z3py.py:1699
bool is_int(a)
Definition z3py.py:2788
If(a, b, c, ctx=None)
Definition z3py.py:1443
bool eq(AstRef a, AstRef b)
Definition z3py.py:486
is_app_of(a, k)
Definition z3py.py:1430
is_app(a)
Definition z3py.py:1327
bool is_add(Any a)
Definition z3py.py:2894
z3_error_handler(c, e)
Definition z3py.py:184
None reset_params()
Definition z3py.py:305
Reals(names, ctx=None)
Definition z3py.py:3418
is_int_value(a)
Definition z3py.py:2834
set_param(*args, **kws)
Definition z3py.py:281
is_pattern(a)
Definition z3py.py:2025
_coerce_seq(s, ctx=None)
Definition z3py.py:11180
bool is_distinct(Any a)
Definition z3py.py:1771
bool is_lt(Any a)
Definition z3py.py:2983
ULE(a, b)
Definition z3py.py:4298
is_real(a)
Definition z3py.py:2807
FullSet(s)
Definition z3py.py:5065
to_symbol(s, ctx=None)
Definition z3py.py:132
bool is_mul(Any a)
Definition z3py.py:2906
bool is_ast(Any a)
Definition z3py.py:465
_get_args(args)
Definition z3py.py:152
And(*args)
Definition z3py.py:1941
RepeatBitVec(n, a)
Definition z3py.py:4555
SetHasSize(a, k)
Definition z3py.py:5014
get_version_string()
Definition z3py.py:91
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3448
Array(name, *sorts)
Definition z3py.py:4867
Concat(*args)
Definition z3py.py:4193
_reduce(func, sequence, initial)
Definition z3py.py:1285
_is_algebraic(ctx, a)
Definition z3py.py:2830
Ints(names, ctx=None)
Definition z3py.py:3365
Select(a, *args)
Definition z3py.py:4941
Const(name, sort)
Definition z3py.py:1499
is_array_sort(a)
Definition z3py.py:4741
bool is_div(Any a)
Definition z3py.py:2930
ExprRef Var(int idx, SortRef s)
Definition z3py.py:1534
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4593
Real(name, ctx=None)
Definition z3py.py:3405
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1863
BitVecSort(sz, ctx=None)
Definition z3py.py:4116
open_log(fname)
Definition z3py.py:122
RecFunction(name, *sig)
Definition z3py.py:949
bool is_ge(Any a)
Definition z3py.py:2995
Model(ctx=None, eval={})
Definition z3py.py:6867
BVSubNoOverflow(a, b)
Definition z3py.py:4607
bool is_gt(Any a)
Definition z3py.py:3007
is_default(a)
Definition z3py.py:4801
is_K(a)
Definition z3py.py:4772
Bool(name, ctx=None)
Definition z3py.py:1820
_is_int(v)
Definition z3py.py:76
is_const_array(a)
Definition z3py.py:4759
Sqrt(a, ctx=None)
Definition z3py.py:3517
Default(a)
Definition z3py.py:4913
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:511
SetComplement(s)
Definition z3py.py:5122
is_as_array(n)
Definition z3py.py:6875
is_store(a)
Definition z3py.py:5033
bool is_or(Any a)
Definition z3py.py:1725
is_quantifier(a)
Definition z3py.py:2275
_mk_bin(f, a, b)
Definition z3py.py:1490
K(dom, v)
Definition z3py.py:4980
Xor(a, b, ctx=None)
Definition z3py.py:1891
Store(a, *args)
Definition z3py.py:4924
bool is_array(Any a)
Definition z3py.py:4745
mk_not(a)
Definition z3py.py:1926
is_expr(a)
Definition z3py.py:1304
_array_select(ar, arg)
Definition z3py.py:4732
is_const(a)
Definition z3py.py:1353
BoolVal(val, ctx=None)
Definition z3py.py:1801
RealVal(val, ctx=None)
Definition z3py.py:3304
bool is_implies(Any a)
Definition z3py.py:1737
z3_debug()
Definition z3py.py:70
get_full_version()
Definition z3py.py:109
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3378
_coerce_expr_merge(s, a)
Definition z3py.py:1230
Context get_ctx(ctx)
Definition z3py.py:277
LShR(a, b)
Definition z3py.py:4433
ArraySort(*sig)
Definition z3py.py:4834
Map(f, *args)
Definition z3py.py:4957
is_rational_value(a)
Definition z3py.py:2858
_probe_or(args, ctx)
Definition z3py.py:9002
BVRedAnd(a)
Definition z3py.py:4579
Cbrt(a, ctx=None)
Definition z3py.py:3530
_to_expr_ref(a, ctx)
Definition z3py.py:1180
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5529
IntSort(ctx=None)
Definition z3py.py:3246
is_seq(a)
Definition z3py.py:11201
Not(a, ctx=None)
Definition z3py.py:1907
_to_sort_ref(s, ctx)
Definition z3py.py:678
enable_trace(msg)
Definition z3py.py:83
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2342
ToReal(a)
Definition z3py.py:3462
URem(a, b)
Definition z3py.py:4391
bool is_bool(Any a)
Definition z3py.py:1663
StringVal(s, ctx=None)
Definition z3py.py:11228
IsInt(a)
Definition z3py.py:3500
_is_numeral(ctx, a)
Definition z3py.py:2826
MultiPattern(*args)
Definition z3py.py:2043
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2324
ZeroExt(n, a)
Definition z3py.py:4527
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:569
int _ast_kind(Context ctx, Any a)
Definition z3py.py:505
DatatypeSort(name, params=None, ctx=None)
Definition z3py.py:5492
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4614
UDiv(a, b)
Definition z3py.py:4370
Q(a, b, ctx=None)
Definition z3py.py:3339
Update(a, *args)
Definition z3py.py:4881
get_var_index(a)
Definition z3py.py:1397
append_log(s)
Definition z3py.py:127
is_var(a)
Definition z3py.py:1372
SortRef DeclareSort(name, ctx=None)
Definition z3py.py:713
IntVal(val, ctx=None)
Definition z3py.py:3292
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4635
RotateLeft(a, b)
Definition z3py.py:4465
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2289
_z3_assert(cond, msg)
Definition z3py.py:113