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
5014 """Return `True` if `a` is a Z3 array select application.
5015
5016 >>> a = Array('a', IntSort(), IntSort())
5017 >>> is_select(a)
5018 False
5019 >>> i = Int('i')
5020 >>> is_select(a[i])
5021 True
5022 """
5023 return is_app_of(a, Z3_OP_SELECT)
5024
5025
5027 """Return `True` if `a` is a Z3 array store application.
5028
5029 >>> a = Array('a', IntSort(), IntSort())
5030 >>> is_store(a)
5031 False
5032 >>> is_store(Store(a, 0, 1))
5033 True
5034 """
5035 return is_app_of(a, Z3_OP_STORE)
5036
5037
5042
5043
5044def SetSort(s):
5045 """ Create a set sort over element sort s"""
5046 return ArraySort(s, BoolSort())
5047
5048
5050 """Create the empty set
5051 >>> EmptySet(IntSort())
5052 K(Int, False)
5053 """
5054 ctx = s.ctx
5055 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5056
5057
5058def FullSet(s):
5059 """Create the full set
5060 >>> FullSet(IntSort())
5061 K(Int, True)
5062 """
5063 ctx = s.ctx
5064 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5065
5066
5067def SetUnion(*args):
5068 """ Take the union of sets
5069 >>> a = Const('a', SetSort(IntSort()))
5070 >>> b = Const('b', SetSort(IntSort()))
5071 >>> SetUnion(a, b)
5072 union(a, b)
5073 """
5074 args = _get_args(args)
5075 ctx = _ctx_from_ast_arg_list(args)
5076 _args, sz = _to_ast_array(args)
5077 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5078
5079
5080def SetIntersect(*args):
5081 """ Take the union of sets
5082 >>> a = Const('a', SetSort(IntSort()))
5083 >>> b = Const('b', SetSort(IntSort()))
5084 >>> SetIntersect(a, b)
5085 intersection(a, b)
5086 """
5087 args = _get_args(args)
5088 ctx = _ctx_from_ast_arg_list(args)
5089 _args, sz = _to_ast_array(args)
5090 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5091
5092
5093def SetAdd(s, e):
5094 """ Add element e to set s
5095 >>> a = Const('a', SetSort(IntSort()))
5096 >>> SetAdd(a, 1)
5097 Store(a, 1, True)
5098 """
5099 ctx = _ctx_from_ast_arg_list([s, e])
5100 e = _py2expr(e, ctx)
5101 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5102
5103
5104def SetDel(s, e):
5105 """ Remove element e to set s
5106 >>> a = Const('a', SetSort(IntSort()))
5107 >>> SetDel(a, 1)
5108 Store(a, 1, False)
5109 """
5110 ctx = _ctx_from_ast_arg_list([s, e])
5111 e = _py2expr(e, ctx)
5112 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5113
5114
5116 """ The complement of set s
5117 >>> a = Const('a', SetSort(IntSort()))
5118 >>> SetComplement(a)
5119 complement(a)
5120 """
5121 ctx = s.ctx
5122 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5123
5124
5126 """ The set difference of a and b
5127 >>> a = Const('a', SetSort(IntSort()))
5128 >>> b = Const('b', SetSort(IntSort()))
5129 >>> SetDifference(a, b)
5130 setminus(a, b)
5131 """
5132 ctx = _ctx_from_ast_arg_list([a, b])
5133 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5134
5135
5136def IsMember(e, s):
5137 """ Check if e is a member of set s
5138 >>> a = Const('a', SetSort(IntSort()))
5139 >>> IsMember(1, a)
5140 a[1]
5141 """
5142 ctx = _ctx_from_ast_arg_list([s, e])
5143 e = _py2expr(e, ctx)
5144 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5145
5146
5147def IsSubset(a, b):
5148 """ Check if a is a subset of b
5149 >>> a = Const('a', SetSort(IntSort()))
5150 >>> b = Const('b', SetSort(IntSort()))
5151 >>> IsSubset(a, b)
5152 subset(a, b)
5153 """
5154 ctx = _ctx_from_ast_arg_list([a, b])
5155 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5156
5157
5158
5163
5165 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5166 if not isinstance(acc, tuple):
5167 return False
5168 if len(acc) != 2:
5169 return False
5170 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5171
5172
5174 """Helper class for declaring Z3 datatypes.
5175
5176 >>> List = Datatype('List')
5177 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5178 >>> List.declare('nil')
5179 >>> List = List.create()
5180 >>> # List is now a Z3 declaration
5181 >>> List.nil
5182 nil
5183 >>> List.cons(10, List.nil)
5184 cons(10, nil)
5185 >>> List.cons(10, List.nil).sort()
5186 List
5187 >>> cons = List.cons
5188 >>> nil = List.nil
5189 >>> car = List.car
5190 >>> cdr = List.cdr
5191 >>> n = cons(1, cons(0, nil))
5192 >>> n
5193 cons(1, cons(0, nil))
5194 >>> simplify(cdr(n))
5195 cons(0, nil)
5196 >>> simplify(car(n))
5197 1
5198 """
5199
5200 def __init__(self, name, ctx=None):
5201 self.ctx = _get_ctx(ctx)
5202 self.name = name
5204
5205 def __deepcopy__(self, memo={}):
5206 r = Datatype(self.name, self.ctx)
5207 r.constructors = copy.deepcopy(self.constructors)
5208 return r
5209
5210 def declare_core(self, name, rec_name, *args):
5211 if z3_debug():
5212 _z3_assert(isinstance(name, str), "String expected")
5213 _z3_assert(isinstance(rec_name, str), "String expected")
5214 _z3_assert(
5215 all([_valid_accessor(a) for a in args]),
5216 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5217 )
5218 self.constructors.append((name, rec_name, args))
5219
5220 def declare(self, name, *args):
5221 """Declare constructor named `name` with the given accessors `args`.
5222 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5223 or a reference to the datatypes being declared.
5224
5225 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5226 declares the constructor named `cons` that builds a new List using an integer and a List.
5227 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5228 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5229 we use the method create() to create the actual datatype in Z3.
5230
5231 >>> List = Datatype('List')
5232 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5233 >>> List.declare('nil')
5234 >>> List = List.create()
5235 """
5236 if z3_debug():
5237 _z3_assert(isinstance(name, str), "String expected")
5238 _z3_assert(name != "", "Constructor name cannot be empty")
5239 return self.declare_core(name, "is-" + name, *args)
5240
5241 def __repr__(self):
5242 return "Datatype(%s, %s)" % (self.name, self.constructors)
5243
5244 def create(self):
5245 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5246
5247 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5248
5249 >>> List = Datatype('List')
5250 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5251 >>> List.declare('nil')
5252 >>> List = List.create()
5253 >>> List.nil
5254 nil
5255 >>> List.cons(10, List.nil)
5256 cons(10, nil)
5257 """
5258 return CreateDatatypes([self])[0]
5259
5260
5262 """Auxiliary object used to create Z3 datatypes."""
5263
5264 def __init__(self, c, ctx):
5265 self.c = c
5266 self.ctx = ctx
5267
5268 def __del__(self):
5269 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5270 Z3_del_constructor(self.ctx.ref(), self.c)
5271
5272
5274 """Auxiliary object used to create Z3 datatypes."""
5275
5276 def __init__(self, c, ctx):
5277 self.c = c
5278 self.ctx = ctx
5279
5280 def __del__(self):
5281 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5282 Z3_del_constructor_list(self.ctx.ref(), self.c)
5283
5284
5286 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5287
5288 In the following example we define a Tree-List using two mutually recursive datatypes.
5289
5290 >>> TreeList = Datatype('TreeList')
5291 >>> Tree = Datatype('Tree')
5292 >>> # Tree has two constructors: leaf and node
5293 >>> Tree.declare('leaf', ('val', IntSort()))
5294 >>> # a node contains a list of trees
5295 >>> Tree.declare('node', ('children', TreeList))
5296 >>> TreeList.declare('nil')
5297 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5298 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5299 >>> Tree.val(Tree.leaf(10))
5300 val(leaf(10))
5301 >>> simplify(Tree.val(Tree.leaf(10)))
5302 10
5303 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5304 >>> n1
5305 node(cons(leaf(10), cons(leaf(20), nil)))
5306 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5307 >>> simplify(n2 == n1)
5308 False
5309 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5310 True
5311 """
5312 ds = _get_args(ds)
5313 if z3_debug():
5314 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5315 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5316 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5317 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5318 ctx = ds[0].ctx
5319 num = len(ds)
5320 names = (Symbol * num)()
5321 out = (Sort * num)()
5322 clists = (ConstructorList * num)()
5323 to_delete = []
5324 for i in range(num):
5325 d = ds[i]
5326 names[i] = to_symbol(d.name, ctx)
5327 num_cs = len(d.constructors)
5328 cs = (Constructor * num_cs)()
5329 for j in range(num_cs):
5330 c = d.constructors[j]
5331 cname = to_symbol(c[0], ctx)
5332 rname = to_symbol(c[1], ctx)
5333 fs = c[2]
5334 num_fs = len(fs)
5335 fnames = (Symbol * num_fs)()
5336 sorts = (Sort * num_fs)()
5337 refs = (ctypes.c_uint * num_fs)()
5338 for k in range(num_fs):
5339 fname = fs[k][0]
5340 ftype = fs[k][1]
5341 fnames[k] = to_symbol(fname, ctx)
5342 if isinstance(ftype, Datatype):
5343 if z3_debug():
5344 _z3_assert(
5345 ds.count(ftype) == 1,
5346 "One and only one occurrence of each datatype is expected",
5347 )
5348 sorts[k] = None
5349 refs[k] = ds.index(ftype)
5350 else:
5351 if z3_debug():
5352 _z3_assert(is_sort(ftype), "Z3 sort expected")
5353 sorts[k] = ftype.ast
5354 refs[k] = 0
5355 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5356 to_delete.append(ScopedConstructor(cs[j], ctx))
5357 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5358 to_delete.append(ScopedConstructorList(clists[i], ctx))
5359 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5360 result = []
5361 # Create a field for every constructor, recognizer and accessor
5362 for i in range(num):
5363 dref = DatatypeSortRef(out[i], ctx)
5364 num_cs = dref.num_constructors()
5365 for j in range(num_cs):
5366 cref = dref.constructor(j)
5367 cref_name = cref.name()
5368 cref_arity = cref.arity()
5369 if cref.arity() == 0:
5370 cref = cref()
5371 setattr(dref, cref_name, cref)
5372 rref = dref.recognizer(j)
5373 setattr(dref, "is_" + cref_name, rref)
5374 for k in range(cref_arity):
5375 aref = dref.accessor(j, k)
5376 setattr(dref, aref.name(), aref)
5377 result.append(dref)
5378 return tuple(result)
5379
5380
5382 """Datatype sorts."""
5383
5385 """Return the number of constructors in the given Z3 datatype.
5386
5387 >>> List = Datatype('List')
5388 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5389 >>> List.declare('nil')
5390 >>> List = List.create()
5391 >>> # List is now a Z3 declaration
5392 >>> List.num_constructors()
5393 2
5394 """
5396
5397 def constructor(self, idx):
5398 """Return a constructor of the datatype `self`.
5399
5400 >>> List = Datatype('List')
5401 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5402 >>> List.declare('nil')
5403 >>> List = List.create()
5404 >>> # List is now a Z3 declaration
5405 >>> List.num_constructors()
5406 2
5407 >>> List.constructor(0)
5408 cons
5409 >>> List.constructor(1)
5410 nil
5411 """
5412 if z3_debug():
5413 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5415
5416 def recognizer(self, idx):
5417 """In Z3, each constructor has an associated recognizer predicate.
5418
5419 If the constructor is named `name`, then the recognizer `is_name`.
5420
5421 >>> List = Datatype('List')
5422 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5423 >>> List.declare('nil')
5424 >>> List = List.create()
5425 >>> # List is now a Z3 declaration
5426 >>> List.num_constructors()
5427 2
5428 >>> List.recognizer(0)
5429 is(cons)
5430 >>> List.recognizer(1)
5431 is(nil)
5432 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5433 False
5434 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5435 True
5436 >>> l = Const('l', List)
5437 >>> simplify(List.is_cons(l))
5438 is(cons, l)
5439 """
5440 if z3_debug():
5441 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5443
5444 def accessor(self, i, j):
5445 """In Z3, each constructor has 0 or more accessor.
5446 The number of accessors is equal to the arity of the constructor.
5447
5448 >>> List = Datatype('List')
5449 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5450 >>> List.declare('nil')
5451 >>> List = List.create()
5452 >>> List.num_constructors()
5453 2
5454 >>> List.constructor(0)
5455 cons
5456 >>> num_accs = List.constructor(0).arity()
5457 >>> num_accs
5458 2
5459 >>> List.accessor(0, 0)
5460 car
5461 >>> List.accessor(0, 1)
5462 cdr
5463 >>> List.constructor(1)
5464 nil
5465 >>> num_accs = List.constructor(1).arity()
5466 >>> num_accs
5467 0
5468 """
5469 if z3_debug():
5470 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5471 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5472 return FuncDeclRef(
5474 ctx=self.ctxctxctx,
5475 )
5476
5477
5479 """Datatype expressions."""
5480
5481 def sort(self):
5482 """Return the datatype sort of the datatype expression `self`."""
5484
5485def DatatypeSort(name, params=None, ctx=None):
5486 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype.
5487
5488 Args:
5489 name: name of the datatype sort
5490 params: optional list/tuple of sort parameters for parametric datatypes
5491 ctx: Z3 context (optional)
5492
5493 Example:
5494 >>> # Non-parametric datatype
5495 >>> TreeRef = DatatypeSort('Tree')
5496 >>> # Parametric datatype with one parameter
5497 >>> ListIntRef = DatatypeSort('List', [IntSort()])
5498 >>> # Parametric datatype with multiple parameters
5499 >>> PairRef = DatatypeSort('Pair', [IntSort(), BoolSort()])
5500 """
5501 ctx = _get_ctx(ctx)
5502 if params is None or len(params) == 0:
5503 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), 0, (Sort * 0)()), ctx)
5504 else:
5505 _params = (Sort * len(params))()
5506 for i in range(len(params)):
5507 _params[i] = params[i].ast
5508 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), len(params), _params), ctx)
5509
5510def TupleSort(name, sorts, ctx=None):
5511 """Create a named tuple sort base on a set of underlying sorts
5512 Example:
5513 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5514 """
5515 tuple = Datatype(name, ctx)
5516 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5517 tuple.declare(name, *projects)
5518 tuple = tuple.create()
5519 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5520
5521
5522def DisjointSum(name, sorts, ctx=None):
5523 """Create a named tagged union sort base on a set of underlying sorts
5524 Example:
5525 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5526 """
5527 sum = Datatype(name, ctx)
5528 for i in range(len(sorts)):
5529 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5530 sum = sum.create()
5531 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5532
5533
5534def EnumSort(name, values, ctx=None):
5535 """Return a new enumeration sort named `name` containing the given values.
5536
5537 The result is a pair (sort, list of constants).
5538 Example:
5539 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5540 """
5541 if z3_debug():
5542 _z3_assert(isinstance(name, str), "Name must be a string")
5543 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5544 _z3_assert(len(values) > 0, "At least one value expected")
5545 ctx = _get_ctx(ctx)
5546 num = len(values)
5547 _val_names = (Symbol * num)()
5548 for i in range(num):
5549 _val_names[i] = to_symbol(values[i], ctx)
5550 _values = (FuncDecl * num)()
5551 _testers = (FuncDecl * num)()
5552 name = to_symbol(name, ctx)
5553 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5554 V = []
5555 for i in range(num):
5556 V.append(FuncDeclRef(_values[i], ctx))
5557 V = [a() for a in V]
5558 return S, V
5559
5560
5565
5566
5568 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5569
5570 Consider using the function `args2params` to create instances of this object.
5571 """
5572
5573 def __init__(self, ctx=None, params=None):
5574 self.ctx = _get_ctx(ctx)
5575 if params is None:
5576 self.params = Z3_mk_params(self.ctx.ref())
5577 else:
5578 self.params = params
5579 Z3_params_inc_ref(self.ctx.ref(), self.params)
5580
5581 def __deepcopy__(self, memo={}):
5582 return ParamsRef(self.ctx, self.params)
5583
5584 def __del__(self):
5585 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5586 Z3_params_dec_ref(self.ctx.ref(), self.params)
5587
5588 def set(self, name, val):
5589 """Set parameter name with value val."""
5590 if z3_debug():
5591 _z3_assert(isinstance(name, str), "parameter name must be a string")
5592 name_sym = to_symbol(name, self.ctx)
5593 if isinstance(val, bool):
5594 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5595 elif _is_int(val):
5596 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5597 elif isinstance(val, float):
5598 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5599 elif isinstance(val, str):
5600 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5601 else:
5602 if z3_debug():
5603 _z3_assert(False, "invalid parameter value")
5604
5605 def __repr__(self):
5606 return Z3_params_to_string(self.ctx.ref(), self.params)
5607
5608 def validate(self, ds):
5609 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5610 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5611
5612
5613def args2params(arguments, keywords, ctx=None):
5614 """Convert python arguments into a Z3_params object.
5615 A ':' is added to the keywords, and '_' is replaced with '-'
5616
5617 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5618 (params model true relevancy 2 elim_and true)
5619 """
5620 if z3_debug():
5621 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5622 prev = None
5623 r = ParamsRef(ctx)
5624 for a in arguments:
5625 if prev is None:
5626 prev = a
5627 else:
5628 r.set(prev, a)
5629 prev = None
5630 for k in keywords:
5631 v = keywords[k]
5632 r.set(k, v)
5633 return r
5634
5635
5637 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5638 """
5639
5640 def __init__(self, descr, ctx=None):
5641 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5642 self.ctx = _get_ctx(ctx)
5643 self.descr = descr
5644 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5645
5646 def __deepcopy__(self, memo={}):
5647 return ParamsDescrsRef(self.descr, self.ctx)
5648
5649 def __del__(self):
5650 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5651 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5652
5653 def size(self):
5654 """Return the size of in the parameter description `self`.
5655 """
5656 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5657
5658 def __len__(self):
5659 """Return the size of in the parameter description `self`.
5660 """
5661 return self.size()
5662
5663 def get_name(self, i):
5664 """Return the i-th parameter name in the parameter description `self`.
5665 """
5666 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5667
5668 def get_kind(self, n):
5669 """Return the kind of the parameter named `n`.
5670 """
5671 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5672
5673 def get_documentation(self, n):
5674 """Return the documentation string of the parameter named `n`.
5675 """
5676 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5677
5678 def __getitem__(self, arg):
5679 if _is_int(arg):
5680 return self.get_name(arg)
5681 else:
5682 return self.get_kind(arg)
5683
5684 def __repr__(self):
5685 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5686
5687
5692
5693
5695 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5696
5697 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5698 A goal has a solution if one of its subgoals has a solution.
5699 A goal is unsatisfiable if all subgoals are unsatisfiable.
5700 """
5701
5702 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5703 if z3_debug():
5704 _z3_assert(goal is None or ctx is not None,
5705 "If goal is different from None, then ctx must be also different from None")
5706 self.ctx = _get_ctx(ctx)
5707 self.goal = goal
5708 if self.goal is None:
5709 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5710 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5711
5712 def __del__(self):
5713 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5714 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5715
5716 def depth(self):
5717 """Return the depth of the goal `self`.
5718 The depth corresponds to the number of tactics applied to `self`.
5719
5720 >>> x, y = Ints('x y')
5721 >>> g = Goal()
5722 >>> g.add(x == 0, y >= x + 1)
5723 >>> g.depth()
5724 0
5725 >>> r = Then('simplify', 'solve-eqs')(g)
5726 >>> # r has 1 subgoal
5727 >>> len(r)
5728 1
5729 >>> r[0].depth()
5730 2
5731 """
5732 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5733
5734 def inconsistent(self):
5735 """Return `True` if `self` contains the `False` constraints.
5736
5737 >>> x, y = Ints('x y')
5738 >>> g = Goal()
5739 >>> g.inconsistent()
5740 False
5741 >>> g.add(x == 0, x == 1)
5742 >>> g
5743 [x == 0, x == 1]
5744 >>> g.inconsistent()
5745 False
5746 >>> g2 = Tactic('propagate-values')(g)[0]
5747 >>> g2.inconsistent()
5748 True
5749 """
5750 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5751
5752 def prec(self):
5753 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5754
5755 >>> g = Goal()
5756 >>> g.prec() == Z3_GOAL_PRECISE
5757 True
5758 >>> x, y = Ints('x y')
5759 >>> g.add(x == y + 1)
5760 >>> g.prec() == Z3_GOAL_PRECISE
5761 True
5762 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5763 >>> g2 = t(g)[0]
5764 >>> g2
5765 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5766 >>> g2.prec() == Z3_GOAL_PRECISE
5767 False
5768 >>> g2.prec() == Z3_GOAL_UNDER
5769 True
5770 """
5771 return Z3_goal_precision(self.ctx.ref(), self.goal)
5772
5773 def precision(self):
5774 """Alias for `prec()`.
5775
5776 >>> g = Goal()
5777 >>> g.precision() == Z3_GOAL_PRECISE
5778 True
5779 """
5780 return self.prec()
5781
5782 def size(self):
5783 """Return the number of constraints in the goal `self`.
5784
5785 >>> g = Goal()
5786 >>> g.size()
5787 0
5788 >>> x, y = Ints('x y')
5789 >>> g.add(x == 0, y > x)
5790 >>> g.size()
5791 2
5792 """
5793 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5794
5795 def __len__(self):
5796 """Return the number of constraints in the goal `self`.
5797
5798 >>> g = Goal()
5799 >>> len(g)
5800 0
5801 >>> x, y = Ints('x y')
5802 >>> g.add(x == 0, y > x)
5803 >>> len(g)
5804 2
5805 """
5806 return self.size()
5807
5808 def get(self, i):
5809 """Return a constraint in the goal `self`.
5810
5811 >>> g = Goal()
5812 >>> x, y = Ints('x y')
5813 >>> g.add(x == 0, y > x)
5814 >>> g.get(0)
5815 x == 0
5816 >>> g.get(1)
5817 y > x
5818 """
5819 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5820
5821 def __getitem__(self, arg):
5822 """Return a constraint in the goal `self`.
5823
5824 >>> g = Goal()
5825 >>> x, y = Ints('x y')
5826 >>> g.add(x == 0, y > x)
5827 >>> g[0]
5828 x == 0
5829 >>> g[1]
5830 y > x
5831 """
5832 if arg >= len(self):
5833 raise IndexError
5834 return self.get(arg)
5835
5836 def assert_exprs(self, *args):
5837 """Assert constraints into the goal.
5838
5839 >>> x = Int('x')
5840 >>> g = Goal()
5841 >>> g.assert_exprs(x > 0, x < 2)
5842 >>> g
5843 [x > 0, x < 2]
5844 """
5845 args = _get_args(args)
5846 s = BoolSort(self.ctx)
5847 for arg in args:
5848 arg = s.cast(arg)
5849 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5850
5851 def append(self, *args):
5852 """Add constraints.
5853
5854 >>> x = Int('x')
5855 >>> g = Goal()
5856 >>> g.append(x > 0, x < 2)
5857 >>> g
5858 [x > 0, x < 2]
5859 """
5860 self.assert_exprs(*args)
5861
5862 def insert(self, *args):
5863 """Add constraints.
5864
5865 >>> x = Int('x')
5866 >>> g = Goal()
5867 >>> g.insert(x > 0, x < 2)
5868 >>> g
5869 [x > 0, x < 2]
5870 """
5871 self.assert_exprs(*args)
5872
5873 def add(self, *args):
5874 """Add constraints.
5875
5876 >>> x = Int('x')
5877 >>> g = Goal()
5878 >>> g.add(x > 0, x < 2)
5879 >>> g
5880 [x > 0, x < 2]
5881 """
5882 self.assert_exprs(*args)
5883
5884 def convert_model(self, model):
5885 """Retrieve model from a satisfiable goal
5886 >>> a, b = Ints('a b')
5887 >>> g = Goal()
5888 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5889 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5890 >>> r = t(g)
5891 >>> r[0]
5892 [Or(b == 0, b == 1), Not(0 <= b)]
5893 >>> r[1]
5894 [Or(b == 0, b == 1), Not(1 <= b)]
5895 >>> # Remark: the subgoal r[0] is unsatisfiable
5896 >>> # Creating a solver for solving the second subgoal
5897 >>> s = Solver()
5898 >>> s.add(r[1])
5899 >>> s.check()
5900 sat
5901 >>> s.model()
5902 [b = 0]
5903 >>> # Model s.model() does not assign a value to `a`
5904 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5905 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5906 >>> r[1].convert_model(s.model())
5907 [b = 0, a = 1]
5908 """
5909 if z3_debug():
5910 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5911 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5912
5913 def __repr__(self):
5914 return obj_to_string(self)
5915
5916 def sexpr(self):
5917 """Return a textual representation of the s-expression representing the goal."""
5918 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5919
5920 def dimacs(self, include_names=True):
5921 """Return a textual representation of the goal in DIMACS format."""
5922 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5923
5924 def translate(self, target):
5925 """Copy goal `self` to context `target`.
5926
5927 >>> x = Int('x')
5928 >>> g = Goal()
5929 >>> g.add(x > 10)
5930 >>> g
5931 [x > 10]
5932 >>> c2 = Context()
5933 >>> g2 = g.translate(c2)
5934 >>> g2
5935 [x > 10]
5936 >>> g.ctx == main_ctx()
5937 True
5938 >>> g2.ctx == c2
5939 True
5940 >>> g2.ctx == main_ctx()
5941 False
5942 """
5943 if z3_debug():
5944 _z3_assert(isinstance(target, Context), "target must be a context")
5945 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
5946
5947 def __copy__(self):
5948 return self.translate(self.ctx)
5949
5950 def __deepcopy__(self, memo={}):
5951 return self.translate(self.ctx)
5952
5953 def simplify(self, *arguments, **keywords):
5954 """Return a new simplified goal.
5955
5956 This method is essentially invoking the simplify tactic.
5957
5958 >>> g = Goal()
5959 >>> x = Int('x')
5960 >>> g.add(x + 1 >= 2)
5961 >>> g
5962 [x + 1 >= 2]
5963 >>> g2 = g.simplify()
5964 >>> g2
5965 [x >= 1]
5966 >>> # g was not modified
5967 >>> g
5968 [x + 1 >= 2]
5969 """
5970 t = Tactic("simplify")
5971 return t.apply(self, *arguments, **keywords)[0]
5972
5973 def as_expr(self):
5974 """Return goal `self` as a single Z3 expression.
5975
5976 >>> x = Int('x')
5977 >>> g = Goal()
5978 >>> g.as_expr()
5979 True
5980 >>> g.add(x > 1)
5981 >>> g.as_expr()
5982 x > 1
5983 >>> g.add(x < 10)
5984 >>> g.as_expr()
5985 And(x > 1, x < 10)
5986 """
5987 sz = len(self)
5988 if sz == 0:
5989 return BoolVal(True, self.ctx)
5990 elif sz == 1:
5991 return self.get(0)
5992 else:
5993 return And([self.get(i) for i in range(len(self))], self.ctx)
5994
5995
6000
6001
6003 """A collection (vector) of ASTs."""
6004
6005 def __init__(self, v=None, ctx=None):
6006 self.vector = None
6007 if v is None:
6008 self.ctx = _get_ctx(ctx)
6009 self.vector = Z3_mk_ast_vector(self.ctx.ref())
6010 else:
6011 self.vector = v
6012 assert ctx is not None
6013 self.ctx = ctx
6014 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
6015
6016 def __del__(self):
6017 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
6018 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
6019
6020 def __len__(self):
6021 """Return the size of the vector `self`.
6022
6023 >>> A = AstVector()
6024 >>> len(A)
6025 0
6026 >>> A.push(Int('x'))
6027 >>> A.push(Int('x'))
6028 >>> len(A)
6029 2
6030 """
6031 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
6032
6033 def __getitem__(self, i):
6034 """Return the AST at position `i`.
6035
6036 >>> A = AstVector()
6037 >>> A.push(Int('x') + 1)
6038 >>> A.push(Int('y'))
6039 >>> A[0]
6040 x + 1
6041 >>> A[1]
6042 y
6043 """
6044
6045 if isinstance(i, int):
6046 if i < 0:
6047 i += self.__len__()
6048
6049 if i >= self.__len__():
6050 raise IndexError
6051 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
6052
6053 elif isinstance(i, slice):
6054 result = []
6055 for ii in range(*i.indices(self.__len__())):
6056 result.append(_to_ast_ref(
6057 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6058 self.ctx,
6059 ))
6060 return result
6061
6062 def __setitem__(self, i, v):
6063 """Update AST at position `i`.
6064
6065 >>> A = AstVector()
6066 >>> A.push(Int('x') + 1)
6067 >>> A.push(Int('y'))
6068 >>> A[0]
6069 x + 1
6070 >>> A[0] = Int('x')
6071 >>> A[0]
6072 x
6073 """
6074 if i >= self.__len__():
6075 raise IndexError
6076 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6077
6078 def push(self, v):
6079 """Add `v` in the end of the vector.
6080
6081 >>> A = AstVector()
6082 >>> len(A)
6083 0
6084 >>> A.push(Int('x'))
6085 >>> len(A)
6086 1
6087 """
6088 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6089
6090 def resize(self, sz):
6091 """Resize the vector to `sz` elements.
6092
6093 >>> A = AstVector()
6094 >>> A.resize(10)
6095 >>> len(A)
6096 10
6097 >>> for i in range(10): A[i] = Int('x')
6098 >>> A[5]
6099 x
6100 """
6101 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6102
6103 def __contains__(self, item):
6104 """Return `True` if the vector contains `item`.
6105
6106 >>> x = Int('x')
6107 >>> A = AstVector()
6108 >>> x in A
6109 False
6110 >>> A.push(x)
6111 >>> x in A
6112 True
6113 >>> (x+1) in A
6114 False
6115 >>> A.push(x+1)
6116 >>> (x+1) in A
6117 True
6118 >>> A
6119 [x, x + 1]
6120 """
6121 for elem in self:
6122 if elem.eq(item):
6123 return True
6124 return False
6125
6126 def translate(self, other_ctx):
6127 """Copy vector `self` to context `other_ctx`.
6128
6129 >>> x = Int('x')
6130 >>> A = AstVector()
6131 >>> A.push(x)
6132 >>> c2 = Context()
6133 >>> B = A.translate(c2)
6134 >>> B
6135 [x]
6136 """
6137 return AstVector(
6138 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6139 ctx=other_ctx,
6140 )
6141
6142 def __copy__(self):
6143 return self.translate(self.ctx)
6144
6145 def __deepcopy__(self, memo={}):
6146 return self.translate(self.ctx)
6147
6148 def __repr__(self):
6149 return obj_to_string(self)
6150
6151 def sexpr(self):
6152 """Return a textual representation of the s-expression representing the vector."""
6153 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6154
6155
6160
6161
6163 """A mapping from ASTs to ASTs."""
6164
6165 def __init__(self, m=None, ctx=None):
6166 self.map = None
6167 if m is None:
6168 self.ctx = _get_ctx(ctx)
6169 self.map = Z3_mk_ast_map(self.ctx.ref())
6170 else:
6171 self.map = m
6172 assert ctx is not None
6173 self.ctx = ctx
6174 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6175
6176 def __deepcopy__(self, memo={}):
6177 return AstMap(self.map, self.ctx)
6178
6179 def __del__(self):
6180 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6181 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6182
6183 def __len__(self):
6184 """Return the size of the map.
6185
6186 >>> M = AstMap()
6187 >>> len(M)
6188 0
6189 >>> x = Int('x')
6190 >>> M[x] = IntVal(1)
6191 >>> len(M)
6192 1
6193 """
6194 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6195
6196 def __contains__(self, key):
6197 """Return `True` if the map contains key `key`.
6198
6199 >>> M = AstMap()
6200 >>> x = Int('x')
6201 >>> M[x] = x + 1
6202 >>> x in M
6203 True
6204 >>> x+1 in M
6205 False
6206 """
6207 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6208
6209 def __getitem__(self, key):
6210 """Retrieve the value associated with key `key`.
6211
6212 >>> M = AstMap()
6213 >>> x = Int('x')
6214 >>> M[x] = x + 1
6215 >>> M[x]
6216 x + 1
6217 """
6218 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6219
6220 def __setitem__(self, k, v):
6221 """Add/Update key `k` with value `v`.
6222
6223 >>> M = AstMap()
6224 >>> x = Int('x')
6225 >>> M[x] = x + 1
6226 >>> len(M)
6227 1
6228 >>> M[x]
6229 x + 1
6230 >>> M[x] = IntVal(1)
6231 >>> M[x]
6232 1
6233 """
6234 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6235
6236 def __repr__(self):
6237 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6238
6239 def erase(self, k):
6240 """Remove the entry associated with key `k`.
6241
6242 >>> M = AstMap()
6243 >>> x = Int('x')
6244 >>> M[x] = x + 1
6245 >>> len(M)
6246 1
6247 >>> M.erase(x)
6248 >>> len(M)
6249 0
6250 """
6251 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6252
6253 def reset(self):
6254 """Remove all entries from the map.
6255
6256 >>> M = AstMap()
6257 >>> x = Int('x')
6258 >>> M[x] = x + 1
6259 >>> M[x+x] = IntVal(1)
6260 >>> len(M)
6261 2
6262 >>> M.reset()
6263 >>> len(M)
6264 0
6265 """
6266 Z3_ast_map_reset(self.ctx.ref(), self.map)
6267
6268 def keys(self):
6269 """Return an AstVector containing all keys in the map.
6270
6271 >>> M = AstMap()
6272 >>> x = Int('x')
6273 >>> M[x] = x + 1
6274 >>> M[x+x] = IntVal(1)
6275 >>> M.keys()
6276 [x, x + x]
6277 """
6278 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6279
6280
6285
6286
6288 """Store the value of the interpretation of a function in a particular point."""
6289
6290 def __init__(self, entry, ctx):
6291 self.entry = entry
6292 self.ctx = ctx
6293 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6294
6295 def __deepcopy__(self, memo={}):
6296 return FuncEntry(self.entry, self.ctx)
6297
6298 def __del__(self):
6299 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6300 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6301
6302 def num_args(self):
6303 """Return the number of arguments in the given entry.
6304
6305 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6306 >>> s = Solver()
6307 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6308 >>> s.check()
6309 sat
6310 >>> m = s.model()
6311 >>> f_i = m[f]
6312 >>> f_i.num_entries()
6313 1
6314 >>> e = f_i.entry(0)
6315 >>> e.num_args()
6316 2
6317 """
6318 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6319
6320 def arg_value(self, idx):
6321 """Return the value of argument `idx`.
6322
6323 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6324 >>> s = Solver()
6325 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6326 >>> s.check()
6327 sat
6328 >>> m = s.model()
6329 >>> f_i = m[f]
6330 >>> f_i.num_entries()
6331 1
6332 >>> e = f_i.entry(0)
6333 >>> e
6334 [1, 2, 20]
6335 >>> e.num_args()
6336 2
6337 >>> e.arg_value(0)
6338 1
6339 >>> e.arg_value(1)
6340 2
6341 >>> try:
6342 ... e.arg_value(2)
6343 ... except IndexError:
6344 ... print("index error")
6345 index error
6346 """
6347 if idx >= self.num_args():
6348 raise IndexError
6349 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6350
6351 def value(self):
6352 """Return the value of the function at point `self`.
6353
6354 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6355 >>> s = Solver()
6356 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6357 >>> s.check()
6358 sat
6359 >>> m = s.model()
6360 >>> f_i = m[f]
6361 >>> f_i.num_entries()
6362 1
6363 >>> e = f_i.entry(0)
6364 >>> e
6365 [1, 2, 20]
6366 >>> e.num_args()
6367 2
6368 >>> e.value()
6369 20
6370 """
6371 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6372
6373 def as_list(self):
6374 """Return entry `self` as a Python list.
6375 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6376 >>> s = Solver()
6377 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6378 >>> s.check()
6379 sat
6380 >>> m = s.model()
6381 >>> f_i = m[f]
6382 >>> f_i.num_entries()
6383 1
6384 >>> e = f_i.entry(0)
6385 >>> e.as_list()
6386 [1, 2, 20]
6387 """
6388 args = [self.arg_value(i) for i in range(self.num_args())]
6389 args.append(self.value())
6390 return args
6391
6392 def __repr__(self):
6393 return repr(self.as_list())
6394
6395
6397 """Stores the interpretation of a function in a Z3 model."""
6398
6399 def __init__(self, f, ctx):
6400 self.f = f
6401 self.ctx = ctx
6402 if self.f is not None:
6403 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6404
6405 def __del__(self):
6406 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6407 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6408
6409 def else_value(self):
6410 """
6411 Return the `else` value for a function interpretation.
6412 Return None if Z3 did not specify the `else` value for
6413 this object.
6414
6415 >>> f = Function('f', IntSort(), IntSort())
6416 >>> s = Solver()
6417 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6418 >>> s.check()
6419 sat
6420 >>> m = s.model()
6421 >>> m[f]
6422 [2 -> 0, else -> 1]
6423 >>> m[f].else_value()
6424 1
6425 """
6426 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6427 if r:
6428 return _to_expr_ref(r, self.ctx)
6429 else:
6430 return None
6431
6432 def num_entries(self):
6433 """Return the number of entries/points in the function interpretation `self`.
6434
6435 >>> f = Function('f', IntSort(), IntSort())
6436 >>> s = Solver()
6437 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6438 >>> s.check()
6439 sat
6440 >>> m = s.model()
6441 >>> m[f]
6442 [2 -> 0, else -> 1]
6443 >>> m[f].num_entries()
6444 1
6445 """
6446 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6447
6448 def arity(self):
6449 """Return the number of arguments for each entry in the function interpretation `self`.
6450
6451 >>> f = Function('f', IntSort(), IntSort())
6452 >>> s = Solver()
6453 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6454 >>> s.check()
6455 sat
6456 >>> m = s.model()
6457 >>> m[f].arity()
6458 1
6459 """
6460 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6461
6462 def entry(self, idx):
6463 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6464
6465 >>> f = Function('f', IntSort(), IntSort())
6466 >>> s = Solver()
6467 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6468 >>> s.check()
6469 sat
6470 >>> m = s.model()
6471 >>> m[f]
6472 [2 -> 0, else -> 1]
6473 >>> m[f].num_entries()
6474 1
6475 >>> m[f].entry(0)
6476 [2, 0]
6477 """
6478 if idx >= self.num_entries():
6479 raise IndexError
6480 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6481
6482 def translate(self, other_ctx):
6483 """Copy model 'self' to context 'other_ctx'.
6484 """
6485 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6486
6487 def __copy__(self):
6488 return self.translate(self.ctx)
6489
6490 def __deepcopy__(self, memo={}):
6491 return self.translate(self.ctx)
6492
6493 def as_list(self):
6494 """Return the function interpretation as a Python list.
6495 >>> f = Function('f', IntSort(), IntSort())
6496 >>> s = Solver()
6497 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6498 >>> s.check()
6499 sat
6500 >>> m = s.model()
6501 >>> m[f]
6502 [2 -> 0, else -> 1]
6503 >>> m[f].as_list()
6504 [[2, 0], 1]
6505 """
6506 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6507 r.append(self.else_value())
6508 return r
6509
6510 def __repr__(self):
6511 return obj_to_string(self)
6512
6513
6515 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6516
6517 def __init__(self, m, ctx):
6518 assert ctx is not None
6519 self.model = m
6520 self.ctx = ctx
6521 Z3_model_inc_ref(self.ctx.ref(), self.model)
6522
6523 def __del__(self):
6524 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6525 Z3_model_dec_ref(self.ctx.ref(), self.model)
6526
6527 def __repr__(self):
6528 return obj_to_string(self)
6529
6530 def sexpr(self):
6531 """Return a textual representation of the s-expression representing the model."""
6532 return Z3_model_to_string(self.ctx.ref(), self.model)
6533
6534 def eval(self, t, model_completion=False):
6535 """Evaluate the expression `t` in the model `self`.
6536 If `model_completion` is enabled, then a default interpretation is automatically added
6537 for symbols that do not have an interpretation in the model `self`.
6538
6539 >>> x = Int('x')
6540 >>> s = Solver()
6541 >>> s.add(x > 0, x < 2)
6542 >>> s.check()
6543 sat
6544 >>> m = s.model()
6545 >>> m.eval(x + 1)
6546 2
6547 >>> m.eval(x == 1)
6548 True
6549 >>> y = Int('y')
6550 >>> m.eval(y + x)
6551 1 + y
6552 >>> m.eval(y)
6553 y
6554 >>> m.eval(y, model_completion=True)
6555 0
6556 >>> # Now, m contains an interpretation for y
6557 >>> m.eval(y + x)
6558 1
6559 """
6560 r = (Ast * 1)()
6561 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6562 return _to_expr_ref(r[0], self.ctx)
6563 raise Z3Exception("failed to evaluate expression in the model")
6564
6565 def evaluate(self, t, model_completion=False):
6566 """Alias for `eval`.
6567
6568 >>> x = Int('x')
6569 >>> s = Solver()
6570 >>> s.add(x > 0, x < 2)
6571 >>> s.check()
6572 sat
6573 >>> m = s.model()
6574 >>> m.evaluate(x + 1)
6575 2
6576 >>> m.evaluate(x == 1)
6577 True
6578 >>> y = Int('y')
6579 >>> m.evaluate(y + x)
6580 1 + y
6581 >>> m.evaluate(y)
6582 y
6583 >>> m.evaluate(y, model_completion=True)
6584 0
6585 >>> # Now, m contains an interpretation for y
6586 >>> m.evaluate(y + x)
6587 1
6588 """
6589 return self.eval(t, model_completion)
6590
6591 def __len__(self):
6592 """Return the number of constant and function declarations in the model `self`.
6593
6594 >>> f = Function('f', IntSort(), IntSort())
6595 >>> x = Int('x')
6596 >>> s = Solver()
6597 >>> s.add(x > 0, f(x) != x)
6598 >>> s.check()
6599 sat
6600 >>> m = s.model()
6601 >>> len(m)
6602 2
6603 """
6604 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6605 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6606 return num_consts + num_funcs
6607
6608 def get_interp(self, decl):
6609 """Return the interpretation for a given declaration or constant.
6610
6611 >>> f = Function('f', IntSort(), IntSort())
6612 >>> x = Int('x')
6613 >>> s = Solver()
6614 >>> s.add(x > 0, x < 2, f(x) == 0)
6615 >>> s.check()
6616 sat
6617 >>> m = s.model()
6618 >>> m[x]
6619 1
6620 >>> m[f]
6621 [else -> 0]
6622 """
6623 if z3_debug():
6624 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6625 if is_const(decl):
6626 decl = decl.decl()
6627 try:
6628 if decl.arity() == 0:
6629 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6630 if _r.value is None:
6631 return None
6632 r = _to_expr_ref(_r, self.ctx)
6633 if is_as_array(r):
6634 fi = self.get_interp(get_as_array_func(r))
6635 if fi is None:
6636 return fi
6637 e = fi.else_value()
6638 if e is None:
6639 return fi
6640 if fi.arity() != 1:
6641 return fi
6642 srt = decl.range()
6643 dom = srt.domain()
6644 e = K(dom, e)
6645 i = 0
6646 sz = fi.num_entries()
6647 n = fi.arity()
6648 while i < sz:
6649 fe = fi.entry(i)
6650 e = Store(e, fe.arg_value(0), fe.value())
6651 i += 1
6652 return e
6653 else:
6654 return r
6655 else:
6656 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6657 except Z3Exception:
6658 return None
6659
6660 def num_sorts(self):
6661 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6662
6663 >>> A = DeclareSort('A')
6664 >>> a, b = Consts('a b', A)
6665 >>> s = Solver()
6666 >>> s.add(a != b)
6667 >>> s.check()
6668 sat
6669 >>> m = s.model()
6670 >>> m.num_sorts()
6671 1
6672 """
6673 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6674
6675 def get_sort(self, idx):
6676 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6677
6678 >>> A = DeclareSort('A')
6679 >>> B = DeclareSort('B')
6680 >>> a1, a2 = Consts('a1 a2', A)
6681 >>> b1, b2 = Consts('b1 b2', B)
6682 >>> s = Solver()
6683 >>> s.add(a1 != a2, b1 != b2)
6684 >>> s.check()
6685 sat
6686 >>> m = s.model()
6687 >>> m.num_sorts()
6688 2
6689 >>> m.get_sort(0)
6690 A
6691 >>> m.get_sort(1)
6692 B
6693 """
6694 if idx >= self.num_sorts():
6695 raise IndexError
6696 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6697
6698 def sorts(self):
6699 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6700
6701 >>> A = DeclareSort('A')
6702 >>> B = DeclareSort('B')
6703 >>> a1, a2 = Consts('a1 a2', A)
6704 >>> b1, b2 = Consts('b1 b2', B)
6705 >>> s = Solver()
6706 >>> s.add(a1 != a2, b1 != b2)
6707 >>> s.check()
6708 sat
6709 >>> m = s.model()
6710 >>> m.sorts()
6711 [A, B]
6712 """
6713 return [self.get_sort(i) for i in range(self.num_sorts())]
6714
6715 def get_universe(self, s):
6716 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6717
6718 >>> A = DeclareSort('A')
6719 >>> a, b = Consts('a b', A)
6720 >>> s = Solver()
6721 >>> s.add(a != b)
6722 >>> s.check()
6723 sat
6724 >>> m = s.model()
6725 >>> m.get_universe(A)
6726 [A!val!1, A!val!0]
6727 """
6728 if z3_debug():
6729 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6730 try:
6731 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6732 except Z3Exception:
6733 return None
6734
6735 def __getitem__(self, idx):
6736 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6737 If `idx` is a declaration, then the actual interpretation is returned.
6738
6739 The elements can be retrieved using position or the actual declaration.
6740
6741 >>> f = Function('f', IntSort(), IntSort())
6742 >>> x = Int('x')
6743 >>> s = Solver()
6744 >>> s.add(x > 0, x < 2, f(x) == 0)
6745 >>> s.check()
6746 sat
6747 >>> m = s.model()
6748 >>> len(m)
6749 2
6750 >>> m[0]
6751 x
6752 >>> m[1]
6753 f
6754 >>> m[x]
6755 1
6756 >>> m[f]
6757 [else -> 0]
6758 >>> for d in m: print("%s -> %s" % (d, m[d]))
6759 x -> 1
6760 f -> [else -> 0]
6761 """
6762 if _is_int(idx):
6763 if idx >= len(self):
6764 raise IndexError
6765 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6766 if (idx < num_consts):
6767 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6768 else:
6769 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6770 if isinstance(idx, FuncDeclRef):
6771 return self.get_interp(idx)
6772 if is_const(idx):
6773 return self.get_interp(idx.decl())
6774 if isinstance(idx, SortRef):
6775 return self.get_universe(idx)
6776 if z3_debug():
6777 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6778 return None
6779
6780 def decls(self):
6781 """Return a list with all symbols that have an interpretation in the model `self`.
6782 >>> f = Function('f', IntSort(), IntSort())
6783 >>> x = Int('x')
6784 >>> s = Solver()
6785 >>> s.add(x > 0, x < 2, f(x) == 0)
6786 >>> s.check()
6787 sat
6788 >>> m = s.model()
6789 >>> m.decls()
6790 [x, f]
6791 """
6792 r = []
6793 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6794 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6795 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6796 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6797 return r
6798
6799 def update_value(self, x, value):
6800 """Update the interpretation of a constant"""
6801 if is_expr(x):
6802 x = x.decl()
6803 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6804 fi1 = value.f
6805 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6806 fi2 = FuncInterp(fi2, x.ctx)
6807 for i in range(value.num_entries()):
6808 e = value.entry(i)
6809 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6810 v = AstVector()
6811 for j in range(n):
6812 v.push(e.arg_value(j))
6813 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6814 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6815 return
6816 if not is_func_decl(x) or x.arity() != 0:
6817 raise Z3Exception("Expecting 0-ary function or constant expression")
6818 value = _py2expr(value)
6819 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6820
6821 def translate(self, target):
6822 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6823 """
6824 if z3_debug():
6825 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6826 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6827 return ModelRef(model, target)
6828
6829 def project(self, vars, fml):
6830 """Perform model-based projection on fml with respect to vars.
6831 Assume that the model satisfies fml. Then compute a projection fml_p, such
6832 that vars do not occur free in fml_p, fml_p is true in the model and
6833 fml_p => exists vars . fml
6834 """
6835 ctx = self.ctx.ref()
6836 _vars = (Ast * len(vars))()
6837 for i in range(len(vars)):
6838 _vars[i] = vars[i].as_ast()
6839 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6840
6841 def project_with_witness(self, vars, fml):
6842 """Perform model-based projection, but also include realizer terms for the projected variables"""
6843 ctx = self.ctx.ref()
6844 _vars = (Ast * len(vars))()
6845 for i in range(len(vars)):
6846 _vars[i] = vars[i].as_ast()
6847 defs = AstMap()
6848 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6849 result = _to_expr_ref(result, self.ctx)
6850 return result, defs
6851
6852
6853 def __copy__(self):
6854 return self.translate(self.ctx)
6855
6856 def __deepcopy__(self, memo={}):
6857 return self.translate(self.ctx)
6858
6859
6860def Model(ctx=None, eval = {}):
6861 ctx = _get_ctx(ctx)
6862 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6863 for k, v in eval.items():
6864 mdl.update_value(k, v)
6865 return mdl
6866
6867
6869 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6870 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6871
6872
6874 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6875 if z3_debug():
6876 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6877 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6878
6879
6884
6885
6887 """Statistics for `Solver.check()`."""
6888
6889 def __init__(self, stats, ctx):
6890 self.stats = stats
6891 self.ctx = ctx
6892 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6893
6894 def __deepcopy__(self, memo={}):
6895 return Statistics(self.stats, self.ctx)
6896
6897 def __del__(self):
6898 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6899 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6900
6901 def __repr__(self):
6902 if in_html_mode():
6903 out = io.StringIO()
6904 even = True
6905 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6906 for k, v in self:
6907 if even:
6908 out.write(u('<tr style="background-color:#CFCFCF">'))
6909 even = False
6910 else:
6911 out.write(u("<tr>"))
6912 even = True
6913 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6914 out.write(u("</table>"))
6915 return out.getvalue()
6916 else:
6917 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6918
6919 def __len__(self):
6920 """Return the number of statistical counters.
6921
6922 >>> x = Int('x')
6923 >>> s = Then('simplify', 'nlsat').solver()
6924 >>> s.add(x > 0)
6925 >>> s.check()
6926 sat
6927 >>> st = s.statistics()
6928 >>> len(st)
6929 7
6930 """
6931 return int(Z3_stats_size(self.ctx.ref(), self.stats))
6932
6933 def __getitem__(self, idx):
6934 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
6935
6936 >>> x = Int('x')
6937 >>> s = Then('simplify', 'nlsat').solver()
6938 >>> s.add(x > 0)
6939 >>> s.check()
6940 sat
6941 >>> st = s.statistics()
6942 >>> len(st)
6943 7
6944 >>> st[0]
6945 ('nlsat propagations', 2)
6946 >>> st[1]
6947 ('nlsat restarts', 1)
6948 """
6949 if idx >= len(self):
6950 raise IndexError
6951 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6952 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6953 else:
6954 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6955 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
6956
6957 def keys(self):
6958 """Return the list of statistical counters.
6959
6960 >>> x = Int('x')
6961 >>> s = Then('simplify', 'nlsat').solver()
6962 >>> s.add(x > 0)
6963 >>> s.check()
6964 sat
6965 >>> st = s.statistics()
6966 """
6967 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
6968
6969 def get_key_value(self, key):
6970 """Return the value of a particular statistical counter.
6971
6972 >>> x = Int('x')
6973 >>> s = Then('simplify', 'nlsat').solver()
6974 >>> s.add(x > 0)
6975 >>> s.check()
6976 sat
6977 >>> st = s.statistics()
6978 >>> st.get_key_value('nlsat propagations')
6979 2
6980 """
6981 for idx in range(len(self)):
6982 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
6983 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
6984 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
6985 else:
6986 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
6987 raise Z3Exception("unknown key")
6988
6989 def __getattr__(self, name):
6990 """Access the value of statistical using attributes.
6991
6992 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
6993 we should use '_' (e.g., 'nlsat_propagations').
6994
6995 >>> x = Int('x')
6996 >>> s = Then('simplify', 'nlsat').solver()
6997 >>> s.add(x > 0)
6998 >>> s.check()
6999 sat
7000 >>> st = s.statistics()
7001 >>> st.nlsat_propagations
7002 2
7003 >>> st.nlsat_stages
7004 2
7005 """
7006 key = name.replace("_", " ")
7007 try:
7008 return self.get_key_value(key)
7009 except Z3Exception:
7010 raise AttributeError
7011
7012
7017
7018
7020 """Represents the result of a satisfiability check: sat, unsat, unknown.
7021
7022 >>> s = Solver()
7023 >>> s.check()
7024 sat
7025 >>> r = s.check()
7026 >>> isinstance(r, CheckSatResult)
7027 True
7028 """
7029
7030 def __init__(self, r):
7031 self.r = r
7032
7033 def __deepcopy__(self, memo={}):
7034 return CheckSatResult(self.r)
7035
7036 def __eq__(self, other):
7037 return isinstance(other, CheckSatResult) and self.r == other.r
7038
7039 def __ne__(self, other):
7040 return not self.__eq__(other)
7041
7042 def __repr__(self):
7043 if in_html_mode():
7044 if self.r == Z3_L_TRUE:
7045 return "<b>sat</b>"
7046 elif self.r == Z3_L_FALSE:
7047 return "<b>unsat</b>"
7048 else:
7049 return "<b>unknown</b>"
7050 else:
7051 if self.r == Z3_L_TRUE:
7052 return "sat"
7053 elif self.r == Z3_L_FALSE:
7054 return "unsat"
7055 else:
7056 return "unknown"
7057
7058 def _repr_html_(self):
7059 in_html = in_html_mode()
7060 set_html_mode(True)
7061 res = repr(self)
7062 set_html_mode(in_html)
7063 return res
7064
7065
7066sat = CheckSatResult(Z3_L_TRUE)
7067unsat = CheckSatResult(Z3_L_FALSE)
7068unknown = CheckSatResult(Z3_L_UNDEF)
7069
7070
7072 """
7073 Solver API provides methods for implementing the main SMT 2.0 commands:
7074 push, pop, check, get-model, etc.
7075 """
7076
7077 def __init__(self, solver=None, ctx=None, logFile=None):
7078 assert solver is None or ctx is not None
7079 self.ctx = _get_ctx(ctx)
7080 self.backtrack_level = 4000000000
7081 self.solver = None
7082 if solver is None:
7083 self.solver = Z3_mk_solver(self.ctx.ref())
7084 else:
7085 self.solver = solver
7086 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7087 if logFile is not None:
7088 self.set("smtlib2_log", logFile)
7089
7090 def __del__(self):
7091 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7092 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7093
7094 def __enter__(self):
7095 self.push()
7096 return self
7097
7098 def __exit__(self, *exc_info):
7099 self.pop()
7100
7101 def set(self, *args, **keys):
7102 """Set a configuration option.
7103 The method `help()` return a string containing all available options.
7104
7105 >>> s = Solver()
7106 >>> # The option MBQI can be set using three different approaches.
7107 >>> s.set(mbqi=True)
7108 >>> s.set('MBQI', True)
7109 >>> s.set(':mbqi', True)
7110 """
7111 p = args2params(args, keys, self.ctx)
7112 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7113
7114 def push(self):
7115 """Create a backtracking point.
7116
7117 >>> x = Int('x')
7118 >>> s = Solver()
7119 >>> s.add(x > 0)
7120 >>> s
7121 [x > 0]
7122 >>> s.push()
7123 >>> s.add(x < 1)
7124 >>> s
7125 [x > 0, x < 1]
7126 >>> s.check()
7127 unsat
7128 >>> s.pop()
7129 >>> s.check()
7130 sat
7131 >>> s
7132 [x > 0]
7133 """
7134 Z3_solver_push(self.ctx.ref(), self.solver)
7135
7136 def pop(self, num=1):
7137 """Backtrack \\c num backtracking points.
7138
7139 >>> x = Int('x')
7140 >>> s = Solver()
7141 >>> s.add(x > 0)
7142 >>> s
7143 [x > 0]
7144 >>> s.push()
7145 >>> s.add(x < 1)
7146 >>> s
7147 [x > 0, x < 1]
7148 >>> s.check()
7149 unsat
7150 >>> s.pop()
7151 >>> s.check()
7152 sat
7153 >>> s
7154 [x > 0]
7155 """
7156 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7157
7158 def num_scopes(self):
7159 """Return the current number of backtracking points.
7160
7161 >>> s = Solver()
7162 >>> s.num_scopes()
7163 0
7164 >>> s.push()
7165 >>> s.num_scopes()
7166 1
7167 >>> s.push()
7168 >>> s.num_scopes()
7169 2
7170 >>> s.pop()
7171 >>> s.num_scopes()
7172 1
7173 """
7174 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7175
7176 def reset(self):
7177 """Remove all asserted constraints and backtracking points created using `push()`.
7178
7179 >>> x = Int('x')
7180 >>> s = Solver()
7181 >>> s.add(x > 0)
7182 >>> s
7183 [x > 0]
7184 >>> s.reset()
7185 >>> s
7186 []
7187 """
7188 Z3_solver_reset(self.ctx.ref(), self.solver)
7189
7190 def assert_exprs(self, *args):
7191 """Assert constraints into the solver.
7192
7193 >>> x = Int('x')
7194 >>> s = Solver()
7195 >>> s.assert_exprs(x > 0, x < 2)
7196 >>> s
7197 [x > 0, x < 2]
7198 """
7199 args = _get_args(args)
7200 s = BoolSort(self.ctx)
7201 for arg in args:
7202 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7203 for f in arg:
7204 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7205 else:
7206 arg = s.cast(arg)
7207 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7208
7209 def add(self, *args):
7210 """Assert constraints into the solver.
7211
7212 >>> x = Int('x')
7213 >>> s = Solver()
7214 >>> s.add(x > 0, x < 2)
7215 >>> s
7216 [x > 0, x < 2]
7217 """
7218 self.assert_exprs(*args)
7219
7220 def __iadd__(self, fml):
7221 self.add(fml)
7222 return self
7223
7224 def append(self, *args):
7225 """Assert constraints into the solver.
7226
7227 >>> x = Int('x')
7228 >>> s = Solver()
7229 >>> s.append(x > 0, x < 2)
7230 >>> s
7231 [x > 0, x < 2]
7232 """
7233 self.assert_exprs(*args)
7234
7235 def insert(self, *args):
7236 """Assert constraints into the solver.
7237
7238 >>> x = Int('x')
7239 >>> s = Solver()
7240 >>> s.insert(x > 0, x < 2)
7241 >>> s
7242 [x > 0, x < 2]
7243 """
7244 self.assert_exprs(*args)
7245
7246 def assert_and_track(self, a, p):
7247 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7248
7249 If `p` is a string, it will be automatically converted into a Boolean constant.
7250
7251 >>> x = Int('x')
7252 >>> p3 = Bool('p3')
7253 >>> s = Solver()
7254 >>> s.set(unsat_core=True)
7255 >>> s.assert_and_track(x > 0, 'p1')
7256 >>> s.assert_and_track(x != 1, 'p2')
7257 >>> s.assert_and_track(x < 0, p3)
7258 >>> print(s.check())
7259 unsat
7260 >>> c = s.unsat_core()
7261 >>> len(c)
7262 2
7263 >>> Bool('p1') in c
7264 True
7265 >>> Bool('p2') in c
7266 False
7267 >>> p3 in c
7268 True
7269 """
7270 if isinstance(p, str):
7271 p = Bool(p, self.ctx)
7272 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7273 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7274 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7275
7276 def check(self, *assumptions):
7277 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7278
7279 >>> x = Int('x')
7280 >>> s = Solver()
7281 >>> s.check()
7282 sat
7283 >>> s.add(x > 0, x < 2)
7284 >>> s.check()
7285 sat
7286 >>> s.model().eval(x)
7287 1
7288 >>> s.add(x < 1)
7289 >>> s.check()
7290 unsat
7291 >>> s.reset()
7292 >>> s.add(2**x == 4)
7293 >>> s.check()
7294 sat
7295 """
7296 s = BoolSort(self.ctx)
7297 assumptions = _get_args(assumptions)
7298 num = len(assumptions)
7299 _assumptions = (Ast * num)()
7300 for i in range(num):
7301 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7302 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7303 return CheckSatResult(r)
7304
7305 def model(self):
7306 """Return a model for the last `check()`.
7307
7308 This function raises an exception if
7309 a model is not available (e.g., last `check()` returned unsat).
7310
7311 >>> s = Solver()
7312 >>> a = Int('a')
7313 >>> s.add(a + 2 == 0)
7314 >>> s.check()
7315 sat
7316 >>> s.model()
7317 [a = -2]
7318 """
7319 try:
7320 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7321 except Z3Exception:
7322 raise Z3Exception("model is not available")
7323
7324 def import_model_converter(self, other):
7325 """Import model converter from other into the current solver"""
7326 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7327
7328 def interrupt(self):
7329 """Interrupt the execution of the solver object.
7330 Remarks: This ensures that the interrupt applies only
7331 to the given solver object and it applies only if it is running.
7332 """
7333 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7334
7335 def unsat_core(self):
7336 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7337
7338 These are the assumptions Z3 used in the unsatisfiability proof.
7339 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7340 They may be also used to "retract" assumptions. Note that, assumptions are not really
7341 "soft constraints", but they can be used to implement them.
7342
7343 >>> p1, p2, p3 = Bools('p1 p2 p3')
7344 >>> x, y = Ints('x y')
7345 >>> s = Solver()
7346 >>> s.add(Implies(p1, x > 0))
7347 >>> s.add(Implies(p2, y > x))
7348 >>> s.add(Implies(p2, y < 1))
7349 >>> s.add(Implies(p3, y > -3))
7350 >>> s.check(p1, p2, p3)
7351 unsat
7352 >>> core = s.unsat_core()
7353 >>> len(core)
7354 2
7355 >>> p1 in core
7356 True
7357 >>> p2 in core
7358 True
7359 >>> p3 in core
7360 False
7361 >>> # "Retracting" p2
7362 >>> s.check(p1, p3)
7363 sat
7364 """
7365 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7366
7367 def consequences(self, assumptions, variables):
7368 """Determine fixed values for the variables based on the solver state and assumptions.
7369 >>> s = Solver()
7370 >>> a, b, c, d = Bools('a b c d')
7371 >>> s.add(Implies(a,b), Implies(b, c))
7372 >>> s.consequences([a],[b,c,d])
7373 (sat, [Implies(a, b), Implies(a, c)])
7374 >>> s.consequences([Not(c),d],[a,b,c,d])
7375 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7376 """
7377 if isinstance(assumptions, list):
7378 _asms = AstVector(None, self.ctx)
7379 for a in assumptions:
7380 _asms.push(a)
7381 assumptions = _asms
7382 if isinstance(variables, list):
7383 _vars = AstVector(None, self.ctx)
7384 for a in variables:
7385 _vars.push(a)
7386 variables = _vars
7387 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7388 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7389 consequences = AstVector(None, self.ctx)
7390 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7391 variables.vector, consequences.vector)
7392 sz = len(consequences)
7393 consequences = [consequences[i] for i in range(sz)]
7394 return CheckSatResult(r), consequences
7395
7396 def from_file(self, filename):
7397 """Parse assertions from a file"""
7398 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7399
7400 def from_string(self, s):
7401 """Parse assertions from a string"""
7402 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7403
7404 def cube(self, vars=None):
7405 """Get set of cubes
7406 The method takes an optional set of variables that restrict which
7407 variables may be used as a starting point for cubing.
7408 If vars is not None, then the first case split is based on a variable in
7409 this set.
7410 """
7411 self.cube_vs = AstVector(None, self.ctx)
7412 if vars is not None:
7413 for v in vars:
7414 self.cube_vs.push(v)
7415 while True:
7416 lvl = self.backtrack_level
7417 self.backtrack_level = 4000000000
7418 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7419 if (len(r) == 1 and is_false(r[0])):
7420 return
7421 yield r
7422 if (len(r) == 0):
7423 return
7424
7425 def cube_vars(self):
7426 """Access the set of variables that were touched by the most recently generated cube.
7427 This set of variables can be used as a starting point for additional cubes.
7428 The idea is that variables that appear in clauses that are reduced by the most recent
7429 cube are likely more useful to cube on."""
7430 return self.cube_vs
7431
7432 def root(self, t):
7433 """Retrieve congruence closure root of the term t relative to the current search state
7434 The function primarily works for SimpleSolver. Terms and variables that are
7435 eliminated during pre-processing are not visible to the congruence closure.
7436 """
7437 t = _py2expr(t, self.ctx)
7438 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7439
7440 def next(self, t):
7441 """Retrieve congruence closure sibling of the term t relative to the current search state
7442 The function primarily works for SimpleSolver. Terms and variables that are
7443 eliminated during pre-processing are not visible to the congruence closure.
7444 """
7445 t = _py2expr(t, self.ctx)
7446 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7447
7448 def explain_congruent(self, a, b):
7449 """Explain congruence of a and b relative to the current search state"""
7450 a = _py2expr(a, self.ctx)
7451 b = _py2expr(b, self.ctx)
7452 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7453
7454
7455 def solve_for(self, ts):
7456 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7457 vars = AstVector(ctx=self.ctx);
7458 terms = AstVector(ctx=self.ctx);
7459 guards = AstVector(ctx=self.ctx);
7460 for t in ts:
7461 t = _py2expr(t, self.ctx)
7462 vars.push(t)
7463 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7464 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7465
7466
7467 def proof(self):
7468 """Return a proof for the last `check()`. Proof construction must be enabled."""
7469 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7470
7471 def assertions(self):
7472 """Return an AST vector containing all added constraints.
7473
7474 >>> s = Solver()
7475 >>> s.assertions()
7476 []
7477 >>> a = Int('a')
7478 >>> s.add(a > 0)
7479 >>> s.add(a < 10)
7480 >>> s.assertions()
7481 [a > 0, a < 10]
7482 """
7483 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7484
7485 def units(self):
7486 """Return an AST vector containing all currently inferred units.
7487 """
7488 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7489
7490 def non_units(self):
7491 """Return an AST vector containing all atomic formulas in solver state that are not units.
7492 """
7493 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7494
7495 def trail_levels(self):
7496 """Return trail and decision levels of the solver state after a check() call.
7497 """
7498 trail = self.trail()
7499 levels = (ctypes.c_uint * len(trail))()
7500 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7501 return trail, levels
7502
7503 def set_initial_value(self, var, value):
7504 """initialize the solver's state by setting the initial value of var to value
7505 """
7506 s = var.sort()
7507 value = s.cast(value)
7508 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7509
7510 def trail(self):
7511 """Return trail of the solver state after a check() call.
7512 """
7513 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7514
7515 def statistics(self):
7516 """Return statistics for the last `check()`.
7517
7518 >>> s = SimpleSolver()
7519 >>> x = Int('x')
7520 >>> s.add(x > 0)
7521 >>> s.check()
7522 sat
7523 >>> st = s.statistics()
7524 >>> st.get_key_value('final checks')
7525 1
7526 >>> len(st) > 0
7527 True
7528 >>> st[0] != 0
7529 True
7530 """
7531 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7532
7533 def reason_unknown(self):
7534 """Return a string describing why the last `check()` returned `unknown`.
7535
7536 >>> x = Int('x')
7537 >>> s = SimpleSolver()
7538 >>> s.add(x == 2**x)
7539 >>> s.check()
7540 unknown
7541 >>> s.reason_unknown()
7542 '(incomplete (theory arithmetic))'
7543 """
7544 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7545
7546 def help(self):
7547 """Display a string describing all available options."""
7548 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7549
7550 def param_descrs(self):
7551 """Return the parameter description set."""
7552 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7553
7554 def __repr__(self):
7555 """Return a formatted string with all added constraints."""
7556 return obj_to_string(self)
7557
7558 def translate(self, target):
7559 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7560
7561 >>> c1 = Context()
7562 >>> c2 = Context()
7563 >>> s1 = Solver(ctx=c1)
7564 >>> s2 = s1.translate(c2)
7565 """
7566 if z3_debug():
7567 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7568 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7569 return Solver(solver, target)
7570
7571 def __copy__(self):
7572 return self.translate(self.ctx)
7573
7574 def __deepcopy__(self, memo={}):
7575 return self.translate(self.ctx)
7576
7577 def sexpr(self):
7578 """Return a formatted string (in Lisp-like format) with all added constraints.
7579 We say the string is in s-expression format.
7580
7581 >>> x = Int('x')
7582 >>> s = Solver()
7583 >>> s.add(x > 0)
7584 >>> s.add(x < 2)
7585 >>> r = s.sexpr()
7586 """
7587 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7588
7589 def dimacs(self, include_names=True):
7590 """Return a textual representation of the solver in DIMACS format."""
7591 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7592
7593 def to_smt2(self):
7594 """return SMTLIB2 formatted benchmark for solver's assertions"""
7595 es = self.assertions()
7596 sz = len(es)
7597 sz1 = sz
7598 if sz1 > 0:
7599 sz1 -= 1
7600 v = (Ast * sz1)()
7601 for i in range(sz1):
7602 v[i] = es[i].as_ast()
7603 if sz > 0:
7604 e = es[sz1].as_ast()
7605 else:
7606 e = BoolVal(True, self.ctx).as_ast()
7607 return Z3_benchmark_to_smtlib_string(
7608 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7609 )
7610
7611
7612def SolverFor(logic, ctx=None, logFile=None):
7613 """Create a solver customized for the given logic.
7614
7615 The parameter `logic` is a string. It should be contains
7616 the name of a SMT-LIB logic.
7617 See http://www.smtlib.org/ for the name of all available logics.
7618
7619 >>> s = SolverFor("QF_LIA")
7620 >>> x = Int('x')
7621 >>> s.add(x > 0)
7622 >>> s.add(x < 2)
7623 >>> s.check()
7624 sat
7625 >>> s.model()
7626 [x = 1]
7627 """
7628 ctx = _get_ctx(ctx)
7629 logic = to_symbol(logic)
7630 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7631
7632
7633def SimpleSolver(ctx=None, logFile=None):
7634 """Return a simple general purpose solver with limited amount of preprocessing.
7635
7636 >>> s = SimpleSolver()
7637 >>> x = Int('x')
7638 >>> s.add(x > 0)
7639 >>> s.check()
7640 sat
7641 """
7642 ctx = _get_ctx(ctx)
7643 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7644
7645#########################################
7646#
7647# Fixedpoint
7648#
7649#########################################
7650
7651
7652class Fixedpoint(Z3PPObject):
7653 """Fixedpoint API provides methods for solving with recursive predicates"""
7654
7655 def __init__(self, fixedpoint=None, ctx=None):
7656 assert fixedpoint is None or ctx is not None
7657 self.ctx = _get_ctx(ctx)
7658 self.fixedpoint = None
7659 if fixedpoint is None:
7660 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7661 else:
7662 self.fixedpoint = fixedpoint
7663 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7664 self.vars = []
7665
7666 def __deepcopy__(self, memo={}):
7667 return FixedPoint(self.fixedpoint, self.ctx)
7668
7669 def __del__(self):
7670 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7671 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7672
7673 def set(self, *args, **keys):
7674 """Set a configuration option. The method `help()` return a string containing all available options.
7675 """
7676 p = args2params(args, keys, self.ctx)
7677 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7678
7679 def help(self):
7680 """Display a string describing all available options."""
7681 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7682
7683 def param_descrs(self):
7684 """Return the parameter description set."""
7685 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7686
7687 def assert_exprs(self, *args):
7688 """Assert constraints as background axioms for the fixedpoint solver."""
7689 args = _get_args(args)
7690 s = BoolSort(self.ctx)
7691 for arg in args:
7692 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7693 for f in arg:
7694 f = self.abstract(f)
7695 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7696 else:
7697 arg = s.cast(arg)
7698 arg = self.abstract(arg)
7699 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7700
7701 def add(self, *args):
7702 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7703 self.assert_exprs(*args)
7704
7705 def __iadd__(self, fml):
7706 self.add(fml)
7707 return self
7708
7709 def append(self, *args):
7710 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7711 self.assert_exprs(*args)
7712
7713 def insert(self, *args):
7714 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7715 self.assert_exprs(*args)
7716
7717 def add_rule(self, head, body=None, name=None):
7718 """Assert rules defining recursive predicates to the fixedpoint solver.
7719 >>> a = Bool('a')
7720 >>> b = Bool('b')
7721 >>> s = Fixedpoint()
7722 >>> s.register_relation(a.decl())
7723 >>> s.register_relation(b.decl())
7724 >>> s.fact(a)
7725 >>> s.rule(b, a)
7726 >>> s.query(b)
7727 sat
7728 """
7729 if name is None:
7730 name = ""
7731 name = to_symbol(name, self.ctx)
7732 if body is None:
7733 head = self.abstract(head)
7734 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7735 else:
7736 body = _get_args(body)
7737 f = self.abstract(Implies(And(body, self.ctx), head))
7738 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7739
7740 def rule(self, head, body=None, name=None):
7741 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7742 self.add_rule(head, body, name)
7743
7744 def fact(self, head, name=None):
7745 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7746 self.add_rule(head, None, name)
7747
7748 def query(self, *query):
7749 """Query the fixedpoint engine whether formula is derivable.
7750 You can also pass an tuple or list of recursive predicates.
7751 """
7752 query = _get_args(query)
7753 sz = len(query)
7754 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7755 _decls = (FuncDecl * sz)()
7756 i = 0
7757 for q in query:
7758 _decls[i] = q.ast
7759 i = i + 1
7760 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7761 else:
7762 if sz == 1:
7763 query = query[0]
7764 else:
7765 query = And(query, self.ctx)
7766 query = self.abstract(query, False)
7767 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7768 return CheckSatResult(r)
7769
7770 def query_from_lvl(self, lvl, *query):
7771 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7772 """
7773 query = _get_args(query)
7774 sz = len(query)
7775 if sz >= 1 and isinstance(query[0], FuncDecl):
7776 _z3_assert(False, "unsupported")
7777 else:
7778 if sz == 1:
7779 query = query[0]
7780 else:
7781 query = And(query)
7782 query = self.abstract(query, False)
7783 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7784 return CheckSatResult(r)
7785
7786 def update_rule(self, head, body, name):
7787 """update rule"""
7788 if name is None:
7789 name = ""
7790 name = to_symbol(name, self.ctx)
7791 body = _get_args(body)
7792 f = self.abstract(Implies(And(body, self.ctx), head))
7793 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7794
7795 def get_answer(self):
7796 """Retrieve answer from last query call."""
7797 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7798 return _to_expr_ref(r, self.ctx)
7799
7800 def get_ground_sat_answer(self):
7801 """Retrieve a ground cex from last query call."""
7802 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7803 return _to_expr_ref(r, self.ctx)
7804
7805 def get_rules_along_trace(self):
7806 """retrieve rules along the counterexample trace"""
7807 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7808
7809 def get_rule_names_along_trace(self):
7810 """retrieve rule names along the counterexample trace"""
7811 # this is a hack as I don't know how to return a list of symbols from C++;
7812 # obtain names as a single string separated by semicolons
7813 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7814 # split into individual names
7815 return names.split(";")
7816
7817 def get_num_levels(self, predicate):
7818 """Retrieve number of levels used for predicate in PDR engine"""
7819 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7820
7821 def get_cover_delta(self, level, predicate):
7822 """Retrieve properties known about predicate for the level'th unfolding.
7823 -1 is treated as the limit (infinity)
7824 """
7825 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7826 return _to_expr_ref(r, self.ctx)
7827
7828 def add_cover(self, level, predicate, property):
7829 """Add property to predicate for the level'th unfolding.
7830 -1 is treated as infinity (infinity)
7831 """
7832 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7833
7834 def register_relation(self, *relations):
7835 """Register relation as recursive"""
7836 relations = _get_args(relations)
7837 for f in relations:
7838 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7839
7840 def set_predicate_representation(self, f, *representations):
7841 """Control how relation is represented"""
7842 representations = _get_args(representations)
7843 representations = [to_symbol(s) for s in representations]
7844 sz = len(representations)
7845 args = (Symbol * sz)()
7846 for i in range(sz):
7847 args[i] = representations[i]
7848 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7849
7850 def parse_string(self, s):
7851 """Parse rules and queries from a string"""
7852 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7853
7854 def parse_file(self, f):
7855 """Parse rules and queries from a file"""
7856 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7857
7858 def get_rules(self):
7859 """retrieve rules that have been added to fixedpoint context"""
7860 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7861
7862 def get_assertions(self):
7863 """retrieve assertions that have been added to fixedpoint context"""
7864 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7865
7866 def __repr__(self):
7867 """Return a formatted string with all added rules and constraints."""
7868 return self.sexpr()
7869
7870 def sexpr(self):
7871 """Return a formatted string (in Lisp-like format) with all added constraints.
7872 We say the string is in s-expression format.
7873 """
7874 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7875
7876 def to_string(self, queries):
7877 """Return a formatted string (in Lisp-like format) with all added constraints.
7878 We say the string is in s-expression format.
7879 Include also queries.
7880 """
7881 args, len = _to_ast_array(queries)
7882 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7883
7884 def statistics(self):
7885 """Return statistics for the last `query()`.
7886 """
7887 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7888
7889 def reason_unknown(self):
7890 """Return a string describing why the last `query()` returned `unknown`.
7891 """
7892 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7893
7894 def declare_var(self, *vars):
7895 """Add variable or several variables.
7896 The added variable or variables will be bound in the rules
7897 and queries
7898 """
7899 vars = _get_args(vars)
7900 for v in vars:
7901 self.vars += [v]
7902
7903 def abstract(self, fml, is_forall=True):
7904 if self.vars == []:
7905 return fml
7906 if is_forall:
7907 return ForAll(self.vars, fml)
7908 else:
7909 return Exists(self.vars, fml)
7910
7911
7912#########################################
7913#
7914# Finite domains
7915#
7916#########################################
7917
7918class FiniteDomainSortRef(SortRef):
7919 """Finite domain sort."""
7920
7921 def size(self):
7922 """Return the size of the finite domain sort"""
7923 r = (ctypes.c_ulonglong * 1)()
7924 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
7925 return r[0]
7926 else:
7927 raise Z3Exception("Failed to retrieve finite domain sort size")
7928
7929
7930def FiniteDomainSort(name, sz, ctx=None):
7931 """Create a named finite domain sort of a given size sz"""
7932 if not isinstance(name, Symbol):
7933 name = to_symbol(name)
7934 ctx = _get_ctx(ctx)
7935 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
7936
7937
7938def is_finite_domain_sort(s):
7939 """Return True if `s` is a Z3 finite-domain sort.
7940
7941 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
7942 True
7943 >>> is_finite_domain_sort(IntSort())
7944 False
7945 """
7946 return isinstance(s, FiniteDomainSortRef)
7947
7948
7949class FiniteDomainRef(ExprRef):
7950 """Finite-domain expressions."""
7951
7952 def sort(self):
7953 """Return the sort of the finite-domain expression `self`."""
7954 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
7955
7956 def as_string(self):
7957 """Return a Z3 floating point expression as a Python string."""
7958 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
7959
7960
7961def is_finite_domain(a):
7962 """Return `True` if `a` is a Z3 finite-domain expression.
7963
7964 >>> s = FiniteDomainSort('S', 100)
7965 >>> b = Const('b', s)
7966 >>> is_finite_domain(b)
7967 True
7968 >>> is_finite_domain(Int('x'))
7969 False
7970 """
7971 return isinstance(a, FiniteDomainRef)
7972
7973
7974class FiniteDomainNumRef(FiniteDomainRef):
7975 """Integer values."""
7976
7977 def as_long(self):
7978 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
7979
7980 >>> s = FiniteDomainSort('S', 100)
7981 >>> v = FiniteDomainVal(3, s)
7982 >>> v
7983 3
7984 >>> v.as_long() + 1
7985 4
7986 """
7987 return int(self.as_string())
7988
7989 def as_string(self):
7990 """Return a Z3 finite-domain numeral as a Python string.
7991
7992 >>> s = FiniteDomainSort('S', 100)
7993 >>> v = FiniteDomainVal(42, s)
7994 >>> v.as_string()
7995 '42'
7996 """
7997 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
7998
7999
8000def FiniteDomainVal(val, sort, ctx=None):
8001 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
8002
8003 >>> s = FiniteDomainSort('S', 256)
8004 >>> FiniteDomainVal(255, s)
8005 255
8006 >>> FiniteDomainVal('100', s)
8007 100
8008 """
8009 if z3_debug():
8010 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
8011 ctx = sort.ctx
8012 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
8013
8014
8015def is_finite_domain_value(a):
8016 """Return `True` if `a` is a Z3 finite-domain value.
8017
8018 >>> s = FiniteDomainSort('S', 100)
8019 >>> b = Const('b', s)
8020 >>> is_finite_domain_value(b)
8021 False
8022 >>> b = FiniteDomainVal(10, s)
8023 >>> b
8024 10
8025 >>> is_finite_domain_value(b)
8026 True
8027 """
8028 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
8029
8030
8031#########################################
8032#
8033# Optimize
8034#
8035#########################################
8036
8037class OptimizeObjective:
8038 def __init__(self, opt, value, is_max):
8039 self._opt = opt
8040 self._value = value
8041 self._is_max = is_max
8042
8043 def lower(self):
8044 opt = self._opt
8045 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8046
8047 def upper(self):
8048 opt = self._opt
8049 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8050
8051 def lower_values(self):
8052 opt = self._opt
8053 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8054
8055 def upper_values(self):
8056 opt = self._opt
8057 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8058
8059 def value(self):
8060 if self._is_max:
8061 return self.upper()
8062 else:
8063 return self.lower()
8064
8065 def __str__(self):
8066 return "%s:%s" % (self._value, self._is_max)
8067
8068
8069_on_models = {}
8070
8071
8072def _global_on_model(ctx):
8073 (fn, mdl) = _on_models[ctx]
8074 fn(mdl)
8075
8076
8077_on_model_eh = on_model_eh_type(_global_on_model)
8078
8079
8080class Optimize(Z3PPObject):
8081 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8082
8083 def __init__(self, optimize=None, ctx=None):
8084 self.ctx = _get_ctx(ctx)
8085 if optimize is None:
8086 self.optimize = Z3_mk_optimize(self.ctx.ref())
8087 else:
8088 self.optimize = optimize
8089 self._on_models_id = None
8090 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8091
8092 def __deepcopy__(self, memo={}):
8093 return Optimize(self.optimize, self.ctx)
8094
8095 def __del__(self):
8096 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8097 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8098 if self._on_models_id is not None:
8099 del _on_models[self._on_models_id]
8100
8101 def __enter__(self):
8102 self.push()
8103 return self
8104
8105 def __exit__(self, *exc_info):
8106 self.pop()
8107
8108 def set(self, *args, **keys):
8109 """Set a configuration option.
8110 The method `help()` return a string containing all available options.
8111 """
8112 p = args2params(args, keys, self.ctx)
8113 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8114
8115 def help(self):
8116 """Display a string describing all available options."""
8117 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8118
8119 def param_descrs(self):
8120 """Return the parameter description set."""
8121 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8122
8123 def assert_exprs(self, *args):
8124 """Assert constraints as background axioms for the optimize solver."""
8125 args = _get_args(args)
8126 s = BoolSort(self.ctx)
8127 for arg in args:
8128 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8129 for f in arg:
8130 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8131 else:
8132 arg = s.cast(arg)
8133 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8134
8135 def add(self, *args):
8136 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8137 self.assert_exprs(*args)
8138
8139 def __iadd__(self, fml):
8140 self.add(fml)
8141 return self
8142
8143 def assert_and_track(self, a, p):
8144 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8145
8146 If `p` is a string, it will be automatically converted into a Boolean constant.
8147
8148 >>> x = Int('x')
8149 >>> p3 = Bool('p3')
8150 >>> s = Optimize()
8151 >>> s.assert_and_track(x > 0, 'p1')
8152 >>> s.assert_and_track(x != 1, 'p2')
8153 >>> s.assert_and_track(x < 0, p3)
8154 >>> print(s.check())
8155 unsat
8156 >>> c = s.unsat_core()
8157 >>> len(c)
8158 2
8159 >>> Bool('p1') in c
8160 True
8161 >>> Bool('p2') in c
8162 False
8163 >>> p3 in c
8164 True
8165 """
8166 if isinstance(p, str):
8167 p = Bool(p, self.ctx)
8168 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8169 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8170 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8171
8172 def add_soft(self, arg, weight="1", id=None):
8173 """Add soft constraint with optional weight and optional identifier.
8174 If no weight is supplied, then the penalty for violating the soft constraint
8175 is 1.
8176 Soft constraints are grouped by identifiers. Soft constraints that are
8177 added without identifiers are grouped by default.
8178 """
8179 if _is_int(weight):
8180 weight = "%d" % weight
8181 elif isinstance(weight, float):
8182 weight = "%f" % weight
8183 if not isinstance(weight, str):
8184 raise Z3Exception("weight should be a string or an integer")
8185 if id is None:
8186 id = ""
8187 id = to_symbol(id, self.ctx)
8188
8189 def asoft(a):
8190 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8191 return OptimizeObjective(self, v, False)
8192 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8193 return [asoft(a) for a in arg]
8194 return asoft(arg)
8195
8196 def set_initial_value(self, var, value):
8197 """initialize the solver's state by setting the initial value of var to value
8198 """
8199 s = var.sort()
8200 value = s.cast(value)
8201 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8202
8203 def maximize(self, arg):
8204 """Add objective function to maximize."""
8205 return OptimizeObjective(
8206 self,
8207 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8208 is_max=True,
8209 )
8210
8211 def minimize(self, arg):
8212 """Add objective function to minimize."""
8213 return OptimizeObjective(
8214 self,
8215 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8216 is_max=False,
8217 )
8218
8219 def push(self):
8220 """create a backtracking point for added rules, facts and assertions"""
8221 Z3_optimize_push(self.ctx.ref(), self.optimize)
8222
8223 def pop(self):
8224 """restore to previously created backtracking point"""
8225 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8226
8227 def check(self, *assumptions):
8228 """Check consistency and produce optimal values."""
8229 assumptions = _get_args(assumptions)
8230 num = len(assumptions)
8231 _assumptions = (Ast * num)()
8232 for i in range(num):
8233 _assumptions[i] = assumptions[i].as_ast()
8234 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8235
8236 def reason_unknown(self):
8237 """Return a string that describes why the last `check()` returned `unknown`."""
8238 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8239
8240 def model(self):
8241 """Return a model for the last check()."""
8242 try:
8243 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8244 except Z3Exception:
8245 raise Z3Exception("model is not available")
8246
8247 def unsat_core(self):
8248 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8249
8250 def lower(self, obj):
8251 if not isinstance(obj, OptimizeObjective):
8252 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8253 return obj.lower()
8254
8255 def upper(self, obj):
8256 if not isinstance(obj, OptimizeObjective):
8257 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8258 return obj.upper()
8259
8260 def lower_values(self, obj):
8261 if not isinstance(obj, OptimizeObjective):
8262 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8263 return obj.lower_values()
8264
8265 def upper_values(self, obj):
8266 if not isinstance(obj, OptimizeObjective):
8267 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8268 return obj.upper_values()
8269
8270 def from_file(self, filename):
8271 """Parse assertions and objectives from a file"""
8272 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8273
8274 def from_string(self, s):
8275 """Parse assertions and objectives from a string"""
8276 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8277
8278 def assertions(self):
8279 """Return an AST vector containing all added constraints."""
8280 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8281
8282 def objectives(self):
8283 """returns set of objective functions"""
8284 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8285
8286 def __repr__(self):
8287 """Return a formatted string with all added rules and constraints."""
8288 return self.sexpr()
8289
8290 def sexpr(self):
8291 """Return a formatted string (in Lisp-like format) with all added constraints.
8292 We say the string is in s-expression format.
8293 """
8294 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8295
8296 def statistics(self):
8297 """Return statistics for the last check`.
8298 """
8299 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8300
8301 def set_on_model(self, on_model):
8302 """Register a callback that is invoked with every incremental improvement to
8303 objective values. The callback takes a model as argument.
8304 The life-time of the model is limited to the callback so the
8305 model has to be (deep) copied if it is to be used after the callback
8306 """
8307 id = len(_on_models) + 41
8308 mdl = Model(self.ctx)
8309 _on_models[id] = (on_model, mdl)
8310 self._on_models_id = id
8311 Z3_optimize_register_model_eh(
8312 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8313 )
8314
8315
8316#########################################
8317#
8318# ApplyResult
8319#
8320#########################################
8321class ApplyResult(Z3PPObject):
8322 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8323 It also contains model and proof converters.
8324 """
8325
8326 def __init__(self, result, ctx):
8327 self.result = result
8328 self.ctx = ctx
8329 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8330
8331 def __deepcopy__(self, memo={}):
8332 return ApplyResult(self.result, self.ctx)
8333
8334 def __del__(self):
8335 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8336 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8337
8338 def __len__(self):
8339 """Return the number of subgoals in `self`.
8340
8341 >>> a, b = Ints('a b')
8342 >>> g = Goal()
8343 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8344 >>> t = Tactic('split-clause')
8345 >>> r = t(g)
8346 >>> len(r)
8347 2
8348 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8349 >>> len(t(g))
8350 4
8351 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8352 >>> len(t(g))
8353 1
8354 """
8355 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8356
8357 def __getitem__(self, idx):
8358 """Return one of the subgoals stored in ApplyResult object `self`.
8359
8360 >>> a, b = Ints('a b')
8361 >>> g = Goal()
8362 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8363 >>> t = Tactic('split-clause')
8364 >>> r = t(g)
8365 >>> r[0]
8366 [a == 0, Or(b == 0, b == 1), a > b]
8367 >>> r[1]
8368 [a == 1, Or(b == 0, b == 1), a > b]
8369 """
8370 if idx >= len(self):
8371 raise IndexError
8372 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8373
8374 def __repr__(self):
8375 return obj_to_string(self)
8376
8377 def sexpr(self):
8378 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8379 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8380
8381 def as_expr(self):
8382 """Return a Z3 expression consisting of all subgoals.
8383
8384 >>> x = Int('x')
8385 >>> g = Goal()
8386 >>> g.add(x > 1)
8387 >>> g.add(Or(x == 2, x == 3))
8388 >>> r = Tactic('simplify')(g)
8389 >>> r
8390 [[Not(x <= 1), Or(x == 2, x == 3)]]
8391 >>> r.as_expr()
8392 And(Not(x <= 1), Or(x == 2, x == 3))
8393 >>> r = Tactic('split-clause')(g)
8394 >>> r
8395 [[x > 1, x == 2], [x > 1, x == 3]]
8396 >>> r.as_expr()
8397 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8398 """
8399 sz = len(self)
8400 if sz == 0:
8401 return BoolVal(False, self.ctx)
8402 elif sz == 1:
8403 return self[0].as_expr()
8404 else:
8405 return Or([self[i].as_expr() for i in range(len(self))])
8406
8407#########################################
8408#
8409# Simplifiers
8410#
8411#########################################
8412
8413class Simplifier:
8414 """Simplifiers act as pre-processing utilities for solvers.
8415 Build a custom simplifier and add it to a solver"""
8416
8417 def __init__(self, simplifier, ctx=None):
8418 self.ctx = _get_ctx(ctx)
8419 self.simplifier = None
8420 if isinstance(simplifier, SimplifierObj):
8421 self.simplifier = simplifier
8422 elif isinstance(simplifier, list):
8423 simps = [Simplifier(s, ctx) for s in simplifier]
8424 self.simplifier = simps[0].simplifier
8425 for i in range(1, len(simps)):
8426 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8427 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8428 return
8429 else:
8430 if z3_debug():
8431 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8432 try:
8433 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8434 except Z3Exception:
8435 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8436 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8437
8438 def __deepcopy__(self, memo={}):
8439 return Simplifier(self.simplifier, self.ctx)
8440
8441 def __del__(self):
8442 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8443 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8444
8445 def using_params(self, *args, **keys):
8446 """Return a simplifier that uses the given configuration options"""
8447 p = args2params(args, keys, self.ctx)
8448 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8449
8450 def add(self, solver):
8451 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8452 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8453
8454 def help(self):
8455 """Display a string containing a description of the available options for the `self` simplifier."""
8456 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8457
8458 def param_descrs(self):
8459 """Return the parameter description set."""
8460 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8461
8462
8463#########################################
8464#
8465# Tactics
8466#
8467#########################################
8468
8469
8470class Tactic:
8471 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8472 A Tactic can be converted into a Solver using the method solver().
8473
8474 Several combinators are available for creating new tactics using the built-in ones:
8475 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8476 """
8477
8478 def __init__(self, tactic, ctx=None):
8479 self.ctx = _get_ctx(ctx)
8480 self.tactic = None
8481 if isinstance(tactic, TacticObj):
8482 self.tactic = tactic
8483 else:
8484 if z3_debug():
8485 _z3_assert(isinstance(tactic, str), "tactic name expected")
8486 try:
8487 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8488 except Z3Exception:
8489 raise Z3Exception("unknown tactic '%s'" % tactic)
8490 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8491
8492 def __deepcopy__(self, memo={}):
8493 return Tactic(self.tactic, self.ctx)
8494
8495 def __del__(self):
8496 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8497 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8498
8499 def solver(self, logFile=None):
8500 """Create a solver using the tactic `self`.
8501
8502 The solver supports the methods `push()` and `pop()`, but it
8503 will always solve each `check()` from scratch.
8504
8505 >>> t = Then('simplify', 'nlsat')
8506 >>> s = t.solver()
8507 >>> x = Real('x')
8508 >>> s.add(x**2 == 2, x > 0)
8509 >>> s.check()
8510 sat
8511 >>> s.model()
8512 [x = 1.4142135623?]
8513 """
8514 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8515
8516 def apply(self, goal, *arguments, **keywords):
8517 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8518
8519 >>> x, y = Ints('x y')
8520 >>> t = Tactic('solve-eqs')
8521 >>> t.apply(And(x == 0, y >= x + 1))
8522 [[y >= 1]]
8523 """
8524 if z3_debug():
8525 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8526 goal = _to_goal(goal)
8527 if len(arguments) > 0 or len(keywords) > 0:
8528 p = args2params(arguments, keywords, self.ctx)
8529 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8530 else:
8531 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8532
8533 def __call__(self, goal, *arguments, **keywords):
8534 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8535
8536 >>> x, y = Ints('x y')
8537 >>> t = Tactic('solve-eqs')
8538 >>> t(And(x == 0, y >= x + 1))
8539 [[y >= 1]]
8540 """
8541 return self.apply(goal, *arguments, **keywords)
8542
8543 def help(self):
8544 """Display a string containing a description of the available options for the `self` tactic."""
8545 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8546
8547 def param_descrs(self):
8548 """Return the parameter description set."""
8549 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8550
8551
8552def _to_goal(a):
8553 if isinstance(a, BoolRef):
8554 goal = Goal(ctx=a.ctx)
8555 goal.add(a)
8556 return goal
8557 else:
8558 return a
8559
8560
8561def _to_tactic(t, ctx=None):
8562 if isinstance(t, Tactic):
8563 return t
8564 else:
8565 return Tactic(t, ctx)
8566
8567
8568def _and_then(t1, t2, ctx=None):
8569 t1 = _to_tactic(t1, ctx)
8570 t2 = _to_tactic(t2, ctx)
8571 if z3_debug():
8572 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8573 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8574
8575
8576def _or_else(t1, t2, ctx=None):
8577 t1 = _to_tactic(t1, ctx)
8578 t2 = _to_tactic(t2, ctx)
8579 if z3_debug():
8580 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8581 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8582
8583
8584def AndThen(*ts, **ks):
8585 """Return a tactic that applies the tactics in `*ts` in sequence.
8586
8587 >>> x, y = Ints('x y')
8588 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8589 >>> t(And(x == 0, y > x + 1))
8590 [[Not(y <= 1)]]
8591 >>> t(And(x == 0, y > x + 1)).as_expr()
8592 Not(y <= 1)
8593 """
8594 if z3_debug():
8595 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8596 ctx = ks.get("ctx", None)
8597 num = len(ts)
8598 r = ts[0]
8599 for i in range(num - 1):
8600 r = _and_then(r, ts[i + 1], ctx)
8601 return r
8602
8603
8604def Then(*ts, **ks):
8605 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8606
8607 >>> x, y = Ints('x y')
8608 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8609 >>> t(And(x == 0, y > x + 1))
8610 [[Not(y <= 1)]]
8611 >>> t(And(x == 0, y > x + 1)).as_expr()
8612 Not(y <= 1)
8613 """
8614 return AndThen(*ts, **ks)
8615
8616
8617def OrElse(*ts, **ks):
8618 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8619
8620 >>> x = Int('x')
8621 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8622 >>> # Tactic split-clause fails if there is no clause in the given goal.
8623 >>> t(x == 0)
8624 [[x == 0]]
8625 >>> t(Or(x == 0, x == 1))
8626 [[x == 0], [x == 1]]
8627 """
8628 if z3_debug():
8629 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8630 ctx = ks.get("ctx", None)
8631 num = len(ts)
8632 r = ts[0]
8633 for i in range(num - 1):
8634 r = _or_else(r, ts[i + 1], ctx)
8635 return r
8636
8637
8638def ParOr(*ts, **ks):
8639 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8640
8641 >>> x = Int('x')
8642 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8643 >>> t(x + 1 == 2)
8644 [[x == 1]]
8645 """
8646 if z3_debug():
8647 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8648 ctx = _get_ctx(ks.get("ctx", None))
8649 ts = [_to_tactic(t, ctx) for t in ts]
8650 sz = len(ts)
8651 _args = (TacticObj * sz)()
8652 for i in range(sz):
8653 _args[i] = ts[i].tactic
8654 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8655
8656
8657def ParThen(t1, t2, ctx=None):
8658 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8659 The subgoals are processed in parallel.
8660
8661 >>> x, y = Ints('x y')
8662 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8663 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8664 [[x == 1, y == 2], [x == 2, y == 3]]
8665 """
8666 t1 = _to_tactic(t1, ctx)
8667 t2 = _to_tactic(t2, ctx)
8668 if z3_debug():
8669 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8670 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8671
8672
8673def ParAndThen(t1, t2, ctx=None):
8674 """Alias for ParThen(t1, t2, ctx)."""
8675 return ParThen(t1, t2, ctx)
8676
8677
8678def With(t, *args, **keys):
8679 """Return a tactic that applies tactic `t` using the given configuration options.
8680
8681 >>> x, y = Ints('x y')
8682 >>> t = With(Tactic('simplify'), som=True)
8683 >>> t((x + 1)*(y + 2) == 0)
8684 [[2*x + y + x*y == -2]]
8685 """
8686 ctx = keys.pop("ctx", None)
8687 t = _to_tactic(t, ctx)
8688 p = args2params(args, keys, t.ctx)
8689 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8690
8691
8692def WithParams(t, p):
8693 """Return a tactic that applies tactic `t` using the given configuration options.
8694
8695 >>> x, y = Ints('x y')
8696 >>> p = ParamsRef()
8697 >>> p.set("som", True)
8698 >>> t = WithParams(Tactic('simplify'), p)
8699 >>> t((x + 1)*(y + 2) == 0)
8700 [[2*x + y + x*y == -2]]
8701 """
8702 t = _to_tactic(t, None)
8703 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8704
8705
8706def Repeat(t, max=4294967295, ctx=None):
8707 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8708 or the maximum number of iterations `max` is reached.
8709
8710 >>> x, y = Ints('x y')
8711 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8712 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8713 >>> r = t(c)
8714 >>> for subgoal in r: print(subgoal)
8715 [x == 0, y == 0, x > y]
8716 [x == 0, y == 1, x > y]
8717 [x == 1, y == 0, x > y]
8718 [x == 1, y == 1, x > y]
8719 >>> t = Then(t, Tactic('propagate-values'))
8720 >>> t(c)
8721 [[x == 1, y == 0]]
8722 """
8723 t = _to_tactic(t, ctx)
8724 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8725
8726
8727def TryFor(t, ms, ctx=None):
8728 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8729
8730 If `t` does not terminate in `ms` milliseconds, then it fails.
8731 """
8732 t = _to_tactic(t, ctx)
8733 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8734
8735
8736def tactics(ctx=None):
8737 """Return a list of all available tactics in Z3.
8738
8739 >>> l = tactics()
8740 >>> l.count('simplify') == 1
8741 True
8742 """
8743 ctx = _get_ctx(ctx)
8744 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8745
8746
8747def tactic_description(name, ctx=None):
8748 """Return a short description for the tactic named `name`.
8749
8750 >>> d = tactic_description('simplify')
8751 """
8752 ctx = _get_ctx(ctx)
8753 return Z3_tactic_get_descr(ctx.ref(), name)
8754
8755
8756def describe_tactics():
8757 """Display a (tabular) description of all available tactics in Z3."""
8758 if in_html_mode():
8759 even = True
8760 print('<table border="1" cellpadding="2" cellspacing="0">')
8761 for t in tactics():
8762 if even:
8763 print('<tr style="background-color:#CFCFCF">')
8764 even = False
8765 else:
8766 print("<tr>")
8767 even = True
8768 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8769 print("</table>")
8770 else:
8771 for t in tactics():
8772 print("%s : %s" % (t, tactic_description(t)))
8773
8774
8775class Probe:
8776 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8777 to decide which solver and/or preprocessing step will be used.
8778 """
8779
8780 def __init__(self, probe, ctx=None):
8781 self.ctx = _get_ctx(ctx)
8782 self.probe = None
8783 if isinstance(probe, ProbeObj):
8784 self.probe = probe
8785 elif isinstance(probe, float):
8786 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8787 elif _is_int(probe):
8788 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8789 elif isinstance(probe, bool):
8790 if probe:
8791 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8792 else:
8793 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8794 else:
8795 if z3_debug():
8796 _z3_assert(isinstance(probe, str), "probe name expected")
8797 try:
8798 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8799 except Z3Exception:
8800 raise Z3Exception("unknown probe '%s'" % probe)
8801 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8802
8803 def __deepcopy__(self, memo={}):
8804 return Probe(self.probe, self.ctx)
8805
8806 def __del__(self):
8807 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8808 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8809
8810 def __lt__(self, other):
8811 """Return a probe that evaluates to "true" when the value returned by `self`
8812 is less than the value returned by `other`.
8813
8814 >>> p = Probe('size') < 10
8815 >>> x = Int('x')
8816 >>> g = Goal()
8817 >>> g.add(x > 0)
8818 >>> g.add(x < 10)
8819 >>> p(g)
8820 1.0
8821 """
8822 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8823
8824 def __gt__(self, other):
8825 """Return a probe that evaluates to "true" when the value returned by `self`
8826 is greater than the value returned by `other`.
8827
8828 >>> p = Probe('size') > 10
8829 >>> x = Int('x')
8830 >>> g = Goal()
8831 >>> g.add(x > 0)
8832 >>> g.add(x < 10)
8833 >>> p(g)
8834 0.0
8835 """
8836 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8837
8838 def __le__(self, other):
8839 """Return a probe that evaluates to "true" when the value returned by `self`
8840 is less than or equal to the value returned by `other`.
8841
8842 >>> p = Probe('size') <= 2
8843 >>> x = Int('x')
8844 >>> g = Goal()
8845 >>> g.add(x > 0)
8846 >>> g.add(x < 10)
8847 >>> p(g)
8848 1.0
8849 """
8850 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8851
8852 def __ge__(self, other):
8853 """Return a probe that evaluates to "true" when the value returned by `self`
8854 is greater than or equal to the value returned by `other`.
8855
8856 >>> p = Probe('size') >= 2
8857 >>> x = Int('x')
8858 >>> g = Goal()
8859 >>> g.add(x > 0)
8860 >>> g.add(x < 10)
8861 >>> p(g)
8862 1.0
8863 """
8864 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8865
8866 def __eq__(self, other):
8867 """Return a probe that evaluates to "true" when the value returned by `self`
8868 is equal to the value returned by `other`.
8869
8870 >>> p = Probe('size') == 2
8871 >>> x = Int('x')
8872 >>> g = Goal()
8873 >>> g.add(x > 0)
8874 >>> g.add(x < 10)
8875 >>> p(g)
8876 1.0
8877 """
8878 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8879
8880 def __ne__(self, other):
8881 """Return a probe that evaluates to "true" when the value returned by `self`
8882 is not equal to the value returned by `other`.
8883
8884 >>> p = Probe('size') != 2
8885 >>> x = Int('x')
8886 >>> g = Goal()
8887 >>> g.add(x > 0)
8888 >>> g.add(x < 10)
8889 >>> p(g)
8890 0.0
8891 """
8892 p = self.__eq__(other)
8893 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8894
8895 def __call__(self, goal):
8896 """Evaluate the probe `self` in the given goal.
8897
8898 >>> p = Probe('size')
8899 >>> x = Int('x')
8900 >>> g = Goal()
8901 >>> g.add(x > 0)
8902 >>> g.add(x < 10)
8903 >>> p(g)
8904 2.0
8905 >>> g.add(x < 20)
8906 >>> p(g)
8907 3.0
8908 >>> p = Probe('num-consts')
8909 >>> p(g)
8910 1.0
8911 >>> p = Probe('is-propositional')
8912 >>> p(g)
8913 0.0
8914 >>> p = Probe('is-qflia')
8915 >>> p(g)
8916 1.0
8917 """
8918 if z3_debug():
8919 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8920 goal = _to_goal(goal)
8921 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8922
8923
8924def is_probe(p):
8925 """Return `True` if `p` is a Z3 probe.
8926
8927 >>> is_probe(Int('x'))
8928 False
8929 >>> is_probe(Probe('memory'))
8930 True
8931 """
8932 return isinstance(p, Probe)
8933
8934
8935def _to_probe(p, ctx=None):
8936 if is_probe(p):
8937 return p
8938 else:
8939 return Probe(p, ctx)
8940
8941
8942def probes(ctx=None):
8943 """Return a list of all available probes in Z3.
8944
8945 >>> l = probes()
8946 >>> l.count('memory') == 1
8947 True
8948 """
8949 ctx = _get_ctx(ctx)
8950 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
8951
8952
8953def probe_description(name, ctx=None):
8954 """Return a short description for the probe named `name`.
8955
8956 >>> d = probe_description('memory')
8957 """
8958 ctx = _get_ctx(ctx)
8959 return Z3_probe_get_descr(ctx.ref(), name)
8960
8961
8962def describe_probes():
8963 """Display a (tabular) description of all available probes in Z3."""
8964 if in_html_mode():
8965 even = True
8966 print('<table border="1" cellpadding="2" cellspacing="0">')
8967 for p in probes():
8968 if even:
8969 print('<tr style="background-color:#CFCFCF">')
8970 even = False
8971 else:
8972 print("<tr>")
8973 even = True
8974 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
8975 print("</table>")
8976 else:
8977 for p in probes():
8978 print("%s : %s" % (p, probe_description(p)))
8979
8980
8981def _probe_nary(f, args, ctx):
8982 if z3_debug():
8983 _z3_assert(len(args) > 0, "At least one argument expected")
8984 num = len(args)
8985 r = _to_probe(args[0], ctx)
8986 for i in range(num - 1):
8987 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
8988 return r
8989
8990
8991def _probe_and(args, ctx):
8992 return _probe_nary(Z3_probe_and, args, ctx)
8993
8994
8995def _probe_or(args, ctx):
8996 return _probe_nary(Z3_probe_or, args, ctx)
8997
8998
8999def FailIf(p, ctx=None):
9000 """Return a tactic that fails if the probe `p` evaluates to true.
9001 Otherwise, it returns the input goal unmodified.
9002
9003 In the following example, the tactic applies 'simplify' if and only if there are
9004 more than 2 constraints in the goal.
9005
9006 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
9007 >>> x, y = Ints('x y')
9008 >>> g = Goal()
9009 >>> g.add(x > 0)
9010 >>> g.add(y > 0)
9011 >>> t(g)
9012 [[x > 0, y > 0]]
9013 >>> g.add(x == y + 1)
9014 >>> t(g)
9015 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9016 """
9017 p = _to_probe(p, ctx)
9018 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
9019
9020
9021def When(p, t, ctx=None):
9022 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
9023 Otherwise, it returns the input goal unmodified.
9024
9025 >>> t = When(Probe('size') > 2, Tactic('simplify'))
9026 >>> x, y = Ints('x y')
9027 >>> g = Goal()
9028 >>> g.add(x > 0)
9029 >>> g.add(y > 0)
9030 >>> t(g)
9031 [[x > 0, y > 0]]
9032 >>> g.add(x == y + 1)
9033 >>> t(g)
9034 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9035 """
9036 p = _to_probe(p, ctx)
9037 t = _to_tactic(t, ctx)
9038 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
9039
9040
9041def Cond(p, t1, t2, ctx=None):
9042 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
9043
9044 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
9045 """
9046 p = _to_probe(p, ctx)
9047 t1 = _to_tactic(t1, ctx)
9048 t2 = _to_tactic(t2, ctx)
9049 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
9050
9051#########################################
9052#
9053# Utils
9054#
9055#########################################
9056
9057
9058def simplify(a, *arguments, **keywords):
9059 """Simplify the expression `a` using the given options.
9060
9061 This function has many options. Use `help_simplify` to obtain the complete list.
9062
9063 >>> x = Int('x')
9064 >>> y = Int('y')
9065 >>> simplify(x + 1 + y + x + 1)
9066 2 + 2*x + y
9067 >>> simplify((x + 1)*(y + 1), som=True)
9068 1 + x + y + x*y
9069 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9070 And(Not(x == y), Not(x == 1), Not(y == 1))
9071 >>> simplify(And(x == 0, y == 1), elim_and=True)
9072 Not(Or(Not(x == 0), Not(y == 1)))
9073 """
9074 if z3_debug():
9075 _z3_assert(is_expr(a), "Z3 expression expected")
9076 if len(arguments) > 0 or len(keywords) > 0:
9077 p = args2params(arguments, keywords, a.ctx)
9078 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9079 else:
9080 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9081
9082
9083def help_simplify():
9084 """Return a string describing all options available for Z3 `simplify` procedure."""
9085 print(Z3_simplify_get_help(main_ctx().ref()))
9086
9087
9088def simplify_param_descrs():
9089 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9090 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9091
9092
9093def substitute(t, *m):
9094 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9095 Every occurrence in t of from is replaced with to.
9096
9097 >>> x = Int('x')
9098 >>> y = Int('y')
9099 >>> substitute(x + 1, (x, y + 1))
9100 y + 1 + 1
9101 >>> f = Function('f', IntSort(), IntSort())
9102 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9103 1 + 1
9104 """
9105 if isinstance(m, tuple):
9106 m1 = _get_args(m)
9107 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9108 m = m1
9109 if z3_debug():
9110 _z3_assert(is_expr(t), "Z3 expression expected")
9111 _z3_assert(
9112 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9113 "Z3 invalid substitution, expression pairs expected.")
9114 _z3_assert(
9115 all([p[0].sort().eq(p[1].sort()) for p in m]),
9116 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9117 num = len(m)
9118 _from = (Ast * num)()
9119 _to = (Ast * num)()
9120 for i in range(num):
9121 _from[i] = m[i][0].as_ast()
9122 _to[i] = m[i][1].as_ast()
9123 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9124
9125
9126def substitute_vars(t, *m):
9127 """Substitute the free variables in t with the expression in m.
9128
9129 >>> v0 = Var(0, IntSort())
9130 >>> v1 = Var(1, IntSort())
9131 >>> x = Int('x')
9132 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9133 >>> # replace v0 with x+1 and v1 with x
9134 >>> substitute_vars(f(v0, v1), x + 1, x)
9135 f(x + 1, x)
9136 """
9137 if z3_debug():
9138 _z3_assert(is_expr(t), "Z3 expression expected")
9139 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9140 num = len(m)
9141 _to = (Ast * num)()
9142 for i in range(num):
9143 _to[i] = m[i].as_ast()
9144 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9145
9146def substitute_funs(t, *m):
9147 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9148 Every occurrence in to of the function from is replaced with the expression to.
9149 The expression to can have free variables, that refer to the arguments of from.
9150 For examples, see
9151 """
9152 if isinstance(m, tuple):
9153 m1 = _get_args(m)
9154 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9155 m = m1
9156 if z3_debug():
9157 _z3_assert(is_expr(t), "Z3 expression expected")
9158 _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.")
9159 num = len(m)
9160 _from = (FuncDecl * num)()
9161 _to = (Ast * num)()
9162 for i in range(num):
9163 _from[i] = m[i][0].as_func_decl()
9164 _to[i] = m[i][1].as_ast()
9165 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9166
9167
9168def Sum(*args):
9169 """Create the sum of the Z3 expressions.
9170
9171 >>> a, b, c = Ints('a b c')
9172 >>> Sum(a, b, c)
9173 a + b + c
9174 >>> Sum([a, b, c])
9175 a + b + c
9176 >>> A = IntVector('a', 5)
9177 >>> Sum(A)
9178 a__0 + a__1 + a__2 + a__3 + a__4
9179 """
9180 args = _get_args(args)
9181 if len(args) == 0:
9182 return 0
9183 ctx = _ctx_from_ast_arg_list(args)
9184 if ctx is None:
9185 return _reduce(lambda a, b: a + b, args, 0)
9186 args = _coerce_expr_list(args, ctx)
9187 if is_bv(args[0]):
9188 return _reduce(lambda a, b: a + b, args, 0)
9189 else:
9190 _args, sz = _to_ast_array(args)
9191 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9192
9193
9194def Product(*args):
9195 """Create the product of the Z3 expressions.
9196
9197 >>> a, b, c = Ints('a b c')
9198 >>> Product(a, b, c)
9199 a*b*c
9200 >>> Product([a, b, c])
9201 a*b*c
9202 >>> A = IntVector('a', 5)
9203 >>> Product(A)
9204 a__0*a__1*a__2*a__3*a__4
9205 """
9206 args = _get_args(args)
9207 if len(args) == 0:
9208 return 1
9209 ctx = _ctx_from_ast_arg_list(args)
9210 if ctx is None:
9211 return _reduce(lambda a, b: a * b, args, 1)
9212 args = _coerce_expr_list(args, ctx)
9213 if is_bv(args[0]):
9214 return _reduce(lambda a, b: a * b, args, 1)
9215 else:
9216 _args, sz = _to_ast_array(args)
9217 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9218
9219def Abs(arg):
9220 """Create the absolute value of an arithmetic expression"""
9221 return If(arg > 0, arg, -arg)
9222
9223
9224def AtMost(*args):
9225 """Create an at-most Pseudo-Boolean k constraint.
9226
9227 >>> a, b, c = Bools('a b c')
9228 >>> f = AtMost(a, b, c, 2)
9229 """
9230 args = _get_args(args)
9231 if z3_debug():
9232 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9233 ctx = _ctx_from_ast_arg_list(args)
9234 if z3_debug():
9235 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9236 args1 = _coerce_expr_list(args[:-1], ctx)
9237 k = args[-1]
9238 _args, sz = _to_ast_array(args1)
9239 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9240
9241
9242def AtLeast(*args):
9243 """Create an at-least Pseudo-Boolean k constraint.
9244
9245 >>> a, b, c = Bools('a b c')
9246 >>> f = AtLeast(a, b, c, 2)
9247 """
9248 args = _get_args(args)
9249 if z3_debug():
9250 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9251 ctx = _ctx_from_ast_arg_list(args)
9252 if z3_debug():
9253 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9254 args1 = _coerce_expr_list(args[:-1], ctx)
9255 k = args[-1]
9256 _args, sz = _to_ast_array(args1)
9257 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9258
9259
9260def _reorder_pb_arg(arg):
9261 a, b = arg
9262 if not _is_int(b) and _is_int(a):
9263 return b, a
9264 return arg
9265
9266
9267def _pb_args_coeffs(args, default_ctx=None):
9268 args = _get_args_ast_list(args)
9269 if len(args) == 0:
9270 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9271 args = [_reorder_pb_arg(arg) for arg in args]
9272 args, coeffs = zip(*args)
9273 if z3_debug():
9274 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9275 ctx = _ctx_from_ast_arg_list(args)
9276 if z3_debug():
9277 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9278 args = _coerce_expr_list(args, ctx)
9279 _args, sz = _to_ast_array(args)
9280 _coeffs = (ctypes.c_int * len(coeffs))()
9281 for i in range(len(coeffs)):
9282 _z3_check_cint_overflow(coeffs[i], "coefficient")
9283 _coeffs[i] = coeffs[i]
9284 return ctx, sz, _args, _coeffs, args
9285
9286
9287def PbLe(args, k):
9288 """Create a Pseudo-Boolean inequality k constraint.
9289
9290 >>> a, b, c = Bools('a b c')
9291 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9292 """
9293 _z3_check_cint_overflow(k, "k")
9294 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9295 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9296
9297
9298def PbGe(args, k):
9299 """Create a Pseudo-Boolean inequality k constraint.
9300
9301 >>> a, b, c = Bools('a b c')
9302 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9303 """
9304 _z3_check_cint_overflow(k, "k")
9305 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9306 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9307
9308
9309def PbEq(args, k, ctx=None):
9310 """Create a Pseudo-Boolean equality k constraint.
9311
9312 >>> a, b, c = Bools('a b c')
9313 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9314 """
9315 _z3_check_cint_overflow(k, "k")
9316 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9317 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9318
9319
9320def solve(*args, **keywords):
9321 """Solve the constraints `*args`.
9322
9323 This is a simple function for creating demonstrations. It creates a solver,
9324 configure it using the options in `keywords`, adds the constraints
9325 in `args`, and invokes check.
9326
9327 >>> a = Int('a')
9328 >>> solve(a > 0, a < 2)
9329 [a = 1]
9330 """
9331 show = keywords.pop("show", False)
9332 s = Solver()
9333 s.set(**keywords)
9334 s.add(*args)
9335 if show:
9336 print(s)
9337 r = s.check()
9338 if r == unsat:
9339 print("no solution")
9340 elif r == unknown:
9341 print("failed to solve")
9342 try:
9343 print(s.model())
9344 except Z3Exception:
9345 return
9346 else:
9347 print(s.model())
9348
9349
9350def solve_using(s, *args, **keywords):
9351 """Solve the constraints `*args` using solver `s`.
9352
9353 This is a simple function for creating demonstrations. It is similar to `solve`,
9354 but it uses the given solver `s`.
9355 It configures solver `s` using the options in `keywords`, adds the constraints
9356 in `args`, and invokes check.
9357 """
9358 show = keywords.pop("show", False)
9359 if z3_debug():
9360 _z3_assert(isinstance(s, Solver), "Solver object expected")
9361 s.set(**keywords)
9362 s.add(*args)
9363 if show:
9364 print("Problem:")
9365 print(s)
9366 r = s.check()
9367 if r == unsat:
9368 print("no solution")
9369 elif r == unknown:
9370 print("failed to solve")
9371 try:
9372 print(s.model())
9373 except Z3Exception:
9374 return
9375 else:
9376 if show:
9377 print("Solution:")
9378 print(s.model())
9379
9380
9381def prove(claim, show=False, **keywords):
9382 """Try to prove the given claim.
9383
9384 This is a simple function for creating demonstrations. It tries to prove
9385 `claim` by showing the negation is unsatisfiable.
9386
9387 >>> p, q = Bools('p q')
9388 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9389 proved
9390 """
9391 if z3_debug():
9392 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9393 s = Solver()
9394 s.set(**keywords)
9395 s.add(Not(claim))
9396 if show:
9397 print(s)
9398 r = s.check()
9399 if r == unsat:
9400 print("proved")
9401 elif r == unknown:
9402 print("failed to prove")
9403 print(s.model())
9404 else:
9405 print("counterexample")
9406 print(s.model())
9407
9408
9409def _solve_html(*args, **keywords):
9410 """Version of function `solve` that renders HTML output."""
9411 show = keywords.pop("show", False)
9412 s = Solver()
9413 s.set(**keywords)
9414 s.add(*args)
9415 if show:
9416 print("<b>Problem:</b>")
9417 print(s)
9418 r = s.check()
9419 if r == unsat:
9420 print("<b>no solution</b>")
9421 elif r == unknown:
9422 print("<b>failed to solve</b>")
9423 try:
9424 print(s.model())
9425 except Z3Exception:
9426 return
9427 else:
9428 if show:
9429 print("<b>Solution:</b>")
9430 print(s.model())
9431
9432
9433def _solve_using_html(s, *args, **keywords):
9434 """Version of function `solve_using` that renders HTML."""
9435 show = keywords.pop("show", False)
9436 if z3_debug():
9437 _z3_assert(isinstance(s, Solver), "Solver object expected")
9438 s.set(**keywords)
9439 s.add(*args)
9440 if show:
9441 print("<b>Problem:</b>")
9442 print(s)
9443 r = s.check()
9444 if r == unsat:
9445 print("<b>no solution</b>")
9446 elif r == unknown:
9447 print("<b>failed to solve</b>")
9448 try:
9449 print(s.model())
9450 except Z3Exception:
9451 return
9452 else:
9453 if show:
9454 print("<b>Solution:</b>")
9455 print(s.model())
9456
9457
9458def _prove_html(claim, show=False, **keywords):
9459 """Version of function `prove` that renders HTML."""
9460 if z3_debug():
9461 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9462 s = Solver()
9463 s.set(**keywords)
9464 s.add(Not(claim))
9465 if show:
9466 print(s)
9467 r = s.check()
9468 if r == unsat:
9469 print("<b>proved</b>")
9470 elif r == unknown:
9471 print("<b>failed to prove</b>")
9472 print(s.model())
9473 else:
9474 print("<b>counterexample</b>")
9475 print(s.model())
9476
9477
9478def _dict2sarray(sorts, ctx):
9479 sz = len(sorts)
9480 _names = (Symbol * sz)()
9481 _sorts = (Sort * sz)()
9482 i = 0
9483 for k in sorts:
9484 v = sorts[k]
9485 if z3_debug():
9486 _z3_assert(isinstance(k, str), "String expected")
9487 _z3_assert(is_sort(v), "Z3 sort expected")
9488 _names[i] = to_symbol(k, ctx)
9489 _sorts[i] = v.ast
9490 i = i + 1
9491 return sz, _names, _sorts
9492
9493
9494def _dict2darray(decls, ctx):
9495 sz = len(decls)
9496 _names = (Symbol * sz)()
9497 _decls = (FuncDecl * sz)()
9498 i = 0
9499 for k in decls:
9500 v = decls[k]
9501 if z3_debug():
9502 _z3_assert(isinstance(k, str), "String expected")
9503 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9504 _names[i] = to_symbol(k, ctx)
9505 if is_const(v):
9506 _decls[i] = v.decl().ast
9507 else:
9508 _decls[i] = v.ast
9509 i = i + 1
9510 return sz, _names, _decls
9511
9512class ParserContext:
9513 def __init__(self, ctx= None):
9514 self.ctx = _get_ctx(ctx)
9515 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9516 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9517
9518 def __del__(self):
9519 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9520 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9521 self.pctx = None
9522
9523 def add_sort(self, sort):
9524 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9525
9526 def add_decl(self, decl):
9527 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9528
9529 def from_string(self, s):
9530 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9531
9532def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9533 """Parse a string in SMT 2.0 format using the given sorts and decls.
9534
9535 The arguments sorts and decls are Python dictionaries used to initialize
9536 the symbol table used for the SMT 2.0 parser.
9537
9538 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9539 [x > 0, x < 10]
9540 >>> x, y = Ints('x y')
9541 >>> f = Function('f', IntSort(), IntSort())
9542 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9543 [x + f(y) > 0]
9544 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9545 [a > 0]
9546 """
9547 ctx = _get_ctx(ctx)
9548 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9549 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9550 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9551
9552
9553def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9554 """Parse a file in SMT 2.0 format using the given sorts and decls.
9555
9556 This function is similar to parse_smt2_string().
9557 """
9558 ctx = _get_ctx(ctx)
9559 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9560 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9561 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9562
9563
9564#########################################
9565#
9566# Floating-Point Arithmetic
9567#
9568#########################################
9569
9570
9571# Global default rounding mode
9572_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9573_dflt_fpsort_ebits = 11
9574_dflt_fpsort_sbits = 53
9575
9576
9577def get_default_rounding_mode(ctx=None):
9578 """Retrieves the global default rounding mode."""
9579 global _dflt_rounding_mode
9580 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9581 return RTZ(ctx)
9582 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9583 return RTN(ctx)
9584 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9585 return RTP(ctx)
9586 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9587 return RNE(ctx)
9588 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9589 return RNA(ctx)
9590
9591
9592_ROUNDING_MODES = frozenset({
9593 Z3_OP_FPA_RM_TOWARD_ZERO,
9594 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9595 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9596 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9597 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9598})
9599
9600
9601def set_default_rounding_mode(rm, ctx=None):
9602 global _dflt_rounding_mode
9603 if is_fprm_value(rm):
9604 _dflt_rounding_mode = rm.kind()
9605 else:
9606 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9607 _dflt_rounding_mode = rm
9608
9609
9610def get_default_fp_sort(ctx=None):
9611 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9612
9613
9614def set_default_fp_sort(ebits, sbits, ctx=None):
9615 global _dflt_fpsort_ebits
9616 global _dflt_fpsort_sbits
9617 _dflt_fpsort_ebits = ebits
9618 _dflt_fpsort_sbits = sbits
9619
9620
9621def _dflt_rm(ctx=None):
9622 return get_default_rounding_mode(ctx)
9623
9624
9625def _dflt_fps(ctx=None):
9626 return get_default_fp_sort(ctx)
9627
9628
9629def _coerce_fp_expr_list(alist, ctx):
9630 first_fp_sort = None
9631 for a in alist:
9632 if is_fp(a):
9633 if first_fp_sort is None:
9634 first_fp_sort = a.sort()
9635 elif first_fp_sort == a.sort():
9636 pass # OK, same as before
9637 else:
9638 # we saw at least 2 different float sorts; something will
9639 # throw a sort mismatch later, for now assume None.
9640 first_fp_sort = None
9641 break
9642
9643 r = []
9644 for i in range(len(alist)):
9645 a = alist[i]
9646 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9647 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9648 r.append(FPVal(a, None, first_fp_sort, ctx))
9649 else:
9650 r.append(a)
9651 return _coerce_expr_list(r, ctx)
9652
9653
9654# FP Sorts
9655
9656class FPSortRef(SortRef):
9657 """Floating-point sort."""
9658
9659 def ebits(self):
9660 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9661 >>> b = FPSort(8, 24)
9662 >>> b.ebits()
9663 8
9664 """
9665 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9666
9667 def sbits(self):
9668 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9669 >>> b = FPSort(8, 24)
9670 >>> b.sbits()
9671 24
9672 """
9673 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9674
9675 def cast(self, val):
9676 """Try to cast `val` as a floating-point expression.
9677 >>> b = FPSort(8, 24)
9678 >>> b.cast(1.0)
9679 1
9680 >>> b.cast(1.0).sexpr()
9681 '(fp #b0 #x7f #b00000000000000000000000)'
9682 """
9683 if is_expr(val):
9684 if z3_debug():
9685 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9686 return val
9687 else:
9688 return FPVal(val, None, self, self.ctx)
9689
9690
9691def Float16(ctx=None):
9692 """Floating-point 16-bit (half) sort."""
9693 ctx = _get_ctx(ctx)
9694 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9695
9696
9697def FloatHalf(ctx=None):
9698 """Floating-point 16-bit (half) sort."""
9699 ctx = _get_ctx(ctx)
9700 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9701
9702
9703def Float32(ctx=None):
9704 """Floating-point 32-bit (single) sort."""
9705 ctx = _get_ctx(ctx)
9706 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9707
9708
9709def FloatSingle(ctx=None):
9710 """Floating-point 32-bit (single) sort."""
9711 ctx = _get_ctx(ctx)
9712 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9713
9714
9715def Float64(ctx=None):
9716 """Floating-point 64-bit (double) sort."""
9717 ctx = _get_ctx(ctx)
9718 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9719
9720
9721def FloatDouble(ctx=None):
9722 """Floating-point 64-bit (double) sort."""
9723 ctx = _get_ctx(ctx)
9724 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9725
9726
9727def Float128(ctx=None):
9728 """Floating-point 128-bit (quadruple) sort."""
9729 ctx = _get_ctx(ctx)
9730 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9731
9732
9733def FloatQuadruple(ctx=None):
9734 """Floating-point 128-bit (quadruple) sort."""
9735 ctx = _get_ctx(ctx)
9736 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9737
9738
9739class FPRMSortRef(SortRef):
9740 """"Floating-point rounding mode sort."""
9741
9742
9743def is_fp_sort(s):
9744 """Return True if `s` is a Z3 floating-point sort.
9745
9746 >>> is_fp_sort(FPSort(8, 24))
9747 True
9748 >>> is_fp_sort(IntSort())
9749 False
9750 """
9751 return isinstance(s, FPSortRef)
9752
9753
9754def is_fprm_sort(s):
9755 """Return True if `s` is a Z3 floating-point rounding mode sort.
9756
9757 >>> is_fprm_sort(FPSort(8, 24))
9758 False
9759 >>> is_fprm_sort(RNE().sort())
9760 True
9761 """
9762 return isinstance(s, FPRMSortRef)
9763
9764# FP Expressions
9765
9766
9767class FPRef(ExprRef):
9768 """Floating-point expressions."""
9769
9770 def sort(self):
9771 """Return the sort of the floating-point expression `self`.
9772
9773 >>> x = FP('1.0', FPSort(8, 24))
9774 >>> x.sort()
9775 FPSort(8, 24)
9776 >>> x.sort() == FPSort(8, 24)
9777 True
9778 """
9779 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9780
9781 def ebits(self):
9782 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9783 >>> b = FPSort(8, 24)
9784 >>> b.ebits()
9785 8
9786 """
9787 return self.sort().ebits()
9788
9789 def sbits(self):
9790 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9791 >>> b = FPSort(8, 24)
9792 >>> b.sbits()
9793 24
9794 """
9795 return self.sort().sbits()
9796
9797 def as_string(self):
9798 """Return a Z3 floating point expression as a Python string."""
9799 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9800
9801 def __le__(self, other):
9802 return fpLEQ(self, other, self.ctx)
9803
9804 def __lt__(self, other):
9805 return fpLT(self, other, self.ctx)
9806
9807 def __ge__(self, other):
9808 return fpGEQ(self, other, self.ctx)
9809
9810 def __gt__(self, other):
9811 return fpGT(self, other, self.ctx)
9812
9813 def __add__(self, other):
9814 """Create the Z3 expression `self + other`.
9815
9816 >>> x = FP('x', FPSort(8, 24))
9817 >>> y = FP('y', FPSort(8, 24))
9818 >>> x + y
9819 x + y
9820 >>> (x + y).sort()
9821 FPSort(8, 24)
9822 """
9823 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9824 return fpAdd(_dflt_rm(), a, b, self.ctx)
9825
9826 def __radd__(self, other):
9827 """Create the Z3 expression `other + self`.
9828
9829 >>> x = FP('x', FPSort(8, 24))
9830 >>> 10 + x
9831 1.25*(2**3) + x
9832 """
9833 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9834 return fpAdd(_dflt_rm(), a, b, self.ctx)
9835
9836 def __sub__(self, other):
9837 """Create the Z3 expression `self - other`.
9838
9839 >>> x = FP('x', FPSort(8, 24))
9840 >>> y = FP('y', FPSort(8, 24))
9841 >>> x - y
9842 x - y
9843 >>> (x - y).sort()
9844 FPSort(8, 24)
9845 """
9846 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9847 return fpSub(_dflt_rm(), a, b, self.ctx)
9848
9849 def __rsub__(self, other):
9850 """Create the Z3 expression `other - self`.
9851
9852 >>> x = FP('x', FPSort(8, 24))
9853 >>> 10 - x
9854 1.25*(2**3) - x
9855 """
9856 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9857 return fpSub(_dflt_rm(), a, b, self.ctx)
9858
9859 def __mul__(self, other):
9860 """Create the Z3 expression `self * other`.
9861
9862 >>> x = FP('x', FPSort(8, 24))
9863 >>> y = FP('y', FPSort(8, 24))
9864 >>> x * y
9865 x * y
9866 >>> (x * y).sort()
9867 FPSort(8, 24)
9868 >>> 10 * y
9869 1.25*(2**3) * y
9870 """
9871 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9872 return fpMul(_dflt_rm(), a, b, self.ctx)
9873
9874 def __rmul__(self, other):
9875 """Create the Z3 expression `other * self`.
9876
9877 >>> x = FP('x', FPSort(8, 24))
9878 >>> y = FP('y', FPSort(8, 24))
9879 >>> x * y
9880 x * y
9881 >>> x * 10
9882 x * 1.25*(2**3)
9883 """
9884 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9885 return fpMul(_dflt_rm(), a, b, self.ctx)
9886
9887 def __pos__(self):
9888 """Create the Z3 expression `+self`."""
9889 return self
9890
9891 def __neg__(self):
9892 """Create the Z3 expression `-self`.
9893
9894 >>> x = FP('x', Float32())
9895 >>> -x
9896 -x
9897 """
9898 return fpNeg(self)
9899
9900 def __div__(self, other):
9901 """Create the Z3 expression `self / other`.
9902
9903 >>> x = FP('x', FPSort(8, 24))
9904 >>> y = FP('y', FPSort(8, 24))
9905 >>> x / y
9906 x / y
9907 >>> (x / y).sort()
9908 FPSort(8, 24)
9909 >>> 10 / y
9910 1.25*(2**3) / y
9911 """
9912 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9913 return fpDiv(_dflt_rm(), a, b, self.ctx)
9914
9915 def __rdiv__(self, other):
9916 """Create the Z3 expression `other / self`.
9917
9918 >>> x = FP('x', FPSort(8, 24))
9919 >>> y = FP('y', FPSort(8, 24))
9920 >>> x / y
9921 x / y
9922 >>> x / 10
9923 x / 1.25*(2**3)
9924 """
9925 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9926 return fpDiv(_dflt_rm(), a, b, self.ctx)
9927
9928 def __truediv__(self, other):
9929 """Create the Z3 expression division `self / other`."""
9930 return self.__div__(other)
9931
9932 def __rtruediv__(self, other):
9933 """Create the Z3 expression division `other / self`."""
9934 return self.__rdiv__(other)
9935
9936 def __mod__(self, other):
9937 """Create the Z3 expression mod `self % other`."""
9938 return fpRem(self, other)
9939
9940 def __rmod__(self, other):
9941 """Create the Z3 expression mod `other % self`."""
9942 return fpRem(other, self)
9943
9944
9945class FPRMRef(ExprRef):
9946 """Floating-point rounding mode expressions"""
9947
9948 def as_string(self):
9949 """Return a Z3 floating point expression as a Python string."""
9950 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9951
9952
9953def RoundNearestTiesToEven(ctx=None):
9954 ctx = _get_ctx(ctx)
9955 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9956
9957
9958def RNE(ctx=None):
9959 ctx = _get_ctx(ctx)
9960 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
9961
9962
9963def RoundNearestTiesToAway(ctx=None):
9964 ctx = _get_ctx(ctx)
9965 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9966
9967
9968def RNA(ctx=None):
9969 ctx = _get_ctx(ctx)
9970 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
9971
9972
9973def RoundTowardPositive(ctx=None):
9974 ctx = _get_ctx(ctx)
9975 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9976
9977
9978def RTP(ctx=None):
9979 ctx = _get_ctx(ctx)
9980 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
9981
9982
9983def RoundTowardNegative(ctx=None):
9984 ctx = _get_ctx(ctx)
9985 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9986
9987
9988def RTN(ctx=None):
9989 ctx = _get_ctx(ctx)
9990 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
9991
9992
9993def RoundTowardZero(ctx=None):
9994 ctx = _get_ctx(ctx)
9995 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
9996
9997
9998def RTZ(ctx=None):
9999 ctx = _get_ctx(ctx)
10000 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10001
10002
10003def is_fprm(a):
10004 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
10005
10006 >>> rm = RNE()
10007 >>> is_fprm(rm)
10008 True
10009 >>> rm = 1.0
10010 >>> is_fprm(rm)
10011 False
10012 """
10013 return isinstance(a, FPRMRef)
10014
10015
10016def is_fprm_value(a):
10017 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
10018 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
10019
10020# FP Numerals
10021
10022
10023class FPNumRef(FPRef):
10024 """The sign of the numeral.
10025
10026 >>> x = FPVal(+1.0, FPSort(8, 24))
10027 >>> x.sign()
10028 False
10029 >>> x = FPVal(-1.0, FPSort(8, 24))
10030 >>> x.sign()
10031 True
10032 """
10033
10034 def sign(self):
10035 num = ctypes.c_bool()
10036 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
10037 if nsign is False:
10038 raise Z3Exception("error retrieving the sign of a numeral.")
10039 return num.value != 0
10040
10041 """The sign of a floating-point numeral as a bit-vector expression.
10042
10043 Remark: NaN's are invalid arguments.
10044 """
10045
10046 def sign_as_bv(self):
10047 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10048
10049 """The significand of the numeral.
10050
10051 >>> x = FPVal(2.5, FPSort(8, 24))
10052 >>> x.significand()
10053 1.25
10054 """
10055
10056 def significand(self):
10057 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10058
10059 """The significand of the numeral as a long.
10060
10061 >>> x = FPVal(2.5, FPSort(8, 24))
10062 >>> x.significand_as_long()
10063 1.25
10064 """
10065
10066 def significand_as_long(self):
10067 ptr = (ctypes.c_ulonglong * 1)()
10068 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10069 raise Z3Exception("error retrieving the significand of a numeral.")
10070 return ptr[0]
10071
10072 """The significand of the numeral as a bit-vector expression.
10073
10074 Remark: NaN are invalid arguments.
10075 """
10076
10077 def significand_as_bv(self):
10078 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10079
10080 """The exponent of the numeral.
10081
10082 >>> x = FPVal(2.5, FPSort(8, 24))
10083 >>> x.exponent()
10084 1
10085 """
10086
10087 def exponent(self, biased=True):
10088 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10089
10090 """The exponent of the numeral as a long.
10091
10092 >>> x = FPVal(2.5, FPSort(8, 24))
10093 >>> x.exponent_as_long()
10094 1
10095 """
10096
10097 def exponent_as_long(self, biased=True):
10098 ptr = (ctypes.c_longlong * 1)()
10099 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10100 raise Z3Exception("error retrieving the exponent of a numeral.")
10101 return ptr[0]
10102
10103 """The exponent of the numeral as a bit-vector expression.
10104
10105 Remark: NaNs are invalid arguments.
10106 """
10107
10108 def exponent_as_bv(self, biased=True):
10109 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10110
10111 """Indicates whether the numeral is a NaN."""
10112
10113 def isNaN(self):
10114 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10115
10116 """Indicates whether the numeral is +oo or -oo."""
10117
10118 def isInf(self):
10119 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10120
10121 """Indicates whether the numeral is +zero or -zero."""
10122
10123 def isZero(self):
10124 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10125
10126 """Indicates whether the numeral is normal."""
10127
10128 def isNormal(self):
10129 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10130
10131 """Indicates whether the numeral is subnormal."""
10132
10133 def isSubnormal(self):
10134 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10135
10136 """Indicates whether the numeral is positive."""
10137
10138 def isPositive(self):
10139 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10140
10141 """Indicates whether the numeral is negative."""
10142
10143 def isNegative(self):
10144 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10145
10146 """
10147 The string representation of the numeral.
10148
10149 >>> x = FPVal(20, FPSort(8, 24))
10150 >>> x.as_string()
10151 1.25*(2**4)
10152 """
10153
10154 def as_string(self):
10155 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10156 return ("FPVal(%s, %s)" % (s, self.sort()))
10157
10158 def py_value(self):
10159 bv = simplify(fpToIEEEBV(self))
10160 binary = bv.py_value()
10161 if not isinstance(binary, int):
10162 return None
10163 # Decode the IEEE 754 binary representation
10164 import struct
10165 bytes_rep = binary.to_bytes(8, byteorder='big')
10166 return struct.unpack('>d', bytes_rep)[0]
10167
10168
10169def is_fp(a):
10170 """Return `True` if `a` is a Z3 floating-point expression.
10171
10172 >>> b = FP('b', FPSort(8, 24))
10173 >>> is_fp(b)
10174 True
10175 >>> is_fp(b + 1.0)
10176 True
10177 >>> is_fp(Int('x'))
10178 False
10179 """
10180 return isinstance(a, FPRef)
10181
10182
10183def is_fp_value(a):
10184 """Return `True` if `a` is a Z3 floating-point numeral value.
10185
10186 >>> b = FP('b', FPSort(8, 24))
10187 >>> is_fp_value(b)
10188 False
10189 >>> b = FPVal(1.0, FPSort(8, 24))
10190 >>> b
10191 1
10192 >>> is_fp_value(b)
10193 True
10194 """
10195 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10196
10197
10198def FPSort(ebits, sbits, ctx=None):
10199 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10200
10201 >>> Single = FPSort(8, 24)
10202 >>> Double = FPSort(11, 53)
10203 >>> Single
10204 FPSort(8, 24)
10205 >>> x = Const('x', Single)
10206 >>> eq(x, FP('x', FPSort(8, 24)))
10207 True
10208 """
10209 ctx = _get_ctx(ctx)
10210 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10211
10212
10213def _to_float_str(val, exp=0):
10214 if isinstance(val, float):
10215 if math.isnan(val):
10216 res = "NaN"
10217 elif val == 0.0:
10218 sone = math.copysign(1.0, val)
10219 if sone < 0.0:
10220 return "-0.0"
10221 else:
10222 return "+0.0"
10223 elif val == float("+inf"):
10224 res = "+oo"
10225 elif val == float("-inf"):
10226 res = "-oo"
10227 else:
10228 v = val.as_integer_ratio()
10229 num = v[0]
10230 den = v[1]
10231 rvs = str(num) + "/" + str(den)
10232 res = rvs + "p" + _to_int_str(exp)
10233 elif isinstance(val, bool):
10234 if val:
10235 res = "1.0"
10236 else:
10237 res = "0.0"
10238 elif _is_int(val):
10239 res = str(val)
10240 elif isinstance(val, str):
10241 inx = val.find("*(2**")
10242 if inx == -1:
10243 res = val
10244 elif val[-1] == ")":
10245 res = val[0:inx]
10246 exp = str(int(val[inx + 5:-1]) + int(exp))
10247 else:
10248 _z3_assert(False, "String does not have floating-point numeral form.")
10249 elif z3_debug():
10250 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10251 if exp == 0:
10252 return res
10253 else:
10254 return res + "p" + exp
10255
10256
10257def fpNaN(s):
10258 """Create a Z3 floating-point NaN term.
10259
10260 >>> s = FPSort(8, 24)
10261 >>> set_fpa_pretty(True)
10262 >>> fpNaN(s)
10263 NaN
10264 >>> pb = get_fpa_pretty()
10265 >>> set_fpa_pretty(False)
10266 >>> fpNaN(s)
10267 fpNaN(FPSort(8, 24))
10268 >>> set_fpa_pretty(pb)
10269 """
10270 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10271 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10272
10273
10274def fpPlusInfinity(s):
10275 """Create a Z3 floating-point +oo term.
10276
10277 >>> s = FPSort(8, 24)
10278 >>> pb = get_fpa_pretty()
10279 >>> set_fpa_pretty(True)
10280 >>> fpPlusInfinity(s)
10281 +oo
10282 >>> set_fpa_pretty(False)
10283 >>> fpPlusInfinity(s)
10284 fpPlusInfinity(FPSort(8, 24))
10285 >>> set_fpa_pretty(pb)
10286 """
10287 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10288 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10289
10290
10291def fpMinusInfinity(s):
10292 """Create a Z3 floating-point -oo term."""
10293 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10294 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10295
10296
10297def fpInfinity(s, negative):
10298 """Create a Z3 floating-point +oo or -oo term."""
10299 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10300 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10301 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10302
10303
10304def fpPlusZero(s):
10305 """Create a Z3 floating-point +0.0 term."""
10306 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10307 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10308
10309
10310def fpMinusZero(s):
10311 """Create a Z3 floating-point -0.0 term."""
10312 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10313 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10314
10315
10316def fpZero(s, negative):
10317 """Create a Z3 floating-point +0.0 or -0.0 term."""
10318 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10319 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10320 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10321
10322
10323def FPVal(sig, exp=None, fps=None, ctx=None):
10324 """Return a floating-point value of value `val` and sort `fps`.
10325 If `ctx=None`, then the global context is used.
10326
10327 >>> v = FPVal(20.0, FPSort(8, 24))
10328 >>> v
10329 1.25*(2**4)
10330 >>> print("0x%.8x" % v.exponent_as_long(False))
10331 0x00000004
10332 >>> v = FPVal(2.25, FPSort(8, 24))
10333 >>> v
10334 1.125*(2**1)
10335 >>> v = FPVal(-2.25, FPSort(8, 24))
10336 >>> v
10337 -1.125*(2**1)
10338 >>> FPVal(-0.0, FPSort(8, 24))
10339 -0.0
10340 >>> FPVal(0.0, FPSort(8, 24))
10341 +0.0
10342 >>> FPVal(+0.0, FPSort(8, 24))
10343 +0.0
10344 """
10345 ctx = _get_ctx(ctx)
10346 if is_fp_sort(exp):
10347 fps = exp
10348 exp = None
10349 elif fps is None:
10350 fps = _dflt_fps(ctx)
10351 _z3_assert(is_fp_sort(fps), "sort mismatch")
10352 if exp is None:
10353 exp = 0
10354 val = _to_float_str(sig)
10355 if val == "NaN" or val == "nan":
10356 return fpNaN(fps)
10357 elif val == "-0.0":
10358 return fpMinusZero(fps)
10359 elif val == "0.0" or val == "+0.0":
10360 return fpPlusZero(fps)
10361 elif val == "+oo" or val == "+inf" or val == "+Inf":
10362 return fpPlusInfinity(fps)
10363 elif val == "-oo" or val == "-inf" or val == "-Inf":
10364 return fpMinusInfinity(fps)
10365 else:
10366 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10367
10368
10369def FP(name, fpsort, ctx=None):
10370 """Return a floating-point constant named `name`.
10371 `fpsort` is the floating-point sort.
10372 If `ctx=None`, then the global context is used.
10373
10374 >>> x = FP('x', FPSort(8, 24))
10375 >>> is_fp(x)
10376 True
10377 >>> x.ebits()
10378 8
10379 >>> x.sort()
10380 FPSort(8, 24)
10381 >>> word = FPSort(8, 24)
10382 >>> x2 = FP('x', word)
10383 >>> eq(x, x2)
10384 True
10385 """
10386 if isinstance(fpsort, FPSortRef) and ctx is None:
10387 ctx = fpsort.ctx
10388 else:
10389 ctx = _get_ctx(ctx)
10390 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10391
10392
10393def FPs(names, fpsort, ctx=None):
10394 """Return an array of floating-point constants.
10395
10396 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10397 >>> x.sort()
10398 FPSort(8, 24)
10399 >>> x.sbits()
10400 24
10401 >>> x.ebits()
10402 8
10403 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10404 (x + y) * z
10405 """
10406 ctx = _get_ctx(ctx)
10407 if isinstance(names, str):
10408 names = names.split(" ")
10409 return [FP(name, fpsort, ctx) for name in names]
10410
10411
10412def fpAbs(a, ctx=None):
10413 """Create a Z3 floating-point absolute value expression.
10414
10415 >>> s = FPSort(8, 24)
10416 >>> rm = RNE()
10417 >>> x = FPVal(1.0, s)
10418 >>> fpAbs(x)
10419 fpAbs(1)
10420 >>> y = FPVal(-20.0, s)
10421 >>> y
10422 -1.25*(2**4)
10423 >>> fpAbs(y)
10424 fpAbs(-1.25*(2**4))
10425 >>> fpAbs(-1.25*(2**4))
10426 fpAbs(-1.25*(2**4))
10427 >>> fpAbs(x).sort()
10428 FPSort(8, 24)
10429 """
10430 ctx = _get_ctx(ctx)
10431 [a] = _coerce_fp_expr_list([a], ctx)
10432 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10433
10434
10435def fpNeg(a, ctx=None):
10436 """Create a Z3 floating-point addition expression.
10437
10438 >>> s = FPSort(8, 24)
10439 >>> rm = RNE()
10440 >>> x = FP('x', s)
10441 >>> fpNeg(x)
10442 -x
10443 >>> fpNeg(x).sort()
10444 FPSort(8, 24)
10445 """
10446 ctx = _get_ctx(ctx)
10447 [a] = _coerce_fp_expr_list([a], ctx)
10448 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10449
10450
10451def _mk_fp_unary(f, rm, a, ctx):
10452 ctx = _get_ctx(ctx)
10453 [a] = _coerce_fp_expr_list([a], ctx)
10454 if z3_debug():
10455 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10456 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10457 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10458
10459
10460def _mk_fp_unary_pred(f, a, ctx):
10461 ctx = _get_ctx(ctx)
10462 [a] = _coerce_fp_expr_list([a], ctx)
10463 if z3_debug():
10464 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10465 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10466
10467
10468def _mk_fp_bin(f, rm, a, b, ctx):
10469 ctx = _get_ctx(ctx)
10470 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10471 if z3_debug():
10472 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10473 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10474 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10475
10476
10477def _mk_fp_bin_norm(f, a, b, ctx):
10478 ctx = _get_ctx(ctx)
10479 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10480 if z3_debug():
10481 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10482 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10483
10484
10485def _mk_fp_bin_pred(f, a, b, ctx):
10486 ctx = _get_ctx(ctx)
10487 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10488 if z3_debug():
10489 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10490 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10491
10492
10493def _mk_fp_tern(f, rm, a, b, c, ctx):
10494 ctx = _get_ctx(ctx)
10495 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10496 if z3_debug():
10497 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10498 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10499 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10500 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10501
10502
10503def fpAdd(rm, a, b, ctx=None):
10504 """Create a Z3 floating-point addition expression.
10505
10506 >>> s = FPSort(8, 24)
10507 >>> rm = RNE()
10508 >>> x = FP('x', s)
10509 >>> y = FP('y', s)
10510 >>> fpAdd(rm, x, y)
10511 x + y
10512 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10513 fpAdd(RTZ(), x, y)
10514 >>> fpAdd(rm, x, y).sort()
10515 FPSort(8, 24)
10516 """
10517 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10518
10519
10520def fpSub(rm, a, b, ctx=None):
10521 """Create a Z3 floating-point subtraction expression.
10522
10523 >>> s = FPSort(8, 24)
10524 >>> rm = RNE()
10525 >>> x = FP('x', s)
10526 >>> y = FP('y', s)
10527 >>> fpSub(rm, x, y)
10528 x - y
10529 >>> fpSub(rm, x, y).sort()
10530 FPSort(8, 24)
10531 """
10532 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10533
10534
10535def fpMul(rm, a, b, ctx=None):
10536 """Create a Z3 floating-point multiplication expression.
10537
10538 >>> s = FPSort(8, 24)
10539 >>> rm = RNE()
10540 >>> x = FP('x', s)
10541 >>> y = FP('y', s)
10542 >>> fpMul(rm, x, y)
10543 x * y
10544 >>> fpMul(rm, x, y).sort()
10545 FPSort(8, 24)
10546 """
10547 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10548
10549
10550def fpDiv(rm, a, b, ctx=None):
10551 """Create a Z3 floating-point division expression.
10552
10553 >>> s = FPSort(8, 24)
10554 >>> rm = RNE()
10555 >>> x = FP('x', s)
10556 >>> y = FP('y', s)
10557 >>> fpDiv(rm, x, y)
10558 x / y
10559 >>> fpDiv(rm, x, y).sort()
10560 FPSort(8, 24)
10561 """
10562 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10563
10564
10565def fpRem(a, b, ctx=None):
10566 """Create a Z3 floating-point remainder expression.
10567
10568 >>> s = FPSort(8, 24)
10569 >>> x = FP('x', s)
10570 >>> y = FP('y', s)
10571 >>> fpRem(x, y)
10572 fpRem(x, y)
10573 >>> fpRem(x, y).sort()
10574 FPSort(8, 24)
10575 """
10576 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10577
10578
10579def fpMin(a, b, ctx=None):
10580 """Create a Z3 floating-point minimum expression.
10581
10582 >>> s = FPSort(8, 24)
10583 >>> rm = RNE()
10584 >>> x = FP('x', s)
10585 >>> y = FP('y', s)
10586 >>> fpMin(x, y)
10587 fpMin(x, y)
10588 >>> fpMin(x, y).sort()
10589 FPSort(8, 24)
10590 """
10591 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10592
10593
10594def fpMax(a, b, ctx=None):
10595 """Create a Z3 floating-point maximum expression.
10596
10597 >>> s = FPSort(8, 24)
10598 >>> rm = RNE()
10599 >>> x = FP('x', s)
10600 >>> y = FP('y', s)
10601 >>> fpMax(x, y)
10602 fpMax(x, y)
10603 >>> fpMax(x, y).sort()
10604 FPSort(8, 24)
10605 """
10606 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10607
10608
10609def fpFMA(rm, a, b, c, ctx=None):
10610 """Create a Z3 floating-point fused multiply-add expression.
10611 """
10612 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10613
10614
10615def fpSqrt(rm, a, ctx=None):
10616 """Create a Z3 floating-point square root expression.
10617 """
10618 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10619
10620
10621def fpRoundToIntegral(rm, a, ctx=None):
10622 """Create a Z3 floating-point roundToIntegral expression.
10623 """
10624 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10625
10626
10627def fpIsNaN(a, ctx=None):
10628 """Create a Z3 floating-point isNaN expression.
10629
10630 >>> s = FPSort(8, 24)
10631 >>> x = FP('x', s)
10632 >>> y = FP('y', s)
10633 >>> fpIsNaN(x)
10634 fpIsNaN(x)
10635 """
10636 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10637
10638
10639def fpIsInf(a, ctx=None):
10640 """Create a Z3 floating-point isInfinite expression.
10641
10642 >>> s = FPSort(8, 24)
10643 >>> x = FP('x', s)
10644 >>> fpIsInf(x)
10645 fpIsInf(x)
10646 """
10647 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10648
10649
10650def fpIsZero(a, ctx=None):
10651 """Create a Z3 floating-point isZero expression.
10652 """
10653 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10654
10655
10656def fpIsNormal(a, ctx=None):
10657 """Create a Z3 floating-point isNormal expression.
10658 """
10659 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10660
10661
10662def fpIsSubnormal(a, ctx=None):
10663 """Create a Z3 floating-point isSubnormal expression.
10664 """
10665 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10666
10667
10668def fpIsNegative(a, ctx=None):
10669 """Create a Z3 floating-point isNegative expression.
10670 """
10671 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10672
10673
10674def fpIsPositive(a, ctx=None):
10675 """Create a Z3 floating-point isPositive expression.
10676 """
10677 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10678
10679
10680def _check_fp_args(a, b):
10681 if z3_debug():
10682 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10683
10684
10685def fpLT(a, b, ctx=None):
10686 """Create the Z3 floating-point expression `other < self`.
10687
10688 >>> x, y = FPs('x y', FPSort(8, 24))
10689 >>> fpLT(x, y)
10690 x < y
10691 >>> (x < y).sexpr()
10692 '(fp.lt x y)'
10693 """
10694 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10695
10696
10697def fpLEQ(a, b, ctx=None):
10698 """Create the Z3 floating-point expression `other <= self`.
10699
10700 >>> x, y = FPs('x y', FPSort(8, 24))
10701 >>> fpLEQ(x, y)
10702 x <= y
10703 >>> (x <= y).sexpr()
10704 '(fp.leq x y)'
10705 """
10706 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10707
10708
10709def fpGT(a, b, ctx=None):
10710 """Create the Z3 floating-point expression `other > self`.
10711
10712 >>> x, y = FPs('x y', FPSort(8, 24))
10713 >>> fpGT(x, y)
10714 x > y
10715 >>> (x > y).sexpr()
10716 '(fp.gt x y)'
10717 """
10718 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10719
10720
10721def fpGEQ(a, b, ctx=None):
10722 """Create the Z3 floating-point expression `other >= self`.
10723
10724 >>> x, y = FPs('x y', FPSort(8, 24))
10725 >>> fpGEQ(x, y)
10726 x >= y
10727 >>> (x >= y).sexpr()
10728 '(fp.geq x y)'
10729 """
10730 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10731
10732
10733def fpEQ(a, b, ctx=None):
10734 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10735
10736 >>> x, y = FPs('x y', FPSort(8, 24))
10737 >>> fpEQ(x, y)
10738 fpEQ(x, y)
10739 >>> fpEQ(x, y).sexpr()
10740 '(fp.eq x y)'
10741 """
10742 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10743
10744
10745def fpNEQ(a, b, ctx=None):
10746 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10747
10748 >>> x, y = FPs('x y', FPSort(8, 24))
10749 >>> fpNEQ(x, y)
10750 Not(fpEQ(x, y))
10751 >>> (x != y).sexpr()
10752 '(distinct x y)'
10753 """
10754 return Not(fpEQ(a, b, ctx))
10755
10756
10757def fpFP(sgn, exp, sig, ctx=None):
10758 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10759
10760 >>> s = FPSort(8, 24)
10761 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10762 >>> print(x)
10763 fpFP(1, 127, 4194304)
10764 >>> xv = FPVal(-1.5, s)
10765 >>> print(xv)
10766 -1.5
10767 >>> slvr = Solver()
10768 >>> slvr.add(fpEQ(x, xv))
10769 >>> slvr.check()
10770 sat
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 unsat
10778 """
10779 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10780 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10781 ctx = _get_ctx(ctx)
10782 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10783 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10784
10785
10786def fpToFP(a1, a2=None, a3=None, ctx=None):
10787 """Create a Z3 floating-point conversion expression from other term sorts
10788 to floating-point.
10789
10790 From a bit-vector term in IEEE 754-2008 format:
10791 >>> x = FPVal(1.0, Float32())
10792 >>> x_bv = fpToIEEEBV(x)
10793 >>> simplify(fpToFP(x_bv, Float32()))
10794 1
10795
10796 From a floating-point term with different precision:
10797 >>> x = FPVal(1.0, Float32())
10798 >>> x_db = fpToFP(RNE(), x, Float64())
10799 >>> x_db.sort()
10800 FPSort(11, 53)
10801
10802 From a real term:
10803 >>> x_r = RealVal(1.5)
10804 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10805 1.5
10806
10807 From a signed bit-vector term:
10808 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10809 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10810 -1.25*(2**2)
10811 """
10812 ctx = _get_ctx(ctx)
10813 if is_bv(a1) and is_fp_sort(a2):
10814 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10815 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10816 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10817 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10818 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10819 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10820 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10821 else:
10822 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10823
10824
10825def fpBVToFP(v, sort, ctx=None):
10826 """Create a Z3 floating-point conversion expression that represents the
10827 conversion from a bit-vector term to a floating-point term.
10828
10829 >>> x_bv = BitVecVal(0x3F800000, 32)
10830 >>> x_fp = fpBVToFP(x_bv, Float32())
10831 >>> x_fp
10832 fpToFP(1065353216)
10833 >>> simplify(x_fp)
10834 1
10835 """
10836 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10837 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10838 ctx = _get_ctx(ctx)
10839 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10840
10841
10842def fpFPToFP(rm, v, sort, ctx=None):
10843 """Create a Z3 floating-point conversion expression that represents the
10844 conversion from a floating-point term to a floating-point term of different precision.
10845
10846 >>> x_sgl = FPVal(1.0, Float32())
10847 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10848 >>> x_dbl
10849 fpToFP(RNE(), 1)
10850 >>> simplify(x_dbl)
10851 1
10852 >>> x_dbl.sort()
10853 FPSort(11, 53)
10854 """
10855 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10856 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10857 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10858 ctx = _get_ctx(ctx)
10859 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10860
10861
10862def fpRealToFP(rm, v, sort, ctx=None):
10863 """Create a Z3 floating-point conversion expression that represents the
10864 conversion from a real term to a floating-point term.
10865
10866 >>> x_r = RealVal(1.5)
10867 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10868 >>> x_fp
10869 fpToFP(RNE(), 3/2)
10870 >>> simplify(x_fp)
10871 1.5
10872 """
10873 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10874 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10875 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10876 ctx = _get_ctx(ctx)
10877 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10878
10879
10880def fpSignedToFP(rm, v, sort, ctx=None):
10881 """Create a Z3 floating-point conversion expression that represents the
10882 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10883
10884 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10885 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10886 >>> x_fp
10887 fpToFP(RNE(), 4294967291)
10888 >>> simplify(x_fp)
10889 -1.25*(2**2)
10890 """
10891 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10892 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10893 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10894 ctx = _get_ctx(ctx)
10895 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10896
10897
10898def fpUnsignedToFP(rm, v, sort, ctx=None):
10899 """Create a Z3 floating-point conversion expression that represents the
10900 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10901
10902 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10903 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10904 >>> x_fp
10905 fpToFPUnsigned(RNE(), 4294967291)
10906 >>> simplify(x_fp)
10907 1*(2**32)
10908 """
10909 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10910 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10911 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10912 ctx = _get_ctx(ctx)
10913 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10914
10915
10916def fpToFPUnsigned(rm, x, s, ctx=None):
10917 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10918 if z3_debug():
10919 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10920 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10921 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10922 ctx = _get_ctx(ctx)
10923 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
10924
10925
10926def fpToSBV(rm, x, s, ctx=None):
10927 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
10928
10929 >>> x = FP('x', FPSort(8, 24))
10930 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
10931 >>> print(is_fp(x))
10932 True
10933 >>> print(is_bv(y))
10934 True
10935 >>> print(is_fp(y))
10936 False
10937 >>> print(is_bv(x))
10938 False
10939 """
10940 if z3_debug():
10941 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10942 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10943 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10944 ctx = _get_ctx(ctx)
10945 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10946
10947
10948def fpToUBV(rm, x, s, ctx=None):
10949 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
10950
10951 >>> x = FP('x', FPSort(8, 24))
10952 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
10953 >>> print(is_fp(x))
10954 True
10955 >>> print(is_bv(y))
10956 True
10957 >>> print(is_fp(y))
10958 False
10959 >>> print(is_bv(x))
10960 False
10961 """
10962 if z3_debug():
10963 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10964 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
10965 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
10966 ctx = _get_ctx(ctx)
10967 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
10968
10969
10970def fpToReal(x, ctx=None):
10971 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
10972
10973 >>> x = FP('x', FPSort(8, 24))
10974 >>> y = fpToReal(x)
10975 >>> print(is_fp(x))
10976 True
10977 >>> print(is_real(y))
10978 True
10979 >>> print(is_fp(y))
10980 False
10981 >>> print(is_real(x))
10982 False
10983 """
10984 if z3_debug():
10985 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
10986 ctx = _get_ctx(ctx)
10987 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
10988
10989
10990def fpToIEEEBV(x, ctx=None):
10991 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
10992
10993 The size of the resulting bit-vector is automatically determined.
10994
10995 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
10996 knows only one NaN and it will always produce the same bit-vector representation of
10997 that NaN.
10998
10999 >>> x = FP('x', FPSort(8, 24))
11000 >>> y = fpToIEEEBV(x)
11001 >>> print(is_fp(x))
11002 True
11003 >>> print(is_bv(y))
11004 True
11005 >>> print(is_fp(y))
11006 False
11007 >>> print(is_bv(x))
11008 False
11009 """
11010 if z3_debug():
11011 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11012 ctx = _get_ctx(ctx)
11013 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
11014
11015
11016#########################################
11017#
11018# Strings, Sequences and Regular expressions
11019#
11020#########################################
11021
11022class SeqSortRef(SortRef):
11023 """Sequence sort."""
11024
11025 def is_string(self):
11026 """Determine if sort is a string
11027 >>> s = StringSort()
11028 >>> s.is_string()
11029 True
11030 >>> s = SeqSort(IntSort())
11031 >>> s.is_string()
11032 False
11033 """
11034 return Z3_is_string_sort(self.ctx_ref(), self.ast)
11035
11036 def basis(self):
11037 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11038
11039class CharSortRef(SortRef):
11040 """Character sort."""
11041
11042
11043def StringSort(ctx=None):
11044 """Create a string sort
11045 >>> s = StringSort()
11046 >>> print(s)
11047 String
11048 """
11049 ctx = _get_ctx(ctx)
11050 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
11051
11052def CharSort(ctx=None):
11053 """Create a character sort
11054 >>> ch = CharSort()
11055 >>> print(ch)
11056 Char
11057 """
11058 ctx = _get_ctx(ctx)
11059 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11060
11061
11062def SeqSort(s):
11063 """Create a sequence sort over elements provided in the argument
11064 >>> s = SeqSort(IntSort())
11065 >>> s == Unit(IntVal(1)).sort()
11066 True
11067 """
11068 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11069
11070
11071class SeqRef(ExprRef):
11072 """Sequence expression."""
11073
11074 def sort(self):
11075 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11076
11077 def __add__(self, other):
11078 return Concat(self, other)
11079
11080 def __radd__(self, other):
11081 return Concat(other, self)
11082
11083 def __getitem__(self, i):
11084 if _is_int(i):
11085 i = IntVal(i, self.ctx)
11086 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11087
11088 def at(self, i):
11089 if _is_int(i):
11090 i = IntVal(i, self.ctx)
11091 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11092
11093 def is_string(self):
11094 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11095
11096 def is_string_value(self):
11097 return Z3_is_string(self.ctx_ref(), self.as_ast())
11098
11099 def as_string(self):
11100 """Return a string representation of sequence expression."""
11101 if self.is_string_value():
11102 string_length = ctypes.c_uint()
11103 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11104 return string_at(chars, size=string_length.value).decode("latin-1")
11105 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11106
11107 def py_value(self):
11108 return self.as_string()
11109
11110 def __le__(self, other):
11111 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11112
11113 def __lt__(self, other):
11114 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11115
11116 def __ge__(self, other):
11117 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11118
11119 def __gt__(self, other):
11120 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11121
11122
11123def _coerce_char(ch, ctx=None):
11124 if isinstance(ch, str):
11125 ctx = _get_ctx(ctx)
11126 ch = CharVal(ch, ctx)
11127 if not is_expr(ch):
11128 raise Z3Exception("Character expression expected")
11129 return ch
11130
11131class CharRef(ExprRef):
11132 """Character expression."""
11133
11134 def __le__(self, other):
11135 other = _coerce_char(other, self.ctx)
11136 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11137
11138 def to_int(self):
11139 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11140
11141 def to_bv(self):
11142 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11143
11144 def is_digit(self):
11145 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11146
11147
11148def CharVal(ch, ctx=None):
11149 ctx = _get_ctx(ctx)
11150 if isinstance(ch, str):
11151 ch = ord(ch)
11152 if not isinstance(ch, int):
11153 raise Z3Exception("character value should be an ordinal")
11154 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11155
11156def CharFromBv(bv):
11157 if not is_expr(bv):
11158 raise Z3Exception("Bit-vector expression needed")
11159 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11160
11161def CharToBv(ch, ctx=None):
11162 ch = _coerce_char(ch, ctx)
11163 return ch.to_bv()
11164
11165def CharToInt(ch, ctx=None):
11166 ch = _coerce_char(ch, ctx)
11167 return ch.to_int()
11168
11169def CharIsDigit(ch, ctx=None):
11170 ch = _coerce_char(ch, ctx)
11171 return ch.is_digit()
11172
11173def _coerce_seq(s, ctx=None):
11174 if isinstance(s, str):
11175 ctx = _get_ctx(ctx)
11176 s = StringVal(s, ctx)
11177 if not is_expr(s):
11178 raise Z3Exception("Non-expression passed as a sequence")
11179 if not is_seq(s):
11180 raise Z3Exception("Non-sequence passed as a sequence")
11181 return s
11182
11183
11184def _get_ctx2(a, b, ctx=None):
11185 if is_expr(a):
11186 return a.ctx
11187 if is_expr(b):
11188 return b.ctx
11189 if ctx is None:
11190 ctx = main_ctx()
11191 return ctx
11192
11193
11194def is_seq(a):
11195 """Return `True` if `a` is a Z3 sequence expression.
11196 >>> print (is_seq(Unit(IntVal(0))))
11197 True
11198 >>> print (is_seq(StringVal("abc")))
11199 True
11200 """
11201 return isinstance(a, SeqRef)
11202
11203
11204def is_string(a: Any) -> bool:
11205 """Return `True` if `a` is a Z3 string expression.
11206 >>> print (is_string(StringVal("ab")))
11207 True
11208 """
11209 return isinstance(a, SeqRef) and a.is_string()
11210
11211
11212def is_string_value(a: Any) -> bool:
11213 """return 'True' if 'a' is a Z3 string constant expression.
11214 >>> print (is_string_value(StringVal("a")))
11215 True
11216 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11217 False
11218 """
11219 return isinstance(a, SeqRef) and a.is_string_value()
11220
11221def StringVal(s, ctx=None):
11222 """create a string expression"""
11223 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11224 ctx = _get_ctx(ctx)
11225 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11226
11227
11228def String(name, ctx=None):
11229 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11230
11231 >>> x = String('x')
11232 """
11233 ctx = _get_ctx(ctx)
11234 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11235
11236
11237def Strings(names, ctx=None):
11238 """Return a tuple of String constants. """
11239 ctx = _get_ctx(ctx)
11240 if isinstance(names, str):
11241 names = names.split(" ")
11242 return [String(name, ctx) for name in names]
11243
11244
11245def SubString(s, offset, length):
11246 """Extract substring or subsequence starting at offset.
11247
11248 This is a convenience function that redirects to Extract(s, offset, length).
11249
11250 >>> s = StringVal("hello world")
11251 >>> SubString(s, 6, 5) # Extract "world"
11252 str.substr("hello world", 6, 5)
11253 >>> simplify(SubString(StringVal("hello"), 1, 3))
11254 "ell"
11255 """
11256 return Extract(s, offset, length)
11257
11258
11259def SubSeq(s, offset, length):
11260 """Extract substring or subsequence starting at offset.
11261
11262 This is a convenience function that redirects to Extract(s, offset, length).
11263
11264 >>> s = StringVal("hello world")
11265 >>> SubSeq(s, 0, 5) # Extract "hello"
11266 str.substr("hello world", 0, 5)
11267 >>> simplify(SubSeq(StringVal("testing"), 2, 4))
11268 "stin"
11269 """
11270 return Extract(s, offset, length)
11271
11272
11273def Empty(s):
11274 """Create the empty sequence of the given sort
11275 >>> e = Empty(StringSort())
11276 >>> e2 = StringVal("")
11277 >>> print(e.eq(e2))
11278 True
11279 >>> e3 = Empty(SeqSort(IntSort()))
11280 >>> print(e3)
11281 Empty(Seq(Int))
11282 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11283 >>> print(e4)
11284 Empty(ReSort(Seq(Int)))
11285 """
11286 if isinstance(s, SeqSortRef):
11287 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11288 if isinstance(s, ReSortRef):
11289 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11290 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11291
11292
11293def Full(s):
11294 """Create the regular expression that accepts the universal language
11295 >>> e = Full(ReSort(SeqSort(IntSort())))
11296 >>> print(e)
11297 Full(ReSort(Seq(Int)))
11298 >>> e1 = Full(ReSort(StringSort()))
11299 >>> print(e1)
11300 Full(ReSort(String))
11301 """
11302 if isinstance(s, ReSortRef):
11303 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11304 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11305
11306
11307
11308def Unit(a):
11309 """Create a singleton sequence"""
11310 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11311
11312
11313def PrefixOf(a, b):
11314 """Check if 'a' is a prefix of 'b'
11315 >>> s1 = PrefixOf("ab", "abc")
11316 >>> simplify(s1)
11317 True
11318 >>> s2 = PrefixOf("bc", "abc")
11319 >>> simplify(s2)
11320 False
11321 """
11322 ctx = _get_ctx2(a, b)
11323 a = _coerce_seq(a, ctx)
11324 b = _coerce_seq(b, ctx)
11325 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11326
11327
11328def SuffixOf(a, b):
11329 """Check if 'a' is a suffix of 'b'
11330 >>> s1 = SuffixOf("ab", "abc")
11331 >>> simplify(s1)
11332 False
11333 >>> s2 = SuffixOf("bc", "abc")
11334 >>> simplify(s2)
11335 True
11336 """
11337 ctx = _get_ctx2(a, b)
11338 a = _coerce_seq(a, ctx)
11339 b = _coerce_seq(b, ctx)
11340 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11341
11342
11343def Contains(a, b):
11344 """Check if 'a' contains 'b'
11345 >>> s1 = Contains("abc", "ab")
11346 >>> simplify(s1)
11347 True
11348 >>> s2 = Contains("abc", "bc")
11349 >>> simplify(s2)
11350 True
11351 >>> x, y, z = Strings('x y z')
11352 >>> s3 = Contains(Concat(x,y,z), y)
11353 >>> simplify(s3)
11354 True
11355 """
11356 ctx = _get_ctx2(a, b)
11357 a = _coerce_seq(a, ctx)
11358 b = _coerce_seq(b, ctx)
11359 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11360
11361
11362def Replace(s, src, dst):
11363 """Replace the first occurrence of 'src' by 'dst' in 's'
11364 >>> r = Replace("aaa", "a", "b")
11365 >>> simplify(r)
11366 "baa"
11367 """
11368 ctx = _get_ctx2(dst, s)
11369 if ctx is None and is_expr(src):
11370 ctx = src.ctx
11371 src = _coerce_seq(src, ctx)
11372 dst = _coerce_seq(dst, ctx)
11373 s = _coerce_seq(s, ctx)
11374 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11375
11376
11377def IndexOf(s, substr, offset=None):
11378 """Retrieve the index of substring within a string starting at a specified offset.
11379 >>> simplify(IndexOf("abcabc", "bc", 0))
11380 1
11381 >>> simplify(IndexOf("abcabc", "bc", 2))
11382 4
11383 """
11384 if offset is None:
11385 offset = IntVal(0)
11386 ctx = None
11387 if is_expr(offset):
11388 ctx = offset.ctx
11389 ctx = _get_ctx2(s, substr, ctx)
11390 s = _coerce_seq(s, ctx)
11391 substr = _coerce_seq(substr, ctx)
11392 if _is_int(offset):
11393 offset = IntVal(offset, ctx)
11394 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11395
11396
11397def LastIndexOf(s, substr):
11398 """Retrieve the last index of substring within a string"""
11399 ctx = None
11400 ctx = _get_ctx2(s, substr, ctx)
11401 s = _coerce_seq(s, ctx)
11402 substr = _coerce_seq(substr, ctx)
11403 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11404
11405
11406def Length(s):
11407 """Obtain the length of a sequence 's'
11408 >>> l = Length(StringVal("abc"))
11409 >>> simplify(l)
11410 3
11411 """
11412 s = _coerce_seq(s)
11413 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11414
11415def SeqMap(f, s):
11416 """Map function 'f' over sequence 's'"""
11417 ctx = _get_ctx2(f, s)
11418 s = _coerce_seq(s, ctx)
11419 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11420
11421def SeqMapI(f, i, s):
11422 """Map function 'f' over sequence 's' at index 'i'"""
11423 ctx = _get_ctx2(f, s)
11424 s = _coerce_seq(s, ctx)
11425 if not is_expr(i):
11426 i = _py2expr(i)
11427 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11428
11429def SeqFoldLeft(f, a, s):
11430 ctx = _get_ctx2(f, s)
11431 s = _coerce_seq(s, ctx)
11432 a = _py2expr(a)
11433 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11434
11435def SeqFoldLeftI(f, i, a, s):
11436 ctx = _get_ctx2(f, s)
11437 s = _coerce_seq(s, ctx)
11438 a = _py2expr(a)
11439 i = _py2expr(i)
11440 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11441
11442def StrToInt(s):
11443 """Convert string expression to integer
11444 >>> a = StrToInt("1")
11445 >>> simplify(1 == a)
11446 True
11447 >>> b = StrToInt("2")
11448 >>> simplify(1 == b)
11449 False
11450 >>> c = StrToInt(IntToStr(2))
11451 >>> simplify(1 == c)
11452 False
11453 """
11454 s = _coerce_seq(s)
11455 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11456
11457
11458def IntToStr(s):
11459 """Convert integer expression to string"""
11460 if not is_expr(s):
11461 s = _py2expr(s)
11462 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11463
11464
11465def StrToCode(s):
11466 """Convert a unit length string to integer code"""
11467 if not is_expr(s):
11468 s = _py2expr(s)
11469 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11470
11471def StrFromCode(c):
11472 """Convert code to a string"""
11473 if not is_expr(c):
11474 c = _py2expr(c)
11475 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11476
11477def Re(s, ctx=None):
11478 """The regular expression that accepts sequence 's'
11479 >>> s1 = Re("ab")
11480 >>> s2 = Re(StringVal("ab"))
11481 >>> s3 = Re(Unit(BoolVal(True)))
11482 """
11483 s = _coerce_seq(s, ctx)
11484 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11485
11486
11487# Regular expressions
11488
11489class ReSortRef(SortRef):
11490 """Regular expression sort."""
11491
11492 def basis(self):
11493 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11494
11495
11496def ReSort(s):
11497 if is_ast(s):
11498 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11499 if s is None or isinstance(s, Context):
11500 ctx = _get_ctx(s)
11501 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11502 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11503
11504
11505class ReRef(ExprRef):
11506 """Regular expressions."""
11507
11508 def __add__(self, other):
11509 return Union(self, other)
11510
11511
11512def is_re(s):
11513 return isinstance(s, ReRef)
11514
11515
11516def InRe(s, re):
11517 """Create regular expression membership test
11518 >>> re = Union(Re("a"),Re("b"))
11519 >>> print (simplify(InRe("a", re)))
11520 True
11521 >>> print (simplify(InRe("b", re)))
11522 True
11523 >>> print (simplify(InRe("c", re)))
11524 False
11525 """
11526 s = _coerce_seq(s, re.ctx)
11527 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11528
11529
11530def Union(*args):
11531 """Create union of regular expressions.
11532 >>> re = Union(Re("a"), Re("b"), Re("c"))
11533 >>> print (simplify(InRe("d", re)))
11534 False
11535 """
11536 args = _get_args(args)
11537 sz = len(args)
11538 if z3_debug():
11539 _z3_assert(sz > 0, "At least one argument expected.")
11540 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11541 if sz == 1:
11542 return args[0]
11543 ctx = args[0].ctx
11544 v = (Ast * sz)()
11545 for i in range(sz):
11546 v[i] = args[i].as_ast()
11547 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11548
11549
11550def Intersect(*args):
11551 """Create intersection of regular expressions.
11552 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11553 """
11554 args = _get_args(args)
11555 sz = len(args)
11556 if z3_debug():
11557 _z3_assert(sz > 0, "At least one argument expected.")
11558 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11559 if sz == 1:
11560 return args[0]
11561 ctx = args[0].ctx
11562 v = (Ast * sz)()
11563 for i in range(sz):
11564 v[i] = args[i].as_ast()
11565 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11566
11567
11568def Plus(re):
11569 """Create the regular expression accepting one or more repetitions of argument.
11570 >>> re = Plus(Re("a"))
11571 >>> print(simplify(InRe("aa", re)))
11572 True
11573 >>> print(simplify(InRe("ab", re)))
11574 False
11575 >>> print(simplify(InRe("", re)))
11576 False
11577 """
11578 if z3_debug():
11579 _z3_assert(is_expr(re), "expression expected")
11580 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11581
11582
11583def Option(re):
11584 """Create the regular expression that optionally accepts the argument.
11585 >>> re = Option(Re("a"))
11586 >>> print(simplify(InRe("a", re)))
11587 True
11588 >>> print(simplify(InRe("", re)))
11589 True
11590 >>> print(simplify(InRe("aa", re)))
11591 False
11592 """
11593 if z3_debug():
11594 _z3_assert(is_expr(re), "expression expected")
11595 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11596
11597
11598def Complement(re):
11599 """Create the complement regular expression."""
11600 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11601
11602
11603def Star(re):
11604 """Create the regular expression accepting zero or more repetitions of argument.
11605 >>> re = Star(Re("a"))
11606 >>> print(simplify(InRe("aa", re)))
11607 True
11608 >>> print(simplify(InRe("ab", re)))
11609 False
11610 >>> print(simplify(InRe("", re)))
11611 True
11612 """
11613 if z3_debug():
11614 _z3_assert(is_expr(re), "expression expected")
11615 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11616
11617
11618def Loop(re, lo, hi=0):
11619 """Create the regular expression accepting between a lower and upper bound repetitions
11620 >>> re = Loop(Re("a"), 1, 3)
11621 >>> print(simplify(InRe("aa", re)))
11622 True
11623 >>> print(simplify(InRe("aaaa", re)))
11624 False
11625 >>> print(simplify(InRe("", re)))
11626 False
11627 """
11628 if z3_debug():
11629 _z3_assert(is_expr(re), "expression expected")
11630 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11631
11632
11633def Range(lo, hi, ctx=None):
11634 """Create the range regular expression over two sequences of length 1
11635 >>> range = Range("a","z")
11636 >>> print(simplify(InRe("b", range)))
11637 True
11638 >>> print(simplify(InRe("bb", range)))
11639 False
11640 """
11641 lo = _coerce_seq(lo, ctx)
11642 hi = _coerce_seq(hi, ctx)
11643 if z3_debug():
11644 _z3_assert(is_expr(lo), "expression expected")
11645 _z3_assert(is_expr(hi), "expression expected")
11646 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11647
11648def Diff(a, b, ctx=None):
11649 """Create the difference regular expression
11650 """
11651 if z3_debug():
11652 _z3_assert(is_expr(a), "expression expected")
11653 _z3_assert(is_expr(b), "expression expected")
11654 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11655
11656def AllChar(regex_sort, ctx=None):
11657 """Create a regular expression that accepts all single character strings
11658 """
11659 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11660
11661# Special Relations
11662
11663
11664def PartialOrder(a, index):
11665 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11666
11667
11668def LinearOrder(a, index):
11669 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11670
11671
11672def TreeOrder(a, index):
11673 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11674
11675
11676def PiecewiseLinearOrder(a, index):
11677 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11678
11679
11680def TransitiveClosure(f):
11681 """Given a binary relation R, such that the two arguments have the same sort
11682 create the transitive closure relation R+.
11683 The transitive closure R+ is a new relation.
11684 """
11685 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11686
11687def to_Ast(ptr,):
11688 ast = Ast(ptr)
11689 super(ctypes.c_void_p, ast).__init__(ptr)
11690 return ast
11691
11692def to_ContextObj(ptr,):
11693 ctx = ContextObj(ptr)
11694 super(ctypes.c_void_p, ctx).__init__(ptr)
11695 return ctx
11696
11697def to_AstVectorObj(ptr,):
11698 v = AstVectorObj(ptr)
11699 super(ctypes.c_void_p, v).__init__(ptr)
11700 return v
11701
11702# NB. my-hacky-class only works for a single instance of OnClause
11703# it should be replaced with a proper correlation between OnClause
11704# and object references that can be passed over the FFI.
11705# for UserPropagator we use a global dictionary, which isn't great code.
11706
11707_my_hacky_class = None
11708def on_clause_eh(ctx, p, n, dep, clause):
11709 onc = _my_hacky_class
11710 p = _to_expr_ref(to_Ast(p), onc.ctx)
11711 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11712 deps = [dep[i] for i in range(n)]
11713 onc.on_clause(p, deps, clause)
11714
11715_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11716
11717class OnClause:
11718 def __init__(self, s, on_clause):
11719 self.s = s
11720 self.ctx = s.ctx
11721 self.on_clause = on_clause
11722 self.idx = 22
11723 global _my_hacky_class
11724 _my_hacky_class = self
11725 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11726
11727
11728class PropClosures:
11729 def __init__(self):
11730 self.bases = {}
11731 self.lock = None
11732
11733 def set_threaded(self):
11734 if self.lock is None:
11735 import threading
11736 self.lock = threading.Lock()
11737
11738 def get(self, ctx):
11739 if self.lock:
11740 with self.lock:
11741 r = self.bases[ctx]
11742 else:
11743 r = self.bases[ctx]
11744 return r
11745
11746 def set(self, ctx, r):
11747 if self.lock:
11748 with self.lock:
11749 self.bases[ctx] = r
11750 else:
11751 self.bases[ctx] = r
11752
11753 def insert(self, r):
11754 if self.lock:
11755 with self.lock:
11756 id = len(self.bases) + 3
11757 self.bases[id] = r
11758 else:
11759 id = len(self.bases) + 3
11760 self.bases[id] = r
11761 return id
11762
11763
11764_prop_closures = None
11765
11766
11767def ensure_prop_closures():
11768 global _prop_closures
11769 if _prop_closures is None:
11770 _prop_closures = PropClosures()
11771
11772
11773def user_prop_push(ctx, cb):
11774 prop = _prop_closures.get(ctx)
11775 prop.cb = cb
11776 prop.push()
11777
11778
11779def user_prop_pop(ctx, cb, num_scopes):
11780 prop = _prop_closures.get(ctx)
11781 prop.cb = cb
11782 prop.pop(num_scopes)
11783
11784
11785def user_prop_fresh(ctx, _new_ctx):
11786 _prop_closures.set_threaded()
11787 prop = _prop_closures.get(ctx)
11788 nctx = Context()
11789 Z3_del_context(nctx.ctx)
11790 new_ctx = to_ContextObj(_new_ctx)
11791 nctx.ctx = new_ctx
11792 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11793 nctx.owner = False
11794 new_prop = prop.fresh(nctx)
11795 _prop_closures.set(new_prop.id, new_prop)
11796 return new_prop.id
11797
11798
11799def user_prop_fixed(ctx, cb, id, value):
11800 prop = _prop_closures.get(ctx)
11801 old_cb = prop.cb
11802 prop.cb = cb
11803 id = _to_expr_ref(to_Ast(id), prop.ctx())
11804 value = _to_expr_ref(to_Ast(value), prop.ctx())
11805 prop.fixed(id, value)
11806 prop.cb = old_cb
11807
11808def user_prop_created(ctx, cb, id):
11809 prop = _prop_closures.get(ctx)
11810 old_cb = prop.cb
11811 prop.cb = cb
11812 id = _to_expr_ref(to_Ast(id), prop.ctx())
11813 prop.created(id)
11814 prop.cb = old_cb
11815
11816
11817def user_prop_final(ctx, cb):
11818 prop = _prop_closures.get(ctx)
11819 old_cb = prop.cb
11820 prop.cb = cb
11821 prop.final()
11822 prop.cb = old_cb
11823
11824def user_prop_eq(ctx, cb, x, y):
11825 prop = _prop_closures.get(ctx)
11826 old_cb = prop.cb
11827 prop.cb = cb
11828 x = _to_expr_ref(to_Ast(x), prop.ctx())
11829 y = _to_expr_ref(to_Ast(y), prop.ctx())
11830 prop.eq(x, y)
11831 prop.cb = old_cb
11832
11833def user_prop_diseq(ctx, cb, x, y):
11834 prop = _prop_closures.get(ctx)
11835 old_cb = prop.cb
11836 prop.cb = cb
11837 x = _to_expr_ref(to_Ast(x), prop.ctx())
11838 y = _to_expr_ref(to_Ast(y), prop.ctx())
11839 prop.diseq(x, y)
11840 prop.cb = old_cb
11841
11842def user_prop_decide(ctx, cb, t_ref, idx, phase):
11843 prop = _prop_closures.get(ctx)
11844 old_cb = prop.cb
11845 prop.cb = cb
11846 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11847 prop.decide(t, idx, phase)
11848 prop.cb = old_cb
11849
11850def user_prop_binding(ctx, cb, q_ref, inst_ref):
11851 prop = _prop_closures.get(ctx)
11852 old_cb = prop.cb
11853 prop.cb = cb
11854 q = _to_expr_ref(to_Ast(q_ref), prop.ctx())
11855 inst = _to_expr_ref(to_Ast(inst_ref), prop.ctx())
11856 r = prop.binding(q, inst)
11857 prop.cb = old_cb
11858 return r
11859
11860
11861_user_prop_push = Z3_push_eh(user_prop_push)
11862_user_prop_pop = Z3_pop_eh(user_prop_pop)
11863_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11864_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11865_user_prop_created = Z3_created_eh(user_prop_created)
11866_user_prop_final = Z3_final_eh(user_prop_final)
11867_user_prop_eq = Z3_eq_eh(user_prop_eq)
11868_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11869_user_prop_decide = Z3_decide_eh(user_prop_decide)
11870_user_prop_binding = Z3_on_binding_eh(user_prop_binding)
11871
11872
11873def PropagateFunction(name, *sig):
11874 """Create a function that gets tracked by user propagator.
11875 Every term headed by this function symbol is tracked.
11876 If a term is fixed and the fixed callback is registered a
11877 callback is invoked that the term headed by this function is fixed.
11878 """
11879 sig = _get_args(sig)
11880 if z3_debug():
11881 _z3_assert(len(sig) > 0, "At least two arguments expected")
11882 arity = len(sig) - 1
11883 rng = sig[arity]
11884 if z3_debug():
11885 _z3_assert(is_sort(rng), "Z3 sort expected")
11886 dom = (Sort * arity)()
11887 for i in range(arity):
11888 if z3_debug():
11889 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11890 dom[i] = sig[i].ast
11891 ctx = rng.ctx
11892 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11893
11894
11895
11896class UserPropagateBase:
11897
11898 #
11899 # Either solver is set or ctx is set.
11900 # Propagators that are created through callbacks
11901 # to "fresh" inherit the context of that is supplied
11902 # as argument to the callback.
11903 # This context should not be deleted. It is owned by the solver.
11904 #
11905 def __init__(self, s, ctx=None):
11906 assert s is None or ctx is None
11907 ensure_prop_closures()
11908 self.solver = s
11909 self._ctx = None
11910 self.fresh_ctx = None
11911 self.cb = None
11912 self.id = _prop_closures.insert(self)
11913 self.fixed = None
11914 self.final = None
11915 self.eq = None
11916 self.diseq = None
11917 self.decide = None
11918 self.created = None
11919 self.binding = None
11920 if ctx:
11921 self.fresh_ctx = ctx
11922 if s:
11923 Z3_solver_propagate_init(self.ctx_ref(),
11924 s.solver,
11925 ctypes.c_void_p(self.id),
11926 _user_prop_push,
11927 _user_prop_pop,
11928 _user_prop_fresh)
11929
11930 def __del__(self):
11931 if self._ctx:
11932 self._ctx.ctx = None
11933
11934 def ctx(self):
11935 if self.fresh_ctx:
11936 return self.fresh_ctx
11937 else:
11938 return self.solver.ctx
11939
11940 def ctx_ref(self):
11941 return self.ctx().ref()
11942
11943 def add_fixed(self, fixed):
11944 assert not self.fixed
11945 assert not self._ctx
11946 if self.solver:
11947 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
11948 self.fixed = fixed
11949
11950 def add_created(self, created):
11951 assert not self.created
11952 assert not self._ctx
11953 if self.solver:
11954 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
11955 self.created = created
11956
11957 def add_final(self, final):
11958 assert not self.final
11959 assert not self._ctx
11960 if self.solver:
11961 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
11962 self.final = final
11963
11964 def add_eq(self, eq):
11965 assert not self.eq
11966 assert not self._ctx
11967 if self.solver:
11968 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
11969 self.eq = eq
11970
11971 def add_diseq(self, diseq):
11972 assert not self.diseq
11973 assert not self._ctx
11974 if self.solver:
11975 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
11976 self.diseq = diseq
11977
11978 def add_decide(self, decide):
11979 assert not self.decide
11980 assert not self._ctx
11981 if self.solver:
11982 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
11983 self.decide = decide
11984
11985 def add_on_binding(self, binding):
11986 assert not self.binding
11987 assert not self._ctx
11988 if self.solver:
11989 Z3_solver_propagate_on_binding(self.ctx_ref(), self.solver.solver, _user_prop_binding)
11990 self.binding = binding
11991
11992 def push(self):
11993 raise Z3Exception("push needs to be overwritten")
11994
11995 def pop(self, num_scopes):
11996 raise Z3Exception("pop needs to be overwritten")
11997
11998 def fresh(self, new_ctx):
11999 raise Z3Exception("fresh needs to be overwritten")
12000
12001 def add(self, e):
12002 assert not self._ctx
12003 if self.solver:
12004 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
12005 else:
12006 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
12007
12008 #
12009 # Tell the solver to perform the next split on a given term
12010 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
12011 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
12012 #
12013 def next_split(self, t, idx, phase):
12014 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
12015
12016 #
12017 # Propagation can only be invoked as during a fixed or final callback.
12018 #
12019 def propagate(self, e, ids, eqs=[]):
12020 _ids, num_fixed = _to_ast_array(ids)
12021 num_eqs = len(eqs)
12022 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
12023 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
12024 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
12025 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
12026
12027 def conflict(self, deps = [], eqs = []):
12028 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:6239
__deepcopy__(self, memo={})
Definition z3py.py:6176
__init__(self, m=None, ctx=None)
Definition z3py.py:6165
__repr__(self)
Definition z3py.py:6236
__len__(self)
Definition z3py.py:6183
keys(self)
Definition z3py.py:6268
__setitem__(self, k, v)
Definition z3py.py:6220
__contains__(self, key)
Definition z3py.py:6196
__del__(self)
Definition z3py.py:6179
__getitem__(self, key)
Definition z3py.py:6209
reset(self)
Definition z3py.py:6253
__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:6145
translate(self, other_ctx)
Definition z3py.py:6126
__repr__(self)
Definition z3py.py:6148
__len__(self)
Definition z3py.py:6020
__init__(self, v=None, ctx=None)
Definition z3py.py:6005
push(self, v)
Definition z3py.py:6078
__getitem__(self, i)
Definition z3py.py:6033
sexpr(self)
Definition z3py.py:6151
__del__(self)
Definition z3py.py:6016
__setitem__(self, i, v)
Definition z3py.py:6062
__contains__(self, item)
Definition z3py.py:6103
__copy__(self)
Definition z3py.py:6142
resize(self, sz)
Definition z3py.py:6090
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:7033
__eq__(self, other)
Definition z3py.py:7036
__ne__(self, other)
Definition z3py.py:7039
__init__(self, r)
Definition z3py.py:7030
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:5205
create(self)
Definition z3py.py:5244
__init__(self, name, ctx=None)
Definition z3py.py:5200
__repr__(self)
Definition z3py.py:5241
declare(self, name, *args)
Definition z3py.py:5220
declare_core(self, name, rec_name, *args)
Definition z3py.py:5210
constructor(self, idx)
Definition z3py.py:5397
accessor(self, i, j)
Definition z3py.py:5444
num_constructors(self)
Definition z3py.py:5384
recognizer(self, idx)
Definition z3py.py:5416
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:6287
__deepcopy__(self, memo={})
Definition z3py.py:6295
ctx
Definition z3py.py:6292
__repr__(self)
Definition z3py.py:6392
num_args(self)
Definition z3py.py:6302
entry
Definition z3py.py:6291
value(self)
Definition z3py.py:6351
__init__(self, entry, ctx)
Definition z3py.py:6290
__del__(self)
Definition z3py.py:6298
as_list(self)
Definition z3py.py:6373
arg_value(self, idx)
Definition z3py.py:6320
__deepcopy__(self, memo={})
Definition z3py.py:6490
translate(self, other_ctx)
Definition z3py.py:6482
arity(self)
Definition z3py.py:6448
__repr__(self)
Definition z3py.py:6510
num_entries(self)
Definition z3py.py:6432
__init__(self, f, ctx)
Definition z3py.py:6399
__del__(self)
Definition z3py.py:6405
as_list(self)
Definition z3py.py:6493
else_value(self)
Definition z3py.py:6409
entry(self, idx)
Definition z3py.py:6462
__copy__(self)
Definition z3py.py:6487
__deepcopy__(self, memo={})
Definition z3py.py:5950
get(self, i)
Definition z3py.py:5808
prec(self)
Definition z3py.py:5752
translate(self, target)
Definition z3py.py:5924
append(self, *args)
Definition z3py.py:5851
as_expr(self)
Definition z3py.py:5973
assert_exprs(self, *args)
Definition z3py.py:5836
__repr__(self)
Definition z3py.py:5913
__len__(self)
Definition z3py.py:5795
inconsistent(self)
Definition z3py.py:5734
dimacs(self, include_names=True)
Definition z3py.py:5920
__getitem__(self, arg)
Definition z3py.py:5821
size(self)
Definition z3py.py:5782
precision(self)
Definition z3py.py:5773
simplify(self, *arguments, **keywords)
Definition z3py.py:5953
sexpr(self)
Definition z3py.py:5916
add(self, *args)
Definition z3py.py:5873
__del__(self)
Definition z3py.py:5712
convert_model(self, model)
Definition z3py.py:5884
insert(self, *args)
Definition z3py.py:5862
depth(self)
Definition z3py.py:5716
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5702
__copy__(self)
Definition z3py.py:5947
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:6856
eval(self, t, model_completion=False)
Definition z3py.py:6534
translate(self, target)
Definition z3py.py:6821
__getitem__(self, idx)
Definition z3py.py:6735
num_sorts(self)
Definition z3py.py:6660
get_universe(self, s)
Definition z3py.py:6715
get_sort(self, idx)
Definition z3py.py:6675
project(self, vars, fml)
Definition z3py.py:6829
__repr__(self)
Definition z3py.py:6527
__len__(self)
Definition z3py.py:6591
get_interp(self, decl)
Definition z3py.py:6608
__init__(self, m, ctx)
Definition z3py.py:6517
sexpr(self)
Definition z3py.py:6530
sorts(self)
Definition z3py.py:6698
__del__(self)
Definition z3py.py:6523
decls(self)
Definition z3py.py:6780
project_with_witness(self, vars, fml)
Definition z3py.py:6841
update_value(self, x, value)
Definition z3py.py:6799
evaluate(self, t, model_completion=False)
Definition z3py.py:6565
__copy__(self)
Definition z3py.py:6853
__deepcopy__(self, memo={})
Definition z3py.py:5646
__init__(self, descr, ctx=None)
Definition z3py.py:5640
get_kind(self, n)
Definition z3py.py:5668
get_documentation(self, n)
Definition z3py.py:5673
__getitem__(self, arg)
Definition z3py.py:5678
get_name(self, i)
Definition z3py.py:5663
Parameter Sets.
Definition z3py.py:5567
__deepcopy__(self, memo={})
Definition z3py.py:5581
validate(self, ds)
Definition z3py.py:5608
__repr__(self)
Definition z3py.py:5605
__init__(self, ctx=None, params=None)
Definition z3py.py:5573
set(self, name, val)
Definition z3py.py:5588
__del__(self)
Definition z3py.py:5584
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:5264
__init__(self, c, ctx)
Definition z3py.py:5276
Strings, Sequences and Regular expressions.
Definition z3py.py:11022
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7077
assert_and_track(self, a, p)
Definition z3py.py:7246
num_scopes(self)
Definition z3py.py:7158
append(self, *args)
Definition z3py.py:7224
__iadd__(self, fml)
Definition z3py.py:7220
backtrack_level
Definition z3py.py:7080
pop(self, num=1)
Definition z3py.py:7136
import_model_converter(self, other)
Definition z3py.py:7324
assert_exprs(self, *args)
Definition z3py.py:7190
model(self)
Definition z3py.py:7305
set(self, *args, **keys)
Definition z3py.py:7101
__enter__(self)
Definition z3py.py:7094
add(self, *args)
Definition z3py.py:7209
__del__(self)
Definition z3py.py:7090
insert(self, *args)
Definition z3py.py:7235
check(self, *assumptions)
Definition z3py.py:7276
push(self)
Definition z3py.py:7114
__exit__(self, *exc_info)
Definition z3py.py:7098
reset(self)
Definition z3py.py:7176
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:6886
__deepcopy__(self, memo={})
Definition z3py.py:6894
__getattr__(self, name)
Definition z3py.py:6989
__getitem__(self, idx)
Definition z3py.py:6933
__init__(self, stats, ctx)
Definition z3py.py:6889
__repr__(self)
Definition z3py.py:6901
__len__(self)
Definition z3py.py:6919
__del__(self)
Definition z3py.py:6897
get_key_value(self, key)
Definition z3py.py:6969
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_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:5093
SetSort(s)
Sets.
Definition z3py.py:5044
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1261
UGT(a, b)
Definition z3py.py:4352
is_probe(p)
Definition z3py.py:8924
SetDel(s, e)
Definition z3py.py:5104
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:5067
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5164
BitVec(name, bv, ctx=None)
Definition z3py.py:4148
EmptySet(s)
Definition z3py.py:5049
BVMulNoUnderflow(a, b)
Definition z3py.py:4642
CreateDatatypes(*ds)
Definition z3py.py:5285
is_func_decl(a)
Definition z3py.py:890
get_as_array_func(n)
Definition z3py.py:6873
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:5147
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:5510
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1292
is_select(a)
Definition z3py.py:5013
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:8991
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:5125
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:5136
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:5534
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:5080
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9058
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:11512
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5613
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:9041
_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:11173
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:5058
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
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:6860
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:5115
is_as_array(n)
Definition z3py.py:6868
is_store(a)
Definition z3py.py:5026
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:8995
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:5522
IntSort(ctx=None)
Definition z3py.py:3246
is_seq(a)
Definition z3py.py:11194
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:11221
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:5485
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