Z3
 
Loading...
Searching...
No Matches
z3py.py
Go to the documentation of this file.
8
9"""Z3 is a high performance theorem prover developed at Microsoft Research.
10
11Z3 is used in many applications such as: software/hardware verification and testing,
12constraint solving, analysis of hybrid systems, security, biology (in silico analysis),
13and geometrical problems.
14
15
16Please send feedback, comments and/or corrections on the Issue tracker for
17https://github.com/Z3prover/z3.git. Your comments are very valuable.
18
19Small example:
20
21>>> x = Int('x')
22>>> y = Int('y')
23>>> s = Solver()
24>>> s.add(x > 0)
25>>> s.add(x < 2)
26>>> s.add(y == x + 1)
27>>> s.check()
28sat
29>>> m = s.model()
30>>> m[x]
311
32>>> m[y]
332
34
35Z3 exceptions:
36
37>>> try:
38... x = BitVec('x', 32)
39... y = Bool('y')
40... # the expression x + y is type incorrect
41... n = x + y
42... except Z3Exception as ex:
43... print("failed: %s" % ex)
44failed: sort mismatch
45"""
46from . import z3core
47from .z3core import *
48from .z3types import *
49from .z3consts import *
50from .z3printer import *
51from fractions import Fraction
52import sys
53import io
54import math
55import copy
56if sys.version_info.major >= 3:
57 from typing import Iterable, Iterator
58
59from collections.abc import Callable
60from typing import (
61 Any,
62 Iterable,
63 Sequence
64)
65
66
67Z3_DEBUG = __debug__
68
69
71 global Z3_DEBUG
72 return Z3_DEBUG
73
74
75if sys.version_info.major < 3:
76 def _is_int(v):
77 return isinstance(v, (int, long))
78else:
79 def _is_int(v):
80 return isinstance(v, int)
81
82
83def enable_trace(msg):
85
86
89
90
92 major = ctypes.c_uint(0)
93 minor = ctypes.c_uint(0)
94 build = ctypes.c_uint(0)
95 rev = ctypes.c_uint(0)
96 Z3_get_version(major, minor, build, rev)
97 return "%s.%s.%s" % (major.value, minor.value, build.value)
98
99
101 major = ctypes.c_uint(0)
102 minor = ctypes.c_uint(0)
103 build = ctypes.c_uint(0)
104 rev = ctypes.c_uint(0)
105 Z3_get_version(major, minor, build, rev)
106 return (major.value, minor.value, build.value, rev.value)
107
108
110 return Z3_get_full_version()
111
112
113def _z3_assert(cond, msg):
114 if not cond:
115 raise Z3Exception(msg)
116
117
119 _z3_assert(ctypes.c_int(n).value == n, name + " is too large")
120
121
122def open_log(fname):
123 """Log interaction to a file. This function must be invoked immediately after init(). """
124 Z3_open_log(fname)
125
126
128 """Append user-defined string to interaction log. """
130
131
132def to_symbol(s, ctx = None):
133 """Convert an integer or string into a Z3 symbol."""
134 if _is_int(s):
135 return Z3_mk_int_symbol(_get_ctx(ctx).ref(), s)
136 else:
137 return Z3_mk_string_symbol(_get_ctx(ctx).ref(), s)
138
139
140def _symbol2py(ctx, s):
141 """Convert a Z3 symbol back into a Python object. """
142 if Z3_get_symbol_kind(ctx.ref(), s) == Z3_INT_SYMBOL:
143 return "k!%s" % Z3_get_symbol_int(ctx.ref(), s)
144 else:
145 return Z3_get_symbol_string(ctx.ref(), s)
146
147# Hack for having nary functions that can receive one argument that is the
148# list of arguments.
149# Use this when function takes a single list of arguments
150
151
152def _get_args(args):
153 try:
154 if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
155 return args[0]
156 elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)):
157 return [arg for arg in args[0]]
158 elif len(args) == 1 and isinstance(args[0], Iterator):
159 return list(args[0])
160 else:
161 return args
162 except TypeError: # len is not necessarily defined when args is not a sequence (use reflection?)
163 return args
164
165# Use this when function takes multiple arguments
166
167
169 try:
170 if isinstance(args, (set, AstVector, tuple)):
171 return [arg for arg in args]
172 else:
173 return args
174 except Exception:
175 return args
176
177
179 if isinstance(val, bool):
180 return "true" if val else "false"
181 return str(val)
182
183
185 # Do nothing error handler, just avoid exit(0)
186 # The wrappers in z3core.py will raise a Z3Exception if an error is detected
187 return
188
189
190class Context:
191 """A Context manages all other Z3 objects, global configuration options, etc.
192
193 Z3Py uses a default global context. For most applications this is sufficient.
194 An application may use multiple Z3 contexts. Objects created in one context
195 cannot be used in another one. However, several objects may be "translated" from
196 one context to another. It is not safe to access Z3 objects from multiple threads.
197 The only exception is the method `interrupt()` that can be used to interrupt() a long
198 computation.
199 The initialization method receives global configuration options for the new context.
200 """
201
202 def __init__(self, *args, **kws):
203 if z3_debug():
204 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
205 conf = Z3_mk_config()
206 for key in kws:
207 value = kws[key]
208 Z3_set_param_value(conf, str(key).upper(), _to_param_value(value))
209 prev = None
210 for a in args:
211 if prev is None:
212 prev = a
213 else:
214 Z3_set_param_value(conf, str(prev), _to_param_value(a))
215 prev = None
217 self.owner = True
218 self.eh = Z3_set_error_handler(self.ctx, z3_error_handler)
219 Z3_set_ast_print_mode(self.ctx, Z3_PRINT_SMTLIB2_COMPLIANT)
220 Z3_del_config(conf)
221
222 def __del__(self):
223 if Z3_del_context is not None and self.owner:
224 Z3_del_context(self.ctx)
225 self.ctx = None
226 self.eh = None
227
228 def ref(self):
229 """Return a reference to the actual C pointer to the Z3 context."""
230 return self.ctx
231
232 def interrupt(self):
233 """Interrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions.
234
235 This method can be invoked from a thread different from the one executing the
236 interruptible procedure.
237 """
238 Z3_interrupt(self.ref())
239
240 def param_descrs(self):
241 """Return the global parameter description set."""
242 return ParamDescrsRef(Z3_get_global_param_descrs(self.ref()), self)
243
244 def set_ast_print_mode(self, mode):
245 """Set the pretty printing mode for ASTs.
246
247 The following modes are available:
248 - Z3_PRINT_SMTLIB_FULL (0): Print AST nodes in SMTLIB verbose format.
249 - Z3_PRINT_LOW_LEVEL (1): Print AST nodes using a low-level format.
250 - Z3_PRINT_SMTLIB2_COMPLIANT (2): Print AST nodes in SMTLIB 2.x compliant format.
251
252 Example:
253 >>> c = Context()
254 >>> x = Int('x', c)
255 >>> c.set_ast_print_mode(Z3_PRINT_SMTLIB2_COMPLIANT)
256 >>> print(x)
257 x
258 """
259 Z3_set_ast_print_mode(self.ref(), mode)
260
261
262# Global Z3 context
263_main_ctx = None
264
265
266def main_ctx() -> Context:
267 """Return a reference to the global Z3 context.
268
269 >>> x = Real('x')
270 >>> x.ctx == main_ctx()
271 True
272 >>> c = Context()
273 >>> c == main_ctx()
274 False
275 >>> x2 = Real('x', c)
276 >>> x2.ctx == c
277 True
278 >>> eq(x, x2)
279 False
280 """
281 global _main_ctx
282 if _main_ctx is None:
283 _main_ctx = Context()
284 return _main_ctx
285
286
287def _get_ctx(ctx) -> Context:
288 if ctx is None:
289 return main_ctx()
290 else:
291 return ctx
292
293
294def get_ctx(ctx) -> Context:
295 return _get_ctx(ctx)
296
297
298def set_param(*args, **kws):
299 """Set Z3 global (or module) parameters.
300
301 >>> set_param(precision=10)
302 """
303 if z3_debug():
304 _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
305 new_kws = {}
306 for k in kws:
307 v = kws[k]
308 if not set_pp_option(k, v):
309 new_kws[k] = v
310 for key in new_kws:
311 value = new_kws[key]
312 Z3_global_param_set(str(key).upper(), _to_param_value(value))
313 prev = None
314 for a in args:
315 if prev is None:
316 prev = a
317 else:
319 prev = None
320
321
322def reset_params() -> None:
323 """Reset all global (or module) parameters.
324 """
326
327
328def set_option(*args, **kws):
329 """Alias for 'set_param' for backward compatibility.
330 """
331 return set_param(*args, **kws)
332
333
334def get_param(name):
335 """Return the value of a Z3 global (or module) parameter
336
337 >>> get_param('nlsat.reorder')
338 'true'
339 """
340 ptr = (ctypes.c_char_p * 1)()
341 if Z3_global_param_get(str(name), ptr):
342 r = z3core._to_pystr(ptr[0])
343 return r
344 raise Z3Exception("failed to retrieve value for '%s'" % name)
345
346
351
352# Mark objects that use pretty printer
353
354
356 """Superclass for all Z3 objects that have support for pretty printing."""
357
358 def use_pp(self):
359 return True
360
361 def _repr_html_(self):
362 in_html = in_html_mode()
363 set_html_mode(True)
364 res = repr(self)
365 set_html_mode(in_html)
366 return res
367
368
370 """AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions."""
371
372 def __init__(self, ast, ctx=None):
373 self.ast = ast
374 self.ctx = _get_ctx(ctx)
375 Z3_inc_ref(self.ctx.ref(), self.as_ast())
376
377 def __del__(self):
378 if self.ctx.ref() is not None and self.ast is not None and Z3_dec_ref is not None:
379 Z3_dec_ref(self.ctx.ref(), self.as_ast())
380 self.ast = None
381
382 def __deepcopy__(self, memo={}):
383 return _to_ast_ref(self.ast, self.ctx)
384
385 def __str__(self):
386 return obj_to_string(self)
387
388 def __repr__(self):
389 return obj_to_string(self)
390
391 def __eq__(self, other):
392 return self.eq(other)
393
394 def __hash__(self):
395 return self.hash()
396
397 def __nonzero__(self):
398 return self.__bool__()
399
400 def __bool__(self):
401 if is_true(self):
402 return True
403 elif is_false(self):
404 return False
405 elif is_eq(self) and self.num_args() == 2:
406 return self.arg(0).eq(self.arg(1))
407 else:
408 raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
409
410 def sexpr(self):
411 """Return a string representing the AST node in s-expression notation.
412
413 >>> x = Int('x')
414 >>> ((x + 1)*x).sexpr()
415 '(* (+ x 1) x)'
416 """
417 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
418
419 def as_ast(self):
420 """Return a pointer to the corresponding C Z3_ast object."""
421 return self.ast
422
423 def get_id(self):
424 """Return unique identifier for object. It can be used for hash-tables and maps."""
425 return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
426
427 def ctx_ref(self):
428 """Return a reference to the C context where this AST node is stored."""
429 return self.ctx.ref()
430
431 def eq(self, other):
432 """Return `True` if `self` and `other` are structurally identical.
433
434 >>> x = Int('x')
435 >>> n1 = x + 1
436 >>> n2 = 1 + x
437 >>> n1.eq(n2)
438 False
439 >>> n1 = simplify(n1)
440 >>> n2 = simplify(n2)
441 >>> n1.eq(n2)
442 True
443 """
444 if z3_debug():
445 _z3_assert(is_ast(other), "Z3 AST expected")
446 return Z3_is_eq_ast(self.ctx_ref(), self.as_ast(), other.as_ast())
447
448 def translate(self, target):
449 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
450
451 >>> c1 = Context()
452 >>> c2 = Context()
453 >>> x = Int('x', c1)
454 >>> y = Int('y', c2)
455 >>> # Nodes in different contexts can't be mixed.
456 >>> # However, we can translate nodes from one context to another.
457 >>> x.translate(c2) + y
458 x + y
459 """
460 if z3_debug():
461 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
462 return _to_ast_ref(Z3_translate(self.ctx.ref(), self.as_ast(), target.ref()), target)
463
464 def __copy__(self):
465 return self.translate(self.ctx)
466
467 def hash(self):
468 """Return a hashcode for the `self`.
469
470 >>> n1 = simplify(Int('x') + 1)
471 >>> n2 = simplify(2 + Int('x') - 1)
472 >>> n1.hash() == n2.hash()
473 True
474 """
475 return Z3_get_ast_hash(self.ctx_ref(), self.as_ast())
476
477 def py_value(self):
478 """Return a Python value that is equivalent to `self`."""
479 return None
480
481
482def is_ast(a : Any) -> bool:
483 """Return `True` if `a` is an AST node.
484
485 >>> is_ast(10)
486 False
487 >>> is_ast(IntVal(10))
488 True
489 >>> is_ast(Int('x'))
490 True
491 >>> is_ast(BoolSort())
492 True
493 >>> is_ast(Function('f', IntSort(), IntSort()))
494 True
495 >>> is_ast("x")
496 False
497 >>> is_ast(Solver())
498 False
499 """
500 return isinstance(a, AstRef)
501
502
503def eq(a : AstRef, b : AstRef) -> bool:
504 """Return `True` if `a` and `b` are structurally identical AST nodes.
505
506 >>> x = Int('x')
507 >>> y = Int('y')
508 >>> eq(x, y)
509 False
510 >>> eq(x + 1, x + 1)
511 True
512 >>> eq(x + 1, 1 + x)
513 False
514 >>> eq(simplify(x + 1), simplify(1 + x))
515 True
516 """
517 if z3_debug():
518 _z3_assert(is_ast(a) and is_ast(b), "Z3 ASTs expected")
519 return a.eq(b)
520
521
522def _ast_kind(ctx : Context, a : Any) -> int:
523 if is_ast(a):
524 a = a.as_ast()
525 return Z3_get_ast_kind(ctx.ref(), a)
526
527
528def _ctx_from_ast_arg_list(args, default_ctx=None):
529 ctx = None
530 for a in args:
531 if is_ast(a) or is_probe(a):
532 if ctx is None:
533 ctx = a.ctx
534 else:
535 if z3_debug():
536 _z3_assert(ctx == a.ctx, "Context mismatch")
537 if ctx is None:
538 ctx = default_ctx
539 return ctx
540
541
543 return _ctx_from_ast_arg_list(args)
544
545
547 sz = len(args)
548 _args = (FuncDecl * sz)()
549 for i in range(sz):
550 _args[i] = args[i].as_func_decl()
551 return _args, sz
552
553
555 sz = len(args)
556 _args = (Ast * sz)()
557 for i in range(sz):
558 _args[i] = args[i].as_ast()
559 return _args, sz
560
561
562def _to_ref_array(ref, args):
563 sz = len(args)
564 _args = (ref * sz)()
565 for i in range(sz):
566 _args[i] = args[i].as_ast()
567 return _args, sz
568
569
570def _to_ast_ref(a, ctx):
571 k = _ast_kind(ctx, a)
572 if k == Z3_SORT_AST:
573 return _to_sort_ref(a, ctx)
574 elif k == Z3_FUNC_DECL_AST:
575 return _to_func_decl_ref(a, ctx)
576 else:
577 return _to_expr_ref(a, ctx)
578
579
580
585
586def _sort_kind(ctx, s):
587 return Z3_get_sort_kind(ctx.ref(), s)
588
589
591 """A Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node."""
592
593 def as_ast(self):
594 return Z3_sort_to_ast(self.ctx_ref(), self.astast)
595
596 def get_id(self):
597 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
598
599 def kind(self):
600 """Return the Z3 internal kind of a sort.
601 This method can be used to test if `self` is one of the Z3 builtin sorts.
602
603 >>> b = BoolSort()
604 >>> b.kind() == Z3_BOOL_SORT
605 True
606 >>> b.kind() == Z3_INT_SORT
607 False
608 >>> A = ArraySort(IntSort(), IntSort())
609 >>> A.kind() == Z3_ARRAY_SORT
610 True
611 >>> A.kind() == Z3_INT_SORT
612 False
613 """
614 return _sort_kind(self.ctxctx, self.astast)
615
616 def subsort(self, other):
617 """Return `True` if `self` is a subsort of `other`.
618
619 >>> IntSort().subsort(RealSort())
620 True
621 """
622 return False
623
624 def cast(self, val):
625 """Try to cast `val` as an element of sort `self`.
626
627 This method is used in Z3Py to convert Python objects such as integers,
628 floats, longs and strings into Z3 expressions.
629
630 >>> x = Int('x')
631 >>> RealSort().cast(x)
632 ToReal(x)
633 """
634 if z3_debug():
635 _z3_assert(is_expr(val), "Z3 expression expected")
636 _z3_assert(self.eq(val.sort()), "Sort mismatch")
637 return val
638
639 def name(self):
640 """Return the name (string) of sort `self`.
641
642 >>> BoolSort().name()
643 'Bool'
644 >>> ArraySort(IntSort(), IntSort()).name()
645 'Array'
646 """
647 return _symbol2py(self.ctxctx, Z3_get_sort_name(self.ctx_ref(), self.astast))
648
649 def __eq__(self, other):
650 """Return `True` if `self` and `other` are the same Z3 sort.
651
652 >>> p = Bool('p')
653 >>> p.sort() == BoolSort()
654 True
655 >>> p.sort() == IntSort()
656 False
657 """
658 if other is None:
659 return False
660 return Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
661
662 def __ne__(self, other):
663 """Return `True` if `self` and `other` are not the same Z3 sort.
664
665 >>> p = Bool('p')
666 >>> p.sort() != BoolSort()
667 False
668 >>> p.sort() != IntSort()
669 True
670 """
671 return not Z3_is_eq_sort(self.ctx_ref(), self.astast, other.ast)
672
673 def __gt__(self, other):
674 """Create the function space Array(self, other)"""
675 return ArraySort(self, other)
676
677 def __hash__(self):
678 """ Hash code. """
679 return AstRef.__hash__(self)
680
681
682def is_sort(s : Any) -> bool:
683 """Return `True` if `s` is a Z3 sort.
684
685 >>> is_sort(IntSort())
686 True
687 >>> is_sort(Int('x'))
688 False
689 >>> is_expr(Int('x'))
690 True
691 """
692 return isinstance(s, SortRef)
693
694
695def _to_sort_ref(s, ctx):
696 if z3_debug():
697 _z3_assert(isinstance(s, Sort), "Z3 Sort expected")
698 k = _sort_kind(ctx, s)
699 if k == Z3_BOOL_SORT:
700 return BoolSortRef(s, ctx)
701 elif k == Z3_INT_SORT or k == Z3_REAL_SORT:
702 return ArithSortRef(s, ctx)
703 elif k == Z3_BV_SORT:
704 return BitVecSortRef(s, ctx)
705 elif k == Z3_ARRAY_SORT:
706 return ArraySortRef(s, ctx)
707 elif k == Z3_DATATYPE_SORT:
708 return DatatypeSortRef(s, ctx)
709 elif k == Z3_FINITE_DOMAIN_SORT:
710 return FiniteDomainSortRef(s, ctx)
711 elif k == Z3_FLOATING_POINT_SORT:
712 return FPSortRef(s, ctx)
713 elif k == Z3_ROUNDING_MODE_SORT:
714 return FPRMSortRef(s, ctx)
715 elif k == Z3_RE_SORT:
716 return ReSortRef(s, ctx)
717 elif k == Z3_SEQ_SORT:
718 return SeqSortRef(s, ctx)
719 elif k == Z3_CHAR_SORT:
720 return CharSortRef(s, ctx)
721 elif k == Z3_TYPE_VAR:
722 return TypeVarRef(s, ctx)
723 return SortRef(s, ctx)
724
725
726def _sort(ctx : Context, a : Any) -> SortRef:
727 return _to_sort_ref(Z3_get_sort(ctx.ref(), a), ctx)
728
729
730def DeclareSort(name, ctx= None) -> SortRef:
731 """Create a new uninterpreted sort named `name`.
732
733 If `ctx=None`, then the new sort is declared in the global Z3Py context.
734
735 >>> A = DeclareSort('A')
736 >>> a = Const('a', A)
737 >>> b = Const('b', A)
738 >>> a.sort() == A
739 True
740 >>> b.sort() == A
741 True
742 >>> a == b
743 a == b
744 """
745 ctx = _get_ctx(ctx)
746 return SortRef(Z3_mk_uninterpreted_sort(ctx.ref(), to_symbol(name, ctx)), ctx)
747
749 """Type variable reference"""
750
751 def subsort(self, other):
752 return True
753
754 def cast(self, val):
755 return val
756
757
758def DeclareTypeVar(name, ctx=None):
759 """Create a new type variable named `name`.
760
761 If `ctx=None`, then the new sort is declared in the global Z3Py context.
762
763 """
764 ctx = _get_ctx(ctx)
765 return TypeVarRef(Z3_mk_type_variable(ctx.ref(), to_symbol(name, ctx)), ctx)
766
767
768
773
774
776 """Function declaration. Every constant and function have an associated declaration.
777
778 The declaration assigns a name, a sort (i.e., type), and for function
779 the sort (i.e., type) of each of its arguments. Note that, in Z3,
780 a constant is a function with 0 arguments.
781 """
782
783 def as_ast(self):
784 return Z3_func_decl_to_ast(self.ctx_ref(), self.astast)
785
786 def get_id(self):
787 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
788
789 def as_func_decl(self):
790 return self.astast
791
792 def name(self):
793 """Return the name of the function declaration `self`.
794
795 >>> f = Function('f', IntSort(), IntSort())
796 >>> f.name()
797 'f'
798 >>> isinstance(f.name(), str)
799 True
800 """
801 return _symbol2py(self.ctxctx, Z3_get_decl_name(self.ctx_ref(), self.astast))
802
803 def arity(self):
804 """Return the number of arguments of a function declaration.
805 If `self` is a constant, then `self.arity()` is 0.
806
807 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
808 >>> f.arity()
809 2
810 """
811 return int(Z3_get_arity(self.ctx_ref(), self.astast))
812
813 def domain(self, i):
814 """Return the sort of the argument `i` of a function declaration.
815 This method assumes that `0 <= i < self.arity()`.
816
817 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
818 >>> f.domain(0)
819 Int
820 >>> f.domain(1)
821 Real
822 """
823 return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.astast, i), self.ctxctx)
824
825 def range(self):
826 """Return the sort of the range of a function declaration.
827 For constants, this is the sort of the constant.
828
829 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
830 >>> f.range()
831 Bool
832 """
833 return _to_sort_ref(Z3_get_range(self.ctx_ref(), self.astast), self.ctxctx)
834
835 def kind(self):
836 """Return the internal kind of a function declaration.
837 It can be used to identify Z3 built-in functions such as addition, multiplication, etc.
838
839 >>> x = Int('x')
840 >>> d = (x + 1).decl()
841 >>> d.kind() == Z3_OP_ADD
842 True
843 >>> d.kind() == Z3_OP_MUL
844 False
845 """
846 return Z3_get_decl_kind(self.ctx_ref(), self.astast)
847
848 def params(self):
849 ctx = self.ctxctx
851 result = [None for i in range(n)]
852 for i in range(n):
853 k = Z3_get_decl_parameter_kind(self.ctx_ref(), self.astast, i)
854 if k == Z3_PARAMETER_INT:
855 result[i] = Z3_get_decl_int_parameter(self.ctx_ref(), self.astast, i)
856 elif k == Z3_PARAMETER_DOUBLE:
857 result[i] = Z3_get_decl_double_parameter(self.ctx_ref(), self.astast, i)
858 elif k == Z3_PARAMETER_RATIONAL:
859 result[i] = Z3_get_decl_rational_parameter(self.ctx_ref(), self.astast, i)
860 elif k == Z3_PARAMETER_SYMBOL:
861 result[i] = Z3_get_decl_symbol_parameter(self.ctx_ref(), self.astast, i)
862 elif k == Z3_PARAMETER_SORT:
863 result[i] = SortRef(Z3_get_decl_sort_parameter(self.ctx_ref(), self.astast, i), ctx)
864 elif k == Z3_PARAMETER_AST:
865 result[i] = ExprRef(Z3_get_decl_ast_parameter(self.ctx_ref(), self.astast, i), ctx)
866 elif k == Z3_PARAMETER_FUNC_DECL:
867 result[i] = FuncDeclRef(Z3_get_decl_func_decl_parameter(self.ctx_ref(), self.astast, i), ctx)
868 elif k == Z3_PARAMETER_INTERNAL:
869 result[i] = "internal parameter"
870 elif k == Z3_PARAMETER_ZSTRING:
871 result[i] = "internal string"
872 else:
873 raise Z3Exception("Unexpected parameter kind")
874 return result
875
876 def __call__(self, *args):
877 """Create a Z3 application expression using the function `self`, and the given arguments.
878
879 The arguments must be Z3 expressions. This method assumes that
880 the sorts of the elements in `args` match the sorts of the
881 domain. Limited coercion is supported. For example, if
882 args[0] is a Python integer, and the function expects a Z3
883 integer, then the argument is automatically converted into a
884 Z3 integer.
885
886 >>> f = Function('f', IntSort(), RealSort(), BoolSort())
887 >>> x = Int('x')
888 >>> y = Real('y')
889 >>> f(x, y)
890 f(x, y)
891 >>> f(x, x)
892 f(x, ToReal(x))
893 """
894 args = _get_args(args)
895 num = len(args)
896 _args = (Ast * num)()
897 saved = []
898 for i in range(num):
899 # self.domain(i).cast(args[i]) may create a new Z3 expression,
900 # then we must save in 'saved' to prevent it from being garbage collected.
901 tmp = self.domain(i).cast(args[i])
902 saved.append(tmp)
903 _args[i] = tmp.as_ast()
904 return _to_expr_ref(Z3_mk_app(self.ctx_ref(), self.astast, len(args), _args), self.ctxctx)
905
906
908 """Return `True` if `a` is a Z3 function declaration.
909
910 >>> f = Function('f', IntSort(), IntSort())
911 >>> is_func_decl(f)
912 True
913 >>> x = Real('x')
914 >>> is_func_decl(x)
915 False
916 """
917 return isinstance(a, FuncDeclRef)
918
919
920def Function(name, *sig):
921 """Create a new Z3 uninterpreted function with the given sorts.
922
923 >>> f = Function('f', IntSort(), IntSort())
924 >>> f(f(0))
925 f(f(0))
926 """
927 sig = _get_args(sig)
928 if z3_debug():
929 _z3_assert(len(sig) > 0, "At least two arguments expected")
930 arity = len(sig) - 1
931 rng = sig[arity]
932 if z3_debug():
933 _z3_assert(is_sort(rng), "Z3 sort expected")
934 dom = (Sort * arity)()
935 for i in range(arity):
936 if z3_debug():
937 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
938 dom[i] = sig[i].ast
939 ctx = rng.ctx
940 return FuncDeclRef(Z3_mk_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
941
942
944 """Create a new fresh Z3 uninterpreted function with the given sorts.
945 """
946 sig = _get_args(sig)
947 if z3_debug():
948 _z3_assert(len(sig) > 0, "At least two arguments expected")
949 arity = len(sig) - 1
950 rng = sig[arity]
951 if z3_debug():
952 _z3_assert(is_sort(rng), "Z3 sort expected")
953 dom = (z3.Sort * arity)()
954 for i in range(arity):
955 if z3_debug():
956 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
957 dom[i] = sig[i].ast
958 ctx = rng.ctx
959 return FuncDeclRef(Z3_mk_fresh_func_decl(ctx.ref(), "f", arity, dom, rng.ast), ctx)
960
961
963 return FuncDeclRef(a, ctx)
964
965
966def RecFunction(name, *sig):
967 """Create a new Z3 recursive with the given sorts."""
968 sig = _get_args(sig)
969 if z3_debug():
970 _z3_assert(len(sig) > 0, "At least two arguments expected")
971 arity = len(sig) - 1
972 rng = sig[arity]
973 if z3_debug():
974 _z3_assert(is_sort(rng), "Z3 sort expected")
975 dom = (Sort * arity)()
976 for i in range(arity):
977 if z3_debug():
978 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
979 dom[i] = sig[i].ast
980 ctx = rng.ctx
981 return FuncDeclRef(Z3_mk_rec_func_decl(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
982
983
984def RecAddDefinition(f, args, body):
985 """Set the body of a recursive function.
986 Recursive definitions can be simplified if they are applied to ground
987 arguments.
988 >>> ctx = Context()
989 >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx))
990 >>> n = Int('n', ctx)
991 >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1)))
992 >>> simplify(fac(5))
993 120
994 >>> s = Solver(ctx=ctx)
995 >>> s.add(fac(n) < 3)
996 >>> s.check()
997 sat
998 >>> s.model().eval(fac(5))
999 120
1000 """
1001 if is_app(args):
1002 args = [args]
1003 ctx = body.ctx
1004 args = _get_args(args)
1005 n = len(args)
1006 _args = (Ast * n)()
1007 for i in range(n):
1008 _args[i] = args[i].ast
1009 Z3_add_rec_def(ctx.ref(), f.ast, n, _args, body.ast)
1010
1011
1016
1017
1019 """Constraints, formulas and terms are expressions in Z3.
1020
1021 Expressions are ASTs. Every expression has a sort.
1022 There are three main kinds of expressions:
1023 function applications, quantifiers and bounded variables.
1024 A constant is a function application with 0 arguments.
1025 For quantifier free problems, all expressions are
1026 function applications.
1027 """
1028
1029 def as_ast(self):
1030 return self.astast
1031
1032 def get_id(self):
1033 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_ast())
1034
1035 def sort(self):
1036 """Return the sort of expression `self`.
1037
1038 >>> x = Int('x')
1039 >>> (x + 1).sort()
1040 Int
1041 >>> y = Real('y')
1042 >>> (x + y).sort()
1043 Real
1044 """
1045 return _sort(self.ctxctx, self.as_astas_ast())
1046
1047 def sort_kind(self):
1048 """Shorthand for `self.sort().kind()`.
1049
1050 >>> a = Array('a', IntSort(), IntSort())
1051 >>> a.sort_kind() == Z3_ARRAY_SORT
1052 True
1053 >>> a.sort_kind() == Z3_INT_SORT
1054 False
1055 """
1056 return self.sort().kind()
1057
1058 def __eq__(self, other):
1059 """Return a Z3 expression that represents the constraint `self == other`.
1060
1061 If `other` is `None`, then this method simply returns `False`.
1062
1063 >>> a = Int('a')
1064 >>> b = Int('b')
1065 >>> a == b
1066 a == b
1067 >>> a is None
1068 False
1069 """
1070 if other is None:
1071 return False
1072 a, b = _coerce_exprs(self, other)
1073 return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctx)
1074
1075 def __hash__(self):
1076 """ Hash code. """
1077 return AstRef.__hash__(self)
1078
1079 def __ne__(self, other):
1080 """Return a Z3 expression that represents the constraint `self != other`.
1081
1082 If `other` is `None`, then this method simply returns `True`.
1083
1084 >>> a = Int('a')
1085 >>> b = Int('b')
1086 >>> a != b
1087 a != b
1088 >>> a is not None
1089 True
1090 """
1091 if other is None:
1092 return True
1093 a, b = _coerce_exprs(self, other)
1094 _args, sz = _to_ast_array((a, b))
1095 return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctxctx)
1096
1097 def params(self):
1098 return self.decl().params()
1099
1100 def decl(self):
1101 """Return the Z3 function declaration associated with a Z3 application.
1102
1103 >>> f = Function('f', IntSort(), IntSort())
1104 >>> a = Int('a')
1105 >>> t = f(a)
1106 >>> eq(t.decl(), f)
1107 True
1108 >>> (a + 1).decl()
1109 +
1110 """
1111 if z3_debug():
1112 _z3_assert(is_app(self), "Z3 application expected")
1113 return FuncDeclRef(Z3_get_app_decl(self.ctx_ref(), self.as_astas_ast()), self.ctxctx)
1114
1115 def kind(self):
1116 """Return the Z3 internal kind of a function application."""
1117 if z3_debug():
1118 _z3_assert(is_app(self), "Z3 application expected")
1120
1121
1122 def num_args(self):
1123 """Return the number of arguments of a Z3 application.
1124
1125 >>> a = Int('a')
1126 >>> b = Int('b')
1127 >>> (a + b).num_args()
1128 2
1129 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1130 >>> t = f(a, b, 0)
1131 >>> t.num_args()
1132 3
1133 """
1134 if z3_debug():
1135 _z3_assert(is_app(self), "Z3 application expected")
1136 return int(Z3_get_app_num_args(self.ctx_ref(), self.as_astas_ast()))
1137
1138 def arg(self, idx):
1139 """Return argument `idx` of the application `self`.
1140
1141 This method assumes that `self` is a function application with at least `idx+1` arguments.
1142
1143 >>> a = Int('a')
1144 >>> b = Int('b')
1145 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1146 >>> t = f(a, b, 0)
1147 >>> t.arg(0)
1148 a
1149 >>> t.arg(1)
1150 b
1151 >>> t.arg(2)
1152 0
1153 """
1154 if z3_debug():
1155 _z3_assert(is_app(self), "Z3 application expected")
1156 _z3_assert(idx < self.num_args(), "Invalid argument index")
1157 return _to_expr_ref(Z3_get_app_arg(self.ctx_ref(), self.as_astas_ast(), idx), self.ctxctx)
1158
1159 def children(self):
1160 """Return a list containing the children of the given expression
1161
1162 >>> a = Int('a')
1163 >>> b = Int('b')
1164 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort())
1165 >>> t = f(a, b, 0)
1166 >>> t.children()
1167 [a, b, 0]
1168 """
1169 if is_app(self):
1170 return [self.arg(i) for i in range(self.num_args())]
1171 else:
1172 return []
1173
1174 def update(self, *args):
1175 """Update the arguments of the expression.
1176
1177 Return a new expression with the same function declaration and updated arguments.
1178 The number of new arguments must match the current number of arguments.
1179
1180 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1181 >>> a = Int('a')
1182 >>> b = Int('b')
1183 >>> c = Int('c')
1184 >>> t = f(a, b)
1185 >>> t.update(c, c)
1186 f(c, c)
1187 """
1188 if z3_debug():
1189 _z3_assert(is_app(self), "Z3 application expected")
1190 _z3_assert(len(args) == self.num_args(), "Number of arguments does not match")
1191 _z3_assert(all([is_expr(arg) for arg in args]), "Z3 expressions expected")
1192 num = len(args)
1193 _args = (Ast * num)()
1194 for i in range(num):
1195 _args[i] = args[i].as_ast()
1196 return _to_expr_ref(Z3_update_term(self.ctx_ref(), self.as_astas_ast(), num, _args), self.ctxctx)
1197
1198 def from_string(self, s):
1199 pass
1200
1201 def serialize(self):
1202 s = Solver()
1203 f = Function('F', self.sort(), BoolSort(self.ctx))
1204 s.add(f(self))
1205 return s.sexpr()
1206
1208 """inverse function to the serialize method on ExprRef.
1209 It is made available to make it easier for users to serialize expressions back and forth between
1210 strings. Solvers can be serialized using the 'sexpr()' method.
1211 """
1212 s = Solver()
1213 s.from_string(st)
1214 if len(s.assertions()) != 1:
1215 raise Z3Exception("single assertion expected")
1216 fml = s.assertions()[0]
1217 if fml.num_args() != 1:
1218 raise Z3Exception("dummy function 'F' expected")
1219 return fml.arg(0)
1220
1221def _to_expr_ref(a, ctx):
1222 if isinstance(a, Pattern):
1223 return PatternRef(a, ctx)
1224 ctx_ref = ctx.ref()
1225 k = Z3_get_ast_kind(ctx_ref, a)
1226 if k == Z3_QUANTIFIER_AST:
1227 return QuantifierRef(a, ctx)
1228 sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a))
1229 if sk == Z3_BOOL_SORT:
1230 return BoolRef(a, ctx)
1231 if sk == Z3_INT_SORT:
1232 if k == Z3_NUMERAL_AST:
1233 return IntNumRef(a, ctx)
1234 return ArithRef(a, ctx)
1235 if sk == Z3_REAL_SORT:
1236 if k == Z3_NUMERAL_AST:
1237 return RatNumRef(a, ctx)
1238 if _is_algebraic(ctx, a):
1239 return AlgebraicNumRef(a, ctx)
1240 return ArithRef(a, ctx)
1241 if sk == Z3_BV_SORT:
1242 if k == Z3_NUMERAL_AST:
1243 return BitVecNumRef(a, ctx)
1244 else:
1245 return BitVecRef(a, ctx)
1246 if sk == Z3_ARRAY_SORT:
1247 return ArrayRef(a, ctx)
1248 if sk == Z3_DATATYPE_SORT:
1249 return DatatypeRef(a, ctx)
1250 if sk == Z3_FLOATING_POINT_SORT:
1251 if k == Z3_APP_AST and _is_numeral(ctx, a):
1252 return FPNumRef(a, ctx)
1253 else:
1254 return FPRef(a, ctx)
1255 if sk == Z3_FINITE_DOMAIN_SORT:
1256 if k == Z3_NUMERAL_AST:
1257 return FiniteDomainNumRef(a, ctx)
1258 else:
1259 return FiniteDomainRef(a, ctx)
1260 if sk == Z3_ROUNDING_MODE_SORT:
1261 return FPRMRef(a, ctx)
1262 if sk == Z3_SEQ_SORT:
1263 return SeqRef(a, ctx)
1264 if sk == Z3_CHAR_SORT:
1265 return CharRef(a, ctx)
1266 if sk == Z3_RE_SORT:
1267 return ReRef(a, ctx)
1268 return ExprRef(a, ctx)
1269
1270
1272 if is_expr(a):
1273 s1 = a.sort()
1274 if s is None:
1275 return s1
1276 if s1.eq(s):
1277 return s
1278 elif s.subsort(s1):
1279 return s1
1280 elif s1.subsort(s):
1281 return s
1282 else:
1283 if z3_debug():
1284 _z3_assert(s1.ctx == s.ctx, "context mismatch")
1285 _z3_assert(False, "sort mismatch")
1286 else:
1287 return s
1288
1289def _check_same_sort(a, b, ctx=None):
1290 if not isinstance(a, ExprRef):
1291 return False
1292 if not isinstance(b, ExprRef):
1293 return False
1294 if ctx is None:
1295 ctx = a.ctx
1296
1297 a_sort = Z3_get_sort(ctx.ctx, a.ast)
1298 b_sort = Z3_get_sort(ctx.ctx, b.ast)
1299 return Z3_is_eq_sort(ctx.ctx, a_sort, b_sort)
1300
1301
1302def _coerce_exprs(a, b, ctx=None):
1303 if not is_expr(a) and not is_expr(b):
1304 a = _py2expr(a, ctx)
1305 b = _py2expr(b, ctx)
1306 if isinstance(a, str) and isinstance(b, SeqRef):
1307 a = StringVal(a, b.ctx)
1308 if isinstance(b, str) and isinstance(a, SeqRef):
1309 b = StringVal(b, a.ctx)
1310 if isinstance(a, float) and isinstance(b, ArithRef):
1311 a = RealVal(a, b.ctx)
1312 if isinstance(b, float) and isinstance(a, ArithRef):
1313 b = RealVal(b, a.ctx)
1314
1315 if _check_same_sort(a, b, ctx):
1316 return (a, b)
1317
1318 s = None
1319 s = _coerce_expr_merge(s, a)
1320 s = _coerce_expr_merge(s, b)
1321 a = s.cast(a)
1322 b = s.cast(b)
1323 return (a, b)
1324
1325
1326def _reduce(func, sequence, initial):
1327 result = initial
1328 for element in sequence:
1329 result = func(result, element)
1330 return result
1331
1332
1333def _coerce_expr_list(alist, ctx=None):
1334 has_expr = False
1335 for a in alist:
1336 if is_expr(a):
1337 has_expr = True
1338 break
1339 if not has_expr:
1340 alist = [_py2expr(a, ctx) for a in alist]
1341 s = _reduce(_coerce_expr_merge, alist, None)
1342 return [s.cast(a) for a in alist]
1343
1344
1345def is_expr(a):
1346 """Return `True` if `a` is a Z3 expression.
1347
1348 >>> a = Int('a')
1349 >>> is_expr(a)
1350 True
1351 >>> is_expr(a + 1)
1352 True
1353 >>> is_expr(IntSort())
1354 False
1355 >>> is_expr(1)
1356 False
1357 >>> is_expr(IntVal(1))
1358 True
1359 >>> x = Int('x')
1360 >>> is_expr(ForAll(x, x >= 0))
1361 True
1362 >>> is_expr(FPVal(1.0))
1363 True
1364 """
1365 return isinstance(a, ExprRef)
1366
1367
1368def is_app(a):
1369 """Return `True` if `a` is a Z3 function application.
1370
1371 Note that, constants are function applications with 0 arguments.
1372
1373 >>> a = Int('a')
1374 >>> is_app(a)
1375 True
1376 >>> is_app(a + 1)
1377 True
1378 >>> is_app(IntSort())
1379 False
1380 >>> is_app(1)
1381 False
1382 >>> is_app(IntVal(1))
1383 True
1384 >>> x = Int('x')
1385 >>> is_app(ForAll(x, x >= 0))
1386 False
1387 """
1388 if not isinstance(a, ExprRef):
1389 return False
1390 k = _ast_kind(a.ctx, a)
1391 return k == Z3_NUMERAL_AST or k == Z3_APP_AST
1392
1393
1395 """Return `True` if `a` is Z3 constant/variable expression.
1396
1397 >>> a = Int('a')
1398 >>> is_const(a)
1399 True
1400 >>> is_const(a + 1)
1401 False
1402 >>> is_const(1)
1403 False
1404 >>> is_const(IntVal(1))
1405 True
1406 >>> x = Int('x')
1407 >>> is_const(ForAll(x, x >= 0))
1408 False
1409 """
1410 return is_app(a) and a.num_args() == 0
1411
1412
1413def is_var(a):
1414 """Return `True` if `a` is variable.
1415
1416 Z3 uses de-Bruijn indices for representing bound variables in
1417 quantifiers.
1418
1419 >>> x = Int('x')
1420 >>> is_var(x)
1421 False
1422 >>> is_const(x)
1423 True
1424 >>> f = Function('f', IntSort(), IntSort())
1425 >>> # Z3 replaces x with bound variables when ForAll is executed.
1426 >>> q = ForAll(x, f(x) == x)
1427 >>> b = q.body()
1428 >>> b
1429 f(Var(0)) == Var(0)
1430 >>> b.arg(1)
1431 Var(0)
1432 >>> is_var(b.arg(1))
1433 True
1434 """
1435 return is_expr(a) and _ast_kind(a.ctx, a) == Z3_VAR_AST
1436
1437
1439 """Return the de-Bruijn index of the Z3 bounded variable `a`.
1440
1441 >>> x = Int('x')
1442 >>> y = Int('y')
1443 >>> is_var(x)
1444 False
1445 >>> is_const(x)
1446 True
1447 >>> f = Function('f', IntSort(), IntSort(), IntSort())
1448 >>> # Z3 replaces x and y with bound variables when ForAll is executed.
1449 >>> q = ForAll([x, y], f(x, y) == x + y)
1450 >>> q.body()
1451 f(Var(1), Var(0)) == Var(1) + Var(0)
1452 >>> b = q.body()
1453 >>> b.arg(0)
1454 f(Var(1), Var(0))
1455 >>> v1 = b.arg(0).arg(0)
1456 >>> v2 = b.arg(0).arg(1)
1457 >>> v1
1458 Var(1)
1459 >>> v2
1460 Var(0)
1461 >>> get_var_index(v1)
1462 1
1463 >>> get_var_index(v2)
1464 0
1465 """
1466 if z3_debug():
1467 _z3_assert(is_var(a), "Z3 bound variable expected")
1468 return int(Z3_get_index_value(a.ctx.ref(), a.as_ast()))
1469
1470
1471def is_app_of(a, k):
1472 """Return `True` if `a` is an application of the given kind `k`.
1473
1474 >>> x = Int('x')
1475 >>> n = x + 1
1476 >>> is_app_of(n, Z3_OP_ADD)
1477 True
1478 >>> is_app_of(n, Z3_OP_MUL)
1479 False
1480 """
1481 return is_app(a) and a.kind() == k
1482
1483
1484def If(a, b, c, ctx=None):
1485 """Create a Z3 if-then-else expression.
1486
1487 >>> x = Int('x')
1488 >>> y = Int('y')
1489 >>> max = If(x > y, x, y)
1490 >>> max
1491 If(x > y, x, y)
1492 >>> simplify(max)
1493 If(x <= y, y, x)
1494 """
1495 if isinstance(a, Probe) or isinstance(b, Tactic) or isinstance(c, Tactic):
1496 return Cond(a, b, c, ctx)
1497 else:
1498 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b, c], ctx))
1499 s = BoolSort(ctx)
1500 a = s.cast(a)
1501 b, c = _coerce_exprs(b, c, ctx)
1502 if z3_debug():
1503 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1504 return _to_expr_ref(Z3_mk_ite(ctx.ref(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
1505
1506
1507def Distinct(*args):
1508 """Create a Z3 distinct expression.
1509
1510 >>> x = Int('x')
1511 >>> y = Int('y')
1512 >>> Distinct(x, y)
1513 x != y
1514 >>> z = Int('z')
1515 >>> Distinct(x, y, z)
1516 Distinct(x, y, z)
1517 >>> simplify(Distinct(x, y, z))
1518 Distinct(x, y, z)
1519 >>> simplify(Distinct(x, y, z), blast_distinct=True)
1520 And(Not(x == y), Not(x == z), Not(y == z))
1521 """
1522 args = _get_args(args)
1523 ctx = _ctx_from_ast_arg_list(args)
1524 if z3_debug():
1525 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
1526 args = _coerce_expr_list(args, ctx)
1527 _args, sz = _to_ast_array(args)
1528 return BoolRef(Z3_mk_distinct(ctx.ref(), sz, _args), ctx)
1529
1530
1531def _mk_bin(f, a, b):
1532 args = (Ast * 2)()
1533 if z3_debug():
1534 _z3_assert(a.ctx == b.ctx, "Context mismatch")
1535 args[0] = a.as_ast()
1536 args[1] = b.as_ast()
1537 return f(a.ctx.ref(), 2, args)
1538
1539
1540def Const(name, sort):
1541 """Create a constant of the given sort.
1542
1543 >>> Const('x', IntSort())
1544 x
1545 """
1546 if z3_debug():
1547 _z3_assert(isinstance(sort, SortRef), "Z3 sort expected")
1548 ctx = sort.ctx
1549 return _to_expr_ref(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), sort.ast), ctx)
1550
1551
1552def Consts(names, sort):
1553 """Create several constants of the given sort.
1554
1555 `names` is a string containing the names of all constants to be created.
1556 Blank spaces separate the names of different constants.
1557
1558 >>> x, y, z = Consts('x y z', IntSort())
1559 >>> x + y + z
1560 x + y + z
1561 """
1562 if isinstance(names, str):
1563 names = names.split(" ")
1564 return [Const(name, sort) for name in names]
1565
1566
1567def FreshConst(sort, prefix="c"):
1568 """Create a fresh constant of a specified sort"""
1569 if z3_debug():
1570 _z3_assert(is_sort(sort), f"Z3 sort expected, got {type(sort)}")
1571 ctx = _get_ctx(sort.ctx)
1572 return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
1573
1574
1575def Var(idx : int, s : SortRef) -> ExprRef:
1576 """Create a Z3 free variable. Free variables are used to create quantified formulas.
1577 A free variable with index n is bound when it occurs within the scope of n+1 quantified
1578 declarations.
1579
1580 >>> Var(0, IntSort())
1581 Var(0)
1582 >>> eq(Var(0, IntSort()), Var(0, BoolSort()))
1583 False
1584 """
1585 if z3_debug():
1586 _z3_assert(is_sort(s), "Z3 sort expected")
1587 return _to_expr_ref(Z3_mk_bound(s.ctx_ref(), idx, s.ast), s.ctx)
1588
1589
1590def RealVar(idx: int, ctx=None) -> ExprRef:
1591 """
1592 Create a real free variable. Free variables are used to create quantified formulas.
1593 They are also used to create polynomials.
1594
1595 >>> RealVar(0)
1596 Var(0)
1597 """
1598 return Var(idx, RealSort(ctx))
1599
1600def RealVarVector(n: int, ctx= None):
1601 """
1602 Create a list of Real free variables.
1603 The variables have ids: 0, 1, ..., n-1
1604
1605 >>> x0, x1, x2, x3 = RealVarVector(4)
1606 >>> x2
1607 Var(2)
1608 """
1609 return [RealVar(i, ctx) for i in range(n)]
1610
1611
1616
1617
1619 """Boolean sort."""
1620
1621 def cast(self, val):
1622 """Try to cast `val` as a Boolean.
1623
1624 >>> x = BoolSort().cast(True)
1625 >>> x
1626 True
1627 >>> is_expr(x)
1628 True
1629 >>> is_expr(True)
1630 False
1631 >>> x.sort()
1632 Bool
1633 """
1634 if isinstance(val, bool):
1635 return BoolVal(val, self.ctxctxctx)
1636 if z3_debug():
1637 if not is_expr(val):
1638 msg = "True, False or Z3 Boolean expression expected. Received %s of type %s"
1639 _z3_assert(is_expr(val), msg % (val, type(val)))
1640 if not self.eq(val.sort()):
1641 _z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
1642 return val
1643
1644 def subsort(self, other):
1645 return isinstance(other, ArithSortRef)
1646
1647 def is_int(self):
1648 return True
1649
1650 def is_bool(self):
1651 return True
1652
1653
1655 """All Boolean expressions are instances of this class."""
1656
1657 def sort(self):
1659
1660 def __add__(self, other):
1661 if isinstance(other, BoolRef):
1662 other = If(other, 1, 0)
1663 return If(self, 1, 0) + other
1664
1665 def __radd__(self, other):
1666 return self + other
1667
1668 def __rmul__(self, other):
1669 return self * other
1670
1671 def __mul__(self, other):
1672 """Create the Z3 expression `self * other`.
1673 """
1674 if isinstance(other, int) and other == 1:
1675 return If(self, 1, 0)
1676 if isinstance(other, int) and other == 0:
1677 return IntVal(0, self.ctxctxctx)
1678 if isinstance(other, BoolRef):
1679 other = If(other, 1, 0)
1680 return If(self, other, 0)
1681
1682 def __and__(self, other):
1683 return And(self, other)
1684
1685 def __or__(self, other):
1686 return Or(self, other)
1687
1688 def __xor__(self, other):
1689 return Xor(self, other)
1690
1691 def __invert__(self):
1692 return Not(self)
1693
1694 def py_value(self):
1695 if is_true(self):
1696 return True
1697 if is_false(self):
1698 return False
1699 return None
1700
1701
1702
1703
1704def is_bool(a : Any) -> bool:
1705 """Return `True` if `a` is a Z3 Boolean expression.
1706
1707 >>> p = Bool('p')
1708 >>> is_bool(p)
1709 True
1710 >>> q = Bool('q')
1711 >>> is_bool(And(p, q))
1712 True
1713 >>> x = Real('x')
1714 >>> is_bool(x)
1715 False
1716 >>> is_bool(x == 0)
1717 True
1718 """
1719 return isinstance(a, BoolRef)
1720
1721
1722def is_true(a : Any) -> bool:
1723 """Return `True` if `a` is the Z3 true expression.
1724
1725 >>> p = Bool('p')
1726 >>> is_true(p)
1727 False
1728 >>> is_true(simplify(p == p))
1729 True
1730 >>> x = Real('x')
1731 >>> is_true(x == 0)
1732 False
1733 >>> # True is a Python Boolean expression
1734 >>> is_true(True)
1735 False
1736 """
1737 return is_app_of(a, Z3_OP_TRUE)
1738
1739
1740def is_false(a : Any) -> bool:
1741 """Return `True` if `a` is the Z3 false expression.
1742
1743 >>> p = Bool('p')
1744 >>> is_false(p)
1745 False
1746 >>> is_false(False)
1747 False
1748 >>> is_false(BoolVal(False))
1749 True
1750 """
1751 return is_app_of(a, Z3_OP_FALSE)
1752
1753
1754def is_and(a : Any) -> bool:
1755 """Return `True` if `a` is a Z3 and expression.
1756
1757 >>> p, q = Bools('p q')
1758 >>> is_and(And(p, q))
1759 True
1760 >>> is_and(Or(p, q))
1761 False
1762 """
1763 return is_app_of(a, Z3_OP_AND)
1764
1765
1766def is_or(a : Any) -> bool:
1767 """Return `True` if `a` is a Z3 or expression.
1768
1769 >>> p, q = Bools('p q')
1770 >>> is_or(Or(p, q))
1771 True
1772 >>> is_or(And(p, q))
1773 False
1774 """
1775 return is_app_of(a, Z3_OP_OR)
1776
1777
1778def is_implies(a : Any) -> bool:
1779 """Return `True` if `a` is a Z3 implication expression.
1780
1781 >>> p, q = Bools('p q')
1782 >>> is_implies(Implies(p, q))
1783 True
1784 >>> is_implies(And(p, q))
1785 False
1786 """
1787 return is_app_of(a, Z3_OP_IMPLIES)
1788
1789
1790def is_not(a : Any) -> bool:
1791 """Return `True` if `a` is a Z3 not expression.
1792
1793 >>> p = Bool('p')
1794 >>> is_not(p)
1795 False
1796 >>> is_not(Not(p))
1797 True
1798 """
1799 return is_app_of(a, Z3_OP_NOT)
1800
1801
1802def is_eq(a : Any) -> bool:
1803 """Return `True` if `a` is a Z3 equality expression.
1804
1805 >>> x, y = Ints('x y')
1806 >>> is_eq(x == y)
1807 True
1808 """
1809 return is_app_of(a, Z3_OP_EQ)
1810
1811
1812def is_distinct(a : Any) -> bool:
1813 """Return `True` if `a` is a Z3 distinct expression.
1814
1815 >>> x, y, z = Ints('x y z')
1816 >>> is_distinct(x == y)
1817 False
1818 >>> is_distinct(Distinct(x, y, z))
1819 True
1820 """
1821 return is_app_of(a, Z3_OP_DISTINCT)
1822
1823
1824def BoolSort(ctx=None):
1825 """Return the Boolean Z3 sort. If `ctx=None`, then the global context is used.
1826
1827 >>> BoolSort()
1828 Bool
1829 >>> p = Const('p', BoolSort())
1830 >>> is_bool(p)
1831 True
1832 >>> r = Function('r', IntSort(), IntSort(), BoolSort())
1833 >>> r(0, 1)
1834 r(0, 1)
1835 >>> is_bool(r(0, 1))
1836 True
1837 """
1838 ctx = _get_ctx(ctx)
1839 return BoolSortRef(Z3_mk_bool_sort(ctx.ref()), ctx)
1840
1841
1842def BoolVal(val, ctx=None):
1843 """Return the Boolean value `True` or `False`. If `ctx=None`, then the global context is used.
1844
1845 >>> BoolVal(True)
1846 True
1847 >>> is_true(BoolVal(True))
1848 True
1849 >>> is_true(True)
1850 False
1851 >>> is_false(BoolVal(False))
1852 True
1853 """
1854 ctx = _get_ctx(ctx)
1855 if val:
1856 return BoolRef(Z3_mk_true(ctx.ref()), ctx)
1857 else:
1858 return BoolRef(Z3_mk_false(ctx.ref()), ctx)
1859
1860
1861def Bool(name, ctx=None):
1862 """Return a Boolean constant named `name`. If `ctx=None`, then the global context is used.
1863
1864 >>> p = Bool('p')
1865 >>> q = Bool('q')
1866 >>> And(p, q)
1867 And(p, q)
1868 """
1869 ctx = _get_ctx(ctx)
1870 return BoolRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), BoolSort(ctx).ast), ctx)
1871
1872
1873def Bools(names, ctx=None):
1874 """Return a tuple of Boolean constants.
1875
1876 `names` is a single string containing all names separated by blank spaces.
1877 If `ctx=None`, then the global context is used.
1878
1879 >>> p, q, r = Bools('p q r')
1880 >>> And(p, Or(q, r))
1881 And(p, Or(q, r))
1882 """
1883 ctx = _get_ctx(ctx)
1884 if isinstance(names, str):
1885 names = names.split(" ")
1886 return [Bool(name, ctx) for name in names]
1887
1888
1889def BoolVector(prefix, sz, ctx=None):
1890 """Return a list of Boolean constants of size `sz`.
1891
1892 The constants are named using the given prefix.
1893 If `ctx=None`, then the global context is used.
1894
1895 >>> P = BoolVector('p', 3)
1896 >>> P
1897 [p__0, p__1, p__2]
1898 >>> And(P)
1899 And(p__0, p__1, p__2)
1900 """
1901 return [Bool("%s__%s" % (prefix, i)) for i in range(sz)]
1902
1903
1904def FreshBool(prefix="b", ctx=None):
1905 """Return a fresh Boolean constant in the given context using the given prefix.
1906
1907 If `ctx=None`, then the global context is used.
1908
1909 >>> b1 = FreshBool()
1910 >>> b2 = FreshBool()
1911 >>> eq(b1, b2)
1912 False
1913 """
1914 ctx = _get_ctx(ctx)
1915 return BoolRef(Z3_mk_fresh_const(ctx.ref(), prefix, BoolSort(ctx).ast), ctx)
1916
1917
1918def Implies(a, b, ctx=None):
1919 """Create a Z3 implies expression.
1920
1921 >>> p, q = Bools('p q')
1922 >>> Implies(p, q)
1923 Implies(p, q)
1924 """
1925 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1926 s = BoolSort(ctx)
1927 a = s.cast(a)
1928 b = s.cast(b)
1929 return BoolRef(Z3_mk_implies(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1930
1931
1932def Xor(a, b, ctx=None):
1933 """Create a Z3 Xor expression.
1934
1935 >>> p, q = Bools('p q')
1936 >>> Xor(p, q)
1937 Xor(p, q)
1938 >>> simplify(Xor(p, q))
1939 Not(p == q)
1940 """
1941 ctx = _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))
1942 s = BoolSort(ctx)
1943 a = s.cast(a)
1944 b = s.cast(b)
1945 return BoolRef(Z3_mk_xor(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
1946
1947
1948def Not(a, ctx=None):
1949 """Create a Z3 not expression or probe.
1950
1951 >>> p = Bool('p')
1952 >>> Not(Not(p))
1953 Not(Not(p))
1954 >>> simplify(Not(Not(p)))
1955 p
1956 """
1957 ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx))
1958 if is_probe(a):
1959 # Not is also used to build probes
1960 return Probe(Z3_probe_not(ctx.ref(), a.probe), ctx)
1961 else:
1962 s = BoolSort(ctx)
1963 a = s.cast(a)
1964 return BoolRef(Z3_mk_not(ctx.ref(), a.as_ast()), ctx)
1965
1966
1967def mk_not(a):
1968 if is_not(a):
1969 return a.arg(0)
1970 else:
1971 return Not(a)
1972
1973
1974def _has_probe(args):
1975 """Return `True` if one of the elements of the given collection is a Z3 probe."""
1976 for arg in args:
1977 if is_probe(arg):
1978 return True
1979 return False
1980
1981
1982def And(*args):
1983 """Create a Z3 and-expression or and-probe.
1984
1985 >>> p, q, r = Bools('p q r')
1986 >>> And(p, q, r)
1987 And(p, q, r)
1988 >>> P = BoolVector('p', 5)
1989 >>> And(P)
1990 And(p__0, p__1, p__2, p__3, p__4)
1991 """
1992 last_arg = None
1993 if len(args) > 0:
1994 last_arg = args[len(args) - 1]
1995 if isinstance(last_arg, Context):
1996 ctx = args[len(args) - 1]
1997 args = args[:len(args) - 1]
1998 elif len(args) == 1 and isinstance(args[0], AstVector):
1999 ctx = args[0].ctx
2000 args = [a for a in args[0]]
2001 else:
2002 ctx = None
2003 args = _get_args(args)
2004 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2005 if z3_debug():
2006 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2007 if _has_probe(args):
2008 return _probe_and(args, ctx)
2009 else:
2010 args = _coerce_expr_list(args, ctx)
2011 _args, sz = _to_ast_array(args)
2012 return BoolRef(Z3_mk_and(ctx.ref(), sz, _args), ctx)
2013
2014
2015def Or(*args):
2016 """Create a Z3 or-expression or or-probe.
2017
2018 >>> p, q, r = Bools('p q r')
2019 >>> Or(p, q, r)
2020 Or(p, q, r)
2021 >>> P = BoolVector('p', 5)
2022 >>> Or(P)
2023 Or(p__0, p__1, p__2, p__3, p__4)
2024 """
2025 last_arg = None
2026 if len(args) > 0:
2027 last_arg = args[len(args) - 1]
2028 if isinstance(last_arg, Context):
2029 ctx = args[len(args) - 1]
2030 args = args[:len(args) - 1]
2031 elif len(args) == 1 and isinstance(args[0], AstVector):
2032 ctx = args[0].ctx
2033 args = [a for a in args[0]]
2034 else:
2035 ctx = None
2036 args = _get_args(args)
2037 ctx = _get_ctx(_ctx_from_ast_arg_list(args, ctx))
2038 if z3_debug():
2039 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression or probe")
2040 if _has_probe(args):
2041 return _probe_or(args, ctx)
2042 else:
2043 args = _coerce_expr_list(args, ctx)
2044 _args, sz = _to_ast_array(args)
2045 return BoolRef(Z3_mk_or(ctx.ref(), sz, _args), ctx)
2046
2047
2052
2053
2055 """Patterns are hints for quantifier instantiation.
2056
2057 """
2058
2059 def as_ast(self):
2061
2062 def get_id(self):
2063 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2064
2065
2067 """Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
2068
2069 >>> f = Function('f', IntSort(), IntSort())
2070 >>> x = Int('x')
2071 >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
2072 >>> q
2073 ForAll(x, f(x) == 0)
2074 >>> q.num_patterns()
2075 1
2076 >>> is_pattern(q.pattern(0))
2077 True
2078 >>> q.pattern(0)
2079 f(Var(0))
2080 """
2081 return isinstance(a, PatternRef)
2082
2083
2084def MultiPattern(*args):
2085 """Create a Z3 multi-pattern using the given expressions `*args`
2086
2087 >>> f = Function('f', IntSort(), IntSort())
2088 >>> g = Function('g', IntSort(), IntSort())
2089 >>> x = Int('x')
2090 >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ])
2091 >>> q
2092 ForAll(x, f(x) != g(x))
2093 >>> q.num_patterns()
2094 1
2095 >>> is_pattern(q.pattern(0))
2096 True
2097 >>> q.pattern(0)
2098 MultiPattern(f(Var(0)), g(Var(0)))
2099 """
2100 if z3_debug():
2101 _z3_assert(len(args) > 0, "At least one argument expected")
2102 _z3_assert(all([is_expr(a) for a in args]), "Z3 expressions expected")
2103 ctx = args[0].ctx
2104 args, sz = _to_ast_array(args)
2105 return PatternRef(Z3_mk_pattern(ctx.ref(), sz, args), ctx)
2106
2107
2109 if is_pattern(arg):
2110 return arg
2111 else:
2112 return MultiPattern(arg)
2113
2114
2119
2120
2122 """Universally and Existentially quantified formulas."""
2123
2124 def as_ast(self):
2125 return self.astastast
2126
2127 def get_id(self):
2128 return Z3_get_ast_id(self.ctx_ref(), self.as_astas_astas_ast())
2129
2130 def sort(self):
2131 """Return the Boolean sort or sort of Lambda."""
2132 if self.is_lambda():
2134 return BoolSort(self.ctxctxctxctx)
2135
2136 def is_forall(self):
2137 """Return `True` if `self` is a universal quantifier.
2138
2139 >>> f = Function('f', IntSort(), IntSort())
2140 >>> x = Int('x')
2141 >>> q = ForAll(x, f(x) == 0)
2142 >>> q.is_forall()
2143 True
2144 >>> q = Exists(x, f(x) != 0)
2145 >>> q.is_forall()
2146 False
2147 """
2149
2150 def is_exists(self):
2151 """Return `True` if `self` is an existential quantifier.
2152
2153 >>> f = Function('f', IntSort(), IntSort())
2154 >>> x = Int('x')
2155 >>> q = ForAll(x, f(x) == 0)
2156 >>> q.is_exists()
2157 False
2158 >>> q = Exists(x, f(x) != 0)
2159 >>> q.is_exists()
2160 True
2161 """
2162 return Z3_is_quantifier_exists(self.ctx_ref(), self.astastast)
2163
2164 def is_lambda(self):
2165 """Return `True` if `self` is a lambda expression.
2166
2167 >>> f = Function('f', IntSort(), IntSort())
2168 >>> x = Int('x')
2169 >>> q = Lambda(x, f(x))
2170 >>> q.is_lambda()
2171 True
2172 >>> q = Exists(x, f(x) != 0)
2173 >>> q.is_lambda()
2174 False
2175 """
2176 return Z3_is_lambda(self.ctx_ref(), self.astastast)
2177
2178 def __getitem__(self, arg):
2179 """Return the Z3 expression `self[arg]`.
2180 """
2181 if z3_debug():
2182 _z3_assert(self.is_lambda(), "quantifier should be a lambda expression")
2183 return _array_select(self, arg)
2184
2185 def weight(self):
2186 """Return the weight annotation of `self`.
2187
2188 >>> f = Function('f', IntSort(), IntSort())
2189 >>> x = Int('x')
2190 >>> q = ForAll(x, f(x) == 0)
2191 >>> q.weight()
2192 1
2193 >>> q = ForAll(x, f(x) == 0, weight=10)
2194 >>> q.weight()
2195 10
2196 """
2197 return int(Z3_get_quantifier_weight(self.ctx_ref(), self.astastast))
2198
2199 def skolem_id(self):
2200 """Return the skolem id of `self`.
2201 """
2203
2204 def qid(self):
2205 """Return the quantifier id of `self`.
2206 """
2208
2209 def num_patterns(self):
2210 """Return the number of patterns (i.e., quantifier instantiation hints) in `self`.
2211
2212 >>> f = Function('f', IntSort(), IntSort())
2213 >>> g = Function('g', IntSort(), IntSort())
2214 >>> x = Int('x')
2215 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2216 >>> q.num_patterns()
2217 2
2218 """
2219 return int(Z3_get_quantifier_num_patterns(self.ctx_ref(), self.astastast))
2220
2221 def pattern(self, idx):
2222 """Return a pattern (i.e., quantifier instantiation hints) in `self`.
2223
2224 >>> f = Function('f', IntSort(), IntSort())
2225 >>> g = Function('g', IntSort(), IntSort())
2226 >>> x = Int('x')
2227 >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ])
2228 >>> q.num_patterns()
2229 2
2230 >>> q.pattern(0)
2231 f(Var(0))
2232 >>> q.pattern(1)
2233 g(Var(0))
2234 """
2235 if z3_debug():
2236 _z3_assert(idx < self.num_patterns(), "Invalid pattern idx")
2238
2240 """Return the number of no-patterns."""
2242
2243 def no_pattern(self, idx):
2244 """Return a no-pattern."""
2245 if z3_debug():
2246 _z3_assert(idx < self.num_no_patterns(), "Invalid no-pattern idx")
2248
2249 def body(self):
2250 """Return the expression being quantified.
2251
2252 >>> f = Function('f', IntSort(), IntSort())
2253 >>> x = Int('x')
2254 >>> q = ForAll(x, f(x) == 0)
2255 >>> q.body()
2256 f(Var(0)) == 0
2257 """
2259
2260 def num_vars(self):
2261 """Return the number of variables bounded by this quantifier.
2262
2263 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2264 >>> x = Int('x')
2265 >>> y = Int('y')
2266 >>> q = ForAll([x, y], f(x, y) >= x)
2267 >>> q.num_vars()
2268 2
2269 """
2270 return int(Z3_get_quantifier_num_bound(self.ctx_ref(), self.astastast))
2271
2272 def var_name(self, idx):
2273 """Return a string representing a name used when displaying the quantifier.
2274
2275 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2276 >>> x = Int('x')
2277 >>> y = Int('y')
2278 >>> q = ForAll([x, y], f(x, y) >= x)
2279 >>> q.var_name(0)
2280 'x'
2281 >>> q.var_name(1)
2282 'y'
2283 """
2284 if z3_debug():
2285 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2287
2288 def var_sort(self, idx):
2289 """Return the sort of a bound variable.
2290
2291 >>> f = Function('f', IntSort(), RealSort(), IntSort())
2292 >>> x = Int('x')
2293 >>> y = Real('y')
2294 >>> q = ForAll([x, y], f(x, y) >= x)
2295 >>> q.var_sort(0)
2296 Int
2297 >>> q.var_sort(1)
2298 Real
2299 """
2300 if z3_debug():
2301 _z3_assert(idx < self.num_vars(), "Invalid variable idx")
2303
2304 def children(self):
2305 """Return a list containing a single element self.body()
2306
2307 >>> f = Function('f', IntSort(), IntSort())
2308 >>> x = Int('x')
2309 >>> q = ForAll(x, f(x) == 0)
2310 >>> q.children()
2311 [f(Var(0)) == 0]
2312 """
2313 return [self.body()]
2314
2315
2317 """Return `True` if `a` is a Z3 quantifier.
2318
2319 >>> f = Function('f', IntSort(), IntSort())
2320 >>> x = Int('x')
2321 >>> q = ForAll(x, f(x) == 0)
2322 >>> is_quantifier(q)
2323 True
2324 >>> is_quantifier(f(x))
2325 False
2326 """
2327 return isinstance(a, QuantifierRef)
2328
2329
2330def _mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2331 if z3_debug():
2332 _z3_assert(is_bool(body) or is_app(vs) or (len(vs) > 0 and is_app(vs[0])), "Z3 expression expected")
2333 _z3_assert(is_const(vs) or (len(vs) > 0 and all([is_const(v) for v in vs])), "Invalid bounded variable(s)")
2334 _z3_assert(all([is_pattern(a) or is_expr(a) for a in patterns]), "Z3 patterns expected")
2335 _z3_assert(all([is_expr(p) for p in no_patterns]), "no patterns are Z3 expressions")
2336 if is_app(vs):
2337 ctx = vs.ctx
2338 vs = [vs]
2339 else:
2340 ctx = vs[0].ctx
2341 if not is_expr(body):
2342 body = BoolVal(body, ctx)
2343 num_vars = len(vs)
2344 if num_vars == 0:
2345 return body
2346 _vs = (Ast * num_vars)()
2347 for i in range(num_vars):
2348 # TODO: Check if is constant
2349 _vs[i] = vs[i].as_ast()
2350 patterns = [_to_pattern(p) for p in patterns]
2351 num_pats = len(patterns)
2352 _pats = (Pattern * num_pats)()
2353 for i in range(num_pats):
2354 _pats[i] = patterns[i].ast
2355 _no_pats, num_no_pats = _to_ast_array(no_patterns)
2356 qid = to_symbol(qid, ctx)
2357 skid = to_symbol(skid, ctx)
2358 return QuantifierRef(Z3_mk_quantifier_const_ex(ctx.ref(), is_forall, weight, qid, skid,
2359 num_vars, _vs,
2360 num_pats, _pats,
2361 num_no_pats, _no_pats,
2362 body.as_ast()), ctx)
2363
2364
2365def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2366 """Create a Z3 forall formula.
2367
2368 The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations.
2369
2370 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2371 >>> x = Int('x')
2372 >>> y = Int('y')
2373 >>> ForAll([x, y], f(x, y) >= x)
2374 ForAll([x, y], f(x, y) >= x)
2375 >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ])
2376 ForAll([x, y], f(x, y) >= x)
2377 >>> ForAll([x, y], f(x, y) >= x, weight=10)
2378 ForAll([x, y], f(x, y) >= x)
2379 """
2380 return _mk_quantifier(True, vs, body, weight, qid, skid, patterns, no_patterns)
2381
2382
2383def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
2384 """Create a Z3 exists formula.
2385
2386 The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
2387
2388
2389 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2390 >>> x = Int('x')
2391 >>> y = Int('y')
2392 >>> q = Exists([x, y], f(x, y) >= x, skid="foo")
2393 >>> q
2394 Exists([x, y], f(x, y) >= x)
2395 >>> is_quantifier(q)
2396 True
2397 >>> r = Tactic('nnf')(q).as_expr()
2398 >>> is_quantifier(r)
2399 False
2400 """
2401 return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
2402
2403
2404def Lambda(vs, body):
2405 """Create a Z3 lambda expression.
2406
2407 >>> f = Function('f', IntSort(), IntSort(), IntSort())
2408 >>> mem0 = Array('mem0', IntSort(), IntSort())
2409 >>> lo, hi, e, i = Ints('lo hi e i')
2410 >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
2411 >>> mem1
2412 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
2413 """
2414 ctx = body.ctx
2415 if is_app(vs):
2416 vs = [vs]
2417 num_vars = len(vs)
2418 _vs = (Ast * num_vars)()
2419 for i in range(num_vars):
2420 # TODO: Check if is constant
2421 _vs[i] = vs[i].as_ast()
2422 return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
2423
2424
2429
2430
2432 """Real and Integer sorts."""
2433
2434 def is_real(self):
2435 """Return `True` if `self` is of the sort Real.
2436
2437 >>> x = Real('x')
2438 >>> x.is_real()
2439 True
2440 >>> (x + 1).is_real()
2441 True
2442 >>> x = Int('x')
2443 >>> x.is_real()
2444 False
2445 """
2446 return self.kind() == Z3_REAL_SORT
2447
2448 def is_int(self):
2449 """Return `True` if `self` is of the sort Integer.
2450
2451 >>> x = Int('x')
2452 >>> x.is_int()
2453 True
2454 >>> (x + 1).is_int()
2455 True
2456 >>> x = Real('x')
2457 >>> x.is_int()
2458 False
2459 """
2460 return self.kind() == Z3_INT_SORT
2461
2462 def is_bool(self):
2463 return False
2464
2465 def subsort(self, other):
2466 """Return `True` if `self` is a subsort of `other`."""
2467 return self.is_int() and is_arith_sort(other) and other.is_real()
2468
2469 def cast(self, val):
2470 """Try to cast `val` as an Integer or Real.
2471
2472 >>> IntSort().cast(10)
2473 10
2474 >>> is_int(IntSort().cast(10))
2475 True
2476 >>> is_int(10)
2477 False
2478 >>> RealSort().cast(10)
2479 10
2480 >>> is_real(RealSort().cast(10))
2481 True
2482 """
2483 if is_expr(val):
2484 if z3_debug():
2485 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
2486 val_s = val.sort()
2487 if self.eq(val_s):
2488 return val
2489 if val_s.is_int() and self.is_real():
2490 return ToReal(val)
2491 if val_s.is_bool() and self.is_int():
2492 return If(val, 1, 0)
2493 if val_s.is_bool() and self.is_real():
2494 return ToReal(If(val, 1, 0))
2495 if z3_debug():
2496 _z3_assert(False, "Z3 Integer/Real expression expected")
2497 else:
2498 if self.is_int():
2499 return IntVal(val, self.ctxctxctx)
2500 if self.is_real():
2501 return RealVal(val, self.ctxctxctx)
2502 if z3_debug():
2503 msg = "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s"
2504 _z3_assert(False, msg % self)
2505
2506
2507def is_arith_sort(s : Any) -> bool:
2508 """Return `True` if s is an arithmetical sort (type).
2509
2510 >>> is_arith_sort(IntSort())
2511 True
2512 >>> is_arith_sort(RealSort())
2513 True
2514 >>> is_arith_sort(BoolSort())
2515 False
2516 >>> n = Int('x') + 1
2517 >>> is_arith_sort(n.sort())
2518 True
2519 """
2520 return isinstance(s, ArithSortRef)
2521
2522
2524 """Integer and Real expressions."""
2525
2526 def sort(self):
2527 """Return the sort (type) of the arithmetical expression `self`.
2528
2529 >>> Int('x').sort()
2530 Int
2531 >>> (Real('x') + 1).sort()
2532 Real
2533 """
2535
2536 def is_int(self):
2537 """Return `True` if `self` is an integer expression.
2538
2539 >>> x = Int('x')
2540 >>> x.is_int()
2541 True
2542 >>> (x + 1).is_int()
2543 True
2544 >>> y = Real('y')
2545 >>> (x + y).is_int()
2546 False
2547 """
2548 return self.sortsort().is_int()
2549
2550 def is_real(self):
2551 """Return `True` if `self` is an real expression.
2552
2553 >>> x = Real('x')
2554 >>> x.is_real()
2555 True
2556 >>> (x + 1).is_real()
2557 True
2558 """
2559 return self.sortsort().is_real()
2560
2561 def __add__(self, other):
2562 """Create the Z3 expression `self + other`.
2563
2564 >>> x = Int('x')
2565 >>> y = Int('y')
2566 >>> x + y
2567 x + y
2568 >>> (x + y).sort()
2569 Int
2570 """
2571 a, b = _coerce_exprs(self, other)
2572 return ArithRef(_mk_bin(Z3_mk_add, a, b), self.ctxctxctx)
2573
2574 def __radd__(self, other):
2575 """Create the Z3 expression `other + self`.
2576
2577 >>> x = Int('x')
2578 >>> 10 + x
2579 10 + x
2580 """
2581 a, b = _coerce_exprs(self, other)
2582 return ArithRef(_mk_bin(Z3_mk_add, b, a), self.ctxctxctx)
2583
2584 def __mul__(self, other):
2585 """Create the Z3 expression `self * other`.
2586
2587 >>> x = Real('x')
2588 >>> y = Real('y')
2589 >>> x * y
2590 x*y
2591 >>> (x * y).sort()
2592 Real
2593 """
2594 if isinstance(other, BoolRef):
2595 return If(other, self, 0)
2596 a, b = _coerce_exprs(self, other)
2597 return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctxctxctx)
2598
2599 def __rmul__(self, other):
2600 """Create the Z3 expression `other * self`.
2601
2602 >>> x = Real('x')
2603 >>> 10 * x
2604 10*x
2605 """
2606 a, b = _coerce_exprs(self, other)
2607 return ArithRef(_mk_bin(Z3_mk_mul, b, a), self.ctxctxctx)
2608
2609 def __sub__(self, other):
2610 """Create the Z3 expression `self - other`.
2611
2612 >>> x = Int('x')
2613 >>> y = Int('y')
2614 >>> x - y
2615 x - y
2616 >>> (x - y).sort()
2617 Int
2618 """
2619 a, b = _coerce_exprs(self, other)
2620 return ArithRef(_mk_bin(Z3_mk_sub, a, b), self.ctxctxctx)
2621
2622 def __rsub__(self, other):
2623 """Create the Z3 expression `other - self`.
2624
2625 >>> x = Int('x')
2626 >>> 10 - x
2627 10 - x
2628 """
2629 a, b = _coerce_exprs(self, other)
2630 return ArithRef(_mk_bin(Z3_mk_sub, b, a), self.ctxctxctx)
2631
2632 def __pow__(self, other):
2633 """Create the Z3 expression `self**other` (** is the power operator).
2634
2635 >>> x = Real('x')
2636 >>> x**3
2637 x**3
2638 >>> (x**3).sort()
2639 Real
2640 >>> simplify(IntVal(2)**8)
2641 256
2642 """
2643 a, b = _coerce_exprs(self, other)
2644 return ArithRef(Z3_mk_power(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2645
2646 def __rpow__(self, other):
2647 """Create the Z3 expression `other**self` (** is the power operator).
2648
2649 >>> x = Real('x')
2650 >>> 2**x
2651 2**x
2652 >>> (2**x).sort()
2653 Real
2654 >>> simplify(2**IntVal(8))
2655 256
2656 """
2657 a, b = _coerce_exprs(self, other)
2658 return ArithRef(Z3_mk_power(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2659
2660 def __div__(self, other):
2661 """Create the Z3 expression `other/self`.
2662
2663 >>> x = Int('x')
2664 >>> y = Int('y')
2665 >>> x/y
2666 x/y
2667 >>> (x/y).sort()
2668 Int
2669 >>> (x/y).sexpr()
2670 '(div x y)'
2671 >>> x = Real('x')
2672 >>> y = Real('y')
2673 >>> x/y
2674 x/y
2675 >>> (x/y).sort()
2676 Real
2677 >>> (x/y).sexpr()
2678 '(/ x y)'
2679 """
2680 a, b = _coerce_exprs(self, other)
2681 return ArithRef(Z3_mk_div(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2682
2683 def __truediv__(self, other):
2684 """Create the Z3 expression `other/self`."""
2685 return self.__div__(other)
2686
2687 def __rdiv__(self, other):
2688 """Create the Z3 expression `other/self`.
2689
2690 >>> x = Int('x')
2691 >>> 10/x
2692 10/x
2693 >>> (10/x).sexpr()
2694 '(div 10 x)'
2695 >>> x = Real('x')
2696 >>> 10/x
2697 10/x
2698 >>> (10/x).sexpr()
2699 '(/ 10.0 x)'
2700 """
2701 a, b = _coerce_exprs(self, other)
2702 return ArithRef(Z3_mk_div(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2703
2704 def __rtruediv__(self, other):
2705 """Create the Z3 expression `other/self`."""
2706 return self.__rdiv__(other)
2707
2708 def __mod__(self, other):
2709 """Create the Z3 expression `other%self`.
2710
2711 >>> x = Int('x')
2712 >>> y = Int('y')
2713 >>> x % y
2714 x%y
2715 >>> simplify(IntVal(10) % IntVal(3))
2716 1
2717 """
2718 a, b = _coerce_exprs(self, other)
2719 if z3_debug():
2720 _z3_assert(a.is_int(), "Z3 integer expression expected")
2721 return ArithRef(Z3_mk_mod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2722
2723 def __rmod__(self, other):
2724 """Create the Z3 expression `other%self`.
2725
2726 >>> x = Int('x')
2727 >>> 10 % x
2728 10%x
2729 """
2730 a, b = _coerce_exprs(self, other)
2731 if z3_debug():
2732 _z3_assert(a.is_int(), "Z3 integer expression expected")
2733 return ArithRef(Z3_mk_mod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
2734
2735 def __neg__(self):
2736 """Return an expression representing `-self`.
2737
2738 >>> x = Int('x')
2739 >>> -x
2740 -x
2741 >>> simplify(-(-x))
2742 x
2743 """
2744 return ArithRef(Z3_mk_unary_minus(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
2745
2746 def __pos__(self):
2747 """Return `self`.
2748
2749 >>> x = Int('x')
2750 >>> +x
2751 x
2752 """
2753 return self
2754
2755 def __le__(self, other):
2756 """Create the Z3 expression `other <= self`.
2757
2758 >>> x, y = Ints('x y')
2759 >>> x <= y
2760 x <= y
2761 >>> y = Real('y')
2762 >>> x <= y
2763 ToReal(x) <= y
2764 """
2765 a, b = _coerce_exprs(self, other)
2766 return BoolRef(Z3_mk_le(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2767
2768 def __lt__(self, other):
2769 """Create the Z3 expression `other < self`.
2770
2771 >>> x, y = Ints('x y')
2772 >>> x < y
2773 x < y
2774 >>> y = Real('y')
2775 >>> x < y
2776 ToReal(x) < y
2777 """
2778 a, b = _coerce_exprs(self, other)
2779 return BoolRef(Z3_mk_lt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2780
2781 def __gt__(self, other):
2782 """Create the Z3 expression `other > self`.
2783
2784 >>> x, y = Ints('x y')
2785 >>> x > y
2786 x > y
2787 >>> y = Real('y')
2788 >>> x > y
2789 ToReal(x) > y
2790 """
2791 a, b = _coerce_exprs(self, other)
2792 return BoolRef(Z3_mk_gt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2793
2794 def __ge__(self, other):
2795 """Create the Z3 expression `other >= self`.
2796
2797 >>> x, y = Ints('x y')
2798 >>> x >= y
2799 x >= y
2800 >>> y = Real('y')
2801 >>> x >= y
2802 ToReal(x) >= y
2803 """
2804 a, b = _coerce_exprs(self, other)
2805 return BoolRef(Z3_mk_ge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
2806
2807
2809 """Return `True` if `a` is an arithmetical expression.
2810
2811 >>> x = Int('x')
2812 >>> is_arith(x)
2813 True
2814 >>> is_arith(x + 1)
2815 True
2816 >>> is_arith(1)
2817 False
2818 >>> is_arith(IntVal(1))
2819 True
2820 >>> y = Real('y')
2821 >>> is_arith(y)
2822 True
2823 >>> is_arith(y + 1)
2824 True
2825 """
2826 return isinstance(a, ArithRef)
2827
2828
2829def is_int(a) -> bool:
2830 """Return `True` if `a` is an integer expression.
2831
2832 >>> x = Int('x')
2833 >>> is_int(x + 1)
2834 True
2835 >>> is_int(1)
2836 False
2837 >>> is_int(IntVal(1))
2838 True
2839 >>> y = Real('y')
2840 >>> is_int(y)
2841 False
2842 >>> is_int(y + 1)
2843 False
2844 """
2845 return is_arith(a) and a.is_int()
2846
2847
2848def is_real(a):
2849 """Return `True` if `a` is a real expression.
2850
2851 >>> x = Int('x')
2852 >>> is_real(x + 1)
2853 False
2854 >>> y = Real('y')
2855 >>> is_real(y)
2856 True
2857 >>> is_real(y + 1)
2858 True
2859 >>> is_real(1)
2860 False
2861 >>> is_real(RealVal(1))
2862 True
2863 """
2864 return is_arith(a) and a.is_real()
2865
2866
2867def _is_numeral(ctx, a):
2868 return Z3_is_numeral_ast(ctx.ref(), a)
2869
2870
2871def _is_algebraic(ctx, a):
2872 return Z3_is_algebraic_number(ctx.ref(), a)
2873
2874
2876 """Return `True` if `a` is an integer value of sort Int.
2877
2878 >>> is_int_value(IntVal(1))
2879 True
2880 >>> is_int_value(1)
2881 False
2882 >>> is_int_value(Int('x'))
2883 False
2884 >>> n = Int('x') + 1
2885 >>> n
2886 x + 1
2887 >>> n.arg(1)
2888 1
2889 >>> is_int_value(n.arg(1))
2890 True
2891 >>> is_int_value(RealVal("1/3"))
2892 False
2893 >>> is_int_value(RealVal(1))
2894 False
2895 """
2896 return is_arith(a) and a.is_int() and _is_numeral(a.ctx, a.as_ast())
2897
2898
2900 """Return `True` if `a` is rational value of sort Real.
2901
2902 >>> is_rational_value(RealVal(1))
2903 True
2904 >>> is_rational_value(RealVal("3/5"))
2905 True
2906 >>> is_rational_value(IntVal(1))
2907 False
2908 >>> is_rational_value(1)
2909 False
2910 >>> n = Real('x') + 1
2911 >>> n.arg(1)
2912 1
2913 >>> is_rational_value(n.arg(1))
2914 True
2915 >>> is_rational_value(Real('x'))
2916 False
2917 """
2918 return is_arith(a) and a.is_real() and _is_numeral(a.ctx, a.as_ast())
2919
2920
2922 """Return `True` if `a` is an algebraic value of sort Real.
2923
2924 >>> is_algebraic_value(RealVal("3/5"))
2925 False
2926 >>> n = simplify(Sqrt(2))
2927 >>> n
2928 1.4142135623?
2929 >>> is_algebraic_value(n)
2930 True
2931 """
2932 return is_arith(a) and a.is_real() and _is_algebraic(a.ctx, a.as_ast())
2933
2934
2935def is_add(a : Any) -> bool:
2936 """Return `True` if `a` is an expression of the form b + c.
2937
2938 >>> x, y = Ints('x y')
2939 >>> is_add(x + y)
2940 True
2941 >>> is_add(x - y)
2942 False
2943 """
2944 return is_app_of(a, Z3_OP_ADD)
2945
2946
2947def is_mul(a : Any) -> bool:
2948 """Return `True` if `a` is an expression of the form b * c.
2949
2950 >>> x, y = Ints('x y')
2951 >>> is_mul(x * y)
2952 True
2953 >>> is_mul(x - y)
2954 False
2955 """
2956 return is_app_of(a, Z3_OP_MUL)
2957
2958
2959def is_sub(a : Any) -> bool:
2960 """Return `True` if `a` is an expression of the form b - c.
2961
2962 >>> x, y = Ints('x y')
2963 >>> is_sub(x - y)
2964 True
2965 >>> is_sub(x + y)
2966 False
2967 """
2968 return is_app_of(a, Z3_OP_SUB)
2969
2970
2971def is_div(a : Any) -> bool:
2972 """Return `True` if `a` is an expression of the form b / c.
2973
2974 >>> x, y = Reals('x y')
2975 >>> is_div(x / y)
2976 True
2977 >>> is_div(x + y)
2978 False
2979 >>> x, y = Ints('x y')
2980 >>> is_div(x / y)
2981 False
2982 >>> is_idiv(x / y)
2983 True
2984 """
2985 return is_app_of(a, Z3_OP_DIV)
2986
2987
2988def is_idiv(a : Any) -> bool:
2989 """Return `True` if `a` is an expression of the form b div c.
2990
2991 >>> x, y = Ints('x y')
2992 >>> is_idiv(x / y)
2993 True
2994 >>> is_idiv(x + y)
2995 False
2996 """
2997 return is_app_of(a, Z3_OP_IDIV)
2998
2999
3000def is_mod(a : Any) -> bool:
3001 """Return `True` if `a` is an expression of the form b % c.
3002
3003 >>> x, y = Ints('x y')
3004 >>> is_mod(x % y)
3005 True
3006 >>> is_mod(x + y)
3007 False
3008 """
3009 return is_app_of(a, Z3_OP_MOD)
3010
3011
3012def is_le(a : Any) -> bool:
3013 """Return `True` if `a` is an expression of the form b <= c.
3014
3015 >>> x, y = Ints('x y')
3016 >>> is_le(x <= y)
3017 True
3018 >>> is_le(x < y)
3019 False
3020 """
3021 return is_app_of(a, Z3_OP_LE)
3022
3023
3024def is_lt(a : Any) -> bool:
3025 """Return `True` if `a` is an expression of the form b < c.
3026
3027 >>> x, y = Ints('x y')
3028 >>> is_lt(x < y)
3029 True
3030 >>> is_lt(x == y)
3031 False
3032 """
3033 return is_app_of(a, Z3_OP_LT)
3034
3035
3036def is_ge(a : Any) -> bool:
3037 """Return `True` if `a` is an expression of the form b >= c.
3038
3039 >>> x, y = Ints('x y')
3040 >>> is_ge(x >= y)
3041 True
3042 >>> is_ge(x == y)
3043 False
3044 """
3045 return is_app_of(a, Z3_OP_GE)
3046
3047
3048def is_gt(a : Any) -> bool:
3049 """Return `True` if `a` is an expression of the form b > c.
3050
3051 >>> x, y = Ints('x y')
3052 >>> is_gt(x > y)
3053 True
3054 >>> is_gt(x == y)
3055 False
3056 """
3057 return is_app_of(a, Z3_OP_GT)
3058
3059
3060def is_is_int(a : Any) -> bool:
3061 """Return `True` if `a` is an expression of the form IsInt(b).
3062
3063 >>> x = Real('x')
3064 >>> is_is_int(IsInt(x))
3065 True
3066 >>> is_is_int(x)
3067 False
3068 """
3069 return is_app_of(a, Z3_OP_IS_INT)
3070
3071
3072def is_to_real(a : Any) -> bool:
3073 """Return `True` if `a` is an expression of the form ToReal(b).
3074
3075 >>> x = Int('x')
3076 >>> n = ToReal(x)
3077 >>> n
3078 ToReal(x)
3079 >>> is_to_real(n)
3080 True
3081 >>> is_to_real(x)
3082 False
3083 """
3084 return is_app_of(a, Z3_OP_TO_REAL)
3085
3086
3087def is_to_int(a : Any) -> bool:
3088 """Return `True` if `a` is an expression of the form ToInt(b).
3089
3090 >>> x = Real('x')
3091 >>> n = ToInt(x)
3092 >>> n
3093 ToInt(x)
3094 >>> is_to_int(n)
3095 True
3096 >>> is_to_int(x)
3097 False
3098 """
3099 return is_app_of(a, Z3_OP_TO_INT)
3100
3101
3103 """Integer values."""
3104
3105 def as_long(self):
3106 """Return a Z3 integer numeral as a Python long (bignum) numeral.
3107
3108 >>> v = IntVal(1)
3109 >>> v + 1
3110 1 + 1
3111 >>> v.as_long() + 1
3112 2
3113 """
3114 if z3_debug():
3115 _z3_assert(self.is_int(), "Integer value expected")
3116 return int(self.as_string())
3117
3118 def as_string(self):
3119 """Return a Z3 integer numeral as a Python string.
3120 >>> v = IntVal(100)
3121 >>> v.as_string()
3122 '100'
3123 """
3124 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3125
3127 """Return a Z3 integer numeral as a Python binary string.
3128 >>> v = IntVal(10)
3129 >>> v.as_binary_string()
3130 '1010'
3131 """
3133
3134 def py_value(self):
3135 return self.as_long()
3136
3137
3139 """Rational values."""
3140
3141 def numerator(self):
3142 """ Return the numerator of a Z3 rational numeral.
3143
3144 >>> is_rational_value(RealVal("3/5"))
3145 True
3146 >>> n = RealVal("3/5")
3147 >>> n.numerator()
3148 3
3149 >>> is_rational_value(Q(3,5))
3150 True
3151 >>> Q(3,5).numerator()
3152 3
3153 """
3155
3156 def denominator(self):
3157 """ Return the denominator of a Z3 rational numeral.
3158
3159 >>> is_rational_value(Q(3,5))
3160 True
3161 >>> n = Q(3,5)
3162 >>> n.denominator()
3163 5
3164 """
3165 return IntNumRef(Z3_get_denominator(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctxctx)
3166
3168 """ Return the numerator as a Python long.
3169
3170 >>> v = RealVal(10000000000)
3171 >>> v
3172 10000000000
3173 >>> v + 1
3174 10000000000 + 1
3175 >>> v.numerator_as_long() + 1 == 10000000001
3176 True
3177 """
3178 return self.numerator().as_long()
3179
3181 """ Return the denominator as a Python long.
3182
3183 >>> v = RealVal("1/3")
3184 >>> v
3185 1/3
3186 >>> v.denominator_as_long()
3187 3
3188 """
3189 return self.denominator().as_long()
3190
3191 def is_int(self):
3192 return False
3193
3194 def is_real(self):
3195 return True
3196
3197 def is_int_value(self):
3198 return self.denominator().is_int() and self.denominator_as_long() == 1
3199
3200 def as_long(self):
3201 _z3_assert(self.is_int_value(), "Expected integer fraction")
3202 return self.numerator_as_long()
3203
3204 def as_decimal(self, prec):
3205 """ Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places.
3206
3207 >>> v = RealVal("1/5")
3208 >>> v.as_decimal(3)
3209 '0.2'
3210 >>> v = RealVal("1/3")
3211 >>> v.as_decimal(3)
3212 '0.333?'
3213 """
3214 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3215
3216 def as_string(self):
3217 """Return a Z3 rational numeral as a Python string.
3218
3219 >>> v = Q(3,6)
3220 >>> v.as_string()
3221 '1/2'
3222 """
3223 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
3224
3225 def as_fraction(self):
3226 """Return a Z3 rational as a Python Fraction object.
3227
3228 >>> v = RealVal("1/5")
3229 >>> v.as_fraction()
3230 Fraction(1, 5)
3231 """
3232 return Fraction(self.numerator_as_long(), self.denominator_as_long())
3233
3234 def py_value(self):
3235 return Z3_get_numeral_double(self.ctx_ref(), self.as_astas_ast())
3236
3237
3239 """Algebraic irrational values."""
3240
3241 def approx(self, precision=10):
3242 """Return a Z3 rational number that approximates the algebraic number `self`.
3243 The result `r` is such that |r - self| <= 1/10^precision
3244
3245 >>> x = simplify(Sqrt(2))
3246 >>> x.approx(20)
3247 6838717160008073720548335/4835703278458516698824704
3248 >>> x.approx(5)
3249 2965821/2097152
3250 """
3252
3253 def as_decimal(self, prec):
3254 """Return a string representation of the algebraic number `self` in decimal notation
3255 using `prec` decimal places.
3256
3257 >>> x = simplify(Sqrt(2))
3258 >>> x.as_decimal(10)
3259 '1.4142135623?'
3260 >>> x.as_decimal(20)
3261 '1.41421356237309504880?'
3262 """
3263 return Z3_get_numeral_decimal_string(self.ctx_ref(), self.as_astas_ast(), prec)
3264
3265 def poly(self):
3267
3268 def index(self):
3269 return Z3_algebraic_get_i(self.ctx_ref(), self.as_astas_ast())
3270
3271
3272def _py2expr(a, ctx=None):
3273 if isinstance(a, bool):
3274 return BoolVal(a, ctx)
3275 if _is_int(a):
3276 return IntVal(a, ctx)
3277 if isinstance(a, float):
3278 return RealVal(a, ctx)
3279 if isinstance(a, str):
3280 return StringVal(a, ctx)
3281 if is_expr(a):
3282 return a
3283 if z3_debug():
3284 _z3_assert(False, "Python bool, int, long or float expected")
3285
3286
3287def IntSort(ctx=None):
3288 """Return the integer sort in the given context. If `ctx=None`, then the global context is used.
3289
3290 >>> IntSort()
3291 Int
3292 >>> x = Const('x', IntSort())
3293 >>> is_int(x)
3294 True
3295 >>> x.sort() == IntSort()
3296 True
3297 >>> x.sort() == BoolSort()
3298 False
3299 """
3300 ctx = _get_ctx(ctx)
3301 return ArithSortRef(Z3_mk_int_sort(ctx.ref()), ctx)
3302
3303
3304def RealSort(ctx=None):
3305 """Return the real sort in the given context. If `ctx=None`, then the global context is used.
3306
3307 >>> RealSort()
3308 Real
3309 >>> x = Const('x', RealSort())
3310 >>> is_real(x)
3311 True
3312 >>> is_int(x)
3313 False
3314 >>> x.sort() == RealSort()
3315 True
3316 """
3317 ctx = _get_ctx(ctx)
3318 return ArithSortRef(Z3_mk_real_sort(ctx.ref()), ctx)
3319
3320
3322 if isinstance(val, float):
3323 return str(int(val))
3324 elif isinstance(val, bool):
3325 if val:
3326 return "1"
3327 else:
3328 return "0"
3329 else:
3330 return str(val)
3331
3332
3333def IntVal(val, ctx=None):
3334 """Return a Z3 integer value. If `ctx=None`, then the global context is used.
3335
3336 >>> IntVal(1)
3337 1
3338 >>> IntVal("100")
3339 100
3340 """
3341 ctx = _get_ctx(ctx)
3342 return IntNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), IntSort(ctx).ast), ctx)
3343
3344
3345def RealVal(val, ctx=None):
3346 """Return a Z3 real value.
3347
3348 `val` may be a Python int, long, float or string representing a number in decimal or rational notation.
3349 If `ctx=None`, then the global context is used.
3350
3351 >>> RealVal(1)
3352 1
3353 >>> RealVal(1).sort()
3354 Real
3355 >>> RealVal("3/5")
3356 3/5
3357 >>> RealVal("1.5")
3358 3/2
3359 """
3360 ctx = _get_ctx(ctx)
3361 return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
3362
3363
3364def RatVal(a, b, ctx=None):
3365 """Return a Z3 rational a/b.
3366
3367 If `ctx=None`, then the global context is used.
3368
3369 >>> RatVal(3,5)
3370 3/5
3371 >>> RatVal(3,5).sort()
3372 Real
3373 """
3374 if z3_debug():
3375 _z3_assert(_is_int(a) or isinstance(a, str), "First argument cannot be converted into an integer")
3376 _z3_assert(_is_int(b) or isinstance(b, str), "Second argument cannot be converted into an integer")
3377 if b == 0:
3378 pass # division by 0 is legal in z3 expressions.
3379 return simplify(RealVal(a, ctx) / RealVal(b, ctx))
3380
3381
3382def Q(a, b, ctx=None):
3383 """Return a Z3 rational a/b.
3384
3385 If `ctx=None`, then the global context is used.
3386
3387 >>> Q(3,5)
3388 3/5
3389 >>> Q(3,5).sort()
3390 Real
3391 """
3392 return simplify(RatVal(a, b, ctx=ctx))
3393
3394
3395def Int(name, ctx=None):
3396 """Return an integer constant named `name`. If `ctx=None`, then the global context is used.
3397
3398 >>> x = Int('x')
3399 >>> is_int(x)
3400 True
3401 >>> is_int(x + 1)
3402 True
3403 """
3404 ctx = _get_ctx(ctx)
3405 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), IntSort(ctx).ast), ctx)
3406
3407
3408def Ints(names, ctx=None):
3409 """Return a tuple of Integer constants.
3410
3411 >>> x, y, z = Ints('x y z')
3412 >>> Sum(x, y, z)
3413 x + y + z
3414 """
3415 ctx = _get_ctx(ctx)
3416 if isinstance(names, str):
3417 names = names.split(" ")
3418 return [Int(name, ctx) for name in names]
3419
3420
3421def IntVector(prefix, sz, ctx=None):
3422 """Return a list of integer constants of size `sz`.
3423
3424 >>> X = IntVector('x', 3)
3425 >>> X
3426 [x__0, x__1, x__2]
3427 >>> Sum(X)
3428 x__0 + x__1 + x__2
3429 """
3430 ctx = _get_ctx(ctx)
3431 return [Int("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3432
3433
3434def FreshInt(prefix="x", ctx=None):
3435 """Return a fresh integer constant in the given context using the given prefix.
3436
3437 >>> x = FreshInt()
3438 >>> y = FreshInt()
3439 >>> eq(x, y)
3440 False
3441 >>> x.sort()
3442 Int
3443 """
3444 ctx = _get_ctx(ctx)
3445 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, IntSort(ctx).ast), ctx)
3446
3447
3448def Real(name, ctx=None):
3449 """Return a real constant named `name`. If `ctx=None`, then the global context is used.
3450
3451 >>> x = Real('x')
3452 >>> is_real(x)
3453 True
3454 >>> is_real(x + 1)
3455 True
3456 """
3457 ctx = _get_ctx(ctx)
3458 return ArithRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), RealSort(ctx).ast), ctx)
3459
3460
3461def Reals(names, ctx=None):
3462 """Return a tuple of real constants.
3463
3464 >>> x, y, z = Reals('x y z')
3465 >>> Sum(x, y, z)
3466 x + y + z
3467 >>> Sum(x, y, z).sort()
3468 Real
3469 """
3470 ctx = _get_ctx(ctx)
3471 if isinstance(names, str):
3472 names = names.split(" ")
3473 return [Real(name, ctx) for name in names]
3474
3475
3476def RealVector(prefix, sz, ctx=None):
3477 """Return a list of real constants of size `sz`.
3478
3479 >>> X = RealVector('x', 3)
3480 >>> X
3481 [x__0, x__1, x__2]
3482 >>> Sum(X)
3483 x__0 + x__1 + x__2
3484 >>> Sum(X).sort()
3485 Real
3486 """
3487 ctx = _get_ctx(ctx)
3488 return [Real("%s__%s" % (prefix, i), ctx) for i in range(sz)]
3489
3490
3491def FreshReal(prefix="b", ctx=None):
3492 """Return a fresh real constant in the given context using the given prefix.
3493
3494 >>> x = FreshReal()
3495 >>> y = FreshReal()
3496 >>> eq(x, y)
3497 False
3498 >>> x.sort()
3499 Real
3500 """
3501 ctx = _get_ctx(ctx)
3502 return ArithRef(Z3_mk_fresh_const(ctx.ref(), prefix, RealSort(ctx).ast), ctx)
3503
3504
3505def ToReal(a):
3506 """ Return the Z3 expression ToReal(a).
3507
3508 >>> x = Int('x')
3509 >>> x.sort()
3510 Int
3511 >>> n = ToReal(x)
3512 >>> n
3513 ToReal(x)
3514 >>> n.sort()
3515 Real
3516 """
3517 ctx = a.ctx
3518 if isinstance(a, BoolRef):
3519 return If(a, RealVal(1, ctx), RealVal(0, ctx))
3520 if z3_debug():
3521 _z3_assert(a.is_int(), "Z3 integer expression expected.")
3522 return ArithRef(Z3_mk_int2real(ctx.ref(), a.as_ast()), ctx)
3523
3524
3525def ToInt(a):
3526 """ Return the Z3 expression ToInt(a).
3527
3528 >>> x = Real('x')
3529 >>> x.sort()
3530 Real
3531 >>> n = ToInt(x)
3532 >>> n
3533 ToInt(x)
3534 >>> n.sort()
3535 Int
3536 """
3537 if z3_debug():
3538 _z3_assert(a.is_real(), "Z3 real expression expected.")
3539 ctx = a.ctx
3540 return ArithRef(Z3_mk_real2int(ctx.ref(), a.as_ast()), ctx)
3541
3542
3543def IsInt(a):
3544 """ Return the Z3 predicate IsInt(a).
3545
3546 >>> x = Real('x')
3547 >>> IsInt(x + "1/2")
3548 IsInt(x + 1/2)
3549 >>> solve(IsInt(x + "1/2"), x > 0, x < 1)
3550 [x = 1/2]
3551 >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2")
3552 no solution
3553 """
3554 if z3_debug():
3555 _z3_assert(a.is_real(), "Z3 real expression expected.")
3556 ctx = a.ctx
3557 return BoolRef(Z3_mk_is_int(ctx.ref(), a.as_ast()), ctx)
3558
3559
3560def Sqrt(a, ctx=None):
3561 """ Return a Z3 expression which represents the square root of a.
3562
3563 >>> x = Real('x')
3564 >>> Sqrt(x)
3565 x**(1/2)
3566 """
3567 if not is_expr(a):
3568 ctx = _get_ctx(ctx)
3569 a = RealVal(a, ctx)
3570 return a ** "1/2"
3571
3572
3573def Cbrt(a, ctx=None):
3574 """ Return a Z3 expression which represents the cubic root of a.
3575
3576 >>> x = Real('x')
3577 >>> Cbrt(x)
3578 x**(1/3)
3579 """
3580 if not is_expr(a):
3581 ctx = _get_ctx(ctx)
3582 a = RealVal(a, ctx)
3583 return a ** "1/3"
3584
3585
3590
3591
3593 """Bit-vector sort."""
3594
3595 def size(self):
3596 """Return the size (number of bits) of the bit-vector sort `self`.
3597
3598 >>> b = BitVecSort(32)
3599 >>> b.size()
3600 32
3601 """
3602 return int(Z3_get_bv_sort_size(self.ctx_ref(), self.astastast))
3603
3604 def subsort(self, other):
3605 return is_bv_sort(other) and self.size() < other.size()
3606
3607 def cast(self, val):
3608 """Try to cast `val` as a Bit-Vector.
3609
3610 >>> b = BitVecSort(32)
3611 >>> b.cast(10)
3612 10
3613 >>> b.cast(10).sexpr()
3614 '#x0000000a'
3615 """
3616 if is_expr(val):
3617 if z3_debug():
3618 _z3_assert(self.ctxctxctx == val.ctx, "Context mismatch")
3619 # Idea: use sign_extend if sort of val is a bitvector of smaller size
3620 return val
3621 else:
3622 return BitVecVal(val, self)
3623
3624
3626 """Return True if `s` is a Z3 bit-vector sort.
3627
3628 >>> is_bv_sort(BitVecSort(32))
3629 True
3630 >>> is_bv_sort(IntSort())
3631 False
3632 """
3633 return isinstance(s, BitVecSortRef)
3634
3635
3637 """Bit-vector expressions."""
3638
3639 def sort(self):
3640 """Return the sort of the bit-vector expression `self`.
3641
3642 >>> x = BitVec('x', 32)
3643 >>> x.sort()
3644 BitVec(32)
3645 >>> x.sort() == BitVecSort(32)
3646 True
3647 """
3649
3650 def size(self):
3651 """Return the number of bits of the bit-vector expression `self`.
3652
3653 >>> x = BitVec('x', 32)
3654 >>> (x + 1).size()
3655 32
3656 >>> Concat(x, x).size()
3657 64
3658 """
3659 return self.sortsort().size()
3660
3661 def __add__(self, other):
3662 """Create the Z3 expression `self + other`.
3663
3664 >>> x = BitVec('x', 32)
3665 >>> y = BitVec('y', 32)
3666 >>> x + y
3667 x + y
3668 >>> (x + y).sort()
3669 BitVec(32)
3670 """
3671 a, b = _coerce_exprs(self, other)
3672 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3673
3674 def __radd__(self, other):
3675 """Create the Z3 expression `other + self`.
3676
3677 >>> x = BitVec('x', 32)
3678 >>> 10 + x
3679 10 + x
3680 """
3681 a, b = _coerce_exprs(self, other)
3682 return BitVecRef(Z3_mk_bvadd(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3683
3684 def __mul__(self, other):
3685 """Create the Z3 expression `self * other`.
3686
3687 >>> x = BitVec('x', 32)
3688 >>> y = BitVec('y', 32)
3689 >>> x * y
3690 x*y
3691 >>> (x * y).sort()
3692 BitVec(32)
3693 """
3694 a, b = _coerce_exprs(self, other)
3695 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3696
3697 def __rmul__(self, other):
3698 """Create the Z3 expression `other * self`.
3699
3700 >>> x = BitVec('x', 32)
3701 >>> 10 * x
3702 10*x
3703 """
3704 a, b = _coerce_exprs(self, other)
3705 return BitVecRef(Z3_mk_bvmul(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3706
3707 def __sub__(self, other):
3708 """Create the Z3 expression `self - other`.
3709
3710 >>> x = BitVec('x', 32)
3711 >>> y = BitVec('y', 32)
3712 >>> x - y
3713 x - y
3714 >>> (x - y).sort()
3715 BitVec(32)
3716 """
3717 a, b = _coerce_exprs(self, other)
3718 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3719
3720 def __rsub__(self, other):
3721 """Create the Z3 expression `other - self`.
3722
3723 >>> x = BitVec('x', 32)
3724 >>> 10 - x
3725 10 - x
3726 """
3727 a, b = _coerce_exprs(self, other)
3728 return BitVecRef(Z3_mk_bvsub(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3729
3730 def __or__(self, other):
3731 """Create the Z3 expression bitwise-or `self | other`.
3732
3733 >>> x = BitVec('x', 32)
3734 >>> y = BitVec('y', 32)
3735 >>> x | y
3736 x | y
3737 >>> (x | y).sort()
3738 BitVec(32)
3739 """
3740 a, b = _coerce_exprs(self, other)
3741 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3742
3743 def __ror__(self, other):
3744 """Create the Z3 expression bitwise-or `other | self`.
3745
3746 >>> x = BitVec('x', 32)
3747 >>> 10 | x
3748 10 | x
3749 """
3750 a, b = _coerce_exprs(self, other)
3751 return BitVecRef(Z3_mk_bvor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3752
3753 def __and__(self, other):
3754 """Create the Z3 expression bitwise-and `self & other`.
3755
3756 >>> x = BitVec('x', 32)
3757 >>> y = BitVec('y', 32)
3758 >>> x & y
3759 x & y
3760 >>> (x & y).sort()
3761 BitVec(32)
3762 """
3763 a, b = _coerce_exprs(self, other)
3764 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3765
3766 def __rand__(self, other):
3767 """Create the Z3 expression bitwise-or `other & self`.
3768
3769 >>> x = BitVec('x', 32)
3770 >>> 10 & x
3771 10 & x
3772 """
3773 a, b = _coerce_exprs(self, other)
3774 return BitVecRef(Z3_mk_bvand(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3775
3776 def __xor__(self, other):
3777 """Create the Z3 expression bitwise-xor `self ^ other`.
3778
3779 >>> x = BitVec('x', 32)
3780 >>> y = BitVec('y', 32)
3781 >>> x ^ y
3782 x ^ y
3783 >>> (x ^ y).sort()
3784 BitVec(32)
3785 """
3786 a, b = _coerce_exprs(self, other)
3787 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3788
3789 def __rxor__(self, other):
3790 """Create the Z3 expression bitwise-xor `other ^ self`.
3791
3792 >>> x = BitVec('x', 32)
3793 >>> 10 ^ x
3794 10 ^ x
3795 """
3796 a, b = _coerce_exprs(self, other)
3797 return BitVecRef(Z3_mk_bvxor(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3798
3799 def __pos__(self):
3800 """Return `self`.
3801
3802 >>> x = BitVec('x', 32)
3803 >>> +x
3804 x
3805 """
3806 return self
3807
3808 def __neg__(self):
3809 """Return an expression representing `-self`.
3810
3811 >>> x = BitVec('x', 32)
3812 >>> -x
3813 -x
3814 >>> simplify(-(-x))
3815 x
3816 """
3817 return BitVecRef(Z3_mk_bvneg(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3818
3819 def __invert__(self):
3820 """Create the Z3 expression bitwise-not `~self`.
3821
3822 >>> x = BitVec('x', 32)
3823 >>> ~x
3824 ~x
3825 >>> simplify(~(~x))
3826 x
3827 """
3828 return BitVecRef(Z3_mk_bvnot(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
3829
3830 def __div__(self, other):
3831 """Create the Z3 expression (signed) division `self / other`.
3832
3833 Use the function UDiv() for unsigned division.
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 '(bvsdiv x y)'
3843 >>> UDiv(x, y).sexpr()
3844 '(bvudiv x y)'
3845 """
3846 a, b = _coerce_exprs(self, other)
3847 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3848
3849 def __truediv__(self, other):
3850 """Create the Z3 expression (signed) division `self / other`."""
3851 return self.__div__(other)
3852
3853 def __rdiv__(self, other):
3854 """Create the Z3 expression (signed) division `other / self`.
3855
3856 Use the function UDiv() for unsigned division.
3857
3858 >>> x = BitVec('x', 32)
3859 >>> 10 / x
3860 10/x
3861 >>> (10 / x).sexpr()
3862 '(bvsdiv #x0000000a x)'
3863 >>> UDiv(10, x).sexpr()
3864 '(bvudiv #x0000000a x)'
3865 """
3866 a, b = _coerce_exprs(self, other)
3867 return BitVecRef(Z3_mk_bvsdiv(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3868
3869 def __rtruediv__(self, other):
3870 """Create the Z3 expression (signed) division `other / self`."""
3871 return self.__rdiv__(other)
3872
3873 def __mod__(self, other):
3874 """Create the Z3 expression (signed) mod `self % other`.
3875
3876 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3877
3878 >>> x = BitVec('x', 32)
3879 >>> y = BitVec('y', 32)
3880 >>> x % y
3881 x%y
3882 >>> (x % y).sort()
3883 BitVec(32)
3884 >>> (x % y).sexpr()
3885 '(bvsmod x y)'
3886 >>> URem(x, y).sexpr()
3887 '(bvurem x y)'
3888 >>> SRem(x, y).sexpr()
3889 '(bvsrem x y)'
3890 """
3891 a, b = _coerce_exprs(self, other)
3892 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3893
3894 def __rmod__(self, other):
3895 """Create the Z3 expression (signed) mod `other % self`.
3896
3897 Use the function URem() for unsigned remainder, and SRem() for signed remainder.
3898
3899 >>> x = BitVec('x', 32)
3900 >>> 10 % x
3901 10%x
3902 >>> (10 % x).sexpr()
3903 '(bvsmod #x0000000a x)'
3904 >>> URem(10, x).sexpr()
3905 '(bvurem #x0000000a x)'
3906 >>> SRem(10, x).sexpr()
3907 '(bvsrem #x0000000a x)'
3908 """
3909 a, b = _coerce_exprs(self, other)
3910 return BitVecRef(Z3_mk_bvsmod(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
3911
3912 def __le__(self, other):
3913 """Create the Z3 expression (signed) `other <= self`.
3914
3915 Use the function ULE() for unsigned less than or equal to.
3916
3917 >>> x, y = BitVecs('x y', 32)
3918 >>> x <= y
3919 x <= y
3920 >>> (x <= y).sexpr()
3921 '(bvsle x y)'
3922 >>> ULE(x, y).sexpr()
3923 '(bvule x y)'
3924 """
3925 a, b = _coerce_exprs(self, other)
3926 return BoolRef(Z3_mk_bvsle(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3927
3928 def __lt__(self, other):
3929 """Create the Z3 expression (signed) `other < self`.
3930
3931 Use the function ULT() for unsigned less than.
3932
3933 >>> x, y = BitVecs('x y', 32)
3934 >>> x < y
3935 x < y
3936 >>> (x < y).sexpr()
3937 '(bvslt x y)'
3938 >>> ULT(x, y).sexpr()
3939 '(bvult x y)'
3940 """
3941 a, b = _coerce_exprs(self, other)
3942 return BoolRef(Z3_mk_bvslt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3943
3944 def __gt__(self, other):
3945 """Create the Z3 expression (signed) `other > self`.
3946
3947 Use the function UGT() for unsigned greater than.
3948
3949 >>> x, y = BitVecs('x y', 32)
3950 >>> x > y
3951 x > y
3952 >>> (x > y).sexpr()
3953 '(bvsgt x y)'
3954 >>> UGT(x, y).sexpr()
3955 '(bvugt x y)'
3956 """
3957 a, b = _coerce_exprs(self, other)
3958 return BoolRef(Z3_mk_bvsgt(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3959
3960 def __ge__(self, other):
3961 """Create the Z3 expression (signed) `other >= self`.
3962
3963 Use the function UGE() for unsigned greater than or equal to.
3964
3965 >>> x, y = BitVecs('x y', 32)
3966 >>> x >= y
3967 x >= y
3968 >>> (x >= y).sexpr()
3969 '(bvsge x y)'
3970 >>> UGE(x, y).sexpr()
3971 '(bvuge x y)'
3972 """
3973 a, b = _coerce_exprs(self, other)
3974 return BoolRef(Z3_mk_bvsge(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
3975
3976 def __rshift__(self, other):
3977 """Create the Z3 expression (arithmetical) right shift `self >> other`
3978
3979 Use the function LShR() for the right logical shift
3980
3981 >>> x, y = BitVecs('x y', 32)
3982 >>> x >> y
3983 x >> y
3984 >>> (x >> y).sexpr()
3985 '(bvashr x y)'
3986 >>> LShR(x, y).sexpr()
3987 '(bvlshr x y)'
3988 >>> BitVecVal(4, 3)
3989 4
3990 >>> BitVecVal(4, 3).as_signed_long()
3991 -4
3992 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
3993 -2
3994 >>> simplify(BitVecVal(4, 3) >> 1)
3995 6
3996 >>> simplify(LShR(BitVecVal(4, 3), 1))
3997 2
3998 >>> simplify(BitVecVal(2, 3) >> 1)
3999 1
4000 >>> simplify(LShR(BitVecVal(2, 3), 1))
4001 1
4002 """
4003 a, b = _coerce_exprs(self, other)
4004 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
4005
4006 def __lshift__(self, other):
4007 """Create the Z3 expression left shift `self << other`
4008
4009 >>> x, y = BitVecs('x y', 32)
4010 >>> x << y
4011 x << y
4012 >>> (x << y).sexpr()
4013 '(bvshl x y)'
4014 >>> simplify(BitVecVal(2, 3) << 1)
4015 4
4016 """
4017 a, b = _coerce_exprs(self, other)
4018 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctxctxctx)
4019
4020 def __rrshift__(self, other):
4021 """Create the Z3 expression (arithmetical) right shift `other` >> `self`.
4022
4023 Use the function LShR() for the right logical shift
4024
4025 >>> x = BitVec('x', 32)
4026 >>> 10 >> x
4027 10 >> x
4028 >>> (10 >> x).sexpr()
4029 '(bvashr #x0000000a x)'
4030 """
4031 a, b = _coerce_exprs(self, other)
4032 return BitVecRef(Z3_mk_bvashr(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
4033
4034 def __rlshift__(self, other):
4035 """Create the Z3 expression left shift `other << self`.
4036
4037 Use the function LShR() for the right logical shift
4038
4039 >>> x = BitVec('x', 32)
4040 >>> 10 << x
4041 10 << x
4042 >>> (10 << x).sexpr()
4043 '(bvshl #x0000000a x)'
4044 """
4045 a, b = _coerce_exprs(self, other)
4046 return BitVecRef(Z3_mk_bvshl(self.ctx_ref(), b.as_ast(), a.as_ast()), self.ctxctxctx)
4047
4048
4050 """Bit-vector values."""
4051
4052 def as_long(self):
4053 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4054
4055 >>> v = BitVecVal(0xbadc0de, 32)
4056 >>> v
4057 195936478
4058 >>> print("0x%.8x" % v.as_long())
4059 0x0badc0de
4060 """
4061 return int(self.as_string())
4062
4064 """Return a Z3 bit-vector numeral as a Python long (bignum) numeral.
4065 The most significant bit is assumed to be the sign.
4066
4067 >>> BitVecVal(4, 3).as_signed_long()
4068 -4
4069 >>> BitVecVal(7, 3).as_signed_long()
4070 -1
4071 >>> BitVecVal(3, 3).as_signed_long()
4072 3
4073 >>> BitVecVal(2**32 - 1, 32).as_signed_long()
4074 -1
4075 >>> BitVecVal(2**64 - 1, 64).as_signed_long()
4076 -1
4077 """
4078 sz = self.size()
4079 val = self.as_long()
4080 if val >= 2**(sz - 1):
4081 val = val - 2**sz
4082 if val < -2**(sz - 1):
4083 val = val + 2**sz
4084 return int(val)
4085
4086 def as_string(self):
4087 return Z3_get_numeral_string(self.ctx_ref(), self.as_astas_ast())
4088
4091
4092 def py_value(self):
4093 """Return the Python value of a Z3 bit-vector numeral."""
4094 return self.as_long()
4095
4096
4097
4098def is_bv(a):
4099 """Return `True` if `a` is a Z3 bit-vector expression.
4100
4101 >>> b = BitVec('b', 32)
4102 >>> is_bv(b)
4103 True
4104 >>> is_bv(b + 10)
4105 True
4106 >>> is_bv(Int('x'))
4107 False
4108 """
4109 return isinstance(a, BitVecRef)
4110
4111
4113 """Return `True` if `a` is a Z3 bit-vector numeral value.
4114
4115 >>> b = BitVec('b', 32)
4116 >>> is_bv_value(b)
4117 False
4118 >>> b = BitVecVal(10, 32)
4119 >>> b
4120 10
4121 >>> is_bv_value(b)
4122 True
4123 """
4124 return is_bv(a) and _is_numeral(a.ctx, a.as_ast())
4125
4126
4127def BV2Int(a, is_signed=False):
4128 """Return the Z3 expression BV2Int(a).
4129
4130 >>> b = BitVec('b', 3)
4131 >>> BV2Int(b).sort()
4132 Int
4133 >>> x = Int('x')
4134 >>> x > BV2Int(b)
4135 x > BV2Int(b)
4136 >>> x > BV2Int(b, is_signed=False)
4137 x > BV2Int(b)
4138 >>> x > BV2Int(b, is_signed=True)
4139 x > If(b < 0, BV2Int(b) - 8, BV2Int(b))
4140 >>> solve(x > BV2Int(b), b == 1, x < 3)
4141 [x = 2, b = 1]
4142 """
4143 if z3_debug():
4144 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4145 ctx = a.ctx
4146 # investigate problem with bv2int
4147 return ArithRef(Z3_mk_bv2int(ctx.ref(), a.as_ast(), is_signed), ctx)
4148
4149
4150def Int2BV(a, num_bits):
4151 """Return the z3 expression Int2BV(a, num_bits).
4152 It is a bit-vector of width num_bits and represents the
4153 modulo of a by 2^num_bits
4154 """
4155 ctx = a.ctx
4156 return BitVecRef(Z3_mk_int2bv(ctx.ref(), num_bits, a.as_ast()), ctx)
4157
4158
4159def BitVecSort(sz, ctx=None):
4160 """Return a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used.
4161
4162 >>> Byte = BitVecSort(8)
4163 >>> Word = BitVecSort(16)
4164 >>> Byte
4165 BitVec(8)
4166 >>> x = Const('x', Byte)
4167 >>> eq(x, BitVec('x', 8))
4168 True
4169 """
4170 ctx = _get_ctx(ctx)
4171 return BitVecSortRef(Z3_mk_bv_sort(ctx.ref(), sz), ctx)
4172
4173
4174def BitVecVal(val, bv, ctx=None):
4175 """Return a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used.
4176
4177 >>> v = BitVecVal(10, 32)
4178 >>> v
4179 10
4180 >>> print("0x%.8x" % v.as_long())
4181 0x0000000a
4182 """
4183 if is_bv_sort(bv):
4184 ctx = bv.ctx
4185 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), bv.ast), ctx)
4186 else:
4187 ctx = _get_ctx(ctx)
4188 return BitVecNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), BitVecSort(bv, ctx).ast), ctx)
4189
4190
4191def BitVec(name, bv, ctx=None):
4192 """Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort.
4193 If `ctx=None`, then the global context is used.
4194
4195 >>> x = BitVec('x', 16)
4196 >>> is_bv(x)
4197 True
4198 >>> x.size()
4199 16
4200 >>> x.sort()
4201 BitVec(16)
4202 >>> word = BitVecSort(16)
4203 >>> x2 = BitVec('x', word)
4204 >>> eq(x, x2)
4205 True
4206 """
4207 if isinstance(bv, BitVecSortRef):
4208 ctx = bv.ctx
4209 else:
4210 ctx = _get_ctx(ctx)
4211 bv = BitVecSort(bv, ctx)
4212 return BitVecRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), bv.ast), ctx)
4213
4214
4215def BitVecs(names, bv, ctx=None):
4216 """Return a tuple of bit-vector constants of size bv.
4217
4218 >>> x, y, z = BitVecs('x y z', 16)
4219 >>> x.size()
4220 16
4221 >>> x.sort()
4222 BitVec(16)
4223 >>> Sum(x, y, z)
4224 0 + x + y + z
4225 >>> Product(x, y, z)
4226 1*x*y*z
4227 >>> simplify(Product(x, y, z))
4228 x*y*z
4229 """
4230 ctx = _get_ctx(ctx)
4231 if isinstance(names, str):
4232 names = names.split(" ")
4233 return [BitVec(name, bv, ctx) for name in names]
4234
4235
4236def Concat(*args):
4237 """Create a Z3 bit-vector concatenation expression.
4238
4239 >>> v = BitVecVal(1, 4)
4240 >>> Concat(v, v+1, v)
4241 Concat(Concat(1, 1 + 1), 1)
4242 >>> simplify(Concat(v, v+1, v))
4243 289
4244 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long())
4245 121
4246 """
4247 args = _get_args(args)
4248 sz = len(args)
4249 if z3_debug():
4250 _z3_assert(sz >= 2, "At least two arguments expected.")
4251
4252 ctx = None
4253 for a in args:
4254 if is_expr(a):
4255 ctx = a.ctx
4256 break
4257 if is_seq(args[0]) or isinstance(args[0], str):
4258 args = [_coerce_seq(s, ctx) for s in args]
4259 if z3_debug():
4260 _z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
4261 v = (Ast * sz)()
4262 for i in range(sz):
4263 v[i] = args[i].as_ast()
4264 return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
4265
4266 if is_re(args[0]):
4267 if z3_debug():
4268 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
4269 v = (Ast * sz)()
4270 for i in range(sz):
4271 v[i] = args[i].as_ast()
4272 return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
4273
4274 if z3_debug():
4275 _z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
4276 r = args[0]
4277 for i in range(sz - 1):
4278 r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i + 1].as_ast()), ctx)
4279 return r
4280
4281
4282def Extract(high, low, a):
4283 """Create a Z3 bit-vector extraction expression or sequence extraction expression.
4284
4285 Extract is overloaded to work with both bit-vectors and sequences:
4286
4287 **Bit-vector extraction**: Extract(high, low, bitvector)
4288 Extracts bits from position `high` down to position `low` (both inclusive).
4289 - high: int - the highest bit position to extract (0-indexed from right)
4290 - low: int - the lowest bit position to extract (0-indexed from right)
4291 - bitvector: BitVecRef - the bit-vector to extract from
4292 Returns a new bit-vector containing bits [high:low]
4293
4294 **Sequence extraction**: Extract(sequence, offset, length)
4295 Extracts a subsequence starting at the given offset with the specified length.
4296 The functions SubString and SubSeq are redirected to this form of Extract.
4297 - sequence: SeqRef or str - the sequence to extract from
4298 - offset: int - the starting position (0-indexed)
4299 - length: int - the number of elements to extract
4300 Returns a new sequence containing the extracted subsequence
4301
4302 >>> # Bit-vector extraction examples
4303 >>> x = BitVec('x', 8)
4304 >>> Extract(6, 2, x) # Extract bits 6 down to 2 (5 bits total)
4305 Extract(6, 2, x)
4306 >>> Extract(6, 2, x).sort() # Result is a 5-bit vector
4307 BitVec(5)
4308 >>> Extract(7, 0, x) # Extract all 8 bits
4309 Extract(7, 0, x)
4310 >>> Extract(3, 3, x) # Extract single bit at position 3
4311 Extract(3, 3, x)
4312
4313 >>> # Sequence extraction examples
4314 >>> s = StringVal("hello")
4315 >>> Extract(s, 1, 3) # Extract 3 characters starting at position 1
4316 str.substr("hello", 1, 3)
4317 >>> simplify(Extract(StringVal("abcd"), 2, 1)) # Extract 1 character at position 2
4318 "c"
4319 >>> simplify(Extract(StringVal("abcd"), 0, 2)) # Extract first 2 characters
4320 "ab"
4321 """
4322 if isinstance(high, str):
4323 high = StringVal(high)
4324 if is_seq(high):
4325 s = high
4326 offset, length = _coerce_exprs(low, a, s.ctx)
4327 return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
4328 if z3_debug():
4329 _z3_assert(low <= high, "First argument must be greater than or equal to second argument")
4330 _z3_assert(_is_int(high) and high >= 0 and _is_int(low) and low >= 0,
4331 "First and second arguments must be non negative integers")
4332 _z3_assert(is_bv(a), "Third argument must be a Z3 bit-vector expression")
4333 return BitVecRef(Z3_mk_extract(a.ctx_ref(), high, low, a.as_ast()), a.ctx)
4334
4335
4337 if z3_debug():
4338 _z3_assert(is_bv(a) or is_bv(b), "First or second argument must be a Z3 bit-vector expression")
4339
4340
4341def ULE(a, b):
4342 """Create the Z3 expression (unsigned) `other <= self`.
4343
4344 Use the operator <= for signed less than or equal to.
4345
4346 >>> x, y = BitVecs('x y', 32)
4347 >>> ULE(x, y)
4348 ULE(x, y)
4349 >>> (x <= y).sexpr()
4350 '(bvsle x y)'
4351 >>> ULE(x, y).sexpr()
4352 '(bvule x y)'
4353 """
4354 _check_bv_args(a, b)
4355 a, b = _coerce_exprs(a, b)
4356 return BoolRef(Z3_mk_bvule(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4357
4358
4359def ULT(a, b):
4360 """Create the Z3 expression (unsigned) `other < self`.
4361
4362 Use the operator < for signed less than.
4363
4364 >>> x, y = BitVecs('x y', 32)
4365 >>> ULT(x, y)
4366 ULT(x, y)
4367 >>> (x < y).sexpr()
4368 '(bvslt x y)'
4369 >>> ULT(x, y).sexpr()
4370 '(bvult x y)'
4371 """
4372 _check_bv_args(a, b)
4373 a, b = _coerce_exprs(a, b)
4374 return BoolRef(Z3_mk_bvult(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4375
4376
4377def UGE(a, b):
4378 """Create the Z3 expression (unsigned) `other >= self`.
4379
4380 Use the operator >= for signed greater than or equal to.
4381
4382 >>> x, y = BitVecs('x y', 32)
4383 >>> UGE(x, y)
4384 UGE(x, y)
4385 >>> (x >= y).sexpr()
4386 '(bvsge x y)'
4387 >>> UGE(x, y).sexpr()
4388 '(bvuge x y)'
4389 """
4390 _check_bv_args(a, b)
4391 a, b = _coerce_exprs(a, b)
4392 return BoolRef(Z3_mk_bvuge(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4393
4394
4395def UGT(a, b):
4396 """Create the Z3 expression (unsigned) `other > self`.
4397
4398 Use the operator > for signed greater than.
4399
4400 >>> x, y = BitVecs('x y', 32)
4401 >>> UGT(x, y)
4402 UGT(x, y)
4403 >>> (x > y).sexpr()
4404 '(bvsgt x y)'
4405 >>> UGT(x, y).sexpr()
4406 '(bvugt x y)'
4407 """
4408 _check_bv_args(a, b)
4409 a, b = _coerce_exprs(a, b)
4410 return BoolRef(Z3_mk_bvugt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4411
4412
4413def UDiv(a, b):
4414 """Create the Z3 expression (unsigned) division `self / other`.
4415
4416 Use the operator / for signed division.
4417
4418 >>> x = BitVec('x', 32)
4419 >>> y = BitVec('y', 32)
4420 >>> UDiv(x, y)
4421 UDiv(x, y)
4422 >>> UDiv(x, y).sort()
4423 BitVec(32)
4424 >>> (x / y).sexpr()
4425 '(bvsdiv x y)'
4426 >>> UDiv(x, y).sexpr()
4427 '(bvudiv x y)'
4428 """
4429 _check_bv_args(a, b)
4430 a, b = _coerce_exprs(a, b)
4431 return BitVecRef(Z3_mk_bvudiv(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4432
4433
4434def URem(a, b):
4435 """Create the Z3 expression (unsigned) remainder `self % other`.
4436
4437 Use the operator % for signed modulus, and SRem() for signed remainder.
4438
4439 >>> x = BitVec('x', 32)
4440 >>> y = BitVec('y', 32)
4441 >>> URem(x, y)
4442 URem(x, y)
4443 >>> URem(x, y).sort()
4444 BitVec(32)
4445 >>> (x % y).sexpr()
4446 '(bvsmod x y)'
4447 >>> URem(x, y).sexpr()
4448 '(bvurem x y)'
4449 """
4450 _check_bv_args(a, b)
4451 a, b = _coerce_exprs(a, b)
4452 return BitVecRef(Z3_mk_bvurem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4453
4454
4455def SRem(a, b):
4456 """Create the Z3 expression signed remainder.
4457
4458 Use the operator % for signed modulus, and URem() for unsigned remainder.
4459
4460 >>> x = BitVec('x', 32)
4461 >>> y = BitVec('y', 32)
4462 >>> SRem(x, y)
4463 SRem(x, y)
4464 >>> SRem(x, y).sort()
4465 BitVec(32)
4466 >>> (x % y).sexpr()
4467 '(bvsmod x y)'
4468 >>> SRem(x, y).sexpr()
4469 '(bvsrem x y)'
4470 """
4471 _check_bv_args(a, b)
4472 a, b = _coerce_exprs(a, b)
4473 return BitVecRef(Z3_mk_bvsrem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4474
4475
4476def LShR(a, b):
4477 """Create the Z3 expression logical right shift.
4478
4479 Use the operator >> for the arithmetical right shift.
4480
4481 >>> x, y = BitVecs('x y', 32)
4482 >>> LShR(x, y)
4483 LShR(x, y)
4484 >>> (x >> y).sexpr()
4485 '(bvashr x y)'
4486 >>> LShR(x, y).sexpr()
4487 '(bvlshr x y)'
4488 >>> BitVecVal(4, 3)
4489 4
4490 >>> BitVecVal(4, 3).as_signed_long()
4491 -4
4492 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long()
4493 -2
4494 >>> simplify(BitVecVal(4, 3) >> 1)
4495 6
4496 >>> simplify(LShR(BitVecVal(4, 3), 1))
4497 2
4498 >>> simplify(BitVecVal(2, 3) >> 1)
4499 1
4500 >>> simplify(LShR(BitVecVal(2, 3), 1))
4501 1
4502 """
4503 _check_bv_args(a, b)
4504 a, b = _coerce_exprs(a, b)
4505 return BitVecRef(Z3_mk_bvlshr(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4506
4507
4508def RotateLeft(a, b):
4509 """Return an expression representing `a` rotated to the left `b` times.
4510
4511 >>> a, b = BitVecs('a b', 16)
4512 >>> RotateLeft(a, b)
4513 RotateLeft(a, b)
4514 >>> simplify(RotateLeft(a, 0))
4515 a
4516 >>> simplify(RotateLeft(a, 16))
4517 a
4518 """
4519 _check_bv_args(a, b)
4520 a, b = _coerce_exprs(a, b)
4521 return BitVecRef(Z3_mk_ext_rotate_left(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4522
4523
4524def RotateRight(a, b):
4525 """Return an expression representing `a` rotated to the right `b` times.
4526
4527 >>> a, b = BitVecs('a b', 16)
4528 >>> RotateRight(a, b)
4529 RotateRight(a, b)
4530 >>> simplify(RotateRight(a, 0))
4531 a
4532 >>> simplify(RotateRight(a, 16))
4533 a
4534 """
4535 _check_bv_args(a, b)
4536 a, b = _coerce_exprs(a, b)
4537 return BitVecRef(Z3_mk_ext_rotate_right(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4538
4539
4540def SignExt(n, a):
4541 """Return a bit-vector expression with `n` extra sign-bits.
4542
4543 >>> x = BitVec('x', 16)
4544 >>> n = SignExt(8, x)
4545 >>> n.size()
4546 24
4547 >>> n
4548 SignExt(8, x)
4549 >>> n.sort()
4550 BitVec(24)
4551 >>> v0 = BitVecVal(2, 2)
4552 >>> v0
4553 2
4554 >>> v0.size()
4555 2
4556 >>> v = simplify(SignExt(6, v0))
4557 >>> v
4558 254
4559 >>> v.size()
4560 8
4561 >>> print("%.x" % v.as_long())
4562 fe
4563 """
4564 if z3_debug():
4565 _z3_assert(_is_int(n), "First argument must be an integer")
4566 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4567 return BitVecRef(Z3_mk_sign_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4568
4569
4570def ZeroExt(n, a):
4571 """Return a bit-vector expression with `n` extra zero-bits.
4572
4573 >>> x = BitVec('x', 16)
4574 >>> n = ZeroExt(8, x)
4575 >>> n.size()
4576 24
4577 >>> n
4578 ZeroExt(8, x)
4579 >>> n.sort()
4580 BitVec(24)
4581 >>> v0 = BitVecVal(2, 2)
4582 >>> v0
4583 2
4584 >>> v0.size()
4585 2
4586 >>> v = simplify(ZeroExt(6, v0))
4587 >>> v
4588 2
4589 >>> v.size()
4590 8
4591 """
4592 if z3_debug():
4593 _z3_assert(_is_int(n), "First argument must be an integer")
4594 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4595 return BitVecRef(Z3_mk_zero_ext(a.ctx_ref(), n, a.as_ast()), a.ctx)
4596
4597
4599 """Return an expression representing `n` copies of `a`.
4600
4601 >>> x = BitVec('x', 8)
4602 >>> n = RepeatBitVec(4, x)
4603 >>> n
4604 RepeatBitVec(4, x)
4605 >>> n.size()
4606 32
4607 >>> v0 = BitVecVal(10, 4)
4608 >>> print("%.x" % v0.as_long())
4609 a
4610 >>> v = simplify(RepeatBitVec(4, v0))
4611 >>> v.size()
4612 16
4613 >>> print("%.x" % v.as_long())
4614 aaaa
4615 """
4616 if z3_debug():
4617 _z3_assert(_is_int(n), "First argument must be an integer")
4618 _z3_assert(is_bv(a), "Second argument must be a Z3 bit-vector expression")
4619 return BitVecRef(Z3_mk_repeat(a.ctx_ref(), n, a.as_ast()), a.ctx)
4620
4621
4623 """Return the reduction-and expression of `a`."""
4624 if z3_debug():
4625 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4626 return BitVecRef(Z3_mk_bvredand(a.ctx_ref(), a.as_ast()), a.ctx)
4627
4628
4629def BVRedOr(a):
4630 """Return the reduction-or expression of `a`."""
4631 if z3_debug():
4632 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4633 return BitVecRef(Z3_mk_bvredor(a.ctx_ref(), a.as_ast()), a.ctx)
4634
4635
4636def BVAddNoOverflow(a, b, signed):
4637 """A predicate the determines that bit-vector addition does not overflow"""
4638 _check_bv_args(a, b)
4639 a, b = _coerce_exprs(a, b)
4640 return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4641
4642
4644 """A predicate the determines that signed bit-vector addition does not underflow"""
4645 _check_bv_args(a, b)
4646 a, b = _coerce_exprs(a, b)
4647 return BoolRef(Z3_mk_bvadd_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4648
4649
4651 """A predicate the determines that bit-vector subtraction does not overflow"""
4652 _check_bv_args(a, b)
4653 a, b = _coerce_exprs(a, b)
4654 return BoolRef(Z3_mk_bvsub_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4655
4656
4657def BVSubNoUnderflow(a, b, signed):
4658 """A predicate the determines that bit-vector subtraction does not underflow"""
4659 _check_bv_args(a, b)
4660 a, b = _coerce_exprs(a, b)
4661 return BoolRef(Z3_mk_bvsub_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4662
4663
4665 """A predicate the determines that bit-vector signed division does not overflow"""
4666 _check_bv_args(a, b)
4667 a, b = _coerce_exprs(a, b)
4668 return BoolRef(Z3_mk_bvsdiv_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4669
4670
4672 """A predicate the determines that bit-vector unary negation does not overflow"""
4673 if z3_debug():
4674 _z3_assert(is_bv(a), "First argument must be a Z3 bit-vector expression")
4675 return BoolRef(Z3_mk_bvneg_no_overflow(a.ctx_ref(), a.as_ast()), a.ctx)
4676
4677
4678def BVMulNoOverflow(a, b, signed):
4679 """A predicate the determines that bit-vector multiplication does not overflow"""
4680 _check_bv_args(a, b)
4681 a, b = _coerce_exprs(a, b)
4682 return BoolRef(Z3_mk_bvmul_no_overflow(a.ctx_ref(), a.as_ast(), b.as_ast(), signed), a.ctx)
4683
4684
4686 """A predicate the determines that bit-vector signed multiplication does not underflow"""
4687 _check_bv_args(a, b)
4688 a, b = _coerce_exprs(a, b)
4689 return BoolRef(Z3_mk_bvmul_no_underflow(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
4690
4691
4692
4697
4699 """Array sorts."""
4700
4701 def domain(self):
4702 """Return the domain of the array sort `self`.
4703
4704 >>> A = ArraySort(IntSort(), BoolSort())
4705 >>> A.domain()
4706 Int
4707 """
4709
4710 def domain_n(self, i):
4711 """Return the domain of the array sort `self`.
4712 """
4714
4715 def range(self):
4716 """Return the range of the array sort `self`.
4717
4718 >>> A = ArraySort(IntSort(), BoolSort())
4719 >>> A.range()
4720 Bool
4721 """
4723
4724
4726 """Array expressions. """
4727
4728 def sort(self):
4729 """Return the array sort of the array expression `self`.
4730
4731 >>> a = Array('a', IntSort(), BoolSort())
4732 >>> a.sort()
4733 Array(Int, Bool)
4734 """
4736
4737 def domain(self):
4738 """Shorthand for `self.sort().domain()`.
4739
4740 >>> a = Array('a', IntSort(), BoolSort())
4741 >>> a.domain()
4742 Int
4743 """
4744 return self.sortsort().domain()
4745
4746 def domain_n(self, i):
4747 """Shorthand for self.sort().domain_n(i)`."""
4748 return self.sortsort().domain_n(i)
4749
4750 def range(self):
4751 """Shorthand for `self.sort().range()`.
4752
4753 >>> a = Array('a', IntSort(), BoolSort())
4754 >>> a.range()
4755 Bool
4756 """
4757 return self.sortsort().range()
4758
4759 def __getitem__(self, arg):
4760 """Return the Z3 expression `self[arg]`.
4761
4762 >>> a = Array('a', IntSort(), BoolSort())
4763 >>> i = Int('i')
4764 >>> a[i]
4765 a[i]
4766 >>> a[i].sexpr()
4767 '(select a i)'
4768 """
4769 return _array_select(self, arg)
4770
4771 def default(self):
4772 return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_astas_ast()), self.ctxctxctx)
4773
4774
4775def _array_select(ar, arg):
4776 if isinstance(arg, tuple):
4777 args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
4778 _args, sz = _to_ast_array(args)
4779 return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
4780 arg = ar.sort().domain().cast(arg)
4781 return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
4782
4783
4785 return Z3_get_sort_kind(a.ctx.ref(), Z3_get_sort(a.ctx.ref(), a.ast)) == Z3_ARRAY_SORT
4786
4787
4788def is_array(a : Any) -> bool:
4789 """Return `True` if `a` is a Z3 array expression.
4790
4791 >>> a = Array('a', IntSort(), IntSort())
4792 >>> is_array(a)
4793 True
4794 >>> is_array(Store(a, 0, 1))
4795 True
4796 >>> is_array(a[0])
4797 False
4798 """
4799 return isinstance(a, ArrayRef)
4800
4801
4803 """Return `True` if `a` is a Z3 constant array.
4804
4805 >>> a = K(IntSort(), 10)
4806 >>> is_const_array(a)
4807 True
4808 >>> a = Array('a', IntSort(), IntSort())
4809 >>> is_const_array(a)
4810 False
4811 """
4812 return is_app_of(a, Z3_OP_CONST_ARRAY)
4813
4814
4815def is_K(a):
4816 """Return `True` if `a` is a Z3 constant array.
4817
4818 >>> a = K(IntSort(), 10)
4819 >>> is_K(a)
4820 True
4821 >>> a = Array('a', IntSort(), IntSort())
4822 >>> is_K(a)
4823 False
4824 """
4825 return is_app_of(a, Z3_OP_CONST_ARRAY)
4826
4827
4828def is_map(a):
4829 """Return `True` if `a` is a Z3 map array expression.
4830
4831 >>> f = Function('f', IntSort(), IntSort())
4832 >>> b = Array('b', IntSort(), IntSort())
4833 >>> a = Map(f, b)
4834 >>> a
4835 Map(f, b)
4836 >>> is_map(a)
4837 True
4838 >>> is_map(b)
4839 False
4840 """
4841 return is_app_of(a, Z3_OP_ARRAY_MAP)
4842
4843
4845 """Return `True` if `a` is a Z3 default array expression.
4846 >>> d = Default(K(IntSort(), 10))
4847 >>> is_default(d)
4848 True
4849 """
4850 return is_app_of(a, Z3_OP_ARRAY_DEFAULT)
4851
4852
4854 """Return the function declaration associated with a Z3 map array expression.
4855
4856 >>> f = Function('f', IntSort(), IntSort())
4857 >>> b = Array('b', IntSort(), IntSort())
4858 >>> a = Map(f, b)
4859 >>> eq(f, get_map_func(a))
4860 True
4861 >>> get_map_func(a)
4862 f
4863 >>> get_map_func(a)(0)
4864 f(0)
4865 """
4866 if z3_debug():
4867 _z3_assert(is_map(a), "Z3 array map expression expected.")
4868 return FuncDeclRef(
4870 a.ctx_ref(),
4871 Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0),
4872 ),
4873 ctx=a.ctx,
4874 )
4875
4876
4877def ArraySort(*sig):
4878 """Return the Z3 array sort with the given domain and range sorts.
4879
4880 >>> A = ArraySort(IntSort(), BoolSort())
4881 >>> A
4882 Array(Int, Bool)
4883 >>> A.domain()
4884 Int
4885 >>> A.range()
4886 Bool
4887 >>> AA = ArraySort(IntSort(), A)
4888 >>> AA
4889 Array(Int, Array(Int, Bool))
4890 """
4891 sig = _get_args(sig)
4892 if z3_debug():
4893 _z3_assert(len(sig) > 1, "At least two arguments expected")
4894 arity = len(sig) - 1
4895 r = sig[arity]
4896 d = sig[0]
4897 if z3_debug():
4898 for s in sig:
4899 _z3_assert(is_sort(s), "Z3 sort expected")
4900 _z3_assert(s.ctx == r.ctx, "Context mismatch")
4901 ctx = d.ctx
4902 if len(sig) == 2:
4903 return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
4904 dom = (Sort * arity)()
4905 for i in range(arity):
4906 dom[i] = sig[i].ast
4907 return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
4908
4909
4910def Array(name, *sorts):
4911 """Return an array constant named `name` with the given domain and range sorts.
4912
4913 >>> a = Array('a', IntSort(), IntSort())
4914 >>> a.sort()
4915 Array(Int, Int)
4916 >>> a[0]
4917 a[0]
4918 """
4919 s = ArraySort(sorts)
4920 ctx = s.ctx
4921 return ArrayRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), s.ast), ctx)
4922
4923
4924def Update(a, *args):
4925 """Return a Z3 store array expression.
4926
4927 >>> a = Array('a', IntSort(), IntSort())
4928 >>> i, v = Ints('i v')
4929 >>> s = Update(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 if z3_debug():
4939 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4940 args = _get_args(args)
4941 ctx = a.ctx
4942 if len(args) <= 1:
4943 raise Z3Exception("array update requires index and value arguments")
4944 if len(args) == 2:
4945 i = args[0]
4946 v = args[1]
4947 i = a.sort().domain().cast(i)
4948 v = a.sort().range().cast(v)
4949 return _to_expr_ref(Z3_mk_store(ctx.ref(), a.as_ast(), i.as_ast(), v.as_ast()), ctx)
4950 v = a.sort().range().cast(args[-1])
4951 idxs = [a.sort().domain_n(i).cast(args[i]) for i in range(len(args)-1)]
4952 _args, sz = _to_ast_array(idxs)
4953 return _to_expr_ref(Z3_mk_store_n(ctx.ref(), a.as_ast(), sz, _args, v.as_ast()), ctx)
4954
4955
4956def Default(a):
4957 """ Return a default value for array expression.
4958 >>> b = K(IntSort(), 1)
4959 >>> prove(Default(b) == 1)
4960 proved
4961 """
4962 if z3_debug():
4963 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4964 return a.default()
4965
4966
4967def Store(a, *args):
4968 """Return a Z3 store array expression.
4969
4970 >>> a = Array('a', IntSort(), IntSort())
4971 >>> i, v = Ints('i v')
4972 >>> s = Store(a, i, v)
4973 >>> s.sort()
4974 Array(Int, Int)
4975 >>> prove(s[i] == v)
4976 proved
4977 >>> j = Int('j')
4978 >>> prove(Implies(i != j, s[j] == a[j]))
4979 proved
4980 """
4981 return Update(a, args)
4982
4983
4984def Select(a, *args):
4985 """Return a Z3 select array expression.
4986
4987 >>> a = Array('a', IntSort(), IntSort())
4988 >>> i = Int('i')
4989 >>> Select(a, i)
4990 a[i]
4991 >>> eq(Select(a, i), a[i])
4992 True
4993 """
4994 args = _get_args(args)
4995 if z3_debug():
4996 _z3_assert(is_array_sort(a), "First argument must be a Z3 array expression")
4997 return a[args]
4998
4999
5000def Map(f, *args):
5001 """Return a Z3 map array expression.
5002
5003 >>> f = Function('f', IntSort(), IntSort(), IntSort())
5004 >>> a1 = Array('a1', IntSort(), IntSort())
5005 >>> a2 = Array('a2', IntSort(), IntSort())
5006 >>> b = Map(f, a1, a2)
5007 >>> b
5008 Map(f, a1, a2)
5009 >>> prove(b[0] == f(a1[0], a2[0]))
5010 proved
5011 """
5012 args = _get_args(args)
5013 if z3_debug():
5014 _z3_assert(len(args) > 0, "At least one Z3 array expression expected")
5015 _z3_assert(is_func_decl(f), "First argument must be a Z3 function declaration")
5016 _z3_assert(all([is_array(a) for a in args]), "Z3 array expected expected")
5017 _z3_assert(len(args) == f.arity(), "Number of arguments mismatch")
5018 _args, sz = _to_ast_array(args)
5019 ctx = f.ctx
5020 return ArrayRef(Z3_mk_map(ctx.ref(), f.ast, sz, _args), ctx)
5021
5022
5023def K(dom, v):
5024 """Return a Z3 constant array expression.
5025
5026 >>> a = K(IntSort(), 10)
5027 >>> a
5028 K(Int, 10)
5029 >>> a.sort()
5030 Array(Int, Int)
5031 >>> i = Int('i')
5032 >>> a[i]
5033 K(Int, 10)[i]
5034 >>> simplify(a[i])
5035 10
5036 """
5037 if z3_debug():
5038 _z3_assert(is_sort(dom), "Z3 sort expected")
5039 ctx = dom.ctx
5040 if not is_expr(v):
5041 v = _py2expr(v, ctx)
5042 return ArrayRef(Z3_mk_const_array(ctx.ref(), dom.ast, v.as_ast()), ctx)
5043
5044
5045def Ext(a, b):
5046 """Return extensionality index for one-dimensional arrays.
5047 >> a, b = Consts('a b', SetSort(IntSort()))
5048 >> Ext(a, b)
5049 Ext(a, b)
5050 """
5051 ctx = a.ctx
5052 if z3_debug():
5053 _z3_assert(is_array_sort(a) and (is_array(b) or b.is_lambda()), "arguments must be arrays")
5054 return _to_expr_ref(Z3_mk_array_ext(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5055
5057 """Return `True` if `a` is a Z3 array select application.
5058
5059 >>> a = Array('a', IntSort(), IntSort())
5060 >>> is_select(a)
5061 False
5062 >>> i = Int('i')
5063 >>> is_select(a[i])
5064 True
5065 """
5066 return is_app_of(a, Z3_OP_SELECT)
5067
5068
5070 """Return `True` if `a` is a Z3 array store application.
5071
5072 >>> a = Array('a', IntSort(), IntSort())
5073 >>> is_store(a)
5074 False
5075 >>> is_store(Store(a, 0, 1))
5076 True
5077 """
5078 return is_app_of(a, Z3_OP_STORE)
5079
5080
5085
5086
5087def SetSort(s):
5088 """ Create a set sort over element sort s"""
5089 return ArraySort(s, BoolSort())
5090
5091
5093 """Create the empty set
5094 >>> EmptySet(IntSort())
5095 K(Int, False)
5096 """
5097 ctx = s.ctx
5098 return ArrayRef(Z3_mk_empty_set(ctx.ref(), s.ast), ctx)
5099
5100
5101def FullSet(s):
5102 """Create the full set
5103 >>> FullSet(IntSort())
5104 K(Int, True)
5105 """
5106 ctx = s.ctx
5107 return ArrayRef(Z3_mk_full_set(ctx.ref(), s.ast), ctx)
5108
5109
5110def SetUnion(*args):
5111 """ Take the union of sets
5112 >>> a = Const('a', SetSort(IntSort()))
5113 >>> b = Const('b', SetSort(IntSort()))
5114 >>> SetUnion(a, b)
5115 union(a, b)
5116 """
5117 args = _get_args(args)
5118 ctx = _ctx_from_ast_arg_list(args)
5119 _args, sz = _to_ast_array(args)
5120 return ArrayRef(Z3_mk_set_union(ctx.ref(), sz, _args), ctx)
5121
5122
5123def SetIntersect(*args):
5124 """ Take the union of sets
5125 >>> a = Const('a', SetSort(IntSort()))
5126 >>> b = Const('b', SetSort(IntSort()))
5127 >>> SetIntersect(a, b)
5128 intersection(a, b)
5129 """
5130 args = _get_args(args)
5131 ctx = _ctx_from_ast_arg_list(args)
5132 _args, sz = _to_ast_array(args)
5133 return ArrayRef(Z3_mk_set_intersect(ctx.ref(), sz, _args), ctx)
5134
5135
5136def SetAdd(s, e):
5137 """ Add element e to set s
5138 >>> a = Const('a', SetSort(IntSort()))
5139 >>> SetAdd(a, 1)
5140 Store(a, 1, True)
5141 """
5142 ctx = _ctx_from_ast_arg_list([s, e])
5143 e = _py2expr(e, ctx)
5144 return ArrayRef(Z3_mk_set_add(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5145
5146
5147def SetDel(s, e):
5148 """ Remove element e to set s
5149 >>> a = Const('a', SetSort(IntSort()))
5150 >>> SetDel(a, 1)
5151 Store(a, 1, False)
5152 """
5153 ctx = _ctx_from_ast_arg_list([s, e])
5154 e = _py2expr(e, ctx)
5155 return ArrayRef(Z3_mk_set_del(ctx.ref(), s.as_ast(), e.as_ast()), ctx)
5156
5157
5159 """ The complement of set s
5160 >>> a = Const('a', SetSort(IntSort()))
5161 >>> SetComplement(a)
5162 complement(a)
5163 """
5164 ctx = s.ctx
5165 return ArrayRef(Z3_mk_set_complement(ctx.ref(), s.as_ast()), ctx)
5166
5167
5169 """ The set difference of a and b
5170 >>> a = Const('a', SetSort(IntSort()))
5171 >>> b = Const('b', SetSort(IntSort()))
5172 >>> SetDifference(a, b)
5173 setminus(a, b)
5174 """
5175 ctx = _ctx_from_ast_arg_list([a, b])
5176 return ArrayRef(Z3_mk_set_difference(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5177
5178
5179def IsMember(e, s):
5180 """ Check if e is a member of set s
5181 >>> a = Const('a', SetSort(IntSort()))
5182 >>> IsMember(1, a)
5183 a[1]
5184 """
5185 ctx = _ctx_from_ast_arg_list([s, e])
5186 e = _py2expr(e, ctx)
5187 return BoolRef(Z3_mk_set_member(ctx.ref(), e.as_ast(), s.as_ast()), ctx)
5188
5189
5190def IsSubset(a, b):
5191 """ Check if a is a subset of b
5192 >>> a = Const('a', SetSort(IntSort()))
5193 >>> b = Const('b', SetSort(IntSort()))
5194 >>> IsSubset(a, b)
5195 subset(a, b)
5196 """
5197 ctx = _ctx_from_ast_arg_list([a, b])
5198 return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
5199
5200
5201
5206
5208 """Return `True` if acc is pair of the form (String, Datatype or Sort). """
5209 if not isinstance(acc, tuple):
5210 return False
5211 if len(acc) != 2:
5212 return False
5213 return isinstance(acc[0], str) and (isinstance(acc[1], Datatype) or is_sort(acc[1]))
5214
5215
5217 """Helper class for declaring Z3 datatypes.
5218
5219 >>> List = Datatype('List')
5220 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5221 >>> List.declare('nil')
5222 >>> List = List.create()
5223 >>> # List is now a Z3 declaration
5224 >>> List.nil
5225 nil
5226 >>> List.cons(10, List.nil)
5227 cons(10, nil)
5228 >>> List.cons(10, List.nil).sort()
5229 List
5230 >>> cons = List.cons
5231 >>> nil = List.nil
5232 >>> car = List.car
5233 >>> cdr = List.cdr
5234 >>> n = cons(1, cons(0, nil))
5235 >>> n
5236 cons(1, cons(0, nil))
5237 >>> simplify(cdr(n))
5238 cons(0, nil)
5239 >>> simplify(car(n))
5240 1
5241 """
5242
5243 def __init__(self, name, ctx=None):
5244 self.ctx = _get_ctx(ctx)
5245 self.name = name
5247
5248 def __deepcopy__(self, memo={}):
5249 r = Datatype(self.name, self.ctx)
5250 r.constructors = copy.deepcopy(self.constructors)
5251 return r
5252
5253 def declare_core(self, name, rec_name, *args):
5254 if z3_debug():
5255 _z3_assert(isinstance(name, str), "String expected")
5256 _z3_assert(isinstance(rec_name, str), "String expected")
5257 _z3_assert(
5258 all([_valid_accessor(a) for a in args]),
5259 "Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort)",
5260 )
5261 self.constructors.append((name, rec_name, args))
5262
5263 def declare(self, name, *args):
5264 """Declare constructor named `name` with the given accessors `args`.
5265 Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort
5266 or a reference to the datatypes being declared.
5267
5268 In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))`
5269 declares the constructor named `cons` that builds a new List using an integer and a List.
5270 It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer
5271 of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared,
5272 we use the method create() to create the actual datatype in Z3.
5273
5274 >>> List = Datatype('List')
5275 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5276 >>> List.declare('nil')
5277 >>> List = List.create()
5278 """
5279 if z3_debug():
5280 _z3_assert(isinstance(name, str), "String expected")
5281 _z3_assert(name != "", "Constructor name cannot be empty")
5282 return self.declare_core(name, "is-" + name, *args)
5283
5284 def __repr__(self):
5285 return "Datatype(%s, %s)" % (self.name, self.constructors)
5286
5287 def create(self):
5288 """Create a Z3 datatype based on the constructors declared using the method `declare()`.
5289
5290 The function `CreateDatatypes()` must be used to define mutually recursive datatypes.
5291
5292 >>> List = Datatype('List')
5293 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5294 >>> List.declare('nil')
5295 >>> List = List.create()
5296 >>> List.nil
5297 nil
5298 >>> List.cons(10, List.nil)
5299 cons(10, nil)
5300 """
5301 return CreateDatatypes([self])[0]
5302
5303
5305 """Auxiliary object used to create Z3 datatypes."""
5306
5307 def __init__(self, c, ctx):
5308 self.c = c
5309 self.ctx = ctx
5310
5311 def __del__(self):
5312 if self.ctx.ref() is not None and Z3_del_constructor is not None:
5313 Z3_del_constructor(self.ctx.ref(), self.c)
5314
5315
5317 """Auxiliary object used to create Z3 datatypes."""
5318
5319 def __init__(self, c, ctx):
5320 self.c = c
5321 self.ctx = ctx
5322
5323 def __del__(self):
5324 if self.ctx.ref() is not None and Z3_del_constructor_list is not None:
5325 Z3_del_constructor_list(self.ctx.ref(), self.c)
5326
5327
5329 """Create mutually recursive Z3 datatypes using 1 or more Datatype helper objects.
5330
5331 In the following example we define a Tree-List using two mutually recursive datatypes.
5332
5333 >>> TreeList = Datatype('TreeList')
5334 >>> Tree = Datatype('Tree')
5335 >>> # Tree has two constructors: leaf and node
5336 >>> Tree.declare('leaf', ('val', IntSort()))
5337 >>> # a node contains a list of trees
5338 >>> Tree.declare('node', ('children', TreeList))
5339 >>> TreeList.declare('nil')
5340 >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList))
5341 >>> Tree, TreeList = CreateDatatypes(Tree, TreeList)
5342 >>> Tree.val(Tree.leaf(10))
5343 val(leaf(10))
5344 >>> simplify(Tree.val(Tree.leaf(10)))
5345 10
5346 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil)))
5347 >>> n1
5348 node(cons(leaf(10), cons(leaf(20), nil)))
5349 >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil))
5350 >>> simplify(n2 == n1)
5351 False
5352 >>> simplify(TreeList.car(Tree.children(n2)) == n1)
5353 True
5354 """
5355 ds = _get_args(ds)
5356 if z3_debug():
5357 _z3_assert(len(ds) > 0, "At least one Datatype must be specified")
5358 _z3_assert(all([isinstance(d, Datatype) for d in ds]), "Arguments must be Datatypes")
5359 _z3_assert(all([d.ctx == ds[0].ctx for d in ds]), "Context mismatch")
5360 _z3_assert(all([d.constructors != [] for d in ds]), "Non-empty Datatypes expected")
5361 ctx = ds[0].ctx
5362 num = len(ds)
5363 names = (Symbol * num)()
5364 out = (Sort * num)()
5365 clists = (ConstructorList * num)()
5366 to_delete = []
5367 for i in range(num):
5368 d = ds[i]
5369 names[i] = to_symbol(d.name, ctx)
5370 num_cs = len(d.constructors)
5371 cs = (Constructor * num_cs)()
5372 for j in range(num_cs):
5373 c = d.constructors[j]
5374 cname = to_symbol(c[0], ctx)
5375 rname = to_symbol(c[1], ctx)
5376 fs = c[2]
5377 num_fs = len(fs)
5378 fnames = (Symbol * num_fs)()
5379 sorts = (Sort * num_fs)()
5380 refs = (ctypes.c_uint * num_fs)()
5381 for k in range(num_fs):
5382 fname = fs[k][0]
5383 ftype = fs[k][1]
5384 fnames[k] = to_symbol(fname, ctx)
5385 if isinstance(ftype, Datatype):
5386 if z3_debug():
5387 _z3_assert(
5388 ds.count(ftype) == 1,
5389 "One and only one occurrence of each datatype is expected",
5390 )
5391 sorts[k] = None
5392 refs[k] = ds.index(ftype)
5393 else:
5394 if z3_debug():
5395 _z3_assert(is_sort(ftype), "Z3 sort expected")
5396 sorts[k] = ftype.ast
5397 refs[k] = 0
5398 cs[j] = Z3_mk_constructor(ctx.ref(), cname, rname, num_fs, fnames, sorts, refs)
5399 to_delete.append(ScopedConstructor(cs[j], ctx))
5400 clists[i] = Z3_mk_constructor_list(ctx.ref(), num_cs, cs)
5401 to_delete.append(ScopedConstructorList(clists[i], ctx))
5402 Z3_mk_datatypes(ctx.ref(), num, names, out, clists)
5403 result = []
5404 # Create a field for every constructor, recognizer and accessor
5405 for i in range(num):
5406 dref = DatatypeSortRef(out[i], ctx)
5407 num_cs = dref.num_constructors()
5408 for j in range(num_cs):
5409 cref = dref.constructor(j)
5410 cref_name = cref.name()
5411 cref_arity = cref.arity()
5412 if cref.arity() == 0:
5413 cref = cref()
5414 setattr(dref, cref_name, cref)
5415 rref = dref.recognizer(j)
5416 setattr(dref, "is_" + cref_name, rref)
5417 for k in range(cref_arity):
5418 aref = dref.accessor(j, k)
5419 setattr(dref, aref.name(), aref)
5420 result.append(dref)
5421 return tuple(result)
5422
5423
5425 """Datatype sorts."""
5426
5428 """Return the number of constructors in the given Z3 datatype.
5429
5430 >>> List = Datatype('List')
5431 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5432 >>> List.declare('nil')
5433 >>> List = List.create()
5434 >>> # List is now a Z3 declaration
5435 >>> List.num_constructors()
5436 2
5437 """
5439
5440 def constructor(self, idx):
5441 """Return a constructor of the datatype `self`.
5442
5443 >>> List = Datatype('List')
5444 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5445 >>> List.declare('nil')
5446 >>> List = List.create()
5447 >>> # List is now a Z3 declaration
5448 >>> List.num_constructors()
5449 2
5450 >>> List.constructor(0)
5451 cons
5452 >>> List.constructor(1)
5453 nil
5454 """
5455 if z3_debug():
5456 _z3_assert(idx < self.num_constructors(), "Invalid constructor index")
5458
5459 def recognizer(self, idx):
5460 """In Z3, each constructor has an associated recognizer predicate.
5461
5462 If the constructor is named `name`, then the recognizer `is_name`.
5463
5464 >>> List = Datatype('List')
5465 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5466 >>> List.declare('nil')
5467 >>> List = List.create()
5468 >>> # List is now a Z3 declaration
5469 >>> List.num_constructors()
5470 2
5471 >>> List.recognizer(0)
5472 is(cons)
5473 >>> List.recognizer(1)
5474 is(nil)
5475 >>> simplify(List.is_nil(List.cons(10, List.nil)))
5476 False
5477 >>> simplify(List.is_cons(List.cons(10, List.nil)))
5478 True
5479 >>> l = Const('l', List)
5480 >>> simplify(List.is_cons(l))
5481 is(cons, l)
5482 """
5483 if z3_debug():
5484 _z3_assert(idx < self.num_constructors(), "Invalid recognizer index")
5486
5487 def accessor(self, i, j):
5488 """In Z3, each constructor has 0 or more accessor.
5489 The number of accessors is equal to the arity of the constructor.
5490
5491 >>> List = Datatype('List')
5492 >>> List.declare('cons', ('car', IntSort()), ('cdr', List))
5493 >>> List.declare('nil')
5494 >>> List = List.create()
5495 >>> List.num_constructors()
5496 2
5497 >>> List.constructor(0)
5498 cons
5499 >>> num_accs = List.constructor(0).arity()
5500 >>> num_accs
5501 2
5502 >>> List.accessor(0, 0)
5503 car
5504 >>> List.accessor(0, 1)
5505 cdr
5506 >>> List.constructor(1)
5507 nil
5508 >>> num_accs = List.constructor(1).arity()
5509 >>> num_accs
5510 0
5511 """
5512 if z3_debug():
5513 _z3_assert(i < self.num_constructors(), "Invalid constructor index")
5514 _z3_assert(j < self.constructor(i).arity(), "Invalid accessor index")
5515 return FuncDeclRef(
5517 ctx=self.ctxctxctx,
5518 )
5519
5520
5522 """Datatype expressions."""
5523
5524 def sort(self):
5525 """Return the datatype sort of the datatype expression `self`."""
5527
5528 def update_field(self, field_accessor, new_value):
5529 """Return a new datatype expression with the specified field updated.
5530
5531 Args:
5532 field_accessor: The accessor function declaration for the field to update
5533 new_value: The new value for the field
5534
5535 Returns:
5536 A new datatype expression with the field updated, other fields unchanged
5537
5538 Example:
5539 >>> Person = Datatype('Person')
5540 >>> Person.declare('person', ('name', StringSort()), ('age', IntSort()))
5541 >>> Person = Person.create()
5542 >>> person_age = Person.accessor(0, 1) # age accessor
5543 >>> p = Const('p', Person)
5544 >>> p2 = p.update_field(person_age, IntVal(30))
5545 """
5546 if z3_debug():
5547 _z3_assert(is_func_decl(field_accessor), "Z3 function declaration expected")
5548 _z3_assert(is_expr(new_value), "Z3 expression expected")
5549 return _to_expr_ref(
5550 Z3_datatype_update_field(self.ctx_ref(), field_accessor.ast, self.as_astas_ast(), new_value.as_ast()),
5551 self.ctxctxctx
5552 )
5553
5554def DatatypeSort(name, params=None, ctx=None):
5555 """Create a reference to a sort that was declared, or will be declared, as a recursive datatype.
5556
5557 Args:
5558 name: name of the datatype sort
5559 params: optional list/tuple of sort parameters for parametric datatypes
5560 ctx: Z3 context (optional)
5561
5562 Example:
5563 >>> # Non-parametric datatype
5564 >>> TreeRef = DatatypeSort('Tree')
5565 >>> # Parametric datatype with one parameter
5566 >>> ListIntRef = DatatypeSort('List', [IntSort()])
5567 >>> # Parametric datatype with multiple parameters
5568 >>> PairRef = DatatypeSort('Pair', [IntSort(), BoolSort()])
5569 """
5570 ctx = _get_ctx(ctx)
5571 if params is None or len(params) == 0:
5572 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), 0, (Sort * 0)()), ctx)
5573 else:
5574 _params = (Sort * len(params))()
5575 for i in range(len(params)):
5576 _params[i] = params[i].ast
5577 return DatatypeSortRef(Z3_mk_datatype_sort(ctx.ref(), to_symbol(name, ctx), len(params), _params), ctx)
5578
5579def TupleSort(name, sorts, ctx=None):
5580 """Create a named tuple sort base on a set of underlying sorts
5581 Example:
5582 >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()])
5583 """
5584 tuple = Datatype(name, ctx)
5585 projects = [("project%d" % i, sorts[i]) for i in range(len(sorts))]
5586 tuple.declare(name, *projects)
5587 tuple = tuple.create()
5588 return tuple, tuple.constructor(0), [tuple.accessor(0, i) for i in range(len(sorts))]
5589
5590
5591def DisjointSum(name, sorts, ctx=None):
5592 """Create a named tagged union sort base on a set of underlying sorts
5593 Example:
5594 >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()])
5595 """
5596 sum = Datatype(name, ctx)
5597 for i in range(len(sorts)):
5598 sum.declare("inject%d" % i, ("project%d" % i, sorts[i]))
5599 sum = sum.create()
5600 return sum, [(sum.constructor(i), sum.accessor(i, 0)) for i in range(len(sorts))]
5601
5602
5603def EnumSort(name, values, ctx=None):
5604 """Return a new enumeration sort named `name` containing the given values.
5605
5606 The result is a pair (sort, list of constants).
5607 Example:
5608 >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue'])
5609 """
5610 if z3_debug():
5611 _z3_assert(isinstance(name, str), "Name must be a string")
5612 _z3_assert(all([isinstance(v, str) for v in values]), "Enumeration sort values must be strings")
5613 _z3_assert(len(values) > 0, "At least one value expected")
5614 ctx = _get_ctx(ctx)
5615 num = len(values)
5616 _val_names = (Symbol * num)()
5617 for i in range(num):
5618 _val_names[i] = to_symbol(values[i], ctx)
5619 _values = (FuncDecl * num)()
5620 _testers = (FuncDecl * num)()
5621 name = to_symbol(name, ctx)
5622 S = DatatypeSortRef(Z3_mk_enumeration_sort(ctx.ref(), name, num, _val_names, _values, _testers), ctx)
5623 V = []
5624 for i in range(num):
5625 V.append(FuncDeclRef(_values[i], ctx))
5626 V = [a() for a in V]
5627 return S, V
5628
5629
5634
5635
5637 """Set of parameters used to configure Solvers, Tactics and Simplifiers in Z3.
5638
5639 Consider using the function `args2params` to create instances of this object.
5640 """
5641
5642 def __init__(self, ctx=None, params=None):
5643 self.ctx = _get_ctx(ctx)
5644 if params is None:
5645 self.params = Z3_mk_params(self.ctx.ref())
5646 else:
5647 self.params = params
5648 Z3_params_inc_ref(self.ctx.ref(), self.params)
5649
5650 def __deepcopy__(self, memo={}):
5651 return ParamsRef(self.ctx, self.params)
5652
5653 def __del__(self):
5654 if self.ctx.ref() is not None and Z3_params_dec_ref is not None:
5655 Z3_params_dec_ref(self.ctx.ref(), self.params)
5656
5657 def set(self, name, val):
5658 """Set parameter name with value val."""
5659 if z3_debug():
5660 _z3_assert(isinstance(name, str), "parameter name must be a string")
5661 name_sym = to_symbol(name, self.ctx)
5662 if isinstance(val, bool):
5663 Z3_params_set_bool(self.ctx.ref(), self.params, name_sym, val)
5664 elif _is_int(val):
5665 Z3_params_set_uint(self.ctx.ref(), self.params, name_sym, val)
5666 elif isinstance(val, float):
5667 Z3_params_set_double(self.ctx.ref(), self.params, name_sym, val)
5668 elif isinstance(val, str):
5669 Z3_params_set_symbol(self.ctx.ref(), self.params, name_sym, to_symbol(val, self.ctx))
5670 else:
5671 if z3_debug():
5672 _z3_assert(False, "invalid parameter value")
5673
5674 def __repr__(self):
5675 return Z3_params_to_string(self.ctx.ref(), self.params)
5676
5677 def validate(self, ds):
5678 _z3_assert(isinstance(ds, ParamDescrsRef), "parameter description set expected")
5679 Z3_params_validate(self.ctx.ref(), self.params, ds.descr)
5680
5681
5682def args2params(arguments, keywords, ctx=None):
5683 """Convert python arguments into a Z3_params object.
5684 A ':' is added to the keywords, and '_' is replaced with '-'
5685
5686 >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
5687 (params model true relevancy 2 elim_and true)
5688 """
5689 if z3_debug():
5690 _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
5691 prev = None
5692 r = ParamsRef(ctx)
5693 for a in arguments:
5694 if prev is None:
5695 prev = a
5696 else:
5697 r.set(prev, a)
5698 prev = None
5699 for k in keywords:
5700 v = keywords[k]
5701 r.set(k, v)
5702 return r
5703
5704
5706 """Set of parameter descriptions for Solvers, Tactics and Simplifiers in Z3.
5707 """
5708
5709 def __init__(self, descr, ctx=None):
5710 _z3_assert(isinstance(descr, ParamDescrs), "parameter description object expected")
5711 self.ctx = _get_ctx(ctx)
5712 self.descr = descr
5713 Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
5714
5715 def __deepcopy__(self, memo={}):
5716 return ParamsDescrsRef(self.descr, self.ctx)
5717
5718 def __del__(self):
5719 if self.ctx.ref() is not None and Z3_param_descrs_dec_ref is not None:
5720 Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
5721
5722 def size(self):
5723 """Return the size of in the parameter description `self`.
5724 """
5725 return int(Z3_param_descrs_size(self.ctx.ref(), self.descr))
5726
5727 def __len__(self):
5728 """Return the size of in the parameter description `self`.
5729 """
5730 return self.size()
5731
5732 def get_name(self, i):
5733 """Return the i-th parameter name in the parameter description `self`.
5734 """
5735 return _symbol2py(self.ctx, Z3_param_descrs_get_name(self.ctx.ref(), self.descr, i))
5736
5737 def get_kind(self, n):
5738 """Return the kind of the parameter named `n`.
5739 """
5740 return Z3_param_descrs_get_kind(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5741
5742 def get_documentation(self, n):
5743 """Return the documentation string of the parameter named `n`.
5744 """
5745 return Z3_param_descrs_get_documentation(self.ctx.ref(), self.descr, to_symbol(n, self.ctx))
5746
5747 def __getitem__(self, arg):
5748 if _is_int(arg):
5749 return self.get_name(arg)
5750 else:
5751 return self.get_kind(arg)
5752
5753 def __repr__(self):
5754 return Z3_param_descrs_to_string(self.ctx.ref(), self.descr)
5755
5756
5761
5762
5764 """Goal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible).
5765
5766 Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals.
5767 A goal has a solution if one of its subgoals has a solution.
5768 A goal is unsatisfiable if all subgoals are unsatisfiable.
5769 """
5770
5771 def __init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None):
5772 if z3_debug():
5773 _z3_assert(goal is None or ctx is not None,
5774 "If goal is different from None, then ctx must be also different from None")
5775 self.ctx = _get_ctx(ctx)
5776 self.goal = goal
5777 if self.goal is None:
5778 self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
5779 Z3_goal_inc_ref(self.ctx.ref(), self.goal)
5780
5781 def __del__(self):
5782 if self.goal is not None and self.ctx.ref() is not None and Z3_goal_dec_ref is not None:
5783 Z3_goal_dec_ref(self.ctx.ref(), self.goal)
5784
5785 def depth(self):
5786 """Return the depth of the goal `self`.
5787 The depth corresponds to the number of tactics applied to `self`.
5788
5789 >>> x, y = Ints('x y')
5790 >>> g = Goal()
5791 >>> g.add(x == 0, y >= x + 1)
5792 >>> g.depth()
5793 0
5794 >>> r = Then('simplify', 'solve-eqs')(g)
5795 >>> # r has 1 subgoal
5796 >>> len(r)
5797 1
5798 >>> r[0].depth()
5799 2
5800 """
5801 return int(Z3_goal_depth(self.ctx.ref(), self.goal))
5802
5803 def inconsistent(self):
5804 """Return `True` if `self` contains the `False` constraints.
5805
5806 >>> x, y = Ints('x y')
5807 >>> g = Goal()
5808 >>> g.inconsistent()
5809 False
5810 >>> g.add(x == 0, x == 1)
5811 >>> g
5812 [x == 0, x == 1]
5813 >>> g.inconsistent()
5814 False
5815 >>> g2 = Tactic('propagate-values')(g)[0]
5816 >>> g2.inconsistent()
5817 True
5818 """
5819 return Z3_goal_inconsistent(self.ctx.ref(), self.goal)
5820
5821 def prec(self):
5822 """Return the precision (under-approximation, over-approximation, or precise) of the goal `self`.
5823
5824 >>> g = Goal()
5825 >>> g.prec() == Z3_GOAL_PRECISE
5826 True
5827 >>> x, y = Ints('x y')
5828 >>> g.add(x == y + 1)
5829 >>> g.prec() == Z3_GOAL_PRECISE
5830 True
5831 >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10)
5832 >>> g2 = t(g)[0]
5833 >>> g2
5834 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0]
5835 >>> g2.prec() == Z3_GOAL_PRECISE
5836 False
5837 >>> g2.prec() == Z3_GOAL_UNDER
5838 True
5839 """
5840 return Z3_goal_precision(self.ctx.ref(), self.goal)
5841
5842 def precision(self):
5843 """Alias for `prec()`.
5844
5845 >>> g = Goal()
5846 >>> g.precision() == Z3_GOAL_PRECISE
5847 True
5848 """
5849 return self.prec()
5850
5851 def size(self):
5852 """Return the number of constraints in the goal `self`.
5853
5854 >>> g = Goal()
5855 >>> g.size()
5856 0
5857 >>> x, y = Ints('x y')
5858 >>> g.add(x == 0, y > x)
5859 >>> g.size()
5860 2
5861 """
5862 return int(Z3_goal_size(self.ctx.ref(), self.goal))
5863
5864 def __len__(self):
5865 """Return the number of constraints in the goal `self`.
5866
5867 >>> g = Goal()
5868 >>> len(g)
5869 0
5870 >>> x, y = Ints('x y')
5871 >>> g.add(x == 0, y > x)
5872 >>> len(g)
5873 2
5874 """
5875 return self.size()
5876
5877 def get(self, i):
5878 """Return a constraint in the goal `self`.
5879
5880 >>> g = Goal()
5881 >>> x, y = Ints('x y')
5882 >>> g.add(x == 0, y > x)
5883 >>> g.get(0)
5884 x == 0
5885 >>> g.get(1)
5886 y > x
5887 """
5888 return _to_expr_ref(Z3_goal_formula(self.ctx.ref(), self.goal, i), self.ctx)
5889
5890 def __getitem__(self, arg):
5891 """Return a constraint in the goal `self`.
5892
5893 >>> g = Goal()
5894 >>> x, y = Ints('x y')
5895 >>> g.add(x == 0, y > x)
5896 >>> g[0]
5897 x == 0
5898 >>> g[1]
5899 y > x
5900 """
5901 if arg < 0:
5902 arg += len(self)
5903 if arg < 0 or arg >= len(self):
5904 raise IndexError
5905 return self.get(arg)
5906
5907 def assert_exprs(self, *args):
5908 """Assert constraints into the goal.
5909
5910 >>> x = Int('x')
5911 >>> g = Goal()
5912 >>> g.assert_exprs(x > 0, x < 2)
5913 >>> g
5914 [x > 0, x < 2]
5915 """
5916 args = _get_args(args)
5917 s = BoolSort(self.ctx)
5918 for arg in args:
5919 arg = s.cast(arg)
5920 Z3_goal_assert(self.ctx.ref(), self.goal, arg.as_ast())
5921
5922 def append(self, *args):
5923 """Add constraints.
5924
5925 >>> x = Int('x')
5926 >>> g = Goal()
5927 >>> g.append(x > 0, x < 2)
5928 >>> g
5929 [x > 0, x < 2]
5930 """
5931 self.assert_exprs(*args)
5932
5933 def insert(self, *args):
5934 """Add constraints.
5935
5936 >>> x = Int('x')
5937 >>> g = Goal()
5938 >>> g.insert(x > 0, x < 2)
5939 >>> g
5940 [x > 0, x < 2]
5941 """
5942 self.assert_exprs(*args)
5943
5944 def add(self, *args):
5945 """Add constraints.
5946
5947 >>> x = Int('x')
5948 >>> g = Goal()
5949 >>> g.add(x > 0, x < 2)
5950 >>> g
5951 [x > 0, x < 2]
5952 """
5953 self.assert_exprs(*args)
5954
5955 def convert_model(self, model):
5956 """Retrieve model from a satisfiable goal
5957 >>> a, b = Ints('a b')
5958 >>> g = Goal()
5959 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
5960 >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs'))
5961 >>> r = t(g)
5962 >>> r[0]
5963 [Or(b == 0, b == 1), Not(0 <= b)]
5964 >>> r[1]
5965 [Or(b == 0, b == 1), Not(1 <= b)]
5966 >>> # Remark: the subgoal r[0] is unsatisfiable
5967 >>> # Creating a solver for solving the second subgoal
5968 >>> s = Solver()
5969 >>> s.add(r[1])
5970 >>> s.check()
5971 sat
5972 >>> s.model()
5973 [b = 0]
5974 >>> # Model s.model() does not assign a value to `a`
5975 >>> # It is a model for subgoal `r[1]`, but not for goal `g`
5976 >>> # The method convert_model creates a model for `g` from a model for `r[1]`.
5977 >>> r[1].convert_model(s.model())
5978 [b = 0, a = 1]
5979 """
5980 if z3_debug():
5981 _z3_assert(isinstance(model, ModelRef), "Z3 Model expected")
5982 return ModelRef(Z3_goal_convert_model(self.ctx.ref(), self.goal, model.model), self.ctx)
5983
5984 def __repr__(self):
5985 return obj_to_string(self)
5986
5987 def sexpr(self):
5988 """Return a textual representation of the s-expression representing the goal."""
5989 return Z3_goal_to_string(self.ctx.ref(), self.goal)
5990
5991 def dimacs(self, include_names=True):
5992 """Return a textual representation of the goal in DIMACS format."""
5993 return Z3_goal_to_dimacs_string(self.ctx.ref(), self.goal, include_names)
5994
5995 def translate(self, target):
5996 """Copy goal `self` to context `target`.
5997
5998 >>> x = Int('x')
5999 >>> g = Goal()
6000 >>> g.add(x > 10)
6001 >>> g
6002 [x > 10]
6003 >>> c2 = Context()
6004 >>> g2 = g.translate(c2)
6005 >>> g2
6006 [x > 10]
6007 >>> g.ctx == main_ctx()
6008 True
6009 >>> g2.ctx == c2
6010 True
6011 >>> g2.ctx == main_ctx()
6012 False
6013 """
6014 if z3_debug():
6015 _z3_assert(isinstance(target, Context), "target must be a context")
6016 return Goal(goal=Z3_goal_translate(self.ctx.ref(), self.goal, target.ref()), ctx=target)
6017
6018 def __copy__(self):
6019 return self.translate(self.ctx)
6020
6021 def __deepcopy__(self, memo={}):
6022 return self.translate(self.ctx)
6023
6024 def simplify(self, *arguments, **keywords):
6025 """Return a new simplified goal.
6026
6027 This method is essentially invoking the simplify tactic.
6028
6029 >>> g = Goal()
6030 >>> x = Int('x')
6031 >>> g.add(x + 1 >= 2)
6032 >>> g
6033 [x + 1 >= 2]
6034 >>> g2 = g.simplify()
6035 >>> g2
6036 [x >= 1]
6037 >>> # g was not modified
6038 >>> g
6039 [x + 1 >= 2]
6040 """
6041 t = Tactic("simplify")
6042 return t.apply(self, *arguments, **keywords)[0]
6043
6044 def as_expr(self):
6045 """Return goal `self` as a single Z3 expression.
6046
6047 >>> x = Int('x')
6048 >>> g = Goal()
6049 >>> g.as_expr()
6050 True
6051 >>> g.add(x > 1)
6052 >>> g.as_expr()
6053 x > 1
6054 >>> g.add(x < 10)
6055 >>> g.as_expr()
6056 And(x > 1, x < 10)
6057 """
6058 sz = len(self)
6059 if sz == 0:
6060 return BoolVal(True, self.ctx)
6061 elif sz == 1:
6062 return self.get(0)
6063 else:
6064 return And([self.get(i) for i in range(len(self))], self.ctx)
6065
6066
6071
6072
6074 """A collection (vector) of ASTs."""
6075
6076 def __init__(self, v=None, ctx=None):
6077 self.vector = None
6078 if v is None:
6079 self.ctx = _get_ctx(ctx)
6080 self.vector = Z3_mk_ast_vector(self.ctx.ref())
6081 else:
6082 self.vector = v
6083 assert ctx is not None
6084 self.ctx = ctx
6085 Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
6086
6087 def __del__(self):
6088 if self.vector is not None and self.ctx.ref() is not None and Z3_ast_vector_dec_ref is not None:
6089 Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
6090
6091 def __len__(self):
6092 """Return the size of the vector `self`.
6093
6094 >>> A = AstVector()
6095 >>> len(A)
6096 0
6097 >>> A.push(Int('x'))
6098 >>> A.push(Int('x'))
6099 >>> len(A)
6100 2
6101 """
6102 return int(Z3_ast_vector_size(self.ctx.ref(), self.vector))
6103
6104 def __getitem__(self, i):
6105 """Return the AST at position `i`.
6106
6107 >>> A = AstVector()
6108 >>> A.push(Int('x') + 1)
6109 >>> A.push(Int('y'))
6110 >>> A[0]
6111 x + 1
6112 >>> A[1]
6113 y
6114 """
6115
6116 if isinstance(i, int):
6117 if i < 0:
6118 i += self.__len__()
6119
6120 if i >= self.__len__():
6121 raise IndexError
6122 return _to_ast_ref(Z3_ast_vector_get(self.ctx.ref(), self.vector, i), self.ctx)
6123
6124 elif isinstance(i, slice):
6125 result = []
6126 for ii in range(*i.indices(self.__len__())):
6127 result.append(_to_ast_ref(
6128 Z3_ast_vector_get(self.ctx.ref(), self.vector, ii),
6129 self.ctx,
6130 ))
6131 return result
6132
6133 def __setitem__(self, i, v):
6134 """Update AST at position `i`.
6135
6136 >>> A = AstVector()
6137 >>> A.push(Int('x') + 1)
6138 >>> A.push(Int('y'))
6139 >>> A[0]
6140 x + 1
6141 >>> A[0] = Int('x')
6142 >>> A[0]
6143 x
6144 """
6145 if i < 0:
6146 i += self.__len__()
6147 if i < 0 or i >= self.__len__():
6148 raise IndexError
6149 Z3_ast_vector_set(self.ctx.ref(), self.vector, i, v.as_ast())
6150
6151 def push(self, v):
6152 """Add `v` in the end of the vector.
6153
6154 >>> A = AstVector()
6155 >>> len(A)
6156 0
6157 >>> A.push(Int('x'))
6158 >>> len(A)
6159 1
6160 """
6161 Z3_ast_vector_push(self.ctx.ref(), self.vector, v.as_ast())
6162
6163 def resize(self, sz):
6164 """Resize the vector to `sz` elements.
6165
6166 >>> A = AstVector()
6167 >>> A.resize(10)
6168 >>> len(A)
6169 10
6170 >>> for i in range(10): A[i] = Int('x')
6171 >>> A[5]
6172 x
6173 """
6174 Z3_ast_vector_resize(self.ctx.ref(), self.vector, sz)
6175
6176 def __contains__(self, item):
6177 """Return `True` if the vector contains `item`.
6178
6179 >>> x = Int('x')
6180 >>> A = AstVector()
6181 >>> x in A
6182 False
6183 >>> A.push(x)
6184 >>> x in A
6185 True
6186 >>> (x+1) in A
6187 False
6188 >>> A.push(x+1)
6189 >>> (x+1) in A
6190 True
6191 >>> A
6192 [x, x + 1]
6193 """
6194 for elem in self:
6195 if elem.eq(item):
6196 return True
6197 return False
6198
6199 def translate(self, other_ctx):
6200 """Copy vector `self` to context `other_ctx`.
6201
6202 >>> x = Int('x')
6203 >>> A = AstVector()
6204 >>> A.push(x)
6205 >>> c2 = Context()
6206 >>> B = A.translate(c2)
6207 >>> B
6208 [x]
6209 """
6210 return AstVector(
6211 Z3_ast_vector_translate(self.ctx.ref(), self.vector, other_ctx.ref()),
6212 ctx=other_ctx,
6213 )
6214
6215 def __copy__(self):
6216 return self.translate(self.ctx)
6217
6218 def __deepcopy__(self, memo={}):
6219 return self.translate(self.ctx)
6220
6221 def __repr__(self):
6222 return obj_to_string(self)
6223
6224 def sexpr(self):
6225 """Return a textual representation of the s-expression representing the vector."""
6226 return Z3_ast_vector_to_string(self.ctx.ref(), self.vector)
6227
6228
6233
6234
6236 """A mapping from ASTs to ASTs."""
6237
6238 def __init__(self, m=None, ctx=None):
6239 self.map = None
6240 if m is None:
6241 self.ctx = _get_ctx(ctx)
6242 self.map = Z3_mk_ast_map(self.ctx.ref())
6243 else:
6244 self.map = m
6245 assert ctx is not None
6246 self.ctx = ctx
6247 Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
6248
6249 def __deepcopy__(self, memo={}):
6250 return AstMap(self.map, self.ctx)
6251
6252 def __del__(self):
6253 if self.map is not None and self.ctx.ref() is not None and Z3_ast_map_dec_ref is not None:
6254 Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
6255
6256 def __len__(self):
6257 """Return the size of the map.
6258
6259 >>> M = AstMap()
6260 >>> len(M)
6261 0
6262 >>> x = Int('x')
6263 >>> M[x] = IntVal(1)
6264 >>> len(M)
6265 1
6266 """
6267 return int(Z3_ast_map_size(self.ctx.ref(), self.map))
6268
6269 def __contains__(self, key):
6270 """Return `True` if the map contains key `key`.
6271
6272 >>> M = AstMap()
6273 >>> x = Int('x')
6274 >>> M[x] = x + 1
6275 >>> x in M
6276 True
6277 >>> x+1 in M
6278 False
6279 """
6280 return Z3_ast_map_contains(self.ctx.ref(), self.map, key.as_ast())
6281
6282 def __getitem__(self, key):
6283 """Retrieve the value associated with key `key`.
6284
6285 >>> M = AstMap()
6286 >>> x = Int('x')
6287 >>> M[x] = x + 1
6288 >>> M[x]
6289 x + 1
6290 """
6291 return _to_ast_ref(Z3_ast_map_find(self.ctx.ref(), self.map, key.as_ast()), self.ctx)
6292
6293 def __setitem__(self, k, v):
6294 """Add/Update key `k` with value `v`.
6295
6296 >>> M = AstMap()
6297 >>> x = Int('x')
6298 >>> M[x] = x + 1
6299 >>> len(M)
6300 1
6301 >>> M[x]
6302 x + 1
6303 >>> M[x] = IntVal(1)
6304 >>> M[x]
6305 1
6306 """
6307 Z3_ast_map_insert(self.ctx.ref(), self.map, k.as_ast(), v.as_ast())
6308
6309 def __repr__(self):
6310 return Z3_ast_map_to_string(self.ctx.ref(), self.map)
6311
6312 def erase(self, k):
6313 """Remove the entry associated with key `k`.
6314
6315 >>> M = AstMap()
6316 >>> x = Int('x')
6317 >>> M[x] = x + 1
6318 >>> len(M)
6319 1
6320 >>> M.erase(x)
6321 >>> len(M)
6322 0
6323 """
6324 Z3_ast_map_erase(self.ctx.ref(), self.map, k.as_ast())
6325
6326 def reset(self):
6327 """Remove all entries from the map.
6328
6329 >>> M = AstMap()
6330 >>> x = Int('x')
6331 >>> M[x] = x + 1
6332 >>> M[x+x] = IntVal(1)
6333 >>> len(M)
6334 2
6335 >>> M.reset()
6336 >>> len(M)
6337 0
6338 """
6339 Z3_ast_map_reset(self.ctx.ref(), self.map)
6340
6341 def keys(self):
6342 """Return an AstVector containing all keys in the map.
6343
6344 >>> M = AstMap()
6345 >>> x = Int('x')
6346 >>> M[x] = x + 1
6347 >>> M[x+x] = IntVal(1)
6348 >>> M.keys()
6349 [x, x + x]
6350 """
6351 return AstVector(Z3_ast_map_keys(self.ctx.ref(), self.map), self.ctx)
6352
6353
6358
6359
6361 """Store the value of the interpretation of a function in a particular point."""
6362
6363 def __init__(self, entry, ctx):
6364 self.entry = entry
6365 self.ctx = ctx
6366 Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
6367
6368 def __deepcopy__(self, memo={}):
6369 return FuncEntry(self.entry, self.ctx)
6370
6371 def __del__(self):
6372 if self.ctx.ref() is not None and Z3_func_entry_dec_ref is not None:
6373 Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
6374
6375 def num_args(self):
6376 """Return the number of arguments in the given entry.
6377
6378 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6379 >>> s = Solver()
6380 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6381 >>> s.check()
6382 sat
6383 >>> m = s.model()
6384 >>> f_i = m[f]
6385 >>> f_i.num_entries()
6386 1
6387 >>> e = f_i.entry(0)
6388 >>> e.num_args()
6389 2
6390 """
6391 return int(Z3_func_entry_get_num_args(self.ctx.ref(), self.entry))
6392
6393 def arg_value(self, idx):
6394 """Return the value of argument `idx`.
6395
6396 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6397 >>> s = Solver()
6398 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6399 >>> s.check()
6400 sat
6401 >>> m = s.model()
6402 >>> f_i = m[f]
6403 >>> f_i.num_entries()
6404 1
6405 >>> e = f_i.entry(0)
6406 >>> e
6407 [1, 2, 20]
6408 >>> e.num_args()
6409 2
6410 >>> e.arg_value(0)
6411 1
6412 >>> e.arg_value(1)
6413 2
6414 >>> try:
6415 ... e.arg_value(2)
6416 ... except IndexError:
6417 ... print("index error")
6418 index error
6419 """
6420 if idx >= self.num_args():
6421 raise IndexError
6422 return _to_expr_ref(Z3_func_entry_get_arg(self.ctx.ref(), self.entry, idx), self.ctx)
6423
6424 def value(self):
6425 """Return the value of the function at point `self`.
6426
6427 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6428 >>> s = Solver()
6429 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6430 >>> s.check()
6431 sat
6432 >>> m = s.model()
6433 >>> f_i = m[f]
6434 >>> f_i.num_entries()
6435 1
6436 >>> e = f_i.entry(0)
6437 >>> e
6438 [1, 2, 20]
6439 >>> e.num_args()
6440 2
6441 >>> e.value()
6442 20
6443 """
6444 return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
6445
6446 def as_list(self):
6447 """Return entry `self` as a Python list.
6448 >>> f = Function('f', IntSort(), IntSort(), IntSort())
6449 >>> s = Solver()
6450 >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10)
6451 >>> s.check()
6452 sat
6453 >>> m = s.model()
6454 >>> f_i = m[f]
6455 >>> f_i.num_entries()
6456 1
6457 >>> e = f_i.entry(0)
6458 >>> e.as_list()
6459 [1, 2, 20]
6460 """
6461 args = [self.arg_value(i) for i in range(self.num_args())]
6462 args.append(self.value())
6463 return args
6464
6465 def __repr__(self):
6466 return repr(self.as_list())
6467
6468
6470 """Stores the interpretation of a function in a Z3 model."""
6471
6472 def __init__(self, f, ctx):
6473 self.f = f
6474 self.ctx = ctx
6475 if self.f is not None:
6476 Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
6477
6478 def __del__(self):
6479 if self.f is not None and self.ctx.ref() is not None and Z3_func_interp_dec_ref is not None:
6480 Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
6481
6482 def else_value(self):
6483 """
6484 Return the `else` value for a function interpretation.
6485 Return None if Z3 did not specify the `else` value for
6486 this object.
6487
6488 >>> f = Function('f', IntSort(), IntSort())
6489 >>> s = Solver()
6490 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6491 >>> s.check()
6492 sat
6493 >>> m = s.model()
6494 >>> m[f]
6495 [2 -> 0, else -> 1]
6496 >>> m[f].else_value()
6497 1
6498 """
6499 r = Z3_func_interp_get_else(self.ctx.ref(), self.f)
6500 if r:
6501 return _to_expr_ref(r, self.ctx)
6502 else:
6503 return None
6504
6505 def num_entries(self):
6506 """Return the number of entries/points in the function interpretation `self`.
6507
6508 >>> f = Function('f', IntSort(), IntSort())
6509 >>> s = Solver()
6510 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6511 >>> s.check()
6512 sat
6513 >>> m = s.model()
6514 >>> m[f]
6515 [2 -> 0, else -> 1]
6516 >>> m[f].num_entries()
6517 1
6518 """
6519 return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
6520
6521 def arity(self):
6522 """Return the number of arguments for each entry in the function interpretation `self`.
6523
6524 >>> f = Function('f', IntSort(), IntSort())
6525 >>> s = Solver()
6526 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6527 >>> s.check()
6528 sat
6529 >>> m = s.model()
6530 >>> m[f].arity()
6531 1
6532 """
6533 return int(Z3_func_interp_get_arity(self.ctx.ref(), self.f))
6534
6535 def entry(self, idx):
6536 """Return an entry at position `idx < self.num_entries()` in the function interpretation `self`.
6537
6538 >>> f = Function('f', IntSort(), IntSort())
6539 >>> s = Solver()
6540 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6541 >>> s.check()
6542 sat
6543 >>> m = s.model()
6544 >>> m[f]
6545 [2 -> 0, else -> 1]
6546 >>> m[f].num_entries()
6547 1
6548 >>> m[f].entry(0)
6549 [2, 0]
6550 """
6551 if idx >= self.num_entries():
6552 raise IndexError
6553 return FuncEntry(Z3_func_interp_get_entry(self.ctx.ref(), self.f, idx), self.ctx)
6554
6555 def translate(self, other_ctx):
6556 """Copy model 'self' to context 'other_ctx'.
6557 """
6558 return ModelRef(Z3_model_translate(self.ctx.ref(), self.model, other_ctx.ref()), other_ctx)
6559
6560 def __copy__(self):
6561 return self.translate(self.ctx)
6562
6563 def __deepcopy__(self, memo={}):
6564 return self.translate(self.ctx)
6565
6566 def as_list(self):
6567 """Return the function interpretation as a Python list.
6568 >>> f = Function('f', IntSort(), IntSort())
6569 >>> s = Solver()
6570 >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0)
6571 >>> s.check()
6572 sat
6573 >>> m = s.model()
6574 >>> m[f]
6575 [2 -> 0, else -> 1]
6576 >>> m[f].as_list()
6577 [[2, 0], 1]
6578 """
6579 r = [self.entry(i).as_list() for i in range(self.num_entries())]
6580 r.append(self.else_value())
6581 return r
6582
6583 def __repr__(self):
6584 return obj_to_string(self)
6585
6586
6588 """Model/Solution of a satisfiability problem (aka system of constraints)."""
6589
6590 def __init__(self, m, ctx):
6591 assert ctx is not None
6592 self.model = m
6593 self.ctx = ctx
6594 Z3_model_inc_ref(self.ctx.ref(), self.model)
6595
6596 def __del__(self):
6597 if self.ctx.ref() is not None and Z3_model_dec_ref is not None:
6598 Z3_model_dec_ref(self.ctx.ref(), self.model)
6599
6600 def __repr__(self):
6601 return obj_to_string(self)
6602
6603 def sexpr(self):
6604 """Return a textual representation of the s-expression representing the model."""
6605 return Z3_model_to_string(self.ctx.ref(), self.model)
6606
6607 def eval(self, t, model_completion=False):
6608 """Evaluate the expression `t` in the model `self`.
6609 If `model_completion` is enabled, then a default interpretation is automatically added
6610 for symbols that do not have an interpretation in the model `self`.
6611
6612 >>> x = Int('x')
6613 >>> s = Solver()
6614 >>> s.add(x > 0, x < 2)
6615 >>> s.check()
6616 sat
6617 >>> m = s.model()
6618 >>> m.eval(x + 1)
6619 2
6620 >>> m.eval(x == 1)
6621 True
6622 >>> y = Int('y')
6623 >>> m.eval(y + x)
6624 1 + y
6625 >>> m.eval(y)
6626 y
6627 >>> m.eval(y, model_completion=True)
6628 0
6629 >>> # Now, m contains an interpretation for y
6630 >>> m.eval(y + x)
6631 1
6632 """
6633 r = (Ast * 1)()
6634 if Z3_model_eval(self.ctx.ref(), self.model, t.as_ast(), model_completion, r):
6635 return _to_expr_ref(r[0], self.ctx)
6636 raise Z3Exception("failed to evaluate expression in the model")
6637
6638 def evaluate(self, t, model_completion=False):
6639 """Alias for `eval`.
6640
6641 >>> x = Int('x')
6642 >>> s = Solver()
6643 >>> s.add(x > 0, x < 2)
6644 >>> s.check()
6645 sat
6646 >>> m = s.model()
6647 >>> m.evaluate(x + 1)
6648 2
6649 >>> m.evaluate(x == 1)
6650 True
6651 >>> y = Int('y')
6652 >>> m.evaluate(y + x)
6653 1 + y
6654 >>> m.evaluate(y)
6655 y
6656 >>> m.evaluate(y, model_completion=True)
6657 0
6658 >>> # Now, m contains an interpretation for y
6659 >>> m.evaluate(y + x)
6660 1
6661 """
6662 return self.eval(t, model_completion)
6663
6664 def __len__(self):
6665 """Return the number of constant and function declarations in the model `self`.
6666
6667 >>> f = Function('f', IntSort(), IntSort())
6668 >>> x = Int('x')
6669 >>> s = Solver()
6670 >>> s.add(x > 0, f(x) != x)
6671 >>> s.check()
6672 sat
6673 >>> m = s.model()
6674 >>> len(m)
6675 2
6676 """
6677 num_consts = int(Z3_model_get_num_consts(self.ctx.ref(), self.model))
6678 num_funcs = int(Z3_model_get_num_funcs(self.ctx.ref(), self.model))
6679 return num_consts + num_funcs
6680
6681 def get_interp(self, decl):
6682 """Return the interpretation for a given declaration or constant.
6683
6684 >>> f = Function('f', IntSort(), IntSort())
6685 >>> x = Int('x')
6686 >>> s = Solver()
6687 >>> s.add(x > 0, x < 2, f(x) == 0)
6688 >>> s.check()
6689 sat
6690 >>> m = s.model()
6691 >>> m[x]
6692 1
6693 >>> m[f]
6694 [else -> 0]
6695 """
6696 if z3_debug():
6697 _z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
6698 if is_const(decl):
6699 decl = decl.decl()
6700 try:
6701 if decl.arity() == 0:
6702 _r = Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast)
6703 if _r.value is None:
6704 return None
6705 r = _to_expr_ref(_r, self.ctx)
6706 if is_as_array(r):
6707 fi = self.get_interp(get_as_array_func(r))
6708 if fi is None:
6709 return fi
6710 e = fi.else_value()
6711 if e is None:
6712 return fi
6713 if fi.arity() != 1:
6714 return fi
6715 srt = decl.range()
6716 dom = srt.domain()
6717 e = K(dom, e)
6718 i = 0
6719 sz = fi.num_entries()
6720 n = fi.arity()
6721 while i < sz:
6722 fe = fi.entry(i)
6723 e = Store(e, fe.arg_value(0), fe.value())
6724 i += 1
6725 return e
6726 else:
6727 return r
6728 else:
6729 return FuncInterp(Z3_model_get_func_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
6730 except Z3Exception:
6731 return None
6732
6733 def num_sorts(self):
6734 """Return the number of uninterpreted sorts that contain an interpretation in the model `self`.
6735
6736 >>> A = DeclareSort('A')
6737 >>> a, b = Consts('a b', A)
6738 >>> s = Solver()
6739 >>> s.add(a != b)
6740 >>> s.check()
6741 sat
6742 >>> m = s.model()
6743 >>> m.num_sorts()
6744 1
6745 """
6746 return int(Z3_model_get_num_sorts(self.ctx.ref(), self.model))
6747
6748 def get_sort(self, idx):
6749 """Return the uninterpreted sort at position `idx` < self.num_sorts().
6750
6751 >>> A = DeclareSort('A')
6752 >>> B = DeclareSort('B')
6753 >>> a1, a2 = Consts('a1 a2', A)
6754 >>> b1, b2 = Consts('b1 b2', B)
6755 >>> s = Solver()
6756 >>> s.add(a1 != a2, b1 != b2)
6757 >>> s.check()
6758 sat
6759 >>> m = s.model()
6760 >>> m.num_sorts()
6761 2
6762 >>> m.get_sort(0)
6763 A
6764 >>> m.get_sort(1)
6765 B
6766 """
6767 if idx >= self.num_sorts():
6768 raise IndexError
6769 return _to_sort_ref(Z3_model_get_sort(self.ctx.ref(), self.model, idx), self.ctx)
6770
6771 def sorts(self):
6772 """Return all uninterpreted sorts that have an interpretation in the model `self`.
6773
6774 >>> A = DeclareSort('A')
6775 >>> B = DeclareSort('B')
6776 >>> a1, a2 = Consts('a1 a2', A)
6777 >>> b1, b2 = Consts('b1 b2', B)
6778 >>> s = Solver()
6779 >>> s.add(a1 != a2, b1 != b2)
6780 >>> s.check()
6781 sat
6782 >>> m = s.model()
6783 >>> m.sorts()
6784 [A, B]
6785 """
6786 return [self.get_sort(i) for i in range(self.num_sorts())]
6787
6788 def get_universe(self, s):
6789 """Return the interpretation for the uninterpreted sort `s` in the model `self`.
6790
6791 >>> A = DeclareSort('A')
6792 >>> a, b = Consts('a b', A)
6793 >>> s = Solver()
6794 >>> s.add(a != b)
6795 >>> s.check()
6796 sat
6797 >>> m = s.model()
6798 >>> m.get_universe(A)
6799 [A!val!1, A!val!0]
6800 """
6801 if z3_debug():
6802 _z3_assert(isinstance(s, SortRef), "Z3 sort expected")
6803 try:
6804 return AstVector(Z3_model_get_sort_universe(self.ctx.ref(), self.model, s.ast), self.ctx)
6805 except Z3Exception:
6806 return None
6807
6808 def __getitem__(self, idx):
6809 """If `idx` is an integer, then the declaration at position `idx` in the model `self` is returned.
6810 If `idx` is a declaration, then the actual interpretation is returned.
6811
6812 The elements can be retrieved using position or the actual declaration.
6813
6814 >>> f = Function('f', IntSort(), IntSort())
6815 >>> x = Int('x')
6816 >>> s = Solver()
6817 >>> s.add(x > 0, x < 2, f(x) == 0)
6818 >>> s.check()
6819 sat
6820 >>> m = s.model()
6821 >>> len(m)
6822 2
6823 >>> m[0]
6824 x
6825 >>> m[1]
6826 f
6827 >>> m[x]
6828 1
6829 >>> m[f]
6830 [else -> 0]
6831 >>> for d in m: print("%s -> %s" % (d, m[d]))
6832 x -> 1
6833 f -> [else -> 0]
6834 """
6835 if _is_int(idx):
6836 if idx < 0:
6837 idx += len(self)
6838 if idx < 0 or idx >= len(self):
6839 raise IndexError
6840 num_consts = Z3_model_get_num_consts(self.ctx.ref(), self.model)
6841 if (idx < num_consts):
6842 return FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, idx), self.ctx)
6843 else:
6844 return FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, idx - num_consts), self.ctx)
6845 if isinstance(idx, FuncDeclRef):
6846 return self.get_interp(idx)
6847 if is_const(idx):
6848 return self.get_interp(idx.decl())
6849 if isinstance(idx, SortRef):
6850 return self.get_universe(idx)
6851 if z3_debug():
6852 _z3_assert(False, "Integer, Z3 declaration, or Z3 constant expected")
6853 return None
6854
6855 def decls(self):
6856 """Return a list with all symbols that have an interpretation in the model `self`.
6857 >>> f = Function('f', IntSort(), IntSort())
6858 >>> x = Int('x')
6859 >>> s = Solver()
6860 >>> s.add(x > 0, x < 2, f(x) == 0)
6861 >>> s.check()
6862 sat
6863 >>> m = s.model()
6864 >>> m.decls()
6865 [x, f]
6866 """
6867 r = []
6868 for i in range(Z3_model_get_num_consts(self.ctx.ref(), self.model)):
6869 r.append(FuncDeclRef(Z3_model_get_const_decl(self.ctx.ref(), self.model, i), self.ctx))
6870 for i in range(Z3_model_get_num_funcs(self.ctx.ref(), self.model)):
6871 r.append(FuncDeclRef(Z3_model_get_func_decl(self.ctx.ref(), self.model, i), self.ctx))
6872 return r
6873
6874 def update_value(self, x, value):
6875 """Update the interpretation of a constant"""
6876 if is_expr(x):
6877 x = x.decl()
6878 if is_func_decl(x) and x.arity() != 0 and isinstance(value, FuncInterp):
6879 fi1 = value.f
6880 fi2 = Z3_add_func_interp(x.ctx_ref(), self.model, x.ast, value.else_value().ast);
6881 fi2 = FuncInterp(fi2, x.ctx)
6882 for i in range(value.num_entries()):
6883 e = value.entry(i)
6884 n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
6885 v = AstVector()
6886 for j in range(n):
6887 v.push(e.arg_value(j))
6888 val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
6889 Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
6890 return
6891 if not is_func_decl(x) or x.arity() != 0:
6892 raise Z3Exception("Expecting 0-ary function or constant expression")
6893 value = _py2expr(value)
6894 Z3_add_const_interp(x.ctx_ref(), self.model, x.ast, value.ast)
6895
6896 def translate(self, target):
6897 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
6898 """
6899 if z3_debug():
6900 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
6901 model = Z3_model_translate(self.ctx.ref(), self.model, target.ref())
6902 return ModelRef(model, target)
6903
6904 def project(self, vars, fml):
6905 """Perform model-based projection on fml with respect to vars.
6906 Assume that the model satisfies fml. Then compute a projection fml_p, such
6907 that vars do not occur free in fml_p, fml_p is true in the model and
6908 fml_p => exists vars . fml
6909 """
6910 ctx = self.ctx.ref()
6911 _vars = (Ast * len(vars))()
6912 for i in range(len(vars)):
6913 _vars[i] = vars[i].as_ast()
6914 return _to_expr_ref(Z3_qe_model_project(ctx, self.model, len(vars), _vars, fml.ast), self.ctx)
6915
6916 def project_with_witness(self, vars, fml):
6917 """Perform model-based projection, but also include realizer terms for the projected variables"""
6918 ctx = self.ctx.ref()
6919 _vars = (Ast * len(vars))()
6920 for i in range(len(vars)):
6921 _vars[i] = vars[i].as_ast()
6922 defs = AstMap()
6923 result = Z3_qe_model_project_with_witness(ctx, self.model, len(vars), _vars, fml.ast, defs.map)
6924 result = _to_expr_ref(result, self.ctx)
6925 return result, defs
6926
6927
6928 def __copy__(self):
6929 return self.translate(self.ctx)
6930
6931 def __deepcopy__(self, memo={}):
6932 return self.translate(self.ctx)
6933
6934
6935def Model(ctx=None, eval = {}):
6936 ctx = _get_ctx(ctx)
6937 mdl = ModelRef(Z3_mk_model(ctx.ref()), ctx)
6938 for k, v in eval.items():
6939 mdl.update_value(k, v)
6940 return mdl
6941
6942
6944 """Return true if n is a Z3 expression of the form (_ as-array f)."""
6945 return isinstance(n, ExprRef) and Z3_is_as_array(n.ctx.ref(), n.as_ast())
6946
6947
6949 """Return the function declaration f associated with a Z3 expression of the form (_ as-array f)."""
6950 if z3_debug():
6951 _z3_assert(is_as_array(n), "as-array Z3 expression expected.")
6952 return FuncDeclRef(Z3_get_as_array_func_decl(n.ctx.ref(), n.as_ast()), n.ctx)
6953
6954
6959
6960
6962 """Statistics for `Solver.check()`."""
6963
6964 def __init__(self, stats, ctx):
6965 self.stats = stats
6966 self.ctx = ctx
6967 Z3_stats_inc_ref(self.ctx.ref(), self.stats)
6968
6969 def __deepcopy__(self, memo={}):
6970 return Statistics(self.stats, self.ctx)
6971
6972 def __del__(self):
6973 if self.ctx.ref() is not None and Z3_stats_dec_ref is not None:
6974 Z3_stats_dec_ref(self.ctx.ref(), self.stats)
6975
6976 def __repr__(self):
6977 if in_html_mode():
6978 out = io.StringIO()
6979 even = True
6980 out.write(u('<table border="1" cellpadding="2" cellspacing="0">'))
6981 for k, v in self:
6982 if even:
6983 out.write(u('<tr style="background-color:#CFCFCF">'))
6984 even = False
6985 else:
6986 out.write(u("<tr>"))
6987 even = True
6988 out.write(u("<td>%s</td><td>%s</td></tr>" % (k, v)))
6989 out.write(u("</table>"))
6990 return out.getvalue()
6991 else:
6992 return Z3_stats_to_string(self.ctx.ref(), self.stats)
6993
6994 def __len__(self):
6995 """Return the number of statistical counters.
6996
6997 >>> x = Int('x')
6998 >>> s = Then('simplify', 'nlsat').solver()
6999 >>> s.add(x > 0)
7000 >>> s.check()
7001 sat
7002 >>> st = s.statistics()
7003 >>> len(st)
7004 7
7005 """
7006 return int(Z3_stats_size(self.ctx.ref(), self.stats))
7007
7008 def __getitem__(self, idx):
7009 """Return the value of statistical counter at position `idx`. The result is a pair (key, value).
7010
7011 >>> x = Int('x')
7012 >>> s = Then('simplify', 'nlsat').solver()
7013 >>> s.add(x > 0)
7014 >>> s.check()
7015 sat
7016 >>> st = s.statistics()
7017 >>> len(st)
7018 7
7019 >>> st[0]
7020 ('nlsat propagations', 2)
7021 >>> st[1]
7022 ('nlsat restarts', 1)
7023 """
7024 if idx >= len(self):
7025 raise IndexError
7026 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7027 val = int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7028 else:
7029 val = Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7030 return (Z3_stats_get_key(self.ctx.ref(), self.stats, idx), val)
7031
7032 def keys(self):
7033 """Return the list of statistical counters.
7034
7035 >>> x = Int('x')
7036 >>> s = Then('simplify', 'nlsat').solver()
7037 >>> s.add(x > 0)
7038 >>> s.check()
7039 sat
7040 >>> st = s.statistics()
7041 """
7042 return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
7043
7044 def get_key_value(self, key):
7045 """Return the value of a particular statistical counter.
7046
7047 >>> x = Int('x')
7048 >>> s = Then('simplify', 'nlsat').solver()
7049 >>> s.add(x > 0)
7050 >>> s.check()
7051 sat
7052 >>> st = s.statistics()
7053 >>> st.get_key_value('nlsat propagations')
7054 2
7055 """
7056 for idx in range(len(self)):
7057 if key == Z3_stats_get_key(self.ctx.ref(), self.stats, idx):
7058 if Z3_stats_is_uint(self.ctx.ref(), self.stats, idx):
7059 return int(Z3_stats_get_uint_value(self.ctx.ref(), self.stats, idx))
7060 else:
7061 return Z3_stats_get_double_value(self.ctx.ref(), self.stats, idx)
7062 raise Z3Exception("unknown key")
7063
7064 def __getattr__(self, name):
7065 """Access the value of statistical using attributes.
7066
7067 Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'),
7068 we should use '_' (e.g., 'nlsat_propagations').
7069
7070 >>> x = Int('x')
7071 >>> s = Then('simplify', 'nlsat').solver()
7072 >>> s.add(x > 0)
7073 >>> s.check()
7074 sat
7075 >>> st = s.statistics()
7076 >>> st.nlsat_propagations
7077 2
7078 >>> st.nlsat_stages
7079 2
7080 """
7081 key = name.replace("_", " ")
7082 try:
7083 return self.get_key_value(key)
7084 except Z3Exception:
7085 raise AttributeError
7086
7087
7092
7093
7095 """Represents the result of a satisfiability check: sat, unsat, unknown.
7096
7097 >>> s = Solver()
7098 >>> s.check()
7099 sat
7100 >>> r = s.check()
7101 >>> isinstance(r, CheckSatResult)
7102 True
7103 """
7104
7105 def __init__(self, r):
7106 self.r = r
7107
7108 def __deepcopy__(self, memo={}):
7109 return CheckSatResult(self.r)
7110
7111 def __eq__(self, other):
7112 return isinstance(other, CheckSatResult) and self.r == other.r
7113
7114 def __ne__(self, other):
7115 return not self.__eq__(other)
7116
7117 def __repr__(self):
7118 if in_html_mode():
7119 if self.r == Z3_L_TRUE:
7120 return "<b>sat</b>"
7121 elif self.r == Z3_L_FALSE:
7122 return "<b>unsat</b>"
7123 else:
7124 return "<b>unknown</b>"
7125 else:
7126 if self.r == Z3_L_TRUE:
7127 return "sat"
7128 elif self.r == Z3_L_FALSE:
7129 return "unsat"
7130 else:
7131 return "unknown"
7132
7133 def _repr_html_(self):
7134 in_html = in_html_mode()
7135 set_html_mode(True)
7136 res = repr(self)
7137 set_html_mode(in_html)
7138 return res
7139
7140
7141sat = CheckSatResult(Z3_L_TRUE)
7142unsat = CheckSatResult(Z3_L_FALSE)
7143unknown = CheckSatResult(Z3_L_UNDEF)
7144
7145
7147 """
7148 Solver API provides methods for implementing the main SMT 2.0 commands:
7149 push, pop, check, get-model, etc.
7150 """
7151
7152 def __init__(self, solver=None, ctx=None, logFile=None):
7153 assert solver is None or ctx is not None
7154 self.ctx = _get_ctx(ctx)
7155 self.backtrack_level = 4000000000
7156 self.solver = None
7157 if solver is None:
7158 self.solver = Z3_mk_solver(self.ctx.ref())
7159 else:
7160 self.solver = solver
7161 Z3_solver_inc_ref(self.ctx.ref(), self.solver)
7162 if logFile is not None:
7163 self.set("smtlib2_log", logFile)
7164
7165 def __del__(self):
7166 if self.solver is not None and self.ctx.ref() is not None and Z3_solver_dec_ref is not None:
7167 Z3_solver_dec_ref(self.ctx.ref(), self.solver)
7168
7169 def __enter__(self):
7170 self.push()
7171 return self
7172
7173 def __exit__(self, *exc_info):
7174 self.pop()
7175
7176 def set(self, *args, **keys):
7177 """Set a configuration option.
7178 The method `help()` return a string containing all available options.
7179
7180 >>> s = Solver()
7181 >>> # The option MBQI can be set using three different approaches.
7182 >>> s.set(mbqi=True)
7183 >>> s.set('MBQI', True)
7184 >>> s.set(':mbqi', True)
7185 """
7186 p = args2params(args, keys, self.ctx)
7187 Z3_solver_set_params(self.ctx.ref(), self.solver, p.params)
7188
7189 def push(self):
7190 """Create a backtracking point.
7191
7192 >>> x = Int('x')
7193 >>> s = Solver()
7194 >>> s.add(x > 0)
7195 >>> s
7196 [x > 0]
7197 >>> s.push()
7198 >>> s.add(x < 1)
7199 >>> s
7200 [x > 0, x < 1]
7201 >>> s.check()
7202 unsat
7203 >>> s.pop()
7204 >>> s.check()
7205 sat
7206 >>> s
7207 [x > 0]
7208 """
7209 Z3_solver_push(self.ctx.ref(), self.solver)
7210
7211 def pop(self, num=1):
7212 """Backtrack \\c num backtracking points.
7213
7214 >>> x = Int('x')
7215 >>> s = Solver()
7216 >>> s.add(x > 0)
7217 >>> s
7218 [x > 0]
7219 >>> s.push()
7220 >>> s.add(x < 1)
7221 >>> s
7222 [x > 0, x < 1]
7223 >>> s.check()
7224 unsat
7225 >>> s.pop()
7226 >>> s.check()
7227 sat
7228 >>> s
7229 [x > 0]
7230 """
7231 Z3_solver_pop(self.ctx.ref(), self.solver, num)
7232
7233 def num_scopes(self):
7234 """Return the current number of backtracking points.
7235
7236 >>> s = Solver()
7237 >>> s.num_scopes()
7238 0
7239 >>> s.push()
7240 >>> s.num_scopes()
7241 1
7242 >>> s.push()
7243 >>> s.num_scopes()
7244 2
7245 >>> s.pop()
7246 >>> s.num_scopes()
7247 1
7248 """
7249 return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
7250
7251 def reset(self):
7252 """Remove all asserted constraints and backtracking points created using `push()`.
7253
7254 >>> x = Int('x')
7255 >>> s = Solver()
7256 >>> s.add(x > 0)
7257 >>> s
7258 [x > 0]
7259 >>> s.reset()
7260 >>> s
7261 []
7262 """
7263 Z3_solver_reset(self.ctx.ref(), self.solver)
7264
7265 def assert_exprs(self, *args):
7266 """Assert constraints into the solver.
7267
7268 >>> x = Int('x')
7269 >>> s = Solver()
7270 >>> s.assert_exprs(x > 0, x < 2)
7271 >>> s
7272 [x > 0, x < 2]
7273 """
7274 args = _get_args(args)
7275 s = BoolSort(self.ctx)
7276 for arg in args:
7277 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7278 for f in arg:
7279 Z3_solver_assert(self.ctx.ref(), self.solver, f.as_ast())
7280 else:
7281 arg = s.cast(arg)
7282 Z3_solver_assert(self.ctx.ref(), self.solver, arg.as_ast())
7283
7284 def add(self, *args):
7285 """Assert constraints into the solver.
7286
7287 >>> x = Int('x')
7288 >>> s = Solver()
7289 >>> s.add(x > 0, x < 2)
7290 >>> s
7291 [x > 0, x < 2]
7292 """
7293 self.assert_exprs(*args)
7294
7295 def __iadd__(self, fml):
7296 self.add(fml)
7297 return self
7298
7299 def append(self, *args):
7300 """Assert constraints into the solver.
7301
7302 >>> x = Int('x')
7303 >>> s = Solver()
7304 >>> s.append(x > 0, x < 2)
7305 >>> s
7306 [x > 0, x < 2]
7307 """
7308 self.assert_exprs(*args)
7309
7310 def insert(self, *args):
7311 """Assert constraints into the solver.
7312
7313 >>> x = Int('x')
7314 >>> s = Solver()
7315 >>> s.insert(x > 0, x < 2)
7316 >>> s
7317 [x > 0, x < 2]
7318 """
7319 self.assert_exprs(*args)
7320
7321 def assert_and_track(self, a, p):
7322 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
7323
7324 If `p` is a string, it will be automatically converted into a Boolean constant.
7325
7326 >>> x = Int('x')
7327 >>> p3 = Bool('p3')
7328 >>> s = Solver()
7329 >>> s.set(unsat_core=True)
7330 >>> s.assert_and_track(x > 0, 'p1')
7331 >>> s.assert_and_track(x != 1, 'p2')
7332 >>> s.assert_and_track(x < 0, p3)
7333 >>> print(s.check())
7334 unsat
7335 >>> c = s.unsat_core()
7336 >>> len(c)
7337 2
7338 >>> Bool('p1') in c
7339 True
7340 >>> Bool('p2') in c
7341 False
7342 >>> p3 in c
7343 True
7344 """
7345 if isinstance(p, str):
7346 p = Bool(p, self.ctx)
7347 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
7348 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
7349 Z3_solver_assert_and_track(self.ctx.ref(), self.solver, a.as_ast(), p.as_ast())
7350
7351 def check(self, *assumptions):
7352 """Check whether the assertions in the given solver plus the optional assumptions are consistent or not.
7353
7354 >>> x = Int('x')
7355 >>> s = Solver()
7356 >>> s.check()
7357 sat
7358 >>> s.add(x > 0, x < 2)
7359 >>> s.check()
7360 sat
7361 >>> s.model().eval(x)
7362 1
7363 >>> s.add(x < 1)
7364 >>> s.check()
7365 unsat
7366 >>> s.reset()
7367 >>> s.add(2**x == 4)
7368 >>> s.check()
7369 sat
7370 """
7371 s = BoolSort(self.ctx)
7372 assumptions = _get_args(assumptions)
7373 num = len(assumptions)
7374 _assumptions = (Ast * num)()
7375 for i in range(num):
7376 _assumptions[i] = s.cast(assumptions[i]).as_ast()
7377 r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
7378 return CheckSatResult(r)
7379
7380 def model(self):
7381 """Return a model for the last `check()`.
7382
7383 This function raises an exception if
7384 a model is not available (e.g., last `check()` returned unsat).
7385
7386 >>> s = Solver()
7387 >>> a = Int('a')
7388 >>> s.add(a + 2 == 0)
7389 >>> s.check()
7390 sat
7391 >>> s.model()
7392 [a = -2]
7393 """
7394 try:
7395 return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
7396 except Z3Exception:
7397 raise Z3Exception("model is not available")
7398
7399 def import_model_converter(self, other):
7400 """Import model converter from other into the current solver"""
7401 Z3_solver_import_model_converter(self.ctx.ref(), other.solver, self.solver)
7402
7403 def interrupt(self):
7404 """Interrupt the execution of the solver object.
7405 Remarks: This ensures that the interrupt applies only
7406 to the given solver object and it applies only if it is running.
7407 """
7408 Z3_solver_interrupt(self.ctx.ref(), self.solver)
7409
7410 def unsat_core(self):
7411 """Return a subset (as an AST vector) of the assumptions provided to the last check().
7412
7413 These are the assumptions Z3 used in the unsatisfiability proof.
7414 Assumptions are available in Z3. They are used to extract unsatisfiable cores.
7415 They may be also used to "retract" assumptions. Note that, assumptions are not really
7416 "soft constraints", but they can be used to implement them.
7417
7418 >>> p1, p2, p3 = Bools('p1 p2 p3')
7419 >>> x, y = Ints('x y')
7420 >>> s = Solver()
7421 >>> s.add(Implies(p1, x > 0))
7422 >>> s.add(Implies(p2, y > x))
7423 >>> s.add(Implies(p2, y < 1))
7424 >>> s.add(Implies(p3, y > -3))
7425 >>> s.check(p1, p2, p3)
7426 unsat
7427 >>> core = s.unsat_core()
7428 >>> len(core)
7429 2
7430 >>> p1 in core
7431 True
7432 >>> p2 in core
7433 True
7434 >>> p3 in core
7435 False
7436 >>> # "Retracting" p2
7437 >>> s.check(p1, p3)
7438 sat
7439 """
7440 return AstVector(Z3_solver_get_unsat_core(self.ctx.ref(), self.solver), self.ctx)
7441
7442 def consequences(self, assumptions, variables):
7443 """Determine fixed values for the variables based on the solver state and assumptions.
7444 >>> s = Solver()
7445 >>> a, b, c, d = Bools('a b c d')
7446 >>> s.add(Implies(a,b), Implies(b, c))
7447 >>> s.consequences([a],[b,c,d])
7448 (sat, [Implies(a, b), Implies(a, c)])
7449 >>> s.consequences([Not(c),d],[a,b,c,d])
7450 (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))])
7451 """
7452 if isinstance(assumptions, list):
7453 _asms = AstVector(None, self.ctx)
7454 for a in assumptions:
7455 _asms.push(a)
7456 assumptions = _asms
7457 if isinstance(variables, list):
7458 _vars = AstVector(None, self.ctx)
7459 for a in variables:
7460 _vars.push(a)
7461 variables = _vars
7462 _z3_assert(isinstance(assumptions, AstVector), "ast vector expected")
7463 _z3_assert(isinstance(variables, AstVector), "ast vector expected")
7464 consequences = AstVector(None, self.ctx)
7465 r = Z3_solver_get_consequences(self.ctx.ref(), self.solver, assumptions.vector,
7466 variables.vector, consequences.vector)
7467 sz = len(consequences)
7468 consequences = [consequences[i] for i in range(sz)]
7469 return CheckSatResult(r), consequences
7470
7471 def from_file(self, filename):
7472 """Parse assertions from a file"""
7473 Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
7474
7475 def from_string(self, s):
7476 """Parse assertions from a string"""
7477 Z3_solver_from_string(self.ctx.ref(), self.solver, s)
7478
7479 def cube(self, vars=None):
7480 """Get set of cubes
7481 The method takes an optional set of variables that restrict which
7482 variables may be used as a starting point for cubing.
7483 If vars is not None, then the first case split is based on a variable in
7484 this set.
7485 """
7486 self.cube_vs = AstVector(None, self.ctx)
7487 if vars is not None:
7488 for v in vars:
7489 self.cube_vs.push(v)
7490 while True:
7491 lvl = self.backtrack_level
7492 self.backtrack_level = 4000000000
7493 r = AstVector(Z3_solver_cube(self.ctx.ref(), self.solver, self.cube_vs.vector, lvl), self.ctx)
7494 if (len(r) == 1 and is_false(r[0])):
7495 return
7496 yield r
7497 if (len(r) == 0):
7498 return
7499
7500 def cube_vars(self):
7501 """Access the set of variables that were touched by the most recently generated cube.
7502 This set of variables can be used as a starting point for additional cubes.
7503 The idea is that variables that appear in clauses that are reduced by the most recent
7504 cube are likely more useful to cube on."""
7505 return self.cube_vs
7506
7507 def root(self, t):
7508 """Retrieve congruence closure root of the term t relative to the current search state
7509 The function primarily works for SimpleSolver. Terms and variables that are
7510 eliminated during pre-processing are not visible to the congruence closure.
7511 """
7512 t = _py2expr(t, self.ctx)
7513 return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
7514
7515 def next(self, t):
7516 """Retrieve congruence closure sibling of the term t relative to the current search state
7517 The function primarily works for SimpleSolver. Terms and variables that are
7518 eliminated during pre-processing are not visible to the congruence closure.
7519 """
7520 t = _py2expr(t, self.ctx)
7521 return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
7522
7523 def explain_congruent(self, a, b):
7524 """Explain congruence of a and b relative to the current search state"""
7525 a = _py2expr(a, self.ctx)
7526 b = _py2expr(b, self.ctx)
7527 return _to_expr_ref(Z3_solver_congruence_explain(self.ctx.ref(), self.solver, a.ast, b.ast), self.ctx)
7528
7529
7530 def solve_for(self, ts):
7531 """Retrieve a solution for t relative to linear equations maintained in the current state."""
7532 vars = AstVector(ctx=self.ctx);
7533 terms = AstVector(ctx=self.ctx);
7534 guards = AstVector(ctx=self.ctx);
7535 for t in ts:
7536 t = _py2expr(t, self.ctx)
7537 vars.push(t)
7538 Z3_solver_solve_for(self.ctx.ref(), self.solver, vars.vector, terms.vector, guards.vector)
7539 return [(vars[i], terms[i], guards[i]) for i in range(len(vars))]
7540
7541
7542 def proof(self):
7543 """Return a proof for the last `check()`. Proof construction must be enabled."""
7544 return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
7545
7546 def assertions(self):
7547 """Return an AST vector containing all added constraints.
7548
7549 >>> s = Solver()
7550 >>> s.assertions()
7551 []
7552 >>> a = Int('a')
7553 >>> s.add(a > 0)
7554 >>> s.add(a < 10)
7555 >>> s.assertions()
7556 [a > 0, a < 10]
7557 """
7558 return AstVector(Z3_solver_get_assertions(self.ctx.ref(), self.solver), self.ctx)
7559
7560 def units(self):
7561 """Return an AST vector containing all currently inferred units.
7562 """
7563 return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
7564
7565 def non_units(self):
7566 """Return an AST vector containing all atomic formulas in solver state that are not units.
7567 """
7568 return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
7569
7570 def trail_levels(self):
7571 """Return trail and decision levels of the solver state after a check() call.
7572 """
7573 trail = self.trail()
7574 levels = (ctypes.c_uint * len(trail))()
7575 Z3_solver_get_levels(self.ctx.ref(), self.solver, trail.vector, len(trail), levels)
7576 return trail, levels
7577
7578 def set_initial_value(self, var, value):
7579 """initialize the solver's state by setting the initial value of var to value
7580 """
7581 s = var.sort()
7582 value = s.cast(value)
7583 Z3_solver_set_initial_value(self.ctx.ref(), self.solver, var.ast, value.ast)
7584
7585 def trail(self):
7586 """Return trail of the solver state after a check() call.
7587 """
7588 return AstVector(Z3_solver_get_trail(self.ctx.ref(), self.solver), self.ctx)
7589
7590 def statistics(self):
7591 """Return statistics for the last `check()`.
7592
7593 >>> s = SimpleSolver()
7594 >>> x = Int('x')
7595 >>> s.add(x > 0)
7596 >>> s.check()
7597 sat
7598 >>> st = s.statistics()
7599 >>> st.get_key_value('final checks')
7600 1
7601 >>> len(st) > 0
7602 True
7603 >>> st[0] != 0
7604 True
7605 """
7606 return Statistics(Z3_solver_get_statistics(self.ctx.ref(), self.solver), self.ctx)
7607
7608 def reason_unknown(self):
7609 """Return a string describing why the last `check()` returned `unknown`.
7610
7611 >>> x = Int('x')
7612 >>> s = SimpleSolver()
7613 >>> s.add(x == 2**x)
7614 >>> s.check()
7615 unknown
7616 >>> s.reason_unknown()
7617 '(incomplete (theory arithmetic))'
7618 """
7619 return Z3_solver_get_reason_unknown(self.ctx.ref(), self.solver)
7620
7621 def help(self):
7622 """Display a string describing all available options."""
7623 print(Z3_solver_get_help(self.ctx.ref(), self.solver))
7624
7625 def param_descrs(self):
7626 """Return the parameter description set."""
7627 return ParamDescrsRef(Z3_solver_get_param_descrs(self.ctx.ref(), self.solver), self.ctx)
7628
7629 def __repr__(self):
7630 """Return a formatted string with all added constraints."""
7631 return obj_to_string(self)
7632
7633 def translate(self, target):
7634 """Translate `self` to the context `target`. That is, return a copy of `self` in the context `target`.
7635
7636 >>> c1 = Context()
7637 >>> c2 = Context()
7638 >>> s1 = Solver(ctx=c1)
7639 >>> s2 = s1.translate(c2)
7640 """
7641 if z3_debug():
7642 _z3_assert(isinstance(target, Context), "argument must be a Z3 context")
7643 solver = Z3_solver_translate(self.ctx.ref(), self.solver, target.ref())
7644 return Solver(solver, target)
7645
7646 def __copy__(self):
7647 return self.translate(self.ctx)
7648
7649 def __deepcopy__(self, memo={}):
7650 return self.translate(self.ctx)
7651
7652 def sexpr(self):
7653 """Return a formatted string (in Lisp-like format) with all added constraints.
7654 We say the string is in s-expression format.
7655
7656 >>> x = Int('x')
7657 >>> s = Solver()
7658 >>> s.add(x > 0)
7659 >>> s.add(x < 2)
7660 >>> r = s.sexpr()
7661 """
7662 return Z3_solver_to_string(self.ctx.ref(), self.solver)
7663
7664 def dimacs(self, include_names=True):
7665 """Return a textual representation of the solver in DIMACS format."""
7666 return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver, include_names)
7667
7668 def to_smt2(self):
7669 """return SMTLIB2 formatted benchmark for solver's assertions"""
7670 es = self.assertions()
7671 sz = len(es)
7672 sz1 = sz
7673 if sz1 > 0:
7674 sz1 -= 1
7675 v = (Ast * sz1)()
7676 for i in range(sz1):
7677 v[i] = es[i].as_ast()
7678 if sz > 0:
7679 e = es[sz1].as_ast()
7680 else:
7681 e = BoolVal(True, self.ctx).as_ast()
7682 return Z3_benchmark_to_smtlib_string(
7683 self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e,
7684 )
7685
7686
7687def SolverFor(logic, ctx=None, logFile=None):
7688 """Create a solver customized for the given logic.
7689
7690 The parameter `logic` is a string. It should be contains
7691 the name of a SMT-LIB logic.
7692 See http://www.smtlib.org/ for the name of all available logics.
7693
7694 >>> s = SolverFor("QF_LIA")
7695 >>> x = Int('x')
7696 >>> s.add(x > 0)
7697 >>> s.add(x < 2)
7698 >>> s.check()
7699 sat
7700 >>> s.model()
7701 [x = 1]
7702 """
7703 ctx = _get_ctx(ctx)
7704 logic = to_symbol(logic)
7705 return Solver(Z3_mk_solver_for_logic(ctx.ref(), logic), ctx, logFile)
7706
7707
7708def SimpleSolver(ctx=None, logFile=None):
7709 """Return a simple general purpose solver with limited amount of preprocessing.
7710
7711 >>> s = SimpleSolver()
7712 >>> x = Int('x')
7713 >>> s.add(x > 0)
7714 >>> s.check()
7715 sat
7716 """
7717 ctx = _get_ctx(ctx)
7718 return Solver(Z3_mk_simple_solver(ctx.ref()), ctx, logFile)
7719
7720#########################################
7721#
7722# Fixedpoint
7723#
7724#########################################
7725
7726
7727class Fixedpoint(Z3PPObject):
7728 """Fixedpoint API provides methods for solving with recursive predicates"""
7729
7730 def __init__(self, fixedpoint=None, ctx=None):
7731 assert fixedpoint is None or ctx is not None
7732 self.ctx = _get_ctx(ctx)
7733 self.fixedpoint = None
7734 if fixedpoint is None:
7735 self.fixedpoint = Z3_mk_fixedpoint(self.ctx.ref())
7736 else:
7737 self.fixedpoint = fixedpoint
7738 Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
7739 self.vars = []
7740
7741 def __deepcopy__(self, memo={}):
7742 return FixedPoint(self.fixedpoint, self.ctx)
7743
7744 def __del__(self):
7745 if self.fixedpoint is not None and self.ctx.ref() is not None and Z3_fixedpoint_dec_ref is not None:
7746 Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
7747
7748 def set(self, *args, **keys):
7749 """Set a configuration option. The method `help()` return a string containing all available options.
7750 """
7751 p = args2params(args, keys, self.ctx)
7752 Z3_fixedpoint_set_params(self.ctx.ref(), self.fixedpoint, p.params)
7753
7754 def help(self):
7755 """Display a string describing all available options."""
7756 print(Z3_fixedpoint_get_help(self.ctx.ref(), self.fixedpoint))
7757
7758 def param_descrs(self):
7759 """Return the parameter description set."""
7760 return ParamDescrsRef(Z3_fixedpoint_get_param_descrs(self.ctx.ref(), self.fixedpoint), self.ctx)
7761
7762 def assert_exprs(self, *args):
7763 """Assert constraints as background axioms for the fixedpoint solver."""
7764 args = _get_args(args)
7765 s = BoolSort(self.ctx)
7766 for arg in args:
7767 if isinstance(arg, Goal) or isinstance(arg, AstVector):
7768 for f in arg:
7769 f = self.abstract(f)
7770 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, f.as_ast())
7771 else:
7772 arg = s.cast(arg)
7773 arg = self.abstract(arg)
7774 Z3_fixedpoint_assert(self.ctx.ref(), self.fixedpoint, arg.as_ast())
7775
7776 def add(self, *args):
7777 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7778 self.assert_exprs(*args)
7779
7780 def __iadd__(self, fml):
7781 self.add(fml)
7782 return self
7783
7784 def append(self, *args):
7785 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7786 self.assert_exprs(*args)
7787
7788 def insert(self, *args):
7789 """Assert constraints as background axioms for the fixedpoint solver. Alias for assert_expr."""
7790 self.assert_exprs(*args)
7791
7792 def add_rule(self, head, body=None, name=None):
7793 """Assert rules defining recursive predicates to the fixedpoint solver.
7794 >>> a = Bool('a')
7795 >>> b = Bool('b')
7796 >>> s = Fixedpoint()
7797 >>> s.register_relation(a.decl())
7798 >>> s.register_relation(b.decl())
7799 >>> s.fact(a)
7800 >>> s.rule(b, a)
7801 >>> s.query(b)
7802 sat
7803 """
7804 if name is None:
7805 name = ""
7806 name = to_symbol(name, self.ctx)
7807 if body is None:
7808 head = self.abstract(head)
7809 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
7810 else:
7811 body = _get_args(body)
7812 f = self.abstract(Implies(And(body, self.ctx), head))
7813 Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7814
7815 def rule(self, head, body=None, name=None):
7816 """Assert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7817 self.add_rule(head, body, name)
7818
7819 def fact(self, head, name=None):
7820 """Assert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule."""
7821 self.add_rule(head, None, name)
7822
7823 def query(self, *query):
7824 """Query the fixedpoint engine whether formula is derivable.
7825 You can also pass an tuple or list of recursive predicates.
7826 """
7827 query = _get_args(query)
7828 sz = len(query)
7829 if sz >= 1 and isinstance(query[0], FuncDeclRef):
7830 _decls = (FuncDecl * sz)()
7831 i = 0
7832 for q in query:
7833 _decls[i] = q.ast
7834 i = i + 1
7835 r = Z3_fixedpoint_query_relations(self.ctx.ref(), self.fixedpoint, sz, _decls)
7836 else:
7837 if sz == 1:
7838 query = query[0]
7839 else:
7840 query = And(query, self.ctx)
7841 query = self.abstract(query, False)
7842 r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
7843 return CheckSatResult(r)
7844
7845 def query_from_lvl(self, lvl, *query):
7846 """Query the fixedpoint engine whether formula is derivable starting at the given query level.
7847 """
7848 query = _get_args(query)
7849 sz = len(query)
7850 if sz >= 1 and isinstance(query[0], FuncDecl):
7851 _z3_assert(False, "unsupported")
7852 else:
7853 if sz == 1:
7854 query = query[0]
7855 else:
7856 query = And(query)
7857 query = self.abstract(query, False)
7858 r = Z3_fixedpoint_query_from_lvl(self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl)
7859 return CheckSatResult(r)
7860
7861 def update_rule(self, head, body, name):
7862 """update rule"""
7863 if name is None:
7864 name = ""
7865 name = to_symbol(name, self.ctx)
7866 body = _get_args(body)
7867 f = self.abstract(Implies(And(body, self.ctx), head))
7868 Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
7869
7870 def get_answer(self):
7871 """Retrieve answer from last query call."""
7872 r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint)
7873 return _to_expr_ref(r, self.ctx)
7874
7875 def get_ground_sat_answer(self):
7876 """Retrieve a ground cex from last query call."""
7877 r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint)
7878 return _to_expr_ref(r, self.ctx)
7879
7880 def get_rules_along_trace(self):
7881 """retrieve rules along the counterexample trace"""
7882 return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx)
7883
7884 def get_rule_names_along_trace(self):
7885 """retrieve rule names along the counterexample trace"""
7886 # this is a hack as I don't know how to return a list of symbols from C++;
7887 # obtain names as a single string separated by semicolons
7888 names = _symbol2py(self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint))
7889 # split into individual names
7890 return names.split(";")
7891
7892 def get_num_levels(self, predicate):
7893 """Retrieve number of levels used for predicate in PDR engine"""
7894 return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast)
7895
7896 def get_cover_delta(self, level, predicate):
7897 """Retrieve properties known about predicate for the level'th unfolding.
7898 -1 is treated as the limit (infinity)
7899 """
7900 r = Z3_fixedpoint_get_cover_delta(self.ctx.ref(), self.fixedpoint, level, predicate.ast)
7901 return _to_expr_ref(r, self.ctx)
7902
7903 def add_cover(self, level, predicate, property):
7904 """Add property to predicate for the level'th unfolding.
7905 -1 is treated as infinity (infinity)
7906 """
7907 Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
7908
7909 def register_relation(self, *relations):
7910 """Register relation as recursive"""
7911 relations = _get_args(relations)
7912 for f in relations:
7913 Z3_fixedpoint_register_relation(self.ctx.ref(), self.fixedpoint, f.ast)
7914
7915 def set_predicate_representation(self, f, *representations):
7916 """Control how relation is represented"""
7917 representations = _get_args(representations)
7918 representations = [to_symbol(s) for s in representations]
7919 sz = len(representations)
7920 args = (Symbol * sz)()
7921 for i in range(sz):
7922 args[i] = representations[i]
7923 Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
7924
7925 def parse_string(self, s):
7926 """Parse rules and queries from a string"""
7927 return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
7928
7929 def parse_file(self, f):
7930 """Parse rules and queries from a file"""
7931 return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
7932
7933 def get_rules(self):
7934 """retrieve rules that have been added to fixedpoint context"""
7935 return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
7936
7937 def get_assertions(self):
7938 """retrieve assertions that have been added to fixedpoint context"""
7939 return AstVector(Z3_fixedpoint_get_assertions(self.ctx.ref(), self.fixedpoint), self.ctx)
7940
7941 def __repr__(self):
7942 """Return a formatted string with all added rules and constraints."""
7943 return self.sexpr()
7944
7945 def sexpr(self):
7946 """Return a formatted string (in Lisp-like format) with all added constraints.
7947 We say the string is in s-expression format.
7948 """
7949 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
7950
7951 def to_string(self, queries):
7952 """Return a formatted string (in Lisp-like format) with all added constraints.
7953 We say the string is in s-expression format.
7954 Include also queries.
7955 """
7956 args, len = _to_ast_array(queries)
7957 return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
7958
7959 def statistics(self):
7960 """Return statistics for the last `query()`.
7961 """
7962 return Statistics(Z3_fixedpoint_get_statistics(self.ctx.ref(), self.fixedpoint), self.ctx)
7963
7964 def reason_unknown(self):
7965 """Return a string describing why the last `query()` returned `unknown`.
7966 """
7967 return Z3_fixedpoint_get_reason_unknown(self.ctx.ref(), self.fixedpoint)
7968
7969 def declare_var(self, *vars):
7970 """Add variable or several variables.
7971 The added variable or variables will be bound in the rules
7972 and queries
7973 """
7974 vars = _get_args(vars)
7975 for v in vars:
7976 self.vars += [v]
7977
7978 def abstract(self, fml, is_forall=True):
7979 if self.vars == []:
7980 return fml
7981 if is_forall:
7982 return ForAll(self.vars, fml)
7983 else:
7984 return Exists(self.vars, fml)
7985
7986
7987#########################################
7988#
7989# Finite domains
7990#
7991#########################################
7992
7993class FiniteDomainSortRef(SortRef):
7994 """Finite domain sort."""
7995
7996 def size(self):
7997 """Return the size of the finite domain sort"""
7998 r = (ctypes.c_ulonglong * 1)()
7999 if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast, r):
8000 return r[0]
8001 else:
8002 raise Z3Exception("Failed to retrieve finite domain sort size")
8003
8004
8005def FiniteDomainSort(name, sz, ctx=None):
8006 """Create a named finite domain sort of a given size sz"""
8007 if not isinstance(name, Symbol):
8008 name = to_symbol(name)
8009 ctx = _get_ctx(ctx)
8010 return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
8011
8012
8013def is_finite_domain_sort(s):
8014 """Return True if `s` is a Z3 finite-domain sort.
8015
8016 >>> is_finite_domain_sort(FiniteDomainSort('S', 100))
8017 True
8018 >>> is_finite_domain_sort(IntSort())
8019 False
8020 """
8021 return isinstance(s, FiniteDomainSortRef)
8022
8023
8024class FiniteDomainRef(ExprRef):
8025 """Finite-domain expressions."""
8026
8027 def sort(self):
8028 """Return the sort of the finite-domain expression `self`."""
8029 return FiniteDomainSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
8030
8031 def as_string(self):
8032 """Return a Z3 floating point expression as a Python string."""
8033 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
8034
8035
8036def is_finite_domain(a):
8037 """Return `True` if `a` is a Z3 finite-domain expression.
8038
8039 >>> s = FiniteDomainSort('S', 100)
8040 >>> b = Const('b', s)
8041 >>> is_finite_domain(b)
8042 True
8043 >>> is_finite_domain(Int('x'))
8044 False
8045 """
8046 return isinstance(a, FiniteDomainRef)
8047
8048
8049class FiniteDomainNumRef(FiniteDomainRef):
8050 """Integer values."""
8051
8052 def as_long(self):
8053 """Return a Z3 finite-domain numeral as a Python long (bignum) numeral.
8054
8055 >>> s = FiniteDomainSort('S', 100)
8056 >>> v = FiniteDomainVal(3, s)
8057 >>> v
8058 3
8059 >>> v.as_long() + 1
8060 4
8061 """
8062 return int(self.as_string())
8063
8064 def as_string(self):
8065 """Return a Z3 finite-domain numeral as a Python string.
8066
8067 >>> s = FiniteDomainSort('S', 100)
8068 >>> v = FiniteDomainVal(42, s)
8069 >>> v.as_string()
8070 '42'
8071 """
8072 return Z3_get_numeral_string(self.ctx_ref(), self.as_ast())
8073
8074
8075def FiniteDomainVal(val, sort, ctx=None):
8076 """Return a Z3 finite-domain value. If `ctx=None`, then the global context is used.
8077
8078 >>> s = FiniteDomainSort('S', 256)
8079 >>> FiniteDomainVal(255, s)
8080 255
8081 >>> FiniteDomainVal('100', s)
8082 100
8083 """
8084 if z3_debug():
8085 _z3_assert(is_finite_domain_sort(sort), "Expected finite-domain sort")
8086 ctx = sort.ctx
8087 return FiniteDomainNumRef(Z3_mk_numeral(ctx.ref(), _to_int_str(val), sort.ast), ctx)
8088
8089
8090def is_finite_domain_value(a):
8091 """Return `True` if `a` is a Z3 finite-domain value.
8092
8093 >>> s = FiniteDomainSort('S', 100)
8094 >>> b = Const('b', s)
8095 >>> is_finite_domain_value(b)
8096 False
8097 >>> b = FiniteDomainVal(10, s)
8098 >>> b
8099 10
8100 >>> is_finite_domain_value(b)
8101 True
8102 """
8103 return is_finite_domain(a) and _is_numeral(a.ctx, a.as_ast())
8104
8105
8106#########################################
8107#
8108# Optimize
8109#
8110#########################################
8111
8112class OptimizeObjective:
8113 def __init__(self, opt, value, is_max):
8114 self._opt = opt
8115 self._value = value
8116 self._is_max = is_max
8117
8118 def lower(self):
8119 opt = self._opt
8120 return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8121
8122 def upper(self):
8123 opt = self._opt
8124 return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8125
8126 def lower_values(self):
8127 opt = self._opt
8128 return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8129
8130 def upper_values(self):
8131 opt = self._opt
8132 return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
8133
8134 def value(self):
8135 if self._is_max:
8136 return self.upper()
8137 else:
8138 return self.lower()
8139
8140 def __str__(self):
8141 return "%s:%s" % (self._value, self._is_max)
8142
8143
8144_on_models = {}
8145
8146
8147def _global_on_model(ctx):
8148 (fn, mdl) = _on_models[ctx]
8149 fn(mdl)
8150
8151
8152_on_model_eh = on_model_eh_type(_global_on_model)
8153
8154
8155class Optimize(Z3PPObject):
8156 """Optimize API provides methods for solving using objective functions and weighted soft constraints"""
8157
8158 def __init__(self, optimize=None, ctx=None):
8159 self.ctx = _get_ctx(ctx)
8160 if optimize is None:
8161 self.optimize = Z3_mk_optimize(self.ctx.ref())
8162 else:
8163 self.optimize = optimize
8164 self._on_models_id = None
8165 Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
8166
8167 def __deepcopy__(self, memo={}):
8168 return Optimize(self.optimize, self.ctx)
8169
8170 def __del__(self):
8171 if self.optimize is not None and self.ctx.ref() is not None and Z3_optimize_dec_ref is not None:
8172 Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
8173 if self._on_models_id is not None:
8174 del _on_models[self._on_models_id]
8175
8176 def __enter__(self):
8177 self.push()
8178 return self
8179
8180 def __exit__(self, *exc_info):
8181 self.pop()
8182
8183 def set(self, *args, **keys):
8184 """Set a configuration option.
8185 The method `help()` return a string containing all available options.
8186 """
8187 p = args2params(args, keys, self.ctx)
8188 Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
8189
8190 def help(self):
8191 """Display a string describing all available options."""
8192 print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
8193
8194 def param_descrs(self):
8195 """Return the parameter description set."""
8196 return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
8197
8198 def assert_exprs(self, *args):
8199 """Assert constraints as background axioms for the optimize solver."""
8200 args = _get_args(args)
8201 s = BoolSort(self.ctx)
8202 for arg in args:
8203 if isinstance(arg, Goal) or isinstance(arg, AstVector):
8204 for f in arg:
8205 Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
8206 else:
8207 arg = s.cast(arg)
8208 Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
8209
8210 def add(self, *args):
8211 """Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
8212 self.assert_exprs(*args)
8213
8214 def __iadd__(self, fml):
8215 self.add(fml)
8216 return self
8217
8218 def assert_and_track(self, a, p):
8219 """Assert constraint `a` and track it in the unsat core using the Boolean constant `p`.
8220
8221 If `p` is a string, it will be automatically converted into a Boolean constant.
8222
8223 >>> x = Int('x')
8224 >>> p3 = Bool('p3')
8225 >>> s = Optimize()
8226 >>> s.assert_and_track(x > 0, 'p1')
8227 >>> s.assert_and_track(x != 1, 'p2')
8228 >>> s.assert_and_track(x < 0, p3)
8229 >>> print(s.check())
8230 unsat
8231 >>> c = s.unsat_core()
8232 >>> len(c)
8233 2
8234 >>> Bool('p1') in c
8235 True
8236 >>> Bool('p2') in c
8237 False
8238 >>> p3 in c
8239 True
8240 """
8241 if isinstance(p, str):
8242 p = Bool(p, self.ctx)
8243 _z3_assert(isinstance(a, BoolRef), "Boolean expression expected")
8244 _z3_assert(isinstance(p, BoolRef) and is_const(p), "Boolean expression expected")
8245 Z3_optimize_assert_and_track(self.ctx.ref(), self.optimize, a.as_ast(), p.as_ast())
8246
8247 def add_soft(self, arg, weight="1", id=None):
8248 """Add soft constraint with optional weight and optional identifier.
8249 If no weight is supplied, then the penalty for violating the soft constraint
8250 is 1.
8251 Soft constraints are grouped by identifiers. Soft constraints that are
8252 added without identifiers are grouped by default.
8253 """
8254 if _is_int(weight):
8255 weight = "%d" % weight
8256 elif isinstance(weight, float):
8257 weight = "%f" % weight
8258 if not isinstance(weight, str):
8259 raise Z3Exception("weight should be a string or an integer")
8260 if id is None:
8261 id = ""
8262 id = to_symbol(id, self.ctx)
8263
8264 def asoft(a):
8265 v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, a.as_ast(), weight, id)
8266 return OptimizeObjective(self, v, False)
8267 if sys.version_info.major >= 3 and isinstance(arg, Iterable):
8268 return [asoft(a) for a in arg]
8269 return asoft(arg)
8270
8271 def set_initial_value(self, var, value):
8272 """initialize the solver's state by setting the initial value of var to value
8273 """
8274 s = var.sort()
8275 value = s.cast(value)
8276 Z3_optimize_set_initial_value(self.ctx.ref(), self.optimize, var.ast, value.ast)
8277
8278 def maximize(self, arg):
8279 """Add objective function to maximize."""
8280 return OptimizeObjective(
8281 self,
8282 Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()),
8283 is_max=True,
8284 )
8285
8286 def minimize(self, arg):
8287 """Add objective function to minimize."""
8288 return OptimizeObjective(
8289 self,
8290 Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()),
8291 is_max=False,
8292 )
8293
8294 def push(self):
8295 """create a backtracking point for added rules, facts and assertions"""
8296 Z3_optimize_push(self.ctx.ref(), self.optimize)
8297
8298 def pop(self):
8299 """restore to previously created backtracking point"""
8300 Z3_optimize_pop(self.ctx.ref(), self.optimize)
8301
8302 def check(self, *assumptions):
8303 """Check consistency and produce optimal values."""
8304 assumptions = _get_args(assumptions)
8305 num = len(assumptions)
8306 _assumptions = (Ast * num)()
8307 for i in range(num):
8308 _assumptions[i] = assumptions[i].as_ast()
8309 return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
8310
8311 def reason_unknown(self):
8312 """Return a string that describes why the last `check()` returned `unknown`."""
8313 return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
8314
8315 def model(self):
8316 """Return a model for the last check()."""
8317 try:
8318 return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
8319 except Z3Exception:
8320 raise Z3Exception("model is not available")
8321
8322 def unsat_core(self):
8323 return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
8324
8325 def lower(self, obj):
8326 if not isinstance(obj, OptimizeObjective):
8327 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8328 return obj.lower()
8329
8330 def upper(self, obj):
8331 if not isinstance(obj, OptimizeObjective):
8332 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8333 return obj.upper()
8334
8335 def lower_values(self, obj):
8336 if not isinstance(obj, OptimizeObjective):
8337 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8338 return obj.lower_values()
8339
8340 def upper_values(self, obj):
8341 if not isinstance(obj, OptimizeObjective):
8342 raise Z3Exception("Expecting objective handle returned by maximize/minimize")
8343 return obj.upper_values()
8344
8345 def from_file(self, filename):
8346 """Parse assertions and objectives from a file"""
8347 Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
8348
8349 def from_string(self, s):
8350 """Parse assertions and objectives from a string"""
8351 Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
8352
8353 def assertions(self):
8354 """Return an AST vector containing all added constraints."""
8355 return AstVector(Z3_optimize_get_assertions(self.ctx.ref(), self.optimize), self.ctx)
8356
8357 def objectives(self):
8358 """returns set of objective functions"""
8359 return AstVector(Z3_optimize_get_objectives(self.ctx.ref(), self.optimize), self.ctx)
8360
8361 def __repr__(self):
8362 """Return a formatted string with all added rules and constraints."""
8363 return self.sexpr()
8364
8365 def sexpr(self):
8366 """Return a formatted string (in Lisp-like format) with all added constraints.
8367 We say the string is in s-expression format.
8368 """
8369 return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
8370
8371 def statistics(self):
8372 """Return statistics for the last check`.
8373 """
8374 return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
8375
8376 def set_on_model(self, on_model):
8377 """Register a callback that is invoked with every incremental improvement to
8378 objective values. The callback takes a model as argument.
8379 The life-time of the model is limited to the callback so the
8380 model has to be (deep) copied if it is to be used after the callback
8381 """
8382 id = len(_on_models) + 41
8383 mdl = Model(self.ctx)
8384 _on_models[id] = (on_model, mdl)
8385 self._on_models_id = id
8386 Z3_optimize_register_model_eh(
8387 self.ctx.ref(), self.optimize, mdl.model, ctypes.c_void_p(id), _on_model_eh,
8388 )
8389
8390
8391#########################################
8392#
8393# ApplyResult
8394#
8395#########################################
8396class ApplyResult(Z3PPObject):
8397 """An ApplyResult object contains the subgoals produced by a tactic when applied to a goal.
8398 It also contains model and proof converters.
8399 """
8400
8401 def __init__(self, result, ctx):
8402 self.result = result
8403 self.ctx = ctx
8404 Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
8405
8406 def __deepcopy__(self, memo={}):
8407 return ApplyResult(self.result, self.ctx)
8408
8409 def __del__(self):
8410 if self.ctx.ref() is not None and Z3_apply_result_dec_ref is not None:
8411 Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
8412
8413 def __len__(self):
8414 """Return the number of subgoals in `self`.
8415
8416 >>> a, b = Ints('a b')
8417 >>> g = Goal()
8418 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8419 >>> t = Tactic('split-clause')
8420 >>> r = t(g)
8421 >>> len(r)
8422 2
8423 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'))
8424 >>> len(t(g))
8425 4
8426 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values'))
8427 >>> len(t(g))
8428 1
8429 """
8430 return int(Z3_apply_result_get_num_subgoals(self.ctx.ref(), self.result))
8431
8432 def __getitem__(self, idx):
8433 """Return one of the subgoals stored in ApplyResult object `self`.
8434
8435 >>> a, b = Ints('a b')
8436 >>> g = Goal()
8437 >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b)
8438 >>> t = Tactic('split-clause')
8439 >>> r = t(g)
8440 >>> r[0]
8441 [a == 0, Or(b == 0, b == 1), a > b]
8442 >>> r[1]
8443 [a == 1, Or(b == 0, b == 1), a > b]
8444 """
8445 if idx < 0:
8446 idx += len(self)
8447 if idx < 0 or idx >= len(self):
8448 raise IndexError
8449 return Goal(goal=Z3_apply_result_get_subgoal(self.ctx.ref(), self.result, idx), ctx=self.ctx)
8450
8451 def __repr__(self):
8452 return obj_to_string(self)
8453
8454 def sexpr(self):
8455 """Return a textual representation of the s-expression representing the set of subgoals in `self`."""
8456 return Z3_apply_result_to_string(self.ctx.ref(), self.result)
8457
8458 def as_expr(self):
8459 """Return a Z3 expression consisting of all subgoals.
8460
8461 >>> x = Int('x')
8462 >>> g = Goal()
8463 >>> g.add(x > 1)
8464 >>> g.add(Or(x == 2, x == 3))
8465 >>> r = Tactic('simplify')(g)
8466 >>> r
8467 [[Not(x <= 1), Or(x == 2, x == 3)]]
8468 >>> r.as_expr()
8469 And(Not(x <= 1), Or(x == 2, x == 3))
8470 >>> r = Tactic('split-clause')(g)
8471 >>> r
8472 [[x > 1, x == 2], [x > 1, x == 3]]
8473 >>> r.as_expr()
8474 Or(And(x > 1, x == 2), And(x > 1, x == 3))
8475 """
8476 sz = len(self)
8477 if sz == 0:
8478 return BoolVal(False, self.ctx)
8479 elif sz == 1:
8480 return self[0].as_expr()
8481 else:
8482 return Or([self[i].as_expr() for i in range(len(self))])
8483
8484#########################################
8485#
8486# Simplifiers
8487#
8488#########################################
8489
8490class Simplifier:
8491 """Simplifiers act as pre-processing utilities for solvers.
8492 Build a custom simplifier and add it to a solver"""
8493
8494 def __init__(self, simplifier, ctx=None):
8495 self.ctx = _get_ctx(ctx)
8496 self.simplifier = None
8497 if isinstance(simplifier, SimplifierObj):
8498 self.simplifier = simplifier
8499 elif isinstance(simplifier, list):
8500 simps = [Simplifier(s, ctx) for s in simplifier]
8501 self.simplifier = simps[0].simplifier
8502 for i in range(1, len(simps)):
8503 self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
8504 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8505 return
8506 else:
8507 if z3_debug():
8508 _z3_assert(isinstance(simplifier, str), "simplifier name expected")
8509 try:
8510 self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
8511 except Z3Exception:
8512 raise Z3Exception("unknown simplifier '%s'" % simplifier)
8513 Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
8514
8515 def __deepcopy__(self, memo={}):
8516 return Simplifier(self.simplifier, self.ctx)
8517
8518 def __del__(self):
8519 if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
8520 Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
8521
8522 def using_params(self, *args, **keys):
8523 """Return a simplifier that uses the given configuration options"""
8524 p = args2params(args, keys, self.ctx)
8525 return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
8526
8527 def add(self, solver):
8528 """Return a solver that applies the simplification pre-processing specified by the simplifier"""
8529 return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
8530
8531 def help(self):
8532 """Display a string containing a description of the available options for the `self` simplifier."""
8533 print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
8534
8535 def param_descrs(self):
8536 """Return the parameter description set."""
8537 return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
8538
8539
8540#########################################
8541#
8542# Tactics
8543#
8544#########################################
8545
8546
8547class Tactic:
8548 """Tactics transform, solver and/or simplify sets of constraints (Goal).
8549 A Tactic can be converted into a Solver using the method solver().
8550
8551 Several combinators are available for creating new tactics using the built-in ones:
8552 Then(), OrElse(), FailIf(), Repeat(), When(), Cond().
8553 """
8554
8555 def __init__(self, tactic, ctx=None):
8556 self.ctx = _get_ctx(ctx)
8557 self.tactic = None
8558 if isinstance(tactic, TacticObj):
8559 self.tactic = tactic
8560 else:
8561 if z3_debug():
8562 _z3_assert(isinstance(tactic, str), "tactic name expected")
8563 try:
8564 self.tactic = Z3_mk_tactic(self.ctx.ref(), str(tactic))
8565 except Z3Exception:
8566 raise Z3Exception("unknown tactic '%s'" % tactic)
8567 Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
8568
8569 def __deepcopy__(self, memo={}):
8570 return Tactic(self.tactic, self.ctx)
8571
8572 def __del__(self):
8573 if self.tactic is not None and self.ctx.ref() is not None and Z3_tactic_dec_ref is not None:
8574 Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
8575
8576 def solver(self, logFile=None):
8577 """Create a solver using the tactic `self`.
8578
8579 The solver supports the methods `push()` and `pop()`, but it
8580 will always solve each `check()` from scratch.
8581
8582 >>> t = Then('simplify', 'nlsat')
8583 >>> s = t.solver()
8584 >>> x = Real('x')
8585 >>> s.add(x**2 == 2, x > 0)
8586 >>> s.check()
8587 sat
8588 >>> s.model()
8589 [x = 1.4142135623?]
8590 """
8591 return Solver(Z3_mk_solver_from_tactic(self.ctx.ref(), self.tactic), self.ctx, logFile)
8592
8593 def apply(self, goal, *arguments, **keywords):
8594 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8595
8596 >>> x, y = Ints('x y')
8597 >>> t = Tactic('solve-eqs')
8598 >>> t.apply(And(x == 0, y >= x + 1))
8599 [[y >= 1]]
8600 """
8601 if z3_debug():
8602 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expressions expected")
8603 goal = _to_goal(goal)
8604 if len(arguments) > 0 or len(keywords) > 0:
8605 p = args2params(arguments, keywords, self.ctx)
8606 return ApplyResult(Z3_tactic_apply_ex(self.ctx.ref(), self.tactic, goal.goal, p.params), self.ctx)
8607 else:
8608 return ApplyResult(Z3_tactic_apply(self.ctx.ref(), self.tactic, goal.goal), self.ctx)
8609
8610 def __call__(self, goal, *arguments, **keywords):
8611 """Apply tactic `self` to the given goal or Z3 Boolean expression using the given options.
8612
8613 >>> x, y = Ints('x y')
8614 >>> t = Tactic('solve-eqs')
8615 >>> t(And(x == 0, y >= x + 1))
8616 [[y >= 1]]
8617 """
8618 return self.apply(goal, *arguments, **keywords)
8619
8620 def help(self):
8621 """Display a string containing a description of the available options for the `self` tactic."""
8622 print(Z3_tactic_get_help(self.ctx.ref(), self.tactic))
8623
8624 def param_descrs(self):
8625 """Return the parameter description set."""
8626 return ParamDescrsRef(Z3_tactic_get_param_descrs(self.ctx.ref(), self.tactic), self.ctx)
8627
8628
8629def _to_goal(a):
8630 if isinstance(a, BoolRef):
8631 goal = Goal(ctx=a.ctx)
8632 goal.add(a)
8633 return goal
8634 else:
8635 return a
8636
8637
8638def _to_tactic(t, ctx=None):
8639 if isinstance(t, Tactic):
8640 return t
8641 else:
8642 return Tactic(t, ctx)
8643
8644
8645def _and_then(t1, t2, ctx=None):
8646 t1 = _to_tactic(t1, ctx)
8647 t2 = _to_tactic(t2, ctx)
8648 if z3_debug():
8649 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8650 return Tactic(Z3_tactic_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8651
8652
8653def _or_else(t1, t2, ctx=None):
8654 t1 = _to_tactic(t1, ctx)
8655 t2 = _to_tactic(t2, ctx)
8656 if z3_debug():
8657 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8658 return Tactic(Z3_tactic_or_else(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8659
8660
8661def AndThen(*ts, **ks):
8662 """Return a tactic that applies the tactics in `*ts` in sequence.
8663
8664 >>> x, y = Ints('x y')
8665 >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs'))
8666 >>> t(And(x == 0, y > x + 1))
8667 [[Not(y <= 1)]]
8668 >>> t(And(x == 0, y > x + 1)).as_expr()
8669 Not(y <= 1)
8670 """
8671 if z3_debug():
8672 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8673 ctx = ks.get("ctx", None)
8674 num = len(ts)
8675 r = ts[0]
8676 for i in range(num - 1):
8677 r = _and_then(r, ts[i + 1], ctx)
8678 return r
8679
8680
8681def Then(*ts, **ks):
8682 """Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks).
8683
8684 >>> x, y = Ints('x y')
8685 >>> t = Then(Tactic('simplify'), Tactic('solve-eqs'))
8686 >>> t(And(x == 0, y > x + 1))
8687 [[Not(y <= 1)]]
8688 >>> t(And(x == 0, y > x + 1)).as_expr()
8689 Not(y <= 1)
8690 """
8691 return AndThen(*ts, **ks)
8692
8693
8694def OrElse(*ts, **ks):
8695 """Return a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail).
8696
8697 >>> x = Int('x')
8698 >>> t = OrElse(Tactic('split-clause'), Tactic('skip'))
8699 >>> # Tactic split-clause fails if there is no clause in the given goal.
8700 >>> t(x == 0)
8701 [[x == 0]]
8702 >>> t(Or(x == 0, x == 1))
8703 [[x == 0], [x == 1]]
8704 """
8705 if z3_debug():
8706 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8707 ctx = ks.get("ctx", None)
8708 num = len(ts)
8709 r = ts[0]
8710 for i in range(num - 1):
8711 r = _or_else(r, ts[i + 1], ctx)
8712 return r
8713
8714
8715def ParOr(*ts, **ks):
8716 """Return a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail).
8717
8718 >>> x = Int('x')
8719 >>> t = ParOr(Tactic('simplify'), Tactic('fail'))
8720 >>> t(x + 1 == 2)
8721 [[x == 1]]
8722 """
8723 if z3_debug():
8724 _z3_assert(len(ts) >= 2, "At least two arguments expected")
8725 ctx = _get_ctx(ks.get("ctx", None))
8726 ts = [_to_tactic(t, ctx) for t in ts]
8727 sz = len(ts)
8728 _args = (TacticObj * sz)()
8729 for i in range(sz):
8730 _args[i] = ts[i].tactic
8731 return Tactic(Z3_tactic_par_or(ctx.ref(), sz, _args), ctx)
8732
8733
8734def ParThen(t1, t2, ctx=None):
8735 """Return a tactic that applies t1 and then t2 to every subgoal produced by t1.
8736 The subgoals are processed in parallel.
8737
8738 >>> x, y = Ints('x y')
8739 >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values'))
8740 >>> t(And(Or(x == 1, x == 2), y == x + 1))
8741 [[x == 1, y == 2], [x == 2, y == 3]]
8742 """
8743 t1 = _to_tactic(t1, ctx)
8744 t2 = _to_tactic(t2, ctx)
8745 if z3_debug():
8746 _z3_assert(t1.ctx == t2.ctx, "Context mismatch")
8747 return Tactic(Z3_tactic_par_and_then(t1.ctx.ref(), t1.tactic, t2.tactic), t1.ctx)
8748
8749
8750def ParAndThen(t1, t2, ctx=None):
8751 """Alias for ParThen(t1, t2, ctx)."""
8752 return ParThen(t1, t2, ctx)
8753
8754
8755def With(t, *args, **keys):
8756 """Return a tactic that applies tactic `t` using the given configuration options.
8757
8758 >>> x, y = Ints('x y')
8759 >>> t = With(Tactic('simplify'), som=True)
8760 >>> t((x + 1)*(y + 2) == 0)
8761 [[2*x + y + x*y == -2]]
8762 """
8763 ctx = keys.pop("ctx", None)
8764 t = _to_tactic(t, ctx)
8765 p = args2params(args, keys, t.ctx)
8766 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8767
8768
8769def WithParams(t, p):
8770 """Return a tactic that applies tactic `t` using the given configuration options.
8771
8772 >>> x, y = Ints('x y')
8773 >>> p = ParamsRef()
8774 >>> p.set("som", True)
8775 >>> t = WithParams(Tactic('simplify'), p)
8776 >>> t((x + 1)*(y + 2) == 0)
8777 [[2*x + y + x*y == -2]]
8778 """
8779 t = _to_tactic(t, None)
8780 return Tactic(Z3_tactic_using_params(t.ctx.ref(), t.tactic, p.params), t.ctx)
8781
8782
8783def Repeat(t, max=4294967295, ctx=None):
8784 """Return a tactic that keeps applying `t` until the goal is not modified anymore
8785 or the maximum number of iterations `max` is reached.
8786
8787 >>> x, y = Ints('x y')
8788 >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y)
8789 >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip')))
8790 >>> r = t(c)
8791 >>> for subgoal in r: print(subgoal)
8792 [x == 0, y == 0, x > y]
8793 [x == 0, y == 1, x > y]
8794 [x == 1, y == 0, x > y]
8795 [x == 1, y == 1, x > y]
8796 >>> t = Then(t, Tactic('propagate-values'))
8797 >>> t(c)
8798 [[x == 1, y == 0]]
8799 """
8800 t = _to_tactic(t, ctx)
8801 return Tactic(Z3_tactic_repeat(t.ctx.ref(), t.tactic, max), t.ctx)
8802
8803
8804def TryFor(t, ms, ctx=None):
8805 """Return a tactic that applies `t` to a given goal for `ms` milliseconds.
8806
8807 If `t` does not terminate in `ms` milliseconds, then it fails.
8808 """
8809 t = _to_tactic(t, ctx)
8810 return Tactic(Z3_tactic_try_for(t.ctx.ref(), t.tactic, ms), t.ctx)
8811
8812
8813def tactics(ctx=None):
8814 """Return a list of all available tactics in Z3.
8815
8816 >>> l = tactics()
8817 >>> l.count('simplify') == 1
8818 True
8819 """
8820 ctx = _get_ctx(ctx)
8821 return [Z3_get_tactic_name(ctx.ref(), i) for i in range(Z3_get_num_tactics(ctx.ref()))]
8822
8823
8824def tactic_description(name, ctx=None):
8825 """Return a short description for the tactic named `name`.
8826
8827 >>> d = tactic_description('simplify')
8828 """
8829 ctx = _get_ctx(ctx)
8830 return Z3_tactic_get_descr(ctx.ref(), name)
8831
8832
8833def describe_tactics():
8834 """Display a (tabular) description of all available tactics in Z3."""
8835 if in_html_mode():
8836 even = True
8837 print('<table border="1" cellpadding="2" cellspacing="0">')
8838 for t in tactics():
8839 if even:
8840 print('<tr style="background-color:#CFCFCF">')
8841 even = False
8842 else:
8843 print("<tr>")
8844 even = True
8845 print("<td>%s</td><td>%s</td></tr>" % (t, insert_line_breaks(tactic_description(t), 40)))
8846 print("</table>")
8847 else:
8848 for t in tactics():
8849 print("%s : %s" % (t, tactic_description(t)))
8850
8851
8852class Probe:
8853 """Probes are used to inspect a goal (aka problem) and collect information that may be used
8854 to decide which solver and/or preprocessing step will be used.
8855 """
8856
8857 def __init__(self, probe, ctx=None):
8858 self.ctx = _get_ctx(ctx)
8859 self.probe = None
8860 if isinstance(probe, ProbeObj):
8861 self.probe = probe
8862 elif isinstance(probe, float):
8863 self.probe = Z3_probe_const(self.ctx.ref(), probe)
8864 elif _is_int(probe):
8865 self.probe = Z3_probe_const(self.ctx.ref(), float(probe))
8866 elif isinstance(probe, bool):
8867 if probe:
8868 self.probe = Z3_probe_const(self.ctx.ref(), 1.0)
8869 else:
8870 self.probe = Z3_probe_const(self.ctx.ref(), 0.0)
8871 else:
8872 if z3_debug():
8873 _z3_assert(isinstance(probe, str), "probe name expected")
8874 try:
8875 self.probe = Z3_mk_probe(self.ctx.ref(), probe)
8876 except Z3Exception:
8877 raise Z3Exception("unknown probe '%s'" % probe)
8878 Z3_probe_inc_ref(self.ctx.ref(), self.probe)
8879
8880 def __deepcopy__(self, memo={}):
8881 return Probe(self.probe, self.ctx)
8882
8883 def __del__(self):
8884 if self.probe is not None and self.ctx.ref() is not None and Z3_probe_dec_ref is not None:
8885 Z3_probe_dec_ref(self.ctx.ref(), self.probe)
8886
8887 def __lt__(self, other):
8888 """Return a probe that evaluates to "true" when the value returned by `self`
8889 is less than the value returned by `other`.
8890
8891 >>> p = Probe('size') < 10
8892 >>> x = Int('x')
8893 >>> g = Goal()
8894 >>> g.add(x > 0)
8895 >>> g.add(x < 10)
8896 >>> p(g)
8897 1.0
8898 """
8899 return Probe(Z3_probe_lt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8900
8901 def __gt__(self, other):
8902 """Return a probe that evaluates to "true" when the value returned by `self`
8903 is greater than the value returned by `other`.
8904
8905 >>> p = Probe('size') > 10
8906 >>> x = Int('x')
8907 >>> g = Goal()
8908 >>> g.add(x > 0)
8909 >>> g.add(x < 10)
8910 >>> p(g)
8911 0.0
8912 """
8913 return Probe(Z3_probe_gt(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8914
8915 def __le__(self, other):
8916 """Return a probe that evaluates to "true" when the value returned by `self`
8917 is less than or equal to the value returned by `other`.
8918
8919 >>> p = Probe('size') <= 2
8920 >>> x = Int('x')
8921 >>> g = Goal()
8922 >>> g.add(x > 0)
8923 >>> g.add(x < 10)
8924 >>> p(g)
8925 1.0
8926 """
8927 return Probe(Z3_probe_le(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8928
8929 def __ge__(self, other):
8930 """Return a probe that evaluates to "true" when the value returned by `self`
8931 is greater than or equal to the value returned by `other`.
8932
8933 >>> p = Probe('size') >= 2
8934 >>> x = Int('x')
8935 >>> g = Goal()
8936 >>> g.add(x > 0)
8937 >>> g.add(x < 10)
8938 >>> p(g)
8939 1.0
8940 """
8941 return Probe(Z3_probe_ge(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8942
8943 def __eq__(self, other):
8944 """Return a probe that evaluates to "true" when the value returned by `self`
8945 is equal to the value returned by `other`.
8946
8947 >>> p = Probe('size') == 2
8948 >>> x = Int('x')
8949 >>> g = Goal()
8950 >>> g.add(x > 0)
8951 >>> g.add(x < 10)
8952 >>> p(g)
8953 1.0
8954 """
8955 return Probe(Z3_probe_eq(self.ctx.ref(), self.probe, _to_probe(other, self.ctx).probe), self.ctx)
8956
8957 def __ne__(self, other):
8958 """Return a probe that evaluates to "true" when the value returned by `self`
8959 is not equal to the value returned by `other`.
8960
8961 >>> p = Probe('size') != 2
8962 >>> x = Int('x')
8963 >>> g = Goal()
8964 >>> g.add(x > 0)
8965 >>> g.add(x < 10)
8966 >>> p(g)
8967 0.0
8968 """
8969 p = self.__eq__(other)
8970 return Probe(Z3_probe_not(self.ctx.ref(), p.probe), self.ctx)
8971
8972 def __call__(self, goal):
8973 """Evaluate the probe `self` in the given goal.
8974
8975 >>> p = Probe('size')
8976 >>> x = Int('x')
8977 >>> g = Goal()
8978 >>> g.add(x > 0)
8979 >>> g.add(x < 10)
8980 >>> p(g)
8981 2.0
8982 >>> g.add(x < 20)
8983 >>> p(g)
8984 3.0
8985 >>> p = Probe('num-consts')
8986 >>> p(g)
8987 1.0
8988 >>> p = Probe('is-propositional')
8989 >>> p(g)
8990 0.0
8991 >>> p = Probe('is-qflia')
8992 >>> p(g)
8993 1.0
8994 """
8995 if z3_debug():
8996 _z3_assert(isinstance(goal, (Goal, BoolRef)), "Z3 Goal or Boolean expression expected")
8997 goal = _to_goal(goal)
8998 return Z3_probe_apply(self.ctx.ref(), self.probe, goal.goal)
8999
9000
9001def is_probe(p):
9002 """Return `True` if `p` is a Z3 probe.
9003
9004 >>> is_probe(Int('x'))
9005 False
9006 >>> is_probe(Probe('memory'))
9007 True
9008 """
9009 return isinstance(p, Probe)
9010
9011
9012def _to_probe(p, ctx=None):
9013 if is_probe(p):
9014 return p
9015 else:
9016 return Probe(p, ctx)
9017
9018
9019def probes(ctx=None):
9020 """Return a list of all available probes in Z3.
9021
9022 >>> l = probes()
9023 >>> l.count('memory') == 1
9024 True
9025 """
9026 ctx = _get_ctx(ctx)
9027 return [Z3_get_probe_name(ctx.ref(), i) for i in range(Z3_get_num_probes(ctx.ref()))]
9028
9029
9030def probe_description(name, ctx=None):
9031 """Return a short description for the probe named `name`.
9032
9033 >>> d = probe_description('memory')
9034 """
9035 ctx = _get_ctx(ctx)
9036 return Z3_probe_get_descr(ctx.ref(), name)
9037
9038
9039def describe_probes():
9040 """Display a (tabular) description of all available probes in Z3."""
9041 if in_html_mode():
9042 even = True
9043 print('<table border="1" cellpadding="2" cellspacing="0">')
9044 for p in probes():
9045 if even:
9046 print('<tr style="background-color:#CFCFCF">')
9047 even = False
9048 else:
9049 print("<tr>")
9050 even = True
9051 print("<td>%s</td><td>%s</td></tr>" % (p, insert_line_breaks(probe_description(p), 40)))
9052 print("</table>")
9053 else:
9054 for p in probes():
9055 print("%s : %s" % (p, probe_description(p)))
9056
9057
9058def _probe_nary(f, args, ctx):
9059 if z3_debug():
9060 _z3_assert(len(args) > 0, "At least one argument expected")
9061 num = len(args)
9062 r = _to_probe(args[0], ctx)
9063 for i in range(num - 1):
9064 r = Probe(f(ctx.ref(), r.probe, _to_probe(args[i + 1], ctx).probe), ctx)
9065 return r
9066
9067
9068def _probe_and(args, ctx):
9069 return _probe_nary(Z3_probe_and, args, ctx)
9070
9071
9072def _probe_or(args, ctx):
9073 return _probe_nary(Z3_probe_or, args, ctx)
9074
9075
9076def FailIf(p, ctx=None):
9077 """Return a tactic that fails if the probe `p` evaluates to true.
9078 Otherwise, it returns the input goal unmodified.
9079
9080 In the following example, the tactic applies 'simplify' if and only if there are
9081 more than 2 constraints in the goal.
9082
9083 >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify'))
9084 >>> x, y = Ints('x y')
9085 >>> g = Goal()
9086 >>> g.add(x > 0)
9087 >>> g.add(y > 0)
9088 >>> t(g)
9089 [[x > 0, y > 0]]
9090 >>> g.add(x == y + 1)
9091 >>> t(g)
9092 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9093 """
9094 p = _to_probe(p, ctx)
9095 return Tactic(Z3_tactic_fail_if(p.ctx.ref(), p.probe), p.ctx)
9096
9097
9098def When(p, t, ctx=None):
9099 """Return a tactic that applies tactic `t` only if probe `p` evaluates to true.
9100 Otherwise, it returns the input goal unmodified.
9101
9102 >>> t = When(Probe('size') > 2, Tactic('simplify'))
9103 >>> x, y = Ints('x y')
9104 >>> g = Goal()
9105 >>> g.add(x > 0)
9106 >>> g.add(y > 0)
9107 >>> t(g)
9108 [[x > 0, y > 0]]
9109 >>> g.add(x == y + 1)
9110 >>> t(g)
9111 [[Not(x <= 0), Not(y <= 0), x == 1 + y]]
9112 """
9113 p = _to_probe(p, ctx)
9114 t = _to_tactic(t, ctx)
9115 return Tactic(Z3_tactic_when(t.ctx.ref(), p.probe, t.tactic), t.ctx)
9116
9117
9118def Cond(p, t1, t2, ctx=None):
9119 """Return a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise.
9120
9121 >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt'))
9122 """
9123 p = _to_probe(p, ctx)
9124 t1 = _to_tactic(t1, ctx)
9125 t2 = _to_tactic(t2, ctx)
9126 return Tactic(Z3_tactic_cond(t1.ctx.ref(), p.probe, t1.tactic, t2.tactic), t1.ctx)
9127
9128#########################################
9129#
9130# Utils
9131#
9132#########################################
9133
9134
9135def simplify(a, *arguments, **keywords):
9136 """Simplify the expression `a` using the given options.
9137
9138 This function has many options. Use `help_simplify` to obtain the complete list.
9139
9140 >>> x = Int('x')
9141 >>> y = Int('y')
9142 >>> simplify(x + 1 + y + x + 1)
9143 2 + 2*x + y
9144 >>> simplify((x + 1)*(y + 1), som=True)
9145 1 + x + y + x*y
9146 >>> simplify(Distinct(x, y, 1), blast_distinct=True)
9147 And(Not(x == y), Not(x == 1), Not(y == 1))
9148 >>> simplify(And(x == 0, y == 1), elim_and=True)
9149 Not(Or(Not(x == 0), Not(y == 1)))
9150 """
9151 if z3_debug():
9152 _z3_assert(is_expr(a), "Z3 expression expected")
9153 if len(arguments) > 0 or len(keywords) > 0:
9154 p = args2params(arguments, keywords, a.ctx)
9155 return _to_expr_ref(Z3_simplify_ex(a.ctx_ref(), a.as_ast(), p.params), a.ctx)
9156 else:
9157 return _to_expr_ref(Z3_simplify(a.ctx_ref(), a.as_ast()), a.ctx)
9158
9159
9160def help_simplify():
9161 """Return a string describing all options available for Z3 `simplify` procedure."""
9162 print(Z3_simplify_get_help(main_ctx().ref()))
9163
9164
9165def simplify_param_descrs():
9166 """Return the set of parameter descriptions for Z3 `simplify` procedure."""
9167 return ParamDescrsRef(Z3_simplify_get_param_descrs(main_ctx().ref()), main_ctx())
9168
9169
9170def substitute(t, *m):
9171 """Apply substitution m on t, m is a list of pairs of the form (from, to).
9172 Every occurrence in t of from is replaced with to.
9173
9174 >>> x = Int('x')
9175 >>> y = Int('y')
9176 >>> substitute(x + 1, (x, y + 1))
9177 y + 1 + 1
9178 >>> f = Function('f', IntSort(), IntSort())
9179 >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1)))
9180 1 + 1
9181 """
9182 if isinstance(m, tuple):
9183 m1 = _get_args(m)
9184 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9185 m = m1
9186 if z3_debug():
9187 _z3_assert(is_expr(t), "Z3 expression expected")
9188 _z3_assert(
9189 all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) for p in m]),
9190 "Z3 invalid substitution, expression pairs expected.")
9191 _z3_assert(
9192 all([p[0].sort().eq(p[1].sort()) for p in m]),
9193 'Z3 invalid substitution, mismatching "from" and "to" sorts.')
9194 num = len(m)
9195 _from = (Ast * num)()
9196 _to = (Ast * num)()
9197 for i in range(num):
9198 _from[i] = m[i][0].as_ast()
9199 _to[i] = m[i][1].as_ast()
9200 return _to_expr_ref(Z3_substitute(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9201
9202
9203def substitute_vars(t, *m):
9204 """Substitute the free variables in t with the expression in m.
9205
9206 >>> v0 = Var(0, IntSort())
9207 >>> v1 = Var(1, IntSort())
9208 >>> x = Int('x')
9209 >>> f = Function('f', IntSort(), IntSort(), IntSort())
9210 >>> # replace v0 with x+1 and v1 with x
9211 >>> substitute_vars(f(v0, v1), x + 1, x)
9212 f(x + 1, x)
9213 """
9214 if z3_debug():
9215 _z3_assert(is_expr(t), "Z3 expression expected")
9216 _z3_assert(all([is_expr(n) for n in m]), "Z3 invalid substitution, list of expressions expected.")
9217 num = len(m)
9218 _to = (Ast * num)()
9219 for i in range(num):
9220 _to[i] = m[i].as_ast()
9221 return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
9222
9223def substitute_funs(t, *m):
9224 """Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
9225 Every occurrence in to of the function from is replaced with the expression to.
9226 The expression to can have free variables, that refer to the arguments of from.
9227 For examples, see
9228 """
9229 if isinstance(m, tuple):
9230 m1 = _get_args(m)
9231 if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
9232 m = m1
9233 if z3_debug():
9234 _z3_assert(is_expr(t), "Z3 expression expected")
9235 _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.")
9236 num = len(m)
9237 _from = (FuncDecl * num)()
9238 _to = (Ast * num)()
9239 for i in range(num):
9240 _from[i] = m[i][0].as_func_decl()
9241 _to[i] = m[i][1].as_ast()
9242 return _to_expr_ref(Z3_substitute_funs(t.ctx.ref(), t.as_ast(), num, _from, _to), t.ctx)
9243
9244
9245def Sum(*args):
9246 """Create the sum of the Z3 expressions.
9247
9248 >>> a, b, c = Ints('a b c')
9249 >>> Sum(a, b, c)
9250 a + b + c
9251 >>> Sum([a, b, c])
9252 a + b + c
9253 >>> A = IntVector('a', 5)
9254 >>> Sum(A)
9255 a__0 + a__1 + a__2 + a__3 + a__4
9256 """
9257 args = _get_args(args)
9258 if len(args) == 0:
9259 return 0
9260 ctx = _ctx_from_ast_arg_list(args)
9261 if ctx is None:
9262 return _reduce(lambda a, b: a + b, args, 0)
9263 args = _coerce_expr_list(args, ctx)
9264 if is_bv(args[0]):
9265 return _reduce(lambda a, b: a + b, args, 0)
9266 else:
9267 _args, sz = _to_ast_array(args)
9268 return ArithRef(Z3_mk_add(ctx.ref(), sz, _args), ctx)
9269
9270
9271def Product(*args):
9272 """Create the product of the Z3 expressions.
9273
9274 >>> a, b, c = Ints('a b c')
9275 >>> Product(a, b, c)
9276 a*b*c
9277 >>> Product([a, b, c])
9278 a*b*c
9279 >>> A = IntVector('a', 5)
9280 >>> Product(A)
9281 a__0*a__1*a__2*a__3*a__4
9282 """
9283 args = _get_args(args)
9284 if len(args) == 0:
9285 return 1
9286 ctx = _ctx_from_ast_arg_list(args)
9287 if ctx is None:
9288 return _reduce(lambda a, b: a * b, args, 1)
9289 args = _coerce_expr_list(args, ctx)
9290 if is_bv(args[0]):
9291 return _reduce(lambda a, b: a * b, args, 1)
9292 else:
9293 _args, sz = _to_ast_array(args)
9294 return ArithRef(Z3_mk_mul(ctx.ref(), sz, _args), ctx)
9295
9296def Abs(arg):
9297 """Create the absolute value of an arithmetic expression"""
9298 return If(arg > 0, arg, -arg)
9299
9300
9301def AtMost(*args):
9302 """Create an at-most Pseudo-Boolean k constraint.
9303
9304 >>> a, b, c = Bools('a b c')
9305 >>> f = AtMost(a, b, c, 2)
9306 """
9307 args = _get_args(args)
9308 if z3_debug():
9309 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9310 ctx = _ctx_from_ast_arg_list(args)
9311 if z3_debug():
9312 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9313 args1 = _coerce_expr_list(args[:-1], ctx)
9314 k = args[-1]
9315 _args, sz = _to_ast_array(args1)
9316 return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
9317
9318
9319def AtLeast(*args):
9320 """Create an at-least Pseudo-Boolean k constraint.
9321
9322 >>> a, b, c = Bools('a b c')
9323 >>> f = AtLeast(a, b, c, 2)
9324 """
9325 args = _get_args(args)
9326 if z3_debug():
9327 _z3_assert(len(args) > 1, "Non empty list of arguments expected")
9328 ctx = _ctx_from_ast_arg_list(args)
9329 if z3_debug():
9330 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9331 args1 = _coerce_expr_list(args[:-1], ctx)
9332 k = args[-1]
9333 _args, sz = _to_ast_array(args1)
9334 return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
9335
9336
9337def _reorder_pb_arg(arg):
9338 a, b = arg
9339 if not _is_int(b) and _is_int(a):
9340 return b, a
9341 return arg
9342
9343
9344def _pb_args_coeffs(args, default_ctx=None):
9345 args = _get_args_ast_list(args)
9346 if len(args) == 0:
9347 return _get_ctx(default_ctx), 0, (Ast * 0)(), (ctypes.c_int * 0)()
9348 args = [_reorder_pb_arg(arg) for arg in args]
9349 args, coeffs = zip(*args)
9350 if z3_debug():
9351 _z3_assert(len(args) > 0, "Non empty list of arguments expected")
9352 ctx = _ctx_from_ast_arg_list(args)
9353 if z3_debug():
9354 _z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
9355 args = _coerce_expr_list(args, ctx)
9356 _args, sz = _to_ast_array(args)
9357 _coeffs = (ctypes.c_int * len(coeffs))()
9358 for i in range(len(coeffs)):
9359 _z3_check_cint_overflow(coeffs[i], "coefficient")
9360 _coeffs[i] = coeffs[i]
9361 return ctx, sz, _args, _coeffs, args
9362
9363
9364def PbLe(args, k):
9365 """Create a Pseudo-Boolean inequality k constraint.
9366
9367 >>> a, b, c = Bools('a b c')
9368 >>> f = PbLe(((a,1),(b,3),(c,2)), 3)
9369 """
9370 _z3_check_cint_overflow(k, "k")
9371 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9372 return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
9373
9374
9375def PbGe(args, k):
9376 """Create a Pseudo-Boolean inequality k constraint.
9377
9378 >>> a, b, c = Bools('a b c')
9379 >>> f = PbGe(((a,1),(b,3),(c,2)), 3)
9380 """
9381 _z3_check_cint_overflow(k, "k")
9382 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9383 return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
9384
9385
9386def PbEq(args, k, ctx=None):
9387 """Create a Pseudo-Boolean equality k constraint.
9388
9389 >>> a, b, c = Bools('a b c')
9390 >>> f = PbEq(((a,1),(b,3),(c,2)), 3)
9391 """
9392 _z3_check_cint_overflow(k, "k")
9393 ctx, sz, _args, _coeffs, args = _pb_args_coeffs(args)
9394 return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
9395
9396
9397def solve(*args, **keywords):
9398 """Solve the constraints `*args`.
9399
9400 This is a simple function for creating demonstrations. It creates a solver,
9401 configure it using the options in `keywords`, adds the constraints
9402 in `args`, and invokes check.
9403
9404 >>> a = Int('a')
9405 >>> solve(a > 0, a < 2)
9406 [a = 1]
9407 """
9408 show = keywords.pop("show", False)
9409 s = Solver()
9410 s.set(**keywords)
9411 s.add(*args)
9412 if show:
9413 print(s)
9414 r = s.check()
9415 if r == unsat:
9416 print("no solution")
9417 elif r == unknown:
9418 print("failed to solve")
9419 try:
9420 print(s.model())
9421 except Z3Exception:
9422 return
9423 else:
9424 print(s.model())
9425
9426
9427def solve_using(s, *args, **keywords):
9428 """Solve the constraints `*args` using solver `s`.
9429
9430 This is a simple function for creating demonstrations. It is similar to `solve`,
9431 but it uses the given solver `s`.
9432 It configures solver `s` using the options in `keywords`, adds the constraints
9433 in `args`, and invokes check.
9434 """
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("Problem:")
9442 print(s)
9443 r = s.check()
9444 if r == unsat:
9445 print("no solution")
9446 elif r == unknown:
9447 print("failed to solve")
9448 try:
9449 print(s.model())
9450 except Z3Exception:
9451 return
9452 else:
9453 if show:
9454 print("Solution:")
9455 print(s.model())
9456
9457
9458def prove(claim, show=False, **keywords):
9459 """Try to prove the given claim.
9460
9461 This is a simple function for creating demonstrations. It tries to prove
9462 `claim` by showing the negation is unsatisfiable.
9463
9464 >>> p, q = Bools('p q')
9465 >>> prove(Not(And(p, q)) == Or(Not(p), Not(q)))
9466 proved
9467 """
9468 if z3_debug():
9469 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9470 s = Solver()
9471 s.set(**keywords)
9472 s.add(Not(claim))
9473 if show:
9474 print(s)
9475 r = s.check()
9476 if r == unsat:
9477 print("proved")
9478 elif r == unknown:
9479 print("failed to prove")
9480 print(s.model())
9481 else:
9482 print("counterexample")
9483 print(s.model())
9484
9485
9486def _solve_html(*args, **keywords):
9487 """Version of function `solve` that renders HTML output."""
9488 show = keywords.pop("show", False)
9489 s = Solver()
9490 s.set(**keywords)
9491 s.add(*args)
9492 if show:
9493 print("<b>Problem:</b>")
9494 print(s)
9495 r = s.check()
9496 if r == unsat:
9497 print("<b>no solution</b>")
9498 elif r == unknown:
9499 print("<b>failed to solve</b>")
9500 try:
9501 print(s.model())
9502 except Z3Exception:
9503 return
9504 else:
9505 if show:
9506 print("<b>Solution:</b>")
9507 print(s.model())
9508
9509
9510def _solve_using_html(s, *args, **keywords):
9511 """Version of function `solve_using` that renders HTML."""
9512 show = keywords.pop("show", False)
9513 if z3_debug():
9514 _z3_assert(isinstance(s, Solver), "Solver object expected")
9515 s.set(**keywords)
9516 s.add(*args)
9517 if show:
9518 print("<b>Problem:</b>")
9519 print(s)
9520 r = s.check()
9521 if r == unsat:
9522 print("<b>no solution</b>")
9523 elif r == unknown:
9524 print("<b>failed to solve</b>")
9525 try:
9526 print(s.model())
9527 except Z3Exception:
9528 return
9529 else:
9530 if show:
9531 print("<b>Solution:</b>")
9532 print(s.model())
9533
9534
9535def _prove_html(claim, show=False, **keywords):
9536 """Version of function `prove` that renders HTML."""
9537 if z3_debug():
9538 _z3_assert(is_bool(claim), "Z3 Boolean expression expected")
9539 s = Solver()
9540 s.set(**keywords)
9541 s.add(Not(claim))
9542 if show:
9543 print(s)
9544 r = s.check()
9545 if r == unsat:
9546 print("<b>proved</b>")
9547 elif r == unknown:
9548 print("<b>failed to prove</b>")
9549 print(s.model())
9550 else:
9551 print("<b>counterexample</b>")
9552 print(s.model())
9553
9554
9555def _dict2sarray(sorts, ctx):
9556 sz = len(sorts)
9557 _names = (Symbol * sz)()
9558 _sorts = (Sort * sz)()
9559 i = 0
9560 for k in sorts:
9561 v = sorts[k]
9562 if z3_debug():
9563 _z3_assert(isinstance(k, str), "String expected")
9564 _z3_assert(is_sort(v), "Z3 sort expected")
9565 _names[i] = to_symbol(k, ctx)
9566 _sorts[i] = v.ast
9567 i = i + 1
9568 return sz, _names, _sorts
9569
9570
9571def _dict2darray(decls, ctx):
9572 sz = len(decls)
9573 _names = (Symbol * sz)()
9574 _decls = (FuncDecl * sz)()
9575 i = 0
9576 for k in decls:
9577 v = decls[k]
9578 if z3_debug():
9579 _z3_assert(isinstance(k, str), "String expected")
9580 _z3_assert(is_func_decl(v) or is_const(v), "Z3 declaration or constant expected")
9581 _names[i] = to_symbol(k, ctx)
9582 if is_const(v):
9583 _decls[i] = v.decl().ast
9584 else:
9585 _decls[i] = v.ast
9586 i = i + 1
9587 return sz, _names, _decls
9588
9589class ParserContext:
9590 def __init__(self, ctx= None):
9591 self.ctx = _get_ctx(ctx)
9592 self.pctx = Z3_mk_parser_context(self.ctx.ref())
9593 Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
9594
9595 def __del__(self):
9596 if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
9597 Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
9598 self.pctx = None
9599
9600 def add_sort(self, sort):
9601 Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
9602
9603 def add_decl(self, decl):
9604 Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
9605
9606 def from_string(self, s):
9607 return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
9608
9609def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
9610 """Parse a string in SMT 2.0 format using the given sorts and decls.
9611
9612 The arguments sorts and decls are Python dictionaries used to initialize
9613 the symbol table used for the SMT 2.0 parser.
9614
9615 >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))')
9616 [x > 0, x < 10]
9617 >>> x, y = Ints('x y')
9618 >>> f = Function('f', IntSort(), IntSort())
9619 >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f})
9620 [x + f(y) > 0]
9621 >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() })
9622 [a > 0]
9623 """
9624 ctx = _get_ctx(ctx)
9625 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9626 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9627 return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9628
9629
9630def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
9631 """Parse a file in SMT 2.0 format using the given sorts and decls.
9632
9633 This function is similar to parse_smt2_string().
9634 """
9635 ctx = _get_ctx(ctx)
9636 ssz, snames, ssorts = _dict2sarray(sorts, ctx)
9637 dsz, dnames, ddecls = _dict2darray(decls, ctx)
9638 return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
9639
9640
9641#########################################
9642#
9643# Floating-Point Arithmetic
9644#
9645#########################################
9646
9647
9648# Global default rounding mode
9649_dflt_rounding_mode = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN
9650_dflt_fpsort_ebits = 11
9651_dflt_fpsort_sbits = 53
9652
9653
9654def get_default_rounding_mode(ctx=None):
9655 """Retrieves the global default rounding mode."""
9656 global _dflt_rounding_mode
9657 if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO:
9658 return RTZ(ctx)
9659 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE:
9660 return RTN(ctx)
9661 elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE:
9662 return RTP(ctx)
9663 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN:
9664 return RNE(ctx)
9665 elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY:
9666 return RNA(ctx)
9667
9668
9669_ROUNDING_MODES = frozenset({
9670 Z3_OP_FPA_RM_TOWARD_ZERO,
9671 Z3_OP_FPA_RM_TOWARD_NEGATIVE,
9672 Z3_OP_FPA_RM_TOWARD_POSITIVE,
9673 Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
9674 Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY
9675})
9676
9677
9678def set_default_rounding_mode(rm, ctx=None):
9679 global _dflt_rounding_mode
9680 if is_fprm_value(rm):
9681 _dflt_rounding_mode = rm.kind()
9682 else:
9683 _z3_assert(_dflt_rounding_mode in _ROUNDING_MODES, "illegal rounding mode")
9684 _dflt_rounding_mode = rm
9685
9686
9687def get_default_fp_sort(ctx=None):
9688 return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx)
9689
9690
9691def set_default_fp_sort(ebits, sbits, ctx=None):
9692 global _dflt_fpsort_ebits
9693 global _dflt_fpsort_sbits
9694 _dflt_fpsort_ebits = ebits
9695 _dflt_fpsort_sbits = sbits
9696
9697
9698def _dflt_rm(ctx=None):
9699 return get_default_rounding_mode(ctx)
9700
9701
9702def _dflt_fps(ctx=None):
9703 return get_default_fp_sort(ctx)
9704
9705
9706def _coerce_fp_expr_list(alist, ctx):
9707 first_fp_sort = None
9708 for a in alist:
9709 if is_fp(a):
9710 if first_fp_sort is None:
9711 first_fp_sort = a.sort()
9712 elif first_fp_sort == a.sort():
9713 pass # OK, same as before
9714 else:
9715 # we saw at least 2 different float sorts; something will
9716 # throw a sort mismatch later, for now assume None.
9717 first_fp_sort = None
9718 break
9719
9720 r = []
9721 for i in range(len(alist)):
9722 a = alist[i]
9723 is_repr = isinstance(a, str) and a.contains("2**(") and a.endswith(")")
9724 if is_repr or _is_int(a) or isinstance(a, (float, bool)):
9725 r.append(FPVal(a, None, first_fp_sort, ctx))
9726 else:
9727 r.append(a)
9728 return _coerce_expr_list(r, ctx)
9729
9730
9731# FP Sorts
9732
9733class FPSortRef(SortRef):
9734 """Floating-point sort."""
9735
9736 def ebits(self):
9737 """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`.
9738 >>> b = FPSort(8, 24)
9739 >>> b.ebits()
9740 8
9741 """
9742 return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast))
9743
9744 def sbits(self):
9745 """Retrieves the number of bits reserved for the significand in the FloatingPoint sort `self`.
9746 >>> b = FPSort(8, 24)
9747 >>> b.sbits()
9748 24
9749 """
9750 return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast))
9751
9752 def cast(self, val):
9753 """Try to cast `val` as a floating-point expression.
9754 >>> b = FPSort(8, 24)
9755 >>> b.cast(1.0)
9756 1
9757 >>> b.cast(1.0).sexpr()
9758 '(fp #b0 #x7f #b00000000000000000000000)'
9759 """
9760 if is_expr(val):
9761 if z3_debug():
9762 _z3_assert(self.ctx == val.ctx, "Context mismatch")
9763 return val
9764 else:
9765 return FPVal(val, None, self, self.ctx)
9766
9767
9768def Float16(ctx=None):
9769 """Floating-point 16-bit (half) sort."""
9770 ctx = _get_ctx(ctx)
9771 return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx)
9772
9773
9774def FloatHalf(ctx=None):
9775 """Floating-point 16-bit (half) sort."""
9776 ctx = _get_ctx(ctx)
9777 return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx)
9778
9779
9780def Float32(ctx=None):
9781 """Floating-point 32-bit (single) sort."""
9782 ctx = _get_ctx(ctx)
9783 return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx)
9784
9785
9786def FloatSingle(ctx=None):
9787 """Floating-point 32-bit (single) sort."""
9788 ctx = _get_ctx(ctx)
9789 return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx)
9790
9791
9792def Float64(ctx=None):
9793 """Floating-point 64-bit (double) sort."""
9794 ctx = _get_ctx(ctx)
9795 return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx)
9796
9797
9798def FloatDouble(ctx=None):
9799 """Floating-point 64-bit (double) sort."""
9800 ctx = _get_ctx(ctx)
9801 return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
9802
9803
9804def Float128(ctx=None):
9805 """Floating-point 128-bit (quadruple) sort."""
9806 ctx = _get_ctx(ctx)
9807 return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx)
9808
9809
9810def FloatQuadruple(ctx=None):
9811 """Floating-point 128-bit (quadruple) sort."""
9812 ctx = _get_ctx(ctx)
9813 return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
9814
9815
9816class FPRMSortRef(SortRef):
9817 """"Floating-point rounding mode sort."""
9818
9819
9820def is_fp_sort(s):
9821 """Return True if `s` is a Z3 floating-point sort.
9822
9823 >>> is_fp_sort(FPSort(8, 24))
9824 True
9825 >>> is_fp_sort(IntSort())
9826 False
9827 """
9828 return isinstance(s, FPSortRef)
9829
9830
9831def is_fprm_sort(s):
9832 """Return True if `s` is a Z3 floating-point rounding mode sort.
9833
9834 >>> is_fprm_sort(FPSort(8, 24))
9835 False
9836 >>> is_fprm_sort(RNE().sort())
9837 True
9838 """
9839 return isinstance(s, FPRMSortRef)
9840
9841# FP Expressions
9842
9843
9844class FPRef(ExprRef):
9845 """Floating-point expressions."""
9846
9847 def sort(self):
9848 """Return the sort of the floating-point expression `self`.
9849
9850 >>> x = FP('1.0', FPSort(8, 24))
9851 >>> x.sort()
9852 FPSort(8, 24)
9853 >>> x.sort() == FPSort(8, 24)
9854 True
9855 """
9856 return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
9857
9858 def ebits(self):
9859 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9860 >>> b = FPSort(8, 24)
9861 >>> b.ebits()
9862 8
9863 """
9864 return self.sort().ebits()
9865
9866 def sbits(self):
9867 """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`.
9868 >>> b = FPSort(8, 24)
9869 >>> b.sbits()
9870 24
9871 """
9872 return self.sort().sbits()
9873
9874 def as_string(self):
9875 """Return a Z3 floating point expression as a Python string."""
9876 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
9877
9878 def __le__(self, other):
9879 return fpLEQ(self, other, self.ctx)
9880
9881 def __lt__(self, other):
9882 return fpLT(self, other, self.ctx)
9883
9884 def __ge__(self, other):
9885 return fpGEQ(self, other, self.ctx)
9886
9887 def __gt__(self, other):
9888 return fpGT(self, other, self.ctx)
9889
9890 def __add__(self, other):
9891 """Create the Z3 expression `self + other`.
9892
9893 >>> x = FP('x', FPSort(8, 24))
9894 >>> y = FP('y', FPSort(8, 24))
9895 >>> x + y
9896 x + y
9897 >>> (x + y).sort()
9898 FPSort(8, 24)
9899 """
9900 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9901 return fpAdd(_dflt_rm(), a, b, self.ctx)
9902
9903 def __radd__(self, other):
9904 """Create the Z3 expression `other + self`.
9905
9906 >>> x = FP('x', FPSort(8, 24))
9907 >>> 10 + x
9908 1.25*(2**3) + x
9909 """
9910 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9911 return fpAdd(_dflt_rm(), a, b, self.ctx)
9912
9913 def __sub__(self, other):
9914 """Create the Z3 expression `self - other`.
9915
9916 >>> x = FP('x', FPSort(8, 24))
9917 >>> y = FP('y', FPSort(8, 24))
9918 >>> x - y
9919 x - y
9920 >>> (x - y).sort()
9921 FPSort(8, 24)
9922 """
9923 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9924 return fpSub(_dflt_rm(), a, b, self.ctx)
9925
9926 def __rsub__(self, other):
9927 """Create the Z3 expression `other - self`.
9928
9929 >>> x = FP('x', FPSort(8, 24))
9930 >>> 10 - x
9931 1.25*(2**3) - x
9932 """
9933 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9934 return fpSub(_dflt_rm(), a, b, self.ctx)
9935
9936 def __mul__(self, other):
9937 """Create the Z3 expression `self * other`.
9938
9939 >>> x = FP('x', FPSort(8, 24))
9940 >>> y = FP('y', FPSort(8, 24))
9941 >>> x * y
9942 x * y
9943 >>> (x * y).sort()
9944 FPSort(8, 24)
9945 >>> 10 * y
9946 1.25*(2**3) * y
9947 """
9948 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9949 return fpMul(_dflt_rm(), a, b, self.ctx)
9950
9951 def __rmul__(self, other):
9952 """Create the Z3 expression `other * self`.
9953
9954 >>> x = FP('x', FPSort(8, 24))
9955 >>> y = FP('y', FPSort(8, 24))
9956 >>> x * y
9957 x * y
9958 >>> x * 10
9959 x * 1.25*(2**3)
9960 """
9961 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
9962 return fpMul(_dflt_rm(), a, b, self.ctx)
9963
9964 def __pos__(self):
9965 """Create the Z3 expression `+self`."""
9966 return self
9967
9968 def __neg__(self):
9969 """Create the Z3 expression `-self`.
9970
9971 >>> x = FP('x', Float32())
9972 >>> -x
9973 -x
9974 """
9975 return fpNeg(self)
9976
9977 def __div__(self, other):
9978 """Create the Z3 expression `self / other`.
9979
9980 >>> x = FP('x', FPSort(8, 24))
9981 >>> y = FP('y', FPSort(8, 24))
9982 >>> x / y
9983 x / y
9984 >>> (x / y).sort()
9985 FPSort(8, 24)
9986 >>> 10 / y
9987 1.25*(2**3) / y
9988 """
9989 [a, b] = _coerce_fp_expr_list([self, other], self.ctx)
9990 return fpDiv(_dflt_rm(), a, b, self.ctx)
9991
9992 def __rdiv__(self, other):
9993 """Create the Z3 expression `other / self`.
9994
9995 >>> x = FP('x', FPSort(8, 24))
9996 >>> y = FP('y', FPSort(8, 24))
9997 >>> x / y
9998 x / y
9999 >>> x / 10
10000 x / 1.25*(2**3)
10001 """
10002 [a, b] = _coerce_fp_expr_list([other, self], self.ctx)
10003 return fpDiv(_dflt_rm(), a, b, self.ctx)
10004
10005 def __truediv__(self, other):
10006 """Create the Z3 expression division `self / other`."""
10007 return self.__div__(other)
10008
10009 def __rtruediv__(self, other):
10010 """Create the Z3 expression division `other / self`."""
10011 return self.__rdiv__(other)
10012
10013 def __mod__(self, other):
10014 """Create the Z3 expression mod `self % other`."""
10015 return fpRem(self, other)
10016
10017 def __rmod__(self, other):
10018 """Create the Z3 expression mod `other % self`."""
10019 return fpRem(other, self)
10020
10021
10022class FPRMRef(ExprRef):
10023 """Floating-point rounding mode expressions"""
10024
10025 def as_string(self):
10026 """Return a Z3 floating point expression as a Python string."""
10027 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
10028
10029
10030def RoundNearestTiesToEven(ctx=None):
10031 ctx = _get_ctx(ctx)
10032 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10033
10034
10035def RNE(ctx=None):
10036 ctx = _get_ctx(ctx)
10037 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx)
10038
10039
10040def RoundNearestTiesToAway(ctx=None):
10041 ctx = _get_ctx(ctx)
10042 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10043
10044
10045def RNA(ctx=None):
10046 ctx = _get_ctx(ctx)
10047 return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx)
10048
10049
10050def RoundTowardPositive(ctx=None):
10051 ctx = _get_ctx(ctx)
10052 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10053
10054
10055def RTP(ctx=None):
10056 ctx = _get_ctx(ctx)
10057 return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx)
10058
10059
10060def RoundTowardNegative(ctx=None):
10061 ctx = _get_ctx(ctx)
10062 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10063
10064
10065def RTN(ctx=None):
10066 ctx = _get_ctx(ctx)
10067 return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx)
10068
10069
10070def RoundTowardZero(ctx=None):
10071 ctx = _get_ctx(ctx)
10072 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10073
10074
10075def RTZ(ctx=None):
10076 ctx = _get_ctx(ctx)
10077 return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx)
10078
10079
10080def is_fprm(a):
10081 """Return `True` if `a` is a Z3 floating-point rounding mode expression.
10082
10083 >>> rm = RNE()
10084 >>> is_fprm(rm)
10085 True
10086 >>> rm = 1.0
10087 >>> is_fprm(rm)
10088 False
10089 """
10090 return isinstance(a, FPRMRef)
10091
10092
10093def is_fprm_value(a):
10094 """Return `True` if `a` is a Z3 floating-point rounding mode numeral value."""
10095 return is_fprm(a) and _is_numeral(a.ctx, a.ast)
10096
10097# FP Numerals
10098
10099
10100class FPNumRef(FPRef):
10101 """The sign of the numeral.
10102
10103 >>> x = FPVal(+1.0, FPSort(8, 24))
10104 >>> x.sign()
10105 False
10106 >>> x = FPVal(-1.0, FPSort(8, 24))
10107 >>> x.sign()
10108 True
10109 """
10110
10111 def sign(self):
10112 num = ctypes.c_bool()
10113 nsign = Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(num))
10114 if nsign is False:
10115 raise Z3Exception("error retrieving the sign of a numeral.")
10116 return num.value != 0
10117
10118 """The sign of a floating-point numeral as a bit-vector expression.
10119
10120 Remark: NaN's are invalid arguments.
10121 """
10122
10123 def sign_as_bv(self):
10124 return BitVecNumRef(Z3_fpa_get_numeral_sign_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10125
10126 """The significand of the numeral.
10127
10128 >>> x = FPVal(2.5, FPSort(8, 24))
10129 >>> x.significand()
10130 1.25
10131 """
10132
10133 def significand(self):
10134 return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast())
10135
10136 """The significand of the numeral as a long.
10137
10138 >>> x = FPVal(2.5, FPSort(8, 24))
10139 >>> x.significand_as_long()
10140 1.25
10141 """
10142
10143 def significand_as_long(self):
10144 ptr = (ctypes.c_ulonglong * 1)()
10145 if not Z3_fpa_get_numeral_significand_uint64(self.ctx.ref(), self.as_ast(), ptr):
10146 raise Z3Exception("error retrieving the significand of a numeral.")
10147 return ptr[0]
10148
10149 """The significand of the numeral as a bit-vector expression.
10150
10151 Remark: NaN are invalid arguments.
10152 """
10153
10154 def significand_as_bv(self):
10155 return BitVecNumRef(Z3_fpa_get_numeral_significand_bv(self.ctx.ref(), self.as_ast()), self.ctx)
10156
10157 """The exponent of the numeral.
10158
10159 >>> x = FPVal(2.5, FPSort(8, 24))
10160 >>> x.exponent()
10161 1
10162 """
10163
10164 def exponent(self, biased=True):
10165 return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast(), biased)
10166
10167 """The exponent of the numeral as a long.
10168
10169 >>> x = FPVal(2.5, FPSort(8, 24))
10170 >>> x.exponent_as_long()
10171 1
10172 """
10173
10174 def exponent_as_long(self, biased=True):
10175 ptr = (ctypes.c_longlong * 1)()
10176 if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr, biased):
10177 raise Z3Exception("error retrieving the exponent of a numeral.")
10178 return ptr[0]
10179
10180 """The exponent of the numeral as a bit-vector expression.
10181
10182 Remark: NaNs are invalid arguments.
10183 """
10184
10185 def exponent_as_bv(self, biased=True):
10186 return BitVecNumRef(Z3_fpa_get_numeral_exponent_bv(self.ctx.ref(), self.as_ast(), biased), self.ctx)
10187
10188 """Indicates whether the numeral is a NaN."""
10189
10190 def isNaN(self):
10191 return Z3_fpa_is_numeral_nan(self.ctx.ref(), self.as_ast())
10192
10193 """Indicates whether the numeral is +oo or -oo."""
10194
10195 def isInf(self):
10196 return Z3_fpa_is_numeral_inf(self.ctx.ref(), self.as_ast())
10197
10198 """Indicates whether the numeral is +zero or -zero."""
10199
10200 def isZero(self):
10201 return Z3_fpa_is_numeral_zero(self.ctx.ref(), self.as_ast())
10202
10203 """Indicates whether the numeral is normal."""
10204
10205 def isNormal(self):
10206 return Z3_fpa_is_numeral_normal(self.ctx.ref(), self.as_ast())
10207
10208 """Indicates whether the numeral is subnormal."""
10209
10210 def isSubnormal(self):
10211 return Z3_fpa_is_numeral_subnormal(self.ctx.ref(), self.as_ast())
10212
10213 """Indicates whether the numeral is positive."""
10214
10215 def isPositive(self):
10216 return Z3_fpa_is_numeral_positive(self.ctx.ref(), self.as_ast())
10217
10218 """Indicates whether the numeral is negative."""
10219
10220 def isNegative(self):
10221 return Z3_fpa_is_numeral_negative(self.ctx.ref(), self.as_ast())
10222
10223 """
10224 The string representation of the numeral.
10225
10226 >>> x = FPVal(20, FPSort(8, 24))
10227 >>> x.as_string()
10228 1.25*(2**4)
10229 """
10230
10231 def as_string(self):
10232 s = Z3_get_numeral_string(self.ctx.ref(), self.as_ast())
10233 return ("FPVal(%s, %s)" % (s, self.sort()))
10234
10235 def py_value(self):
10236 bv = simplify(fpToIEEEBV(self))
10237 binary = bv.py_value()
10238 if not isinstance(binary, int):
10239 return None
10240 # Decode the IEEE 754 binary representation
10241 import struct
10242 bytes_rep = binary.to_bytes(8, byteorder='big')
10243 return struct.unpack('>d', bytes_rep)[0]
10244
10245
10246def is_fp(a):
10247 """Return `True` if `a` is a Z3 floating-point expression.
10248
10249 >>> b = FP('b', FPSort(8, 24))
10250 >>> is_fp(b)
10251 True
10252 >>> is_fp(b + 1.0)
10253 True
10254 >>> is_fp(Int('x'))
10255 False
10256 """
10257 return isinstance(a, FPRef)
10258
10259
10260def is_fp_value(a):
10261 """Return `True` if `a` is a Z3 floating-point numeral value.
10262
10263 >>> b = FP('b', FPSort(8, 24))
10264 >>> is_fp_value(b)
10265 False
10266 >>> b = FPVal(1.0, FPSort(8, 24))
10267 >>> b
10268 1
10269 >>> is_fp_value(b)
10270 True
10271 """
10272 return is_fp(a) and _is_numeral(a.ctx, a.ast)
10273
10274
10275def FPSort(ebits, sbits, ctx=None):
10276 """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used.
10277
10278 >>> Single = FPSort(8, 24)
10279 >>> Double = FPSort(11, 53)
10280 >>> Single
10281 FPSort(8, 24)
10282 >>> x = Const('x', Single)
10283 >>> eq(x, FP('x', FPSort(8, 24)))
10284 True
10285 """
10286 ctx = _get_ctx(ctx)
10287 return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx)
10288
10289
10290def _to_float_str(val, exp=0):
10291 if isinstance(val, float):
10292 if math.isnan(val):
10293 res = "NaN"
10294 elif val == 0.0:
10295 sone = math.copysign(1.0, val)
10296 if sone < 0.0:
10297 return "-0.0"
10298 else:
10299 return "+0.0"
10300 elif val == float("+inf"):
10301 res = "+oo"
10302 elif val == float("-inf"):
10303 res = "-oo"
10304 else:
10305 v = val.as_integer_ratio()
10306 num = v[0]
10307 den = v[1]
10308 rvs = str(num) + "/" + str(den)
10309 res = rvs + "p" + _to_int_str(exp)
10310 elif isinstance(val, bool):
10311 if val:
10312 res = "1.0"
10313 else:
10314 res = "0.0"
10315 elif _is_int(val):
10316 res = str(val)
10317 elif isinstance(val, str):
10318 inx = val.find("*(2**")
10319 if inx == -1:
10320 res = val
10321 elif val[-1] == ")":
10322 res = val[0:inx]
10323 exp = str(int(val[inx + 5:-1]) + int(exp))
10324 else:
10325 _z3_assert(False, "String does not have floating-point numeral form.")
10326 elif z3_debug():
10327 _z3_assert(False, "Python value cannot be used to create floating-point numerals.")
10328 if exp == 0:
10329 return res
10330 else:
10331 return res + "p" + exp
10332
10333
10334def fpNaN(s):
10335 """Create a Z3 floating-point NaN term.
10336
10337 >>> s = FPSort(8, 24)
10338 >>> set_fpa_pretty(True)
10339 >>> fpNaN(s)
10340 NaN
10341 >>> pb = get_fpa_pretty()
10342 >>> set_fpa_pretty(False)
10343 >>> fpNaN(s)
10344 fpNaN(FPSort(8, 24))
10345 >>> set_fpa_pretty(pb)
10346 """
10347 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10348 return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx)
10349
10350
10351def fpPlusInfinity(s):
10352 """Create a Z3 floating-point +oo term.
10353
10354 >>> s = FPSort(8, 24)
10355 >>> pb = get_fpa_pretty()
10356 >>> set_fpa_pretty(True)
10357 >>> fpPlusInfinity(s)
10358 +oo
10359 >>> set_fpa_pretty(False)
10360 >>> fpPlusInfinity(s)
10361 fpPlusInfinity(FPSort(8, 24))
10362 >>> set_fpa_pretty(pb)
10363 """
10364 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10365 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx)
10366
10367
10368def fpMinusInfinity(s):
10369 """Create a Z3 floating-point -oo term."""
10370 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10371 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx)
10372
10373
10374def fpInfinity(s, negative):
10375 """Create a Z3 floating-point +oo or -oo term."""
10376 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10377 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10378 return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx)
10379
10380
10381def fpPlusZero(s):
10382 """Create a Z3 floating-point +0.0 term."""
10383 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10384 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx)
10385
10386
10387def fpMinusZero(s):
10388 """Create a Z3 floating-point -0.0 term."""
10389 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10390 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx)
10391
10392
10393def fpZero(s, negative):
10394 """Create a Z3 floating-point +0.0 or -0.0 term."""
10395 _z3_assert(isinstance(s, FPSortRef), "sort mismatch")
10396 _z3_assert(isinstance(negative, bool), "expected Boolean flag")
10397 return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx)
10398
10399
10400def FPVal(sig, exp=None, fps=None, ctx=None):
10401 """Return a floating-point value of value `val` and sort `fps`.
10402 If `ctx=None`, then the global context is used.
10403
10404 >>> v = FPVal(20.0, FPSort(8, 24))
10405 >>> v
10406 1.25*(2**4)
10407 >>> print("0x%.8x" % v.exponent_as_long(False))
10408 0x00000004
10409 >>> v = FPVal(2.25, FPSort(8, 24))
10410 >>> v
10411 1.125*(2**1)
10412 >>> v = FPVal(-2.25, FPSort(8, 24))
10413 >>> v
10414 -1.125*(2**1)
10415 >>> FPVal(-0.0, FPSort(8, 24))
10416 -0.0
10417 >>> FPVal(0.0, FPSort(8, 24))
10418 +0.0
10419 >>> FPVal(+0.0, FPSort(8, 24))
10420 +0.0
10421 """
10422 ctx = _get_ctx(ctx)
10423 if is_fp_sort(exp):
10424 fps = exp
10425 exp = None
10426 elif fps is None:
10427 fps = _dflt_fps(ctx)
10428 _z3_assert(is_fp_sort(fps), "sort mismatch")
10429 if exp is None:
10430 exp = 0
10431 val = _to_float_str(sig)
10432 if val == "NaN" or val == "nan":
10433 return fpNaN(fps)
10434 elif val == "-0.0":
10435 return fpMinusZero(fps)
10436 elif val == "0.0" or val == "+0.0":
10437 return fpPlusZero(fps)
10438 elif val == "+oo" or val == "+inf" or val == "+Inf":
10439 return fpPlusInfinity(fps)
10440 elif val == "-oo" or val == "-inf" or val == "-Inf":
10441 return fpMinusInfinity(fps)
10442 else:
10443 return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx)
10444
10445
10446def FP(name, fpsort, ctx=None):
10447 """Return a floating-point constant named `name`.
10448 `fpsort` is the floating-point sort.
10449 If `ctx=None`, then the global context is used.
10450
10451 >>> x = FP('x', FPSort(8, 24))
10452 >>> is_fp(x)
10453 True
10454 >>> x.ebits()
10455 8
10456 >>> x.sort()
10457 FPSort(8, 24)
10458 >>> word = FPSort(8, 24)
10459 >>> x2 = FP('x', word)
10460 >>> eq(x, x2)
10461 True
10462 """
10463 if isinstance(fpsort, FPSortRef) and ctx is None:
10464 ctx = fpsort.ctx
10465 else:
10466 ctx = _get_ctx(ctx)
10467 return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
10468
10469
10470def FPs(names, fpsort, ctx=None):
10471 """Return an array of floating-point constants.
10472
10473 >>> x, y, z = FPs('x y z', FPSort(8, 24))
10474 >>> x.sort()
10475 FPSort(8, 24)
10476 >>> x.sbits()
10477 24
10478 >>> x.ebits()
10479 8
10480 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
10481 (x + y) * z
10482 """
10483 ctx = _get_ctx(ctx)
10484 if isinstance(names, str):
10485 names = names.split(" ")
10486 return [FP(name, fpsort, ctx) for name in names]
10487
10488
10489def fpAbs(a, ctx=None):
10490 """Create a Z3 floating-point absolute value expression.
10491
10492 >>> s = FPSort(8, 24)
10493 >>> rm = RNE()
10494 >>> x = FPVal(1.0, s)
10495 >>> fpAbs(x)
10496 fpAbs(1)
10497 >>> y = FPVal(-20.0, s)
10498 >>> y
10499 -1.25*(2**4)
10500 >>> fpAbs(y)
10501 fpAbs(-1.25*(2**4))
10502 >>> fpAbs(-1.25*(2**4))
10503 fpAbs(-1.25*(2**4))
10504 >>> fpAbs(x).sort()
10505 FPSort(8, 24)
10506 """
10507 ctx = _get_ctx(ctx)
10508 [a] = _coerce_fp_expr_list([a], ctx)
10509 return FPRef(Z3_mk_fpa_abs(ctx.ref(), a.as_ast()), ctx)
10510
10511
10512def fpNeg(a, ctx=None):
10513 """Create a Z3 floating-point addition expression.
10514
10515 >>> s = FPSort(8, 24)
10516 >>> rm = RNE()
10517 >>> x = FP('x', s)
10518 >>> fpNeg(x)
10519 -x
10520 >>> fpNeg(x).sort()
10521 FPSort(8, 24)
10522 """
10523 ctx = _get_ctx(ctx)
10524 [a] = _coerce_fp_expr_list([a], ctx)
10525 return FPRef(Z3_mk_fpa_neg(ctx.ref(), a.as_ast()), ctx)
10526
10527
10528def _mk_fp_unary(f, rm, a, ctx):
10529 ctx = _get_ctx(ctx)
10530 [a] = _coerce_fp_expr_list([a], ctx)
10531 if z3_debug():
10532 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10533 _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expression")
10534 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast()), ctx)
10535
10536
10537def _mk_fp_unary_pred(f, a, ctx):
10538 ctx = _get_ctx(ctx)
10539 [a] = _coerce_fp_expr_list([a], ctx)
10540 if z3_debug():
10541 _z3_assert(is_fp(a), "First argument must be a Z3 floating-point expression")
10542 return BoolRef(f(ctx.ref(), a.as_ast()), ctx)
10543
10544
10545def _mk_fp_bin(f, rm, a, b, ctx):
10546 ctx = _get_ctx(ctx)
10547 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10548 if z3_debug():
10549 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10550 _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression")
10551 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast()), ctx)
10552
10553
10554def _mk_fp_bin_norm(f, a, b, ctx):
10555 ctx = _get_ctx(ctx)
10556 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10557 if z3_debug():
10558 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10559 return FPRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10560
10561
10562def _mk_fp_bin_pred(f, a, b, ctx):
10563 ctx = _get_ctx(ctx)
10564 [a, b] = _coerce_fp_expr_list([a, b], ctx)
10565 if z3_debug():
10566 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10567 return BoolRef(f(ctx.ref(), a.as_ast(), b.as_ast()), ctx)
10568
10569
10570def _mk_fp_tern(f, rm, a, b, c, ctx):
10571 ctx = _get_ctx(ctx)
10572 [a, b, c] = _coerce_fp_expr_list([a, b, c], ctx)
10573 if z3_debug():
10574 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10575 _z3_assert(is_fp(a) or is_fp(b) or is_fp(
10576 c), "Second, third or fourth argument must be a Z3 floating-point expression")
10577 return FPRef(f(ctx.ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), ctx)
10578
10579
10580def fpAdd(rm, a, b, ctx=None):
10581 """Create a Z3 floating-point addition expression.
10582
10583 >>> s = FPSort(8, 24)
10584 >>> rm = RNE()
10585 >>> x = FP('x', s)
10586 >>> y = FP('y', s)
10587 >>> fpAdd(rm, x, y)
10588 x + y
10589 >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
10590 fpAdd(RTZ(), x, y)
10591 >>> fpAdd(rm, x, y).sort()
10592 FPSort(8, 24)
10593 """
10594 return _mk_fp_bin(Z3_mk_fpa_add, rm, a, b, ctx)
10595
10596
10597def fpSub(rm, a, b, ctx=None):
10598 """Create a Z3 floating-point subtraction expression.
10599
10600 >>> s = FPSort(8, 24)
10601 >>> rm = RNE()
10602 >>> x = FP('x', s)
10603 >>> y = FP('y', s)
10604 >>> fpSub(rm, x, y)
10605 x - y
10606 >>> fpSub(rm, x, y).sort()
10607 FPSort(8, 24)
10608 """
10609 return _mk_fp_bin(Z3_mk_fpa_sub, rm, a, b, ctx)
10610
10611
10612def fpMul(rm, a, b, ctx=None):
10613 """Create a Z3 floating-point multiplication expression.
10614
10615 >>> s = FPSort(8, 24)
10616 >>> rm = RNE()
10617 >>> x = FP('x', s)
10618 >>> y = FP('y', s)
10619 >>> fpMul(rm, x, y)
10620 x * y
10621 >>> fpMul(rm, x, y).sort()
10622 FPSort(8, 24)
10623 """
10624 return _mk_fp_bin(Z3_mk_fpa_mul, rm, a, b, ctx)
10625
10626
10627def fpDiv(rm, a, b, ctx=None):
10628 """Create a Z3 floating-point division expression.
10629
10630 >>> s = FPSort(8, 24)
10631 >>> rm = RNE()
10632 >>> x = FP('x', s)
10633 >>> y = FP('y', s)
10634 >>> fpDiv(rm, x, y)
10635 x / y
10636 >>> fpDiv(rm, x, y).sort()
10637 FPSort(8, 24)
10638 """
10639 return _mk_fp_bin(Z3_mk_fpa_div, rm, a, b, ctx)
10640
10641
10642def fpRem(a, b, ctx=None):
10643 """Create a Z3 floating-point remainder expression.
10644
10645 >>> s = FPSort(8, 24)
10646 >>> x = FP('x', s)
10647 >>> y = FP('y', s)
10648 >>> fpRem(x, y)
10649 fpRem(x, y)
10650 >>> fpRem(x, y).sort()
10651 FPSort(8, 24)
10652 """
10653 return _mk_fp_bin_norm(Z3_mk_fpa_rem, a, b, ctx)
10654
10655
10656def fpMin(a, b, ctx=None):
10657 """Create a Z3 floating-point minimum expression.
10658
10659 >>> s = FPSort(8, 24)
10660 >>> rm = RNE()
10661 >>> x = FP('x', s)
10662 >>> y = FP('y', s)
10663 >>> fpMin(x, y)
10664 fpMin(x, y)
10665 >>> fpMin(x, y).sort()
10666 FPSort(8, 24)
10667 """
10668 return _mk_fp_bin_norm(Z3_mk_fpa_min, a, b, ctx)
10669
10670
10671def fpMax(a, b, ctx=None):
10672 """Create a Z3 floating-point maximum expression.
10673
10674 >>> s = FPSort(8, 24)
10675 >>> rm = RNE()
10676 >>> x = FP('x', s)
10677 >>> y = FP('y', s)
10678 >>> fpMax(x, y)
10679 fpMax(x, y)
10680 >>> fpMax(x, y).sort()
10681 FPSort(8, 24)
10682 """
10683 return _mk_fp_bin_norm(Z3_mk_fpa_max, a, b, ctx)
10684
10685
10686def fpFMA(rm, a, b, c, ctx=None):
10687 """Create a Z3 floating-point fused multiply-add expression.
10688 """
10689 return _mk_fp_tern(Z3_mk_fpa_fma, rm, a, b, c, ctx)
10690
10691
10692def fpSqrt(rm, a, ctx=None):
10693 """Create a Z3 floating-point square root expression.
10694 """
10695 return _mk_fp_unary(Z3_mk_fpa_sqrt, rm, a, ctx)
10696
10697
10698def fpRoundToIntegral(rm, a, ctx=None):
10699 """Create a Z3 floating-point roundToIntegral expression.
10700 """
10701 return _mk_fp_unary(Z3_mk_fpa_round_to_integral, rm, a, ctx)
10702
10703
10704def fpIsNaN(a, ctx=None):
10705 """Create a Z3 floating-point isNaN expression.
10706
10707 >>> s = FPSort(8, 24)
10708 >>> x = FP('x', s)
10709 >>> y = FP('y', s)
10710 >>> fpIsNaN(x)
10711 fpIsNaN(x)
10712 """
10713 return _mk_fp_unary_pred(Z3_mk_fpa_is_nan, a, ctx)
10714
10715
10716def fpIsInf(a, ctx=None):
10717 """Create a Z3 floating-point isInfinite expression.
10718
10719 >>> s = FPSort(8, 24)
10720 >>> x = FP('x', s)
10721 >>> fpIsInf(x)
10722 fpIsInf(x)
10723 """
10724 return _mk_fp_unary_pred(Z3_mk_fpa_is_infinite, a, ctx)
10725
10726
10727def fpIsZero(a, ctx=None):
10728 """Create a Z3 floating-point isZero expression.
10729 """
10730 return _mk_fp_unary_pred(Z3_mk_fpa_is_zero, a, ctx)
10731
10732
10733def fpIsNormal(a, ctx=None):
10734 """Create a Z3 floating-point isNormal expression.
10735 """
10736 return _mk_fp_unary_pred(Z3_mk_fpa_is_normal, a, ctx)
10737
10738
10739def fpIsSubnormal(a, ctx=None):
10740 """Create a Z3 floating-point isSubnormal expression.
10741 """
10742 return _mk_fp_unary_pred(Z3_mk_fpa_is_subnormal, a, ctx)
10743
10744
10745def fpIsNegative(a, ctx=None):
10746 """Create a Z3 floating-point isNegative expression.
10747 """
10748 return _mk_fp_unary_pred(Z3_mk_fpa_is_negative, a, ctx)
10749
10750
10751def fpIsPositive(a, ctx=None):
10752 """Create a Z3 floating-point isPositive expression.
10753 """
10754 return _mk_fp_unary_pred(Z3_mk_fpa_is_positive, a, ctx)
10755
10756
10757def _check_fp_args(a, b):
10758 if z3_debug():
10759 _z3_assert(is_fp(a) or is_fp(b), "First or second argument must be a Z3 floating-point expression")
10760
10761
10762def fpLT(a, b, ctx=None):
10763 """Create the Z3 floating-point expression `other < self`.
10764
10765 >>> x, y = FPs('x y', FPSort(8, 24))
10766 >>> fpLT(x, y)
10767 x < y
10768 >>> (x < y).sexpr()
10769 '(fp.lt x y)'
10770 """
10771 return _mk_fp_bin_pred(Z3_mk_fpa_lt, a, b, ctx)
10772
10773
10774def fpLEQ(a, b, ctx=None):
10775 """Create the Z3 floating-point expression `other <= self`.
10776
10777 >>> x, y = FPs('x y', FPSort(8, 24))
10778 >>> fpLEQ(x, y)
10779 x <= y
10780 >>> (x <= y).sexpr()
10781 '(fp.leq x y)'
10782 """
10783 return _mk_fp_bin_pred(Z3_mk_fpa_leq, a, b, ctx)
10784
10785
10786def fpGT(a, b, ctx=None):
10787 """Create the Z3 floating-point expression `other > self`.
10788
10789 >>> x, y = FPs('x y', FPSort(8, 24))
10790 >>> fpGT(x, y)
10791 x > y
10792 >>> (x > y).sexpr()
10793 '(fp.gt x y)'
10794 """
10795 return _mk_fp_bin_pred(Z3_mk_fpa_gt, a, b, ctx)
10796
10797
10798def fpGEQ(a, b, ctx=None):
10799 """Create the Z3 floating-point expression `other >= self`.
10800
10801 >>> x, y = FPs('x y', FPSort(8, 24))
10802 >>> fpGEQ(x, y)
10803 x >= y
10804 >>> (x >= y).sexpr()
10805 '(fp.geq x y)'
10806 """
10807 return _mk_fp_bin_pred(Z3_mk_fpa_geq, a, b, ctx)
10808
10809
10810def fpEQ(a, b, ctx=None):
10811 """Create the Z3 floating-point expression `fpEQ(other, self)`.
10812
10813 >>> x, y = FPs('x y', FPSort(8, 24))
10814 >>> fpEQ(x, y)
10815 fpEQ(x, y)
10816 >>> fpEQ(x, y).sexpr()
10817 '(fp.eq x y)'
10818 """
10819 return _mk_fp_bin_pred(Z3_mk_fpa_eq, a, b, ctx)
10820
10821
10822def fpNEQ(a, b, ctx=None):
10823 """Create the Z3 floating-point expression `Not(fpEQ(other, self))`.
10824
10825 >>> x, y = FPs('x y', FPSort(8, 24))
10826 >>> fpNEQ(x, y)
10827 Not(fpEQ(x, y))
10828 >>> (x != y).sexpr()
10829 '(distinct x y)'
10830 """
10831 return Not(fpEQ(a, b, ctx))
10832
10833
10834def fpFP(sgn, exp, sig, ctx=None):
10835 """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp.
10836
10837 >>> s = FPSort(8, 24)
10838 >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23))
10839 >>> print(x)
10840 fpFP(1, 127, 4194304)
10841 >>> xv = FPVal(-1.5, s)
10842 >>> print(xv)
10843 -1.5
10844 >>> slvr = Solver()
10845 >>> slvr.add(fpEQ(x, xv))
10846 >>> slvr.check()
10847 sat
10848 >>> xv = FPVal(+1.5, s)
10849 >>> print(xv)
10850 1.5
10851 >>> slvr = Solver()
10852 >>> slvr.add(fpEQ(x, xv))
10853 >>> slvr.check()
10854 unsat
10855 """
10856 _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch")
10857 _z3_assert(sgn.sort().size() == 1, "sort mismatch")
10858 ctx = _get_ctx(ctx)
10859 _z3_assert(ctx == sgn.ctx == exp.ctx == sig.ctx, "context mismatch")
10860 return FPRef(Z3_mk_fpa_fp(ctx.ref(), sgn.ast, exp.ast, sig.ast), ctx)
10861
10862
10863def fpToFP(a1, a2=None, a3=None, ctx=None):
10864 """Create a Z3 floating-point conversion expression from other term sorts
10865 to floating-point.
10866
10867 From a bit-vector term in IEEE 754-2008 format:
10868 >>> x = FPVal(1.0, Float32())
10869 >>> x_bv = fpToIEEEBV(x)
10870 >>> simplify(fpToFP(x_bv, Float32()))
10871 1
10872
10873 From a floating-point term with different precision:
10874 >>> x = FPVal(1.0, Float32())
10875 >>> x_db = fpToFP(RNE(), x, Float64())
10876 >>> x_db.sort()
10877 FPSort(11, 53)
10878
10879 From a real term:
10880 >>> x_r = RealVal(1.5)
10881 >>> simplify(fpToFP(RNE(), x_r, Float32()))
10882 1.5
10883
10884 From a signed bit-vector term:
10885 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10886 >>> simplify(fpToFP(RNE(), x_signed, Float32()))
10887 -1.25*(2**2)
10888 """
10889 ctx = _get_ctx(ctx)
10890 if is_bv(a1) and is_fp_sort(a2):
10891 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), a1.ast, a2.ast), ctx)
10892 elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3):
10893 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10894 elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3):
10895 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10896 elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3):
10897 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), a1.ast, a2.ast, a3.ast), ctx)
10898 else:
10899 raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.")
10900
10901
10902def fpBVToFP(v, sort, ctx=None):
10903 """Create a Z3 floating-point conversion expression that represents the
10904 conversion from a bit-vector term to a floating-point term.
10905
10906 >>> x_bv = BitVecVal(0x3F800000, 32)
10907 >>> x_fp = fpBVToFP(x_bv, Float32())
10908 >>> x_fp
10909 fpToFP(1065353216)
10910 >>> simplify(x_fp)
10911 1
10912 """
10913 _z3_assert(is_bv(v), "First argument must be a Z3 bit-vector expression")
10914 _z3_assert(is_fp_sort(sort), "Second argument must be a Z3 floating-point sort.")
10915 ctx = _get_ctx(ctx)
10916 return FPRef(Z3_mk_fpa_to_fp_bv(ctx.ref(), v.ast, sort.ast), ctx)
10917
10918
10919def fpFPToFP(rm, v, sort, ctx=None):
10920 """Create a Z3 floating-point conversion expression that represents the
10921 conversion from a floating-point term to a floating-point term of different precision.
10922
10923 >>> x_sgl = FPVal(1.0, Float32())
10924 >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64())
10925 >>> x_dbl
10926 fpToFP(RNE(), 1)
10927 >>> simplify(x_dbl)
10928 1
10929 >>> x_dbl.sort()
10930 FPSort(11, 53)
10931 """
10932 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10933 _z3_assert(is_fp(v), "Second argument must be a Z3 floating-point expression.")
10934 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10935 ctx = _get_ctx(ctx)
10936 return FPRef(Z3_mk_fpa_to_fp_float(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10937
10938
10939def fpRealToFP(rm, v, sort, ctx=None):
10940 """Create a Z3 floating-point conversion expression that represents the
10941 conversion from a real term to a floating-point term.
10942
10943 >>> x_r = RealVal(1.5)
10944 >>> x_fp = fpRealToFP(RNE(), x_r, Float32())
10945 >>> x_fp
10946 fpToFP(RNE(), 3/2)
10947 >>> simplify(x_fp)
10948 1.5
10949 """
10950 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10951 _z3_assert(is_real(v), "Second argument must be a Z3 expression or real sort.")
10952 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10953 ctx = _get_ctx(ctx)
10954 return FPRef(Z3_mk_fpa_to_fp_real(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10955
10956
10957def fpSignedToFP(rm, v, sort, ctx=None):
10958 """Create a Z3 floating-point conversion expression that represents the
10959 conversion from a signed bit-vector term (encoding an integer) to a floating-point term.
10960
10961 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10962 >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32())
10963 >>> x_fp
10964 fpToFP(RNE(), 4294967291)
10965 >>> simplify(x_fp)
10966 -1.25*(2**2)
10967 """
10968 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10969 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10970 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10971 ctx = _get_ctx(ctx)
10972 return FPRef(Z3_mk_fpa_to_fp_signed(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10973
10974
10975def fpUnsignedToFP(rm, v, sort, ctx=None):
10976 """Create a Z3 floating-point conversion expression that represents the
10977 conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term.
10978
10979 >>> x_signed = BitVecVal(-5, BitVecSort(32))
10980 >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32())
10981 >>> x_fp
10982 fpToFPUnsigned(RNE(), 4294967291)
10983 >>> simplify(x_fp)
10984 1*(2**32)
10985 """
10986 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression.")
10987 _z3_assert(is_bv(v), "Second argument must be a Z3 bit-vector expression")
10988 _z3_assert(is_fp_sort(sort), "Third argument must be a Z3 floating-point sort.")
10989 ctx = _get_ctx(ctx)
10990 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, v.ast, sort.ast), ctx)
10991
10992
10993def fpToFPUnsigned(rm, x, s, ctx=None):
10994 """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression."""
10995 if z3_debug():
10996 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
10997 _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression")
10998 _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort")
10999 ctx = _get_ctx(ctx)
11000 return FPRef(Z3_mk_fpa_to_fp_unsigned(ctx.ref(), rm.ast, x.ast, s.ast), ctx)
11001
11002
11003def fpToSBV(rm, x, s, ctx=None):
11004 """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
11005
11006 >>> x = FP('x', FPSort(8, 24))
11007 >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
11008 >>> print(is_fp(x))
11009 True
11010 >>> print(is_bv(y))
11011 True
11012 >>> print(is_fp(y))
11013 False
11014 >>> print(is_bv(x))
11015 False
11016 """
11017 if z3_debug():
11018 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11019 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11020 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11021 ctx = _get_ctx(ctx)
11022 return BitVecRef(Z3_mk_fpa_to_sbv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11023
11024
11025def fpToUBV(rm, x, s, ctx=None):
11026 """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
11027
11028 >>> x = FP('x', FPSort(8, 24))
11029 >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
11030 >>> print(is_fp(x))
11031 True
11032 >>> print(is_bv(y))
11033 True
11034 >>> print(is_fp(y))
11035 False
11036 >>> print(is_bv(x))
11037 False
11038 """
11039 if z3_debug():
11040 _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
11041 _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
11042 _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
11043 ctx = _get_ctx(ctx)
11044 return BitVecRef(Z3_mk_fpa_to_ubv(ctx.ref(), rm.ast, x.ast, s.size()), ctx)
11045
11046
11047def fpToReal(x, ctx=None):
11048 """Create a Z3 floating-point conversion expression, from floating-point expression to real.
11049
11050 >>> x = FP('x', FPSort(8, 24))
11051 >>> y = fpToReal(x)
11052 >>> print(is_fp(x))
11053 True
11054 >>> print(is_real(y))
11055 True
11056 >>> print(is_fp(y))
11057 False
11058 >>> print(is_real(x))
11059 False
11060 """
11061 if z3_debug():
11062 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11063 ctx = _get_ctx(ctx)
11064 return ArithRef(Z3_mk_fpa_to_real(ctx.ref(), x.ast), ctx)
11065
11066
11067def fpToIEEEBV(x, ctx=None):
11068 """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
11069
11070 The size of the resulting bit-vector is automatically determined.
11071
11072 Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
11073 knows only one NaN and it will always produce the same bit-vector representation of
11074 that NaN.
11075
11076 >>> x = FP('x', FPSort(8, 24))
11077 >>> y = fpToIEEEBV(x)
11078 >>> print(is_fp(x))
11079 True
11080 >>> print(is_bv(y))
11081 True
11082 >>> print(is_fp(y))
11083 False
11084 >>> print(is_bv(x))
11085 False
11086 """
11087 if z3_debug():
11088 _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
11089 ctx = _get_ctx(ctx)
11090 return BitVecRef(Z3_mk_fpa_to_ieee_bv(ctx.ref(), x.ast), ctx)
11091
11092
11093#########################################
11094#
11095# Strings, Sequences and Regular expressions
11096#
11097#########################################
11098
11099class SeqSortRef(SortRef):
11100 """Sequence sort."""
11101
11102 def is_string(self):
11103 """Determine if sort is a string
11104 >>> s = StringSort()
11105 >>> s.is_string()
11106 True
11107 >>> s = SeqSort(IntSort())
11108 >>> s.is_string()
11109 False
11110 """
11111 return Z3_is_string_sort(self.ctx_ref(), self.ast)
11112
11113 def basis(self):
11114 return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11115
11116class CharSortRef(SortRef):
11117 """Character sort."""
11118
11119
11120def StringSort(ctx=None):
11121 """Create a string sort
11122 >>> s = StringSort()
11123 >>> print(s)
11124 String
11125 """
11126 ctx = _get_ctx(ctx)
11127 return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
11128
11129def CharSort(ctx=None):
11130 """Create a character sort
11131 >>> ch = CharSort()
11132 >>> print(ch)
11133 Char
11134 """
11135 ctx = _get_ctx(ctx)
11136 return CharSortRef(Z3_mk_char_sort(ctx.ref()), ctx)
11137
11138
11139def SeqSort(s):
11140 """Create a sequence sort over elements provided in the argument
11141 >>> s = SeqSort(IntSort())
11142 >>> s == Unit(IntVal(1)).sort()
11143 True
11144 """
11145 return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
11146
11147
11148class SeqRef(ExprRef):
11149 """Sequence expression."""
11150
11151 def sort(self):
11152 return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
11153
11154 def __add__(self, other):
11155 return Concat(self, other)
11156
11157 def __radd__(self, other):
11158 return Concat(other, self)
11159
11160 def __getitem__(self, i):
11161 if _is_int(i):
11162 i = IntVal(i, self.ctx)
11163 return _to_expr_ref(Z3_mk_seq_nth(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11164
11165 def at(self, i):
11166 if _is_int(i):
11167 i = IntVal(i, self.ctx)
11168 return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
11169
11170 def is_string(self):
11171 return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
11172
11173 def is_string_value(self):
11174 return Z3_is_string(self.ctx_ref(), self.as_ast())
11175
11176 def as_string(self):
11177 """Return a string representation of sequence expression."""
11178 if self.is_string_value():
11179 string_length = ctypes.c_uint()
11180 chars = Z3_get_lstring(self.ctx_ref(), self.as_ast(), byref(string_length))
11181 return string_at(chars, size=string_length.value).decode("latin-1")
11182 return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
11183
11184 def py_value(self):
11185 return self.as_string()
11186
11187 def __le__(self, other):
11188 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11189
11190 def __lt__(self, other):
11191 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11192
11193 def __ge__(self, other):
11194 return _to_expr_ref(Z3_mk_str_le(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11195
11196 def __gt__(self, other):
11197 return _to_expr_ref(Z3_mk_str_lt(self.ctx_ref(), other.as_ast(), self.as_ast()), self.ctx)
11198
11199
11200def _coerce_char(ch, ctx=None):
11201 if isinstance(ch, str):
11202 ctx = _get_ctx(ctx)
11203 ch = CharVal(ch, ctx)
11204 if not is_expr(ch):
11205 raise Z3Exception("Character expression expected")
11206 return ch
11207
11208class CharRef(ExprRef):
11209 """Character expression."""
11210
11211 def __le__(self, other):
11212 other = _coerce_char(other, self.ctx)
11213 return _to_expr_ref(Z3_mk_char_le(self.ctx_ref(), self.as_ast(), other.as_ast()), self.ctx)
11214
11215 def to_int(self):
11216 return _to_expr_ref(Z3_mk_char_to_int(self.ctx_ref(), self.as_ast()), self.ctx)
11217
11218 def to_bv(self):
11219 return _to_expr_ref(Z3_mk_char_to_bv(self.ctx_ref(), self.as_ast()), self.ctx)
11220
11221 def is_digit(self):
11222 return _to_expr_ref(Z3_mk_char_is_digit(self.ctx_ref(), self.as_ast()), self.ctx)
11223
11224
11225def CharVal(ch, ctx=None):
11226 ctx = _get_ctx(ctx)
11227 if isinstance(ch, str):
11228 ch = ord(ch)
11229 if not isinstance(ch, int):
11230 raise Z3Exception("character value should be an ordinal")
11231 return _to_expr_ref(Z3_mk_char(ctx.ref(), ch), ctx)
11232
11233def CharFromBv(bv):
11234 if not is_expr(bv):
11235 raise Z3Exception("Bit-vector expression needed")
11236 return _to_expr_ref(Z3_mk_char_from_bv(bv.ctx_ref(), bv.as_ast()), bv.ctx)
11237
11238def CharToBv(ch, ctx=None):
11239 ch = _coerce_char(ch, ctx)
11240 return ch.to_bv()
11241
11242def CharToInt(ch, ctx=None):
11243 ch = _coerce_char(ch, ctx)
11244 return ch.to_int()
11245
11246def CharIsDigit(ch, ctx=None):
11247 ch = _coerce_char(ch, ctx)
11248 return ch.is_digit()
11249
11250def _coerce_seq(s, ctx=None):
11251 if isinstance(s, str):
11252 ctx = _get_ctx(ctx)
11253 s = StringVal(s, ctx)
11254 if not is_expr(s):
11255 raise Z3Exception("Non-expression passed as a sequence")
11256 if not is_seq(s):
11257 raise Z3Exception("Non-sequence passed as a sequence")
11258 return s
11259
11260
11261def _get_ctx2(a, b, ctx=None):
11262 if is_expr(a):
11263 return a.ctx
11264 if is_expr(b):
11265 return b.ctx
11266 if ctx is None:
11267 ctx = main_ctx()
11268 return ctx
11269
11270
11271def is_seq(a):
11272 """Return `True` if `a` is a Z3 sequence expression.
11273 >>> print (is_seq(Unit(IntVal(0))))
11274 True
11275 >>> print (is_seq(StringVal("abc")))
11276 True
11277 """
11278 return isinstance(a, SeqRef)
11279
11280
11281def is_string(a: Any) -> bool:
11282 """Return `True` if `a` is a Z3 string expression.
11283 >>> print (is_string(StringVal("ab")))
11284 True
11285 """
11286 return isinstance(a, SeqRef) and a.is_string()
11287
11288
11289def is_string_value(a: Any) -> bool:
11290 """return 'True' if 'a' is a Z3 string constant expression.
11291 >>> print (is_string_value(StringVal("a")))
11292 True
11293 >>> print (is_string_value(StringVal("a") + StringVal("b")))
11294 False
11295 """
11296 return isinstance(a, SeqRef) and a.is_string_value()
11297
11298def StringVal(s, ctx=None):
11299 """create a string expression"""
11300 s = "".join(str(ch) if 32 <= ord(ch) and ord(ch) < 127 else "\\u{%x}" % (ord(ch)) for ch in s)
11301 ctx = _get_ctx(ctx)
11302 return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
11303
11304
11305def String(name, ctx=None):
11306 """Return a string constant named `name`. If `ctx=None`, then the global context is used.
11307
11308 >>> x = String('x')
11309 """
11310 ctx = _get_ctx(ctx)
11311 return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
11312
11313
11314def Strings(names, ctx=None):
11315 """Return a tuple of String constants. """
11316 ctx = _get_ctx(ctx)
11317 if isinstance(names, str):
11318 names = names.split(" ")
11319 return [String(name, ctx) for name in names]
11320
11321
11322def SubString(s, offset, length):
11323 """Extract substring or subsequence starting at offset.
11324
11325 This is a convenience function that redirects to Extract(s, offset, length).
11326
11327 >>> s = StringVal("hello world")
11328 >>> SubString(s, 6, 5) # Extract "world"
11329 str.substr("hello world", 6, 5)
11330 >>> simplify(SubString(StringVal("hello"), 1, 3))
11331 "ell"
11332 """
11333 return Extract(s, offset, length)
11334
11335
11336def SubSeq(s, offset, length):
11337 """Extract substring or subsequence starting at offset.
11338
11339 This is a convenience function that redirects to Extract(s, offset, length).
11340
11341 >>> s = StringVal("hello world")
11342 >>> SubSeq(s, 0, 5) # Extract "hello"
11343 str.substr("hello world", 0, 5)
11344 >>> simplify(SubSeq(StringVal("testing"), 2, 4))
11345 "stin"
11346 """
11347 return Extract(s, offset, length)
11348
11349
11350def Empty(s):
11351 """Create the empty sequence of the given sort
11352 >>> e = Empty(StringSort())
11353 >>> e2 = StringVal("")
11354 >>> print(e.eq(e2))
11355 True
11356 >>> e3 = Empty(SeqSort(IntSort()))
11357 >>> print(e3)
11358 Empty(Seq(Int))
11359 >>> e4 = Empty(ReSort(SeqSort(IntSort())))
11360 >>> print(e4)
11361 Empty(ReSort(Seq(Int)))
11362 """
11363 if isinstance(s, SeqSortRef):
11364 return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
11365 if isinstance(s, ReSortRef):
11366 return ReRef(Z3_mk_re_empty(s.ctx_ref(), s.ast), s.ctx)
11367 raise Z3Exception("Non-sequence, non-regular expression sort passed to Empty")
11368
11369
11370def Full(s):
11371 """Create the regular expression that accepts the universal language
11372 >>> e = Full(ReSort(SeqSort(IntSort())))
11373 >>> print(e)
11374 Full(ReSort(Seq(Int)))
11375 >>> e1 = Full(ReSort(StringSort()))
11376 >>> print(e1)
11377 Full(ReSort(String))
11378 """
11379 if isinstance(s, ReSortRef):
11380 return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
11381 raise Z3Exception("Non-sequence, non-regular expression sort passed to Full")
11382
11383
11384
11385def Unit(a):
11386 """Create a singleton sequence"""
11387 return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
11388
11389
11390def PrefixOf(a, b):
11391 """Check if 'a' is a prefix of 'b'
11392 >>> s1 = PrefixOf("ab", "abc")
11393 >>> simplify(s1)
11394 True
11395 >>> s2 = PrefixOf("bc", "abc")
11396 >>> simplify(s2)
11397 False
11398 """
11399 ctx = _get_ctx2(a, b)
11400 a = _coerce_seq(a, ctx)
11401 b = _coerce_seq(b, ctx)
11402 return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11403
11404
11405def SuffixOf(a, b):
11406 """Check if 'a' is a suffix of 'b'
11407 >>> s1 = SuffixOf("ab", "abc")
11408 >>> simplify(s1)
11409 False
11410 >>> s2 = SuffixOf("bc", "abc")
11411 >>> simplify(s2)
11412 True
11413 """
11414 ctx = _get_ctx2(a, b)
11415 a = _coerce_seq(a, ctx)
11416 b = _coerce_seq(b, ctx)
11417 return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11418
11419
11420def Contains(a, b):
11421 """Check if 'a' contains 'b'
11422 >>> s1 = Contains("abc", "ab")
11423 >>> simplify(s1)
11424 True
11425 >>> s2 = Contains("abc", "bc")
11426 >>> simplify(s2)
11427 True
11428 >>> x, y, z = Strings('x y z')
11429 >>> s3 = Contains(Concat(x,y,z), y)
11430 >>> simplify(s3)
11431 True
11432 """
11433 ctx = _get_ctx2(a, b)
11434 a = _coerce_seq(a, ctx)
11435 b = _coerce_seq(b, ctx)
11436 return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
11437
11438
11439def Replace(s, src, dst):
11440 """Replace the first occurrence of 'src' by 'dst' in 's'
11441 >>> r = Replace("aaa", "a", "b")
11442 >>> simplify(r)
11443 "baa"
11444 """
11445 ctx = _get_ctx2(dst, s)
11446 if ctx is None and is_expr(src):
11447 ctx = src.ctx
11448 src = _coerce_seq(src, ctx)
11449 dst = _coerce_seq(dst, ctx)
11450 s = _coerce_seq(s, ctx)
11451 return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
11452
11453
11454def IndexOf(s, substr, offset=None):
11455 """Retrieve the index of substring within a string starting at a specified offset.
11456 >>> simplify(IndexOf("abcabc", "bc", 0))
11457 1
11458 >>> simplify(IndexOf("abcabc", "bc", 2))
11459 4
11460 """
11461 if offset is None:
11462 offset = IntVal(0)
11463 ctx = None
11464 if is_expr(offset):
11465 ctx = offset.ctx
11466 ctx = _get_ctx2(s, substr, ctx)
11467 s = _coerce_seq(s, ctx)
11468 substr = _coerce_seq(substr, ctx)
11469 if _is_int(offset):
11470 offset = IntVal(offset, ctx)
11471 return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
11472
11473
11474def LastIndexOf(s, substr):
11475 """Retrieve the last index of substring within a string"""
11476 ctx = None
11477 ctx = _get_ctx2(s, substr, ctx)
11478 s = _coerce_seq(s, ctx)
11479 substr = _coerce_seq(substr, ctx)
11480 return ArithRef(Z3_mk_seq_last_index(s.ctx_ref(), s.as_ast(), substr.as_ast()), s.ctx)
11481
11482
11483def Length(s):
11484 """Obtain the length of a sequence 's'
11485 >>> l = Length(StringVal("abc"))
11486 >>> simplify(l)
11487 3
11488 """
11489 s = _coerce_seq(s)
11490 return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
11491
11492def SeqMap(f, s):
11493 """Map function 'f' over sequence 's'"""
11494 ctx = _get_ctx2(f, s)
11495 s = _coerce_seq(s, ctx)
11496 return _to_expr_ref(Z3_mk_seq_map(s.ctx_ref(), f.as_ast(), s.as_ast()), ctx)
11497
11498def SeqMapI(f, i, s):
11499 """Map function 'f' over sequence 's' at index 'i'"""
11500 ctx = _get_ctx2(f, s)
11501 s = _coerce_seq(s, ctx)
11502 if not is_expr(i):
11503 i = _py2expr(i)
11504 return _to_expr_ref(Z3_mk_seq_mapi(s.ctx_ref(), f.as_ast(), i.as_ast(), s.as_ast()), ctx)
11505
11506def SeqFoldLeft(f, a, s):
11507 ctx = _get_ctx2(f, s)
11508 s = _coerce_seq(s, ctx)
11509 a = _py2expr(a)
11510 return _to_expr_ref(Z3_mk_seq_foldl(s.ctx_ref(), f.as_ast(), a.as_ast(), s.as_ast()), ctx)
11511
11512def SeqFoldLeftI(f, i, a, s):
11513 ctx = _get_ctx2(f, s)
11514 s = _coerce_seq(s, ctx)
11515 a = _py2expr(a)
11516 i = _py2expr(i)
11517 return _to_expr_ref(Z3_mk_seq_foldli(s.ctx_ref(), f.as_ast(), i.as_ast(), a.as_ast(), s.as_ast()), ctx)
11518
11519def StrToInt(s):
11520 """Convert string expression to integer
11521 >>> a = StrToInt("1")
11522 >>> simplify(1 == a)
11523 True
11524 >>> b = StrToInt("2")
11525 >>> simplify(1 == b)
11526 False
11527 >>> c = StrToInt(IntToStr(2))
11528 >>> simplify(1 == c)
11529 False
11530 """
11531 s = _coerce_seq(s)
11532 return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
11533
11534
11535def IntToStr(s):
11536 """Convert integer expression to string"""
11537 if not is_expr(s):
11538 s = _py2expr(s)
11539 return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
11540
11541
11542def StrToCode(s):
11543 """Convert a unit length string to integer code"""
11544 if not is_expr(s):
11545 s = _py2expr(s)
11546 return ArithRef(Z3_mk_string_to_code(s.ctx_ref(), s.as_ast()), s.ctx)
11547
11548def StrFromCode(c):
11549 """Convert code to a string"""
11550 if not is_expr(c):
11551 c = _py2expr(c)
11552 return SeqRef(Z3_mk_string_from_code(c.ctx_ref(), c.as_ast()), c.ctx)
11553
11554def Re(s, ctx=None):
11555 """The regular expression that accepts sequence 's'
11556 >>> s1 = Re("ab")
11557 >>> s2 = Re(StringVal("ab"))
11558 >>> s3 = Re(Unit(BoolVal(True)))
11559 """
11560 s = _coerce_seq(s, ctx)
11561 return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
11562
11563
11564# Regular expressions
11565
11566class ReSortRef(SortRef):
11567 """Regular expression sort."""
11568
11569 def basis(self):
11570 return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
11571
11572
11573def ReSort(s):
11574 if is_ast(s):
11575 return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.ast), s.ctx)
11576 if s is None or isinstance(s, Context):
11577 ctx = _get_ctx(s)
11578 return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), s.ctx)
11579 raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
11580
11581
11582class ReRef(ExprRef):
11583 """Regular expressions."""
11584
11585 def __add__(self, other):
11586 return Union(self, other)
11587
11588
11589def is_re(s):
11590 return isinstance(s, ReRef)
11591
11592
11593def InRe(s, re):
11594 """Create regular expression membership test
11595 >>> re = Union(Re("a"),Re("b"))
11596 >>> print (simplify(InRe("a", re)))
11597 True
11598 >>> print (simplify(InRe("b", re)))
11599 True
11600 >>> print (simplify(InRe("c", re)))
11601 False
11602 """
11603 s = _coerce_seq(s, re.ctx)
11604 return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
11605
11606
11607def Union(*args):
11608 """Create union of regular expressions.
11609 >>> re = Union(Re("a"), Re("b"), Re("c"))
11610 >>> print (simplify(InRe("d", re)))
11611 False
11612 """
11613 args = _get_args(args)
11614 sz = len(args)
11615 if z3_debug():
11616 _z3_assert(sz > 0, "At least one argument expected.")
11617 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11618 if sz == 1:
11619 return args[0]
11620 ctx = args[0].ctx
11621 v = (Ast * sz)()
11622 for i in range(sz):
11623 v[i] = args[i].as_ast()
11624 return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
11625
11626
11627def Intersect(*args):
11628 """Create intersection of regular expressions.
11629 >>> re = Intersect(Re("a"), Re("b"), Re("c"))
11630 """
11631 args = _get_args(args)
11632 sz = len(args)
11633 if z3_debug():
11634 _z3_assert(sz > 0, "At least one argument expected.")
11635 _z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
11636 if sz == 1:
11637 return args[0]
11638 ctx = args[0].ctx
11639 v = (Ast * sz)()
11640 for i in range(sz):
11641 v[i] = args[i].as_ast()
11642 return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
11643
11644
11645def Plus(re):
11646 """Create the regular expression accepting one or more repetitions of argument.
11647 >>> re = Plus(Re("a"))
11648 >>> print(simplify(InRe("aa", re)))
11649 True
11650 >>> print(simplify(InRe("ab", re)))
11651 False
11652 >>> print(simplify(InRe("", re)))
11653 False
11654 """
11655 if z3_debug():
11656 _z3_assert(is_expr(re), "expression expected")
11657 return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
11658
11659
11660def Option(re):
11661 """Create the regular expression that optionally accepts the argument.
11662 >>> re = Option(Re("a"))
11663 >>> print(simplify(InRe("a", re)))
11664 True
11665 >>> print(simplify(InRe("", re)))
11666 True
11667 >>> print(simplify(InRe("aa", re)))
11668 False
11669 """
11670 if z3_debug():
11671 _z3_assert(is_expr(re), "expression expected")
11672 return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
11673
11674
11675def Complement(re):
11676 """Create the complement regular expression."""
11677 return ReRef(Z3_mk_re_complement(re.ctx_ref(), re.as_ast()), re.ctx)
11678
11679
11680def Star(re):
11681 """Create the regular expression accepting zero or more repetitions of argument.
11682 >>> re = Star(Re("a"))
11683 >>> print(simplify(InRe("aa", re)))
11684 True
11685 >>> print(simplify(InRe("ab", re)))
11686 False
11687 >>> print(simplify(InRe("", re)))
11688 True
11689 """
11690 if z3_debug():
11691 _z3_assert(is_expr(re), "expression expected")
11692 return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)
11693
11694
11695def Loop(re, lo, hi=0):
11696 """Create the regular expression accepting between a lower and upper bound repetitions
11697 >>> re = Loop(Re("a"), 1, 3)
11698 >>> print(simplify(InRe("aa", re)))
11699 True
11700 >>> print(simplify(InRe("aaaa", re)))
11701 False
11702 >>> print(simplify(InRe("", re)))
11703 False
11704 """
11705 if z3_debug():
11706 _z3_assert(is_expr(re), "expression expected")
11707 return ReRef(Z3_mk_re_loop(re.ctx_ref(), re.as_ast(), lo, hi), re.ctx)
11708
11709
11710def Range(lo, hi, ctx=None):
11711 """Create the range regular expression over two sequences of length 1
11712 >>> range = Range("a","z")
11713 >>> print(simplify(InRe("b", range)))
11714 True
11715 >>> print(simplify(InRe("bb", range)))
11716 False
11717 """
11718 lo = _coerce_seq(lo, ctx)
11719 hi = _coerce_seq(hi, ctx)
11720 if z3_debug():
11721 _z3_assert(is_expr(lo), "expression expected")
11722 _z3_assert(is_expr(hi), "expression expected")
11723 return ReRef(Z3_mk_re_range(lo.ctx_ref(), lo.ast, hi.ast), lo.ctx)
11724
11725def Diff(a, b, ctx=None):
11726 """Create the difference regular expression
11727 """
11728 if z3_debug():
11729 _z3_assert(is_expr(a), "expression expected")
11730 _z3_assert(is_expr(b), "expression expected")
11731 return ReRef(Z3_mk_re_diff(a.ctx_ref(), a.ast, b.ast), a.ctx)
11732
11733def AllChar(regex_sort, ctx=None):
11734 """Create a regular expression that accepts all single character strings
11735 """
11736 return ReRef(Z3_mk_re_allchar(regex_sort.ctx_ref(), regex_sort.ast), regex_sort.ctx)
11737
11738# Special Relations
11739
11740
11741def PartialOrder(a, index):
11742 return FuncDeclRef(Z3_mk_partial_order(a.ctx_ref(), a.ast, index), a.ctx)
11743
11744
11745def LinearOrder(a, index):
11746 return FuncDeclRef(Z3_mk_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11747
11748
11749def TreeOrder(a, index):
11750 return FuncDeclRef(Z3_mk_tree_order(a.ctx_ref(), a.ast, index), a.ctx)
11751
11752
11753def PiecewiseLinearOrder(a, index):
11754 return FuncDeclRef(Z3_mk_piecewise_linear_order(a.ctx_ref(), a.ast, index), a.ctx)
11755
11756
11757def TransitiveClosure(f):
11758 """Given a binary relation R, such that the two arguments have the same sort
11759 create the transitive closure relation R+.
11760 The transitive closure R+ is a new relation.
11761 """
11762 return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
11763
11764def to_Ast(ptr,):
11765 ast = Ast(ptr)
11766 super(ctypes.c_void_p, ast).__init__(ptr)
11767 return ast
11768
11769def to_ContextObj(ptr,):
11770 ctx = ContextObj(ptr)
11771 super(ctypes.c_void_p, ctx).__init__(ptr)
11772 return ctx
11773
11774def to_AstVectorObj(ptr,):
11775 v = AstVectorObj(ptr)
11776 super(ctypes.c_void_p, v).__init__(ptr)
11777 return v
11778
11779# NB. my-hacky-class only works for a single instance of OnClause
11780# it should be replaced with a proper correlation between OnClause
11781# and object references that can be passed over the FFI.
11782# for UserPropagator we use a global dictionary, which isn't great code.
11783
11784_my_hacky_class = None
11785def on_clause_eh(ctx, p, n, dep, clause):
11786 onc = _my_hacky_class
11787 p = _to_expr_ref(to_Ast(p), onc.ctx)
11788 clause = AstVector(to_AstVectorObj(clause), onc.ctx)
11789 deps = [dep[i] for i in range(n)]
11790 onc.on_clause(p, deps, clause)
11791
11792_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
11793
11794class OnClause:
11795 def __init__(self, s, on_clause):
11796 self.s = s
11797 self.ctx = s.ctx
11798 self.on_clause = on_clause
11799 self.idx = 22
11800 global _my_hacky_class
11801 _my_hacky_class = self
11802 Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
11803
11804
11805class PropClosures:
11806 def __init__(self):
11807 self.bases = {}
11808 self.lock = None
11809
11810 def set_threaded(self):
11811 if self.lock is None:
11812 import threading
11813 self.lock = threading.Lock()
11814
11815 def get(self, ctx):
11816 if self.lock:
11817 with self.lock:
11818 r = self.bases[ctx]
11819 else:
11820 r = self.bases[ctx]
11821 return r
11822
11823 def set(self, ctx, r):
11824 if self.lock:
11825 with self.lock:
11826 self.bases[ctx] = r
11827 else:
11828 self.bases[ctx] = r
11829
11830 def insert(self, r):
11831 if self.lock:
11832 with self.lock:
11833 id = len(self.bases) + 3
11834 self.bases[id] = r
11835 else:
11836 id = len(self.bases) + 3
11837 self.bases[id] = r
11838 return id
11839
11840
11841_prop_closures = None
11842
11843
11844def ensure_prop_closures():
11845 global _prop_closures
11846 if _prop_closures is None:
11847 _prop_closures = PropClosures()
11848
11849
11850def user_prop_push(ctx, cb):
11851 prop = _prop_closures.get(ctx)
11852 prop.cb = cb
11853 prop.push()
11854
11855
11856def user_prop_pop(ctx, cb, num_scopes):
11857 prop = _prop_closures.get(ctx)
11858 prop.cb = cb
11859 prop.pop(num_scopes)
11860
11861
11862def user_prop_fresh(ctx, _new_ctx):
11863 _prop_closures.set_threaded()
11864 prop = _prop_closures.get(ctx)
11865 nctx = Context()
11866 Z3_del_context(nctx.ctx)
11867 new_ctx = to_ContextObj(_new_ctx)
11868 nctx.ctx = new_ctx
11869 nctx.eh = Z3_set_error_handler(new_ctx, z3_error_handler)
11870 nctx.owner = False
11871 new_prop = prop.fresh(nctx)
11872 _prop_closures.set(new_prop.id, new_prop)
11873 return new_prop.id
11874
11875
11876def user_prop_fixed(ctx, cb, id, value):
11877 prop = _prop_closures.get(ctx)
11878 old_cb = prop.cb
11879 prop.cb = cb
11880 id = _to_expr_ref(to_Ast(id), prop.ctx())
11881 value = _to_expr_ref(to_Ast(value), prop.ctx())
11882 prop.fixed(id, value)
11883 prop.cb = old_cb
11884
11885def user_prop_created(ctx, cb, id):
11886 prop = _prop_closures.get(ctx)
11887 old_cb = prop.cb
11888 prop.cb = cb
11889 id = _to_expr_ref(to_Ast(id), prop.ctx())
11890 prop.created(id)
11891 prop.cb = old_cb
11892
11893
11894def user_prop_final(ctx, cb):
11895 prop = _prop_closures.get(ctx)
11896 old_cb = prop.cb
11897 prop.cb = cb
11898 prop.final()
11899 prop.cb = old_cb
11900
11901def user_prop_eq(ctx, cb, x, y):
11902 prop = _prop_closures.get(ctx)
11903 old_cb = prop.cb
11904 prop.cb = cb
11905 x = _to_expr_ref(to_Ast(x), prop.ctx())
11906 y = _to_expr_ref(to_Ast(y), prop.ctx())
11907 prop.eq(x, y)
11908 prop.cb = old_cb
11909
11910def user_prop_diseq(ctx, cb, x, y):
11911 prop = _prop_closures.get(ctx)
11912 old_cb = prop.cb
11913 prop.cb = cb
11914 x = _to_expr_ref(to_Ast(x), prop.ctx())
11915 y = _to_expr_ref(to_Ast(y), prop.ctx())
11916 prop.diseq(x, y)
11917 prop.cb = old_cb
11918
11919def user_prop_decide(ctx, cb, t_ref, idx, phase):
11920 prop = _prop_closures.get(ctx)
11921 old_cb = prop.cb
11922 prop.cb = cb
11923 t = _to_expr_ref(to_Ast(t_ref), prop.ctx())
11924 prop.decide(t, idx, phase)
11925 prop.cb = old_cb
11926
11927def user_prop_binding(ctx, cb, q_ref, inst_ref):
11928 prop = _prop_closures.get(ctx)
11929 old_cb = prop.cb
11930 prop.cb = cb
11931 q = _to_expr_ref(to_Ast(q_ref), prop.ctx())
11932 inst = _to_expr_ref(to_Ast(inst_ref), prop.ctx())
11933 r = prop.binding(q, inst)
11934 prop.cb = old_cb
11935 return r
11936
11937
11938_user_prop_push = Z3_push_eh(user_prop_push)
11939_user_prop_pop = Z3_pop_eh(user_prop_pop)
11940_user_prop_fresh = Z3_fresh_eh(user_prop_fresh)
11941_user_prop_fixed = Z3_fixed_eh(user_prop_fixed)
11942_user_prop_created = Z3_created_eh(user_prop_created)
11943_user_prop_final = Z3_final_eh(user_prop_final)
11944_user_prop_eq = Z3_eq_eh(user_prop_eq)
11945_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
11946_user_prop_decide = Z3_decide_eh(user_prop_decide)
11947_user_prop_binding = Z3_on_binding_eh(user_prop_binding)
11948
11949
11950def PropagateFunction(name, *sig):
11951 """Create a function that gets tracked by user propagator.
11952 Every term headed by this function symbol is tracked.
11953 If a term is fixed and the fixed callback is registered a
11954 callback is invoked that the term headed by this function is fixed.
11955 """
11956 sig = _get_args(sig)
11957 if z3_debug():
11958 _z3_assert(len(sig) > 0, "At least two arguments expected")
11959 arity = len(sig) - 1
11960 rng = sig[arity]
11961 if z3_debug():
11962 _z3_assert(is_sort(rng), "Z3 sort expected")
11963 dom = (Sort * arity)()
11964 for i in range(arity):
11965 if z3_debug():
11966 _z3_assert(is_sort(sig[i]), "Z3 sort expected")
11967 dom[i] = sig[i].ast
11968 ctx = rng.ctx
11969 return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
11970
11971
11972
11973class UserPropagateBase:
11974
11975 #
11976 # Either solver is set or ctx is set.
11977 # Propagators that are created through callbacks
11978 # to "fresh" inherit the context of that is supplied
11979 # as argument to the callback.
11980 # This context should not be deleted. It is owned by the solver.
11981 #
11982 def __init__(self, s, ctx=None):
11983 assert s is None or ctx is None
11984 ensure_prop_closures()
11985 self.solver = s
11986 self._ctx = None
11987 self.fresh_ctx = None
11988 self.cb = None
11989 self.id = _prop_closures.insert(self)
11990 self.fixed = None
11991 self.final = None
11992 self.eq = None
11993 self.diseq = None
11994 self.decide = None
11995 self.created = None
11996 self.binding = None
11997 if ctx:
11998 self.fresh_ctx = ctx
11999 if s:
12000 Z3_solver_propagate_init(self.ctx_ref(),
12001 s.solver,
12002 ctypes.c_void_p(self.id),
12003 _user_prop_push,
12004 _user_prop_pop,
12005 _user_prop_fresh)
12006
12007 def __del__(self):
12008 if self._ctx:
12009 self._ctx.ctx = None
12010
12011 def ctx(self):
12012 if self.fresh_ctx:
12013 return self.fresh_ctx
12014 else:
12015 return self.solver.ctx
12016
12017 def ctx_ref(self):
12018 return self.ctx().ref()
12019
12020 def add_fixed(self, fixed):
12021 if self.fixed:
12022 raise Z3Exception("fixed callback already registered")
12023 if self._ctx:
12024 raise Z3Exception("context already initialized")
12025 if self.solver:
12026 Z3_solver_propagate_fixed(self.ctx_ref(), self.solver.solver, _user_prop_fixed)
12027 self.fixed = fixed
12028
12029 def add_created(self, created):
12030 if self.created:
12031 raise Z3Exception("created callback already registered")
12032 if self._ctx:
12033 raise Z3Exception("context already initialized")
12034 if self.solver:
12035 Z3_solver_propagate_created(self.ctx_ref(), self.solver.solver, _user_prop_created)
12036 self.created = created
12037
12038 def add_final(self, final):
12039 if self.final:
12040 raise Z3Exception("final callback already registered")
12041 if self._ctx:
12042 raise Z3Exception("context already initialized")
12043 if self.solver:
12044 Z3_solver_propagate_final(self.ctx_ref(), self.solver.solver, _user_prop_final)
12045 self.final = final
12046
12047 def add_eq(self, eq):
12048 if self.eq:
12049 raise Z3Exception("eq callback already registered")
12050 if self._ctx:
12051 raise Z3Exception("context already initialized")
12052 if self.solver:
12053 Z3_solver_propagate_eq(self.ctx_ref(), self.solver.solver, _user_prop_eq)
12054 self.eq = eq
12055
12056 def add_diseq(self, diseq):
12057 if self.diseq:
12058 raise Z3Exception("diseq callback already registered")
12059 if self._ctx:
12060 raise Z3Exception("context already initialized")
12061 if self.solver:
12062 Z3_solver_propagate_diseq(self.ctx_ref(), self.solver.solver, _user_prop_diseq)
12063 self.diseq = diseq
12064
12065 def add_decide(self, decide):
12066 if self.decide:
12067 raise Z3Exception("decide callback already registered")
12068 if self._ctx:
12069 raise Z3Exception("context already initialized")
12070 if self.solver:
12071 Z3_solver_propagate_decide(self.ctx_ref(), self.solver.solver, _user_prop_decide)
12072 self.decide = decide
12073
12074 def add_on_binding(self, binding):
12075 if self.binding:
12076 raise Z3Exception("binding callback already registered")
12077 if self._ctx:
12078 raise Z3Exception("context already initialized")
12079 if self.solver:
12080 Z3_solver_propagate_on_binding(self.ctx_ref(), self.solver.solver, _user_prop_binding)
12081 self.binding = binding
12082
12083 def push(self):
12084 raise Z3Exception("push needs to be overwritten")
12085
12086 def pop(self, num_scopes):
12087 raise Z3Exception("pop needs to be overwritten")
12088
12089 def fresh(self, new_ctx):
12090 raise Z3Exception("fresh needs to be overwritten")
12091
12092 def add(self, e):
12093 if self._ctx:
12094 raise Z3Exception("context already initialized")
12095 if self.solver:
12096 Z3_solver_propagate_register(self.ctx_ref(), self.solver.solver, e.ast)
12097 else:
12098 Z3_solver_propagate_register_cb(self.ctx_ref(), ctypes.c_void_p(self.cb), e.ast)
12099
12100 #
12101 # Tell the solver to perform the next split on a given term
12102 # If the term is a bit-vector the index idx specifies the index of the Boolean variable being
12103 # split on. A phase of true = 1/false = -1/undef = 0 = let solver decide is the last argument.
12104 #
12105 def next_split(self, t, idx, phase):
12106 return Z3_solver_next_split(self.ctx_ref(), ctypes.c_void_p(self.cb), t.ast, idx, phase)
12107
12108 #
12109 # Propagation can only be invoked as during a fixed or final callback.
12110 #
12111 def propagate(self, e, ids, eqs=[]):
12112 _ids, num_fixed = _to_ast_array(ids)
12113 num_eqs = len(eqs)
12114 _lhs, _num_lhs = _to_ast_array([x for x, y in eqs])
12115 _rhs, _num_rhs = _to_ast_array([y for x, y in eqs])
12116 return Z3_solver_propagate_consequence(e.ctx.ref(), ctypes.c_void_p(
12117 self.cb), num_fixed, _ids, num_eqs, _lhs, _rhs, e.ast)
12118
12119 def conflict(self, deps = [], eqs = []):
12120 self.propagate(BoolVal(False, self.ctx()), deps, eqs)
approx(self, precision=10)
Definition z3py.py:3241
as_decimal(self, prec)
Definition z3py.py:3253
__rmod__(self, other)
Definition z3py.py:2723
__mod__(self, other)
Definition z3py.py:2708
__pow__(self, other)
Definition z3py.py:2632
__gt__(self, other)
Definition z3py.py:2781
__lt__(self, other)
Definition z3py.py:2768
__rtruediv__(self, other)
Definition z3py.py:2704
__rmul__(self, other)
Definition z3py.py:2599
__rsub__(self, other)
Definition z3py.py:2622
__add__(self, other)
Definition z3py.py:2561
__sub__(self, other)
Definition z3py.py:2609
is_real(self)
Definition z3py.py:2550
is_int(self)
Definition z3py.py:2536
__radd__(self, other)
Definition z3py.py:2574
__truediv__(self, other)
Definition z3py.py:2683
__le__(self, other)
Definition z3py.py:2755
__rpow__(self, other)
Definition z3py.py:2646
__pos__(self)
Definition z3py.py:2746
sort(self)
Definition z3py.py:2526
__mul__(self, other)
Definition z3py.py:2584
__rdiv__(self, other)
Definition z3py.py:2687
__ge__(self, other)
Definition z3py.py:2794
__neg__(self)
Definition z3py.py:2735
__div__(self, other)
Definition z3py.py:2660
Arithmetic.
Definition z3py.py:2431
subsort(self, other)
Definition z3py.py:2465
cast(self, val)
Definition z3py.py:2469
domain(self)
Definition z3py.py:4737
domain_n(self, i)
Definition z3py.py:4746
__getitem__(self, arg)
Definition z3py.py:4759
range(self)
Definition z3py.py:4750
sort(self)
Definition z3py.py:4728
default(self)
Definition z3py.py:4771
domain_n(self, i)
Definition z3py.py:4710
erase(self, k)
Definition z3py.py:6312
__deepcopy__(self, memo={})
Definition z3py.py:6249
__init__(self, m=None, ctx=None)
Definition z3py.py:6238
__repr__(self)
Definition z3py.py:6309
__len__(self)
Definition z3py.py:6256
keys(self)
Definition z3py.py:6341
__setitem__(self, k, v)
Definition z3py.py:6293
__contains__(self, key)
Definition z3py.py:6269
__del__(self)
Definition z3py.py:6252
__getitem__(self, key)
Definition z3py.py:6282
reset(self)
Definition z3py.py:6326
__deepcopy__(self, memo={})
Definition z3py.py:382
__nonzero__(self)
Definition z3py.py:397
as_ast(self)
Definition z3py.py:419
translate(self, target)
Definition z3py.py:448
__hash__(self)
Definition z3py.py:394
__init__(self, ast, ctx=None)
Definition z3py.py:372
__str__(self)
Definition z3py.py:385
ctx_ref(self)
Definition z3py.py:427
py_value(self)
Definition z3py.py:477
__repr__(self)
Definition z3py.py:388
get_id(self)
Definition z3py.py:423
hash(self)
Definition z3py.py:467
__eq__(self, other)
Definition z3py.py:391
eq(self, other)
Definition z3py.py:431
sexpr(self)
Definition z3py.py:410
__del__(self)
Definition z3py.py:377
__bool__(self)
Definition z3py.py:400
__copy__(self)
Definition z3py.py:464
__deepcopy__(self, memo={})
Definition z3py.py:6218
translate(self, other_ctx)
Definition z3py.py:6199
__repr__(self)
Definition z3py.py:6221
__len__(self)
Definition z3py.py:6091
__init__(self, v=None, ctx=None)
Definition z3py.py:6076
push(self, v)
Definition z3py.py:6151
__getitem__(self, i)
Definition z3py.py:6104
sexpr(self)
Definition z3py.py:6224
__del__(self)
Definition z3py.py:6087
__setitem__(self, i, v)
Definition z3py.py:6133
__contains__(self, item)
Definition z3py.py:6176
__copy__(self)
Definition z3py.py:6215
resize(self, sz)
Definition z3py.py:6163
as_binary_string(self)
Definition z3py.py:4089
as_signed_long(self)
Definition z3py.py:4063
as_string(self)
Definition z3py.py:4086
__and__(self, other)
Definition z3py.py:3753
__rmod__(self, other)
Definition z3py.py:3894
__rrshift__(self, other)
Definition z3py.py:4020
__mod__(self, other)
Definition z3py.py:3873
__or__(self, other)
Definition z3py.py:3730
__rlshift__(self, other)
Definition z3py.py:4034
__gt__(self, other)
Definition z3py.py:3944
__lt__(self, other)
Definition z3py.py:3928
__invert__(self)
Definition z3py.py:3819
__rtruediv__(self, other)
Definition z3py.py:3869
__rmul__(self, other)
Definition z3py.py:3697
__rxor__(self, other)
Definition z3py.py:3789
__ror__(self, other)
Definition z3py.py:3743
__rsub__(self, other)
Definition z3py.py:3720
__add__(self, other)
Definition z3py.py:3661
__sub__(self, other)
Definition z3py.py:3707
__radd__(self, other)
Definition z3py.py:3674
size(self)
Definition z3py.py:3650
__rand__(self, other)
Definition z3py.py:3766
__truediv__(self, other)
Definition z3py.py:3849
__le__(self, other)
Definition z3py.py:3912
__xor__(self, other)
Definition z3py.py:3776
__lshift__(self, other)
Definition z3py.py:4006
__pos__(self)
Definition z3py.py:3799
sort(self)
Definition z3py.py:3639
__mul__(self, other)
Definition z3py.py:3684
__rdiv__(self, other)
Definition z3py.py:3853
__ge__(self, other)
Definition z3py.py:3960
__neg__(self)
Definition z3py.py:3808
__rshift__(self, other)
Definition z3py.py:3976
__div__(self, other)
Definition z3py.py:3830
Bit-Vectors.
Definition z3py.py:3592
subsort(self, other)
Definition z3py.py:3604
cast(self, val)
Definition z3py.py:3607
__and__(self, other)
Definition z3py.py:1682
__or__(self, other)
Definition z3py.py:1685
__invert__(self)
Definition z3py.py:1691
__rmul__(self, other)
Definition z3py.py:1668
__add__(self, other)
Definition z3py.py:1660
py_value(self)
Definition z3py.py:1694
__radd__(self, other)
Definition z3py.py:1665
__xor__(self, other)
Definition z3py.py:1688
sort(self)
Definition z3py.py:1657
__mul__(self, other)
Definition z3py.py:1671
Booleans.
Definition z3py.py:1618
subsort(self, other)
Definition z3py.py:1644
is_bool(self)
Definition z3py.py:1650
cast(self, val)
Definition z3py.py:1621
__deepcopy__(self, memo={})
Definition z3py.py:7108
__eq__(self, other)
Definition z3py.py:7111
__ne__(self, other)
Definition z3py.py:7114
__init__(self, r)
Definition z3py.py:7105
param_descrs(self)
Definition z3py.py:240
set_ast_print_mode(self, mode)
Definition z3py.py:244
__init__(self, *args, **kws)
Definition z3py.py:202
interrupt(self)
Definition z3py.py:232
__del__(self)
Definition z3py.py:222
ref(self)
Definition z3py.py:228
__deepcopy__(self, memo={})
Definition z3py.py:5248
create(self)
Definition z3py.py:5287
__init__(self, name, ctx=None)
Definition z3py.py:5243
__repr__(self)
Definition z3py.py:5284
declare(self, name, *args)
Definition z3py.py:5263
declare_core(self, name, rec_name, *args)
Definition z3py.py:5253
update_field(self, field_accessor, new_value)
Definition z3py.py:5528
constructor(self, idx)
Definition z3py.py:5440
accessor(self, i, j)
Definition z3py.py:5487
num_constructors(self)
Definition z3py.py:5427
recognizer(self, idx)
Definition z3py.py:5459
Expressions.
Definition z3py.py:1018
update(self, *args)
Definition z3py.py:1174
as_ast(self)
Definition z3py.py:1029
__hash__(self)
Definition z3py.py:1075
kind(self)
Definition z3py.py:1115
children(self)
Definition z3py.py:1159
serialize(self)
Definition z3py.py:1201
get_id(self)
Definition z3py.py:1032
num_args(self)
Definition z3py.py:1122
__eq__(self, other)
Definition z3py.py:1058
__ne__(self, other)
Definition z3py.py:1079
from_string(self, s)
Definition z3py.py:1198
sort_kind(self)
Definition z3py.py:1047
arg(self, idx)
Definition z3py.py:1138
sort(self)
Definition z3py.py:1035
params(self)
Definition z3py.py:1097
decl(self)
Definition z3py.py:1100
Function Declarations.
Definition z3py.py:775
as_func_decl(self)
Definition z3py.py:789
domain(self, i)
Definition z3py.py:813
as_ast(self)
Definition z3py.py:783
__call__(self, *args)
Definition z3py.py:876
arity(self)
Definition z3py.py:803
get_id(self)
Definition z3py.py:786
range(self)
Definition z3py.py:825
params(self)
Definition z3py.py:848
Definition z3py.py:6360
__deepcopy__(self, memo={})
Definition z3py.py:6368
ctx
Definition z3py.py:6365
__repr__(self)
Definition z3py.py:6465
num_args(self)
Definition z3py.py:6375
entry
Definition z3py.py:6364
value(self)
Definition z3py.py:6424
__init__(self, entry, ctx)
Definition z3py.py:6363
__del__(self)
Definition z3py.py:6371
as_list(self)
Definition z3py.py:6446
arg_value(self, idx)
Definition z3py.py:6393
__deepcopy__(self, memo={})
Definition z3py.py:6563
translate(self, other_ctx)
Definition z3py.py:6555
arity(self)
Definition z3py.py:6521
__repr__(self)
Definition z3py.py:6583
num_entries(self)
Definition z3py.py:6505
__init__(self, f, ctx)
Definition z3py.py:6472
__del__(self)
Definition z3py.py:6478
as_list(self)
Definition z3py.py:6566
else_value(self)
Definition z3py.py:6482
entry(self, idx)
Definition z3py.py:6535
__copy__(self)
Definition z3py.py:6560
__deepcopy__(self, memo={})
Definition z3py.py:6021
get(self, i)
Definition z3py.py:5877
prec(self)
Definition z3py.py:5821
translate(self, target)
Definition z3py.py:5995
append(self, *args)
Definition z3py.py:5922
as_expr(self)
Definition z3py.py:6044
assert_exprs(self, *args)
Definition z3py.py:5907
__repr__(self)
Definition z3py.py:5984
__len__(self)
Definition z3py.py:5864
inconsistent(self)
Definition z3py.py:5803
dimacs(self, include_names=True)
Definition z3py.py:5991
__getitem__(self, arg)
Definition z3py.py:5890
size(self)
Definition z3py.py:5851
precision(self)
Definition z3py.py:5842
simplify(self, *arguments, **keywords)
Definition z3py.py:6024
sexpr(self)
Definition z3py.py:5987
add(self, *args)
Definition z3py.py:5944
__del__(self)
Definition z3py.py:5781
convert_model(self, model)
Definition z3py.py:5955
insert(self, *args)
Definition z3py.py:5933
depth(self)
Definition z3py.py:5785
__init__(self, models=True, unsat_cores=False, proofs=False, ctx=None, goal=None)
Definition z3py.py:5771
__copy__(self)
Definition z3py.py:6018
as_binary_string(self)
Definition z3py.py:3126
py_value(self)
Definition z3py.py:3134
as_long(self)
Definition z3py.py:3105
as_string(self)
Definition z3py.py:3118
__deepcopy__(self, memo={})
Definition z3py.py:6931
eval(self, t, model_completion=False)
Definition z3py.py:6607
translate(self, target)
Definition z3py.py:6896
__getitem__(self, idx)
Definition z3py.py:6808
num_sorts(self)
Definition z3py.py:6733
get_universe(self, s)
Definition z3py.py:6788
get_sort(self, idx)
Definition z3py.py:6748
project(self, vars, fml)
Definition z3py.py:6904
__repr__(self)
Definition z3py.py:6600
__len__(self)
Definition z3py.py:6664
get_interp(self, decl)
Definition z3py.py:6681
__init__(self, m, ctx)
Definition z3py.py:6590
sexpr(self)
Definition z3py.py:6603
sorts(self)
Definition z3py.py:6771
__del__(self)
Definition z3py.py:6596
decls(self)
Definition z3py.py:6855
project_with_witness(self, vars, fml)
Definition z3py.py:6916
update_value(self, x, value)
Definition z3py.py:6874
evaluate(self, t, model_completion=False)
Definition z3py.py:6638
__copy__(self)
Definition z3py.py:6928
__deepcopy__(self, memo={})
Definition z3py.py:5715
__init__(self, descr, ctx=None)
Definition z3py.py:5709
get_kind(self, n)
Definition z3py.py:5737
get_documentation(self, n)
Definition z3py.py:5742
__getitem__(self, arg)
Definition z3py.py:5747
get_name(self, i)
Definition z3py.py:5732
Parameter Sets.
Definition z3py.py:5636
__deepcopy__(self, memo={})
Definition z3py.py:5650
validate(self, ds)
Definition z3py.py:5677
__repr__(self)
Definition z3py.py:5674
__init__(self, ctx=None, params=None)
Definition z3py.py:5642
set(self, name, val)
Definition z3py.py:5657
__del__(self)
Definition z3py.py:5653
Patterns.
Definition z3py.py:2054
as_ast(self)
Definition z3py.py:2059
get_id(self)
Definition z3py.py:2062
Quantifiers.
Definition z3py.py:2121
num_no_patterns(self)
Definition z3py.py:2239
no_pattern(self, idx)
Definition z3py.py:2243
num_patterns(self)
Definition z3py.py:2209
var_name(self, idx)
Definition z3py.py:2272
__getitem__(self, arg)
Definition z3py.py:2178
var_sort(self, idx)
Definition z3py.py:2288
pattern(self, idx)
Definition z3py.py:2221
numerator_as_long(self)
Definition z3py.py:3167
is_int_value(self)
Definition z3py.py:3197
as_fraction(self)
Definition z3py.py:3225
py_value(self)
Definition z3py.py:3234
numerator(self)
Definition z3py.py:3141
is_real(self)
Definition z3py.py:3194
as_long(self)
Definition z3py.py:3200
is_int(self)
Definition z3py.py:3191
denominator_as_long(self)
Definition z3py.py:3180
as_string(self)
Definition z3py.py:3216
denominator(self)
Definition z3py.py:3156
as_decimal(self, prec)
Definition z3py.py:3204
__init__(self, c, ctx)
Definition z3py.py:5307
__init__(self, c, ctx)
Definition z3py.py:5319
Strings, Sequences and Regular expressions.
Definition z3py.py:11099
__init__(self, solver=None, ctx=None, logFile=None)
Definition z3py.py:7152
assert_and_track(self, a, p)
Definition z3py.py:7321
num_scopes(self)
Definition z3py.py:7233
append(self, *args)
Definition z3py.py:7299
__iadd__(self, fml)
Definition z3py.py:7295
backtrack_level
Definition z3py.py:7155
pop(self, num=1)
Definition z3py.py:7211
import_model_converter(self, other)
Definition z3py.py:7399
assert_exprs(self, *args)
Definition z3py.py:7265
model(self)
Definition z3py.py:7380
set(self, *args, **keys)
Definition z3py.py:7176
__enter__(self)
Definition z3py.py:7169
add(self, *args)
Definition z3py.py:7284
__del__(self)
Definition z3py.py:7165
insert(self, *args)
Definition z3py.py:7310
check(self, *assumptions)
Definition z3py.py:7351
push(self)
Definition z3py.py:7189
__exit__(self, *exc_info)
Definition z3py.py:7173
reset(self)
Definition z3py.py:7251
subsort(self, other)
Definition z3py.py:616
as_ast(self)
Definition z3py.py:593
__hash__(self)
Definition z3py.py:677
kind(self)
Definition z3py.py:599
__gt__(self, other)
Definition z3py.py:673
get_id(self)
Definition z3py.py:596
__eq__(self, other)
Definition z3py.py:649
__ne__(self, other)
Definition z3py.py:662
cast(self, val)
Definition z3py.py:624
name(self)
Definition z3py.py:639
Statistics.
Definition z3py.py:6961
__deepcopy__(self, memo={})
Definition z3py.py:6969
__getattr__(self, name)
Definition z3py.py:7064
__getitem__(self, idx)
Definition z3py.py:7008
__init__(self, stats, ctx)
Definition z3py.py:6964
__repr__(self)
Definition z3py.py:6976
__len__(self)
Definition z3py.py:6994
__del__(self)
Definition z3py.py:6972
get_key_value(self, key)
Definition z3py.py:7044
subsort(self, other)
Definition z3py.py:751
cast(self, val)
Definition z3py.py:754
ASTs base class.
Definition z3py.py:355
_repr_html_(self)
Definition z3py.py:361
use_pp(self)
Definition z3py.py:358
Z3_ast Z3_API Z3_model_get_const_interp(Z3_context c, Z3_model m, Z3_func_decl a)
Return the interpretation (i.e., assignment) of constant a in the model m. Return NULL,...
Z3_sort Z3_API Z3_mk_int_sort(Z3_context c)
Create the integer type.
Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const *domain, Z3_sort range)
Create an array type with N arguments.
bool Z3_API Z3_open_log(Z3_string filename)
Log interaction to a file.
Z3_parameter_kind Z3_API Z3_get_decl_parameter_kind(Z3_context c, Z3_func_decl d, unsigned idx)
Return the parameter type associated with a declaration.
Z3_ast Z3_API Z3_get_denominator(Z3_context c, Z3_ast a)
Return the denominator (as a numeral AST) of a numeral AST of sort Real.
Z3_probe Z3_API Z3_probe_not(Z3_context x, Z3_probe p)
Return a probe that evaluates to "true" when p does not evaluate to true.
Z3_decl_kind Z3_API Z3_get_decl_kind(Z3_context c, Z3_func_decl d)
Return declaration kind corresponding to declaration.
void Z3_API Z3_solver_assert_and_track(Z3_context c, Z3_solver s, Z3_ast a, Z3_ast p)
Assert a constraint a into the solver, and track it (in the unsat) core using the Boolean constant p.
Z3_ast Z3_API Z3_func_interp_get_else(Z3_context c, Z3_func_interp f)
Return the 'else' value of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsge(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than or equal to.
void Z3_API Z3_ast_map_inc_ref(Z3_context c, Z3_ast_map m)
Increment the reference counter of the given AST map.
Z3_ast Z3_API Z3_mk_const_array(Z3_context c, Z3_sort domain, Z3_ast v)
Create the constant array.
Z3_ast Z3_API Z3_mk_bvsle(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than or equal to.
Z3_func_decl Z3_API Z3_get_app_decl(Z3_context c, Z3_app a)
Return the declaration of a constant or function application.
void Z3_API Z3_del_context(Z3_context c)
Delete the given logical context.
Z3_func_decl Z3_API Z3_get_decl_func_decl_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_ast Z3_API Z3_ast_map_find(Z3_context c, Z3_ast_map m, Z3_ast k)
Return the value associated with the key k.
Z3_string Z3_API Z3_ast_map_to_string(Z3_context c, Z3_ast_map m)
Convert the given map into a string.
Z3_string Z3_API Z3_param_descrs_to_string(Z3_context c, Z3_param_descrs p)
Convert a parameter description set into a string. This function is mainly used for printing the cont...
Z3_ast Z3_API Z3_mk_zero_ext(Z3_context c, unsigned i, Z3_ast t1)
Extend the given bit-vector with zeros to the (unsigned) equivalent bit-vector of size m+i,...
void Z3_API Z3_solver_set_params(Z3_context c, Z3_solver s, Z3_params p)
Set the given solver using the given parameters.
Z3_ast Z3_API Z3_mk_set_intersect(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the intersection of a list of sets.
Z3_params Z3_API Z3_mk_params(Z3_context c)
Create a Z3 (empty) parameter set. Starting at Z3 4.0, parameter sets are used to configure many comp...
unsigned Z3_API Z3_get_decl_num_parameters(Z3_context c, Z3_func_decl d)
Return the number of parameters associated with a declaration.
Z3_ast Z3_API Z3_mk_set_subset(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Check for subsetness of sets.
Z3_ast Z3_API Z3_mk_bvule(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than or equal to.
Z3_ast Z3_API Z3_mk_full_set(Z3_context c, Z3_sort domain)
Create the full set.
Z3_param_kind Z3_API Z3_param_descrs_get_kind(Z3_context c, Z3_param_descrs p, Z3_symbol n)
Return the kind associated with the given parameter name n.
void Z3_API Z3_add_rec_def(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast args[], Z3_ast body)
Define the body of a recursive function.
Z3_ast Z3_API Z3_mk_true(Z3_context c)
Create an AST node representing true.
Z3_ast Z3_API Z3_mk_set_union(Z3_context c, unsigned num_args, Z3_ast const args[])
Take the union of a list of sets.
Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast default_value)
Create a fresh func_interp object, add it to a model for a specified function. It has reference count...
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed division of t1 and t2 does not overflow.
unsigned Z3_API Z3_get_arity(Z3_context c, Z3_func_decl d)
Alias for Z3_get_domain_size.
void Z3_API Z3_ast_vector_set(Z3_context c, Z3_ast_vector v, unsigned i, Z3_ast a)
Update position i of the AST vector v with the AST a.
Z3_ast Z3_API Z3_mk_bvxor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise exclusive-or.
Z3_string Z3_API Z3_stats_to_string(Z3_context c, Z3_stats s)
Convert a statistics into a string.
Z3_sort Z3_API Z3_mk_real_sort(Z3_context c)
Create the real type.
Z3_ast Z3_API Z3_mk_le(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than or equal to.
bool Z3_API Z3_global_param_get(Z3_string param_id, Z3_string_ptr param_value)
Get a global (or module) parameter.
bool Z3_API Z3_goal_inconsistent(Z3_context c, Z3_goal g)
Return true if the given goal contains the formula false.
Z3_ast Z3_API Z3_mk_lambda_const(Z3_context c, unsigned num_bound, Z3_app const bound[], Z3_ast body)
Create a lambda expression using a list of constants that form the set of bound variables.
void Z3_API Z3_solver_dec_ref(Z3_context c, Z3_solver s)
Decrement the reference counter of the given solver.
Z3_ast Z3_API Z3_mk_bvslt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed less than.
Z3_func_decl Z3_API Z3_model_get_func_decl(Z3_context c, Z3_model m, unsigned i)
Return the declaration of the i-th function in the given model.
bool Z3_API Z3_ast_map_contains(Z3_context c, Z3_ast_map m, Z3_ast k)
Return true if the map m contains the AST key k.
Z3_ast Z3_API Z3_mk_numeral(Z3_context c, Z3_string numeral, Z3_sort ty)
Create a numeral of a given sort.
unsigned Z3_API Z3_func_entry_get_num_args(Z3_context c, Z3_func_entry e)
Return the number of arguments in a Z3_func_entry object.
Z3_symbol Z3_API Z3_get_decl_symbol_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the double value associated with an double parameter.
Z3_symbol Z3_API Z3_get_quantifier_skolem_id(Z3_context c, Z3_ast a)
Obtain skolem id of quantifier.
Z3_ast Z3_API Z3_get_numerator(Z3_context c, Z3_ast a)
Return the numerator (as a numeral AST) of a numeral AST of sort Real.
Z3_ast Z3_API Z3_mk_unary_minus(Z3_context c, Z3_ast arg)
Create an AST node representing - arg.
Z3_ast Z3_API Z3_mk_and(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] and ... and args[num_args-1].
void Z3_API Z3_interrupt(Z3_context c)
Interrupt the execution of a Z3 procedure. This procedure can be used to interrupt: solvers,...
void Z3_API Z3_goal_assert(Z3_context c, Z3_goal g, Z3_ast a)
Add a new formula a to the given goal. The formula is split according to the following procedure that...
Z3_symbol Z3_API Z3_param_descrs_get_name(Z3_context c, Z3_param_descrs p, unsigned i)
Return the name of the parameter at given index i.
Z3_ast Z3_API Z3_func_entry_get_value(Z3_context c, Z3_func_entry e)
Return the value of this point.
bool Z3_API Z3_is_quantifier_exists(Z3_context c, Z3_ast a)
Determine if ast is an existential quantifier.
Z3_sort Z3_API Z3_mk_uninterpreted_sort(Z3_context c, Z3_symbol s)
Create a free (uninterpreted) type using the given name (symbol).
Z3_ast Z3_API Z3_mk_false(Z3_context c)
Create an AST node representing false.
Z3_ast_vector Z3_API Z3_ast_map_keys(Z3_context c, Z3_ast_map m)
Return the keys stored in the given map.
Z3_ast Z3_API Z3_mk_bvmul(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement multiplication.
Z3_model Z3_API Z3_goal_convert_model(Z3_context c, Z3_goal g, Z3_model m)
Convert a model of the formulas of a goal to a model of an original goal. The model may be null,...
void Z3_API Z3_del_constructor(Z3_context c, Z3_constructor constr)
Reclaim memory allocated to constructor.
Z3_ast Z3_API Z3_mk_bvsgt(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed greater than.
Z3_string Z3_API Z3_ast_to_string(Z3_context c, Z3_ast a)
Convert the given AST node into a string.
Z3_context Z3_API Z3_mk_context_rc(Z3_config c)
Create a context using the given configuration. This function is similar to Z3_mk_context....
Z3_string Z3_API Z3_get_full_version(void)
Return a string that fully describes the version of Z3 in use.
void Z3_API Z3_enable_trace(Z3_string tag)
Enable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_mk_set_complement(Z3_context c, Z3_ast arg)
Take the complement of a set.
unsigned Z3_API Z3_get_quantifier_num_patterns(Z3_context c, Z3_ast a)
Return number of patterns used in quantifier.
Z3_symbol Z3_API Z3_get_quantifier_bound_name(Z3_context c, Z3_ast a, unsigned i)
Return symbol of the i'th bound variable.
bool Z3_API Z3_stats_is_uint(Z3_context c, Z3_stats s, unsigned idx)
Return true if the given statistical data is a unsigned integer.
unsigned Z3_API Z3_model_get_num_consts(Z3_context c, Z3_model m)
Return the number of constants assigned by the given model.
Z3_ast Z3_API Z3_mk_extract(Z3_context c, unsigned high, unsigned low, Z3_ast t1)
Extract the bits high down to low from a bit-vector of size m to yield a new bit-vector of size n,...
Z3_ast Z3_API Z3_mk_mod(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 mod arg2.
Z3_ast Z3_API Z3_mk_bvredand(Z3_context c, Z3_ast t1)
Take conjunction of bits in vector, return vector of length 1.
Z3_ast Z3_API Z3_mk_set_add(Z3_context c, Z3_ast set, Z3_ast elem)
Add an element to a set.
Z3_ast Z3_API Z3_mk_ge(Z3_context c, Z3_ast t1, Z3_ast t2)
Create greater than or equal to.
Z3_ast Z3_API Z3_mk_bvadd_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed addition of t1 and t2 does not underflow.
Z3_ast Z3_API Z3_mk_bvadd_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise addition of t1 and t2 does not overflow.
void Z3_API Z3_set_ast_print_mode(Z3_context c, Z3_ast_print_mode mode)
Select mode for the format used for pretty-printing AST nodes.
Z3_ast Z3_API Z3_mk_array_default(Z3_context c, Z3_ast array)
Access the array default value. Produces the default range value, for arrays that can be represented ...
Z3_ast Z3_API Z3_datatype_update_field(Z3_context c, Z3_func_decl field_access, Z3_ast t, Z3_ast value)
Update record field with a value.
unsigned Z3_API Z3_model_get_num_sorts(Z3_context c, Z3_model m)
Return the number of uninterpreted sorts that m assigns an interpretation to.
Z3_ast_vector Z3_API Z3_ast_vector_translate(Z3_context s, Z3_ast_vector v, Z3_context t)
Translate the AST vector v from context s into an AST vector in context t.
void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e)
Increment the reference counter of the given Z3_func_entry object.
Z3_ast Z3_API Z3_mk_fresh_const(Z3_context c, Z3_string prefix, Z3_sort ty)
Declare and create a fresh constant.
Z3_ast Z3_API Z3_mk_bvsub_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed subtraction of t1 and t2 does not overflow.
void Z3_API Z3_solver_push(Z3_context c, Z3_solver s)
Create a backtracking point.
Z3_ast Z3_API Z3_mk_bvsub_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise subtraction of t1 and t2 does not underflow.
Z3_goal Z3_API Z3_goal_translate(Z3_context source, Z3_goal g, Z3_context target)
Copy a goal g from the context source to the context target.
Z3_ast Z3_API Z3_mk_bvudiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned division.
Z3_string Z3_API Z3_ast_vector_to_string(Z3_context c, Z3_ast_vector v)
Convert AST vector into a string.
Z3_ast Z3_API Z3_mk_bvshl(Z3_context c, Z3_ast t1, Z3_ast t2)
Shift left.
bool Z3_API Z3_is_numeral_ast(Z3_context c, Z3_ast a)
Z3_ast Z3_API Z3_mk_bvsrem(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed remainder (sign follows dividend).
bool Z3_API Z3_is_as_array(Z3_context c, Z3_ast a)
The (_ as-array f) AST node is a construct for assigning interpretations for arrays in Z3....
Z3_func_decl Z3_API Z3_mk_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a constant or function.
Z3_ast Z3_API Z3_mk_is_int(Z3_context c, Z3_ast t1)
Check if a real number is an integer.
void Z3_API Z3_params_set_bool(Z3_context c, Z3_params p, Z3_symbol k, bool v)
Add a Boolean parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_mk_ite(Z3_context c, Z3_ast t1, Z3_ast t2, Z3_ast t3)
Create an AST node representing an if-then-else: ite(t1, t2, t3).
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i)
Array read. The argument a is the array and i is the index of the array that gets read.
Z3_ast Z3_API Z3_mk_sign_ext(Z3_context c, unsigned i, Z3_ast t1)
Sign-extend of the given bit-vector to the (signed) equivalent bit-vector of size m+i,...
unsigned Z3_API Z3_goal_size(Z3_context c, Z3_goal g)
Return the number of formulas in the given goal.
void Z3_API Z3_stats_inc_ref(Z3_context c, Z3_stats s)
Increment the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs)
n-ary Array read. The argument a is the array and idxs are the indices of the array that gets read.
Z3_ast_vector Z3_API Z3_algebraic_get_poly(Z3_context c, Z3_ast a)
Return the coefficients of the defining polynomial.
Z3_ast Z3_API Z3_mk_div(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 div arg2.
void Z3_API Z3_model_dec_ref(Z3_context c, Z3_model m)
Decrement the reference counter of the given model.
Z3_sort Z3_API Z3_mk_datatype_sort(Z3_context c, Z3_symbol name, unsigned num_params, Z3_sort const params[])
create a forward reference to a recursive datatype being declared. The forward reference can be used ...
void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f)
Increment the reference counter of the given Z3_func_interp object.
void Z3_API Z3_params_set_double(Z3_context c, Z3_params p, Z3_symbol k, double v)
Add a double parameter k with value v to the parameter set p.
Z3_string Z3_API Z3_param_descrs_get_documentation(Z3_context c, Z3_param_descrs p, Z3_symbol s)
Retrieve documentation string corresponding to parameter name s.
Z3_solver Z3_API Z3_mk_solver(Z3_context c)
Create a new solver. This solver is a "combined solver" (see combined_solver module) that internally ...
Z3_model Z3_API Z3_solver_get_model(Z3_context c, Z3_solver s)
Retrieve the model for the last Z3_solver_check or Z3_solver_check_assumptions.
int Z3_API Z3_get_symbol_int(Z3_context c, Z3_symbol s)
Return the symbol int value.
Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a)
Return the function declaration f associated with a (_ as_array f) node.
Z3_ast Z3_API Z3_mk_ext_rotate_left(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the left t2 times.
void Z3_API Z3_goal_inc_ref(Z3_context c, Z3_goal g)
Increment the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_implies(Z3_context c, Z3_ast t1, Z3_ast t2)
Create an AST node representing t1 implies t2.
unsigned Z3_API Z3_get_datatype_sort_num_constructors(Z3_context c, Z3_sort t)
Return number of constructors for datatype.
void Z3_API Z3_params_set_uint(Z3_context c, Z3_params p, Z3_symbol k, unsigned v)
Add a unsigned parameter k with value v to the parameter set p.
Z3_lbool Z3_API Z3_solver_check_assumptions(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[])
Check whether the assertions in the given solver and optional assumptions are consistent or not.
Z3_sort Z3_API Z3_model_get_sort(Z3_context c, Z3_model m, unsigned i)
Return a uninterpreted sort that m assigns an interpretation.
Z3_ast Z3_API Z3_mk_bvashr(Z3_context c, Z3_ast t1, Z3_ast t2)
Arithmetic shift right.
Z3_ast Z3_API Z3_mk_bv2int(Z3_context c, Z3_ast t1, bool is_signed)
Create an integer from the bit-vector argument t1. If is_signed is false, then the bit-vector t1 is t...
Z3_sort Z3_API Z3_get_array_sort_domain_n(Z3_context c, Z3_sort t, unsigned idx)
Return the i'th domain sort of an n-dimensional array.
Z3_ast Z3_API Z3_mk_set_del(Z3_context c, Z3_ast set, Z3_ast elem)
Remove an element to a set.
Z3_ast Z3_API Z3_mk_bvmul_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2, bool is_signed)
Create a predicate that checks that the bit-wise multiplication of t1 and t2 does not overflow.
Z3_ast Z3_API Z3_mk_bvor(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise or.
int Z3_API Z3_get_decl_int_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the integer value associated with an integer parameter.
unsigned Z3_API Z3_get_quantifier_num_no_patterns(Z3_context c, Z3_ast a)
Return number of no_patterns used in quantifier.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor(Z3_context c, Z3_sort t, unsigned idx)
Return idx'th constructor.
void Z3_API Z3_ast_vector_resize(Z3_context c, Z3_ast_vector v, unsigned n)
Resize the AST vector v.
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c, bool is_forall, unsigned weight, Z3_symbol quantifier_id, Z3_symbol skolem_id, unsigned num_bound, Z3_app const bound[], unsigned num_patterns, Z3_pattern const patterns[], unsigned num_no_patterns, Z3_ast const no_patterns[], Z3_ast body)
Create a universal or existential quantifier using a list of constants that will form the set of boun...
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[])
Create a pattern for quantifier instantiation.
Z3_symbol_kind Z3_API Z3_get_symbol_kind(Z3_context c, Z3_symbol s)
Return Z3_INT_SYMBOL if the symbol was constructed using Z3_mk_int_symbol, and Z3_STRING_SYMBOL if th...
bool Z3_API Z3_is_lambda(Z3_context c, Z3_ast a)
Determine if ast is a lambda expression.
unsigned Z3_API Z3_stats_get_uint_value(Z3_context c, Z3_stats s, unsigned idx)
Return the unsigned value of the given statistical data.
Z3_sort Z3_API Z3_get_array_sort_domain(Z3_context c, Z3_sort t)
Return the domain of the given array sort. In the case of a multi-dimensional array,...
Z3_ast Z3_API Z3_mk_bvmul_no_underflow(Z3_context c, Z3_ast t1, Z3_ast t2)
Create a predicate that checks that the bit-wise signed multiplication of t1 and t2 does not underflo...
Z3_ast Z3_API Z3_func_decl_to_ast(Z3_context c, Z3_func_decl f)
Convert a Z3_func_decl into Z3_ast. This is just type casting.
void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a)
Add a constant interpretation.
Z3_ast Z3_API Z3_mk_bvadd(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement addition.
unsigned Z3_API Z3_algebraic_get_i(Z3_context c, Z3_ast a)
Return which root of the polynomial the algebraic number represents.
void Z3_API Z3_params_dec_ref(Z3_context c, Z3_params p)
Decrement the reference counter of the given parameter set.
Z3_ast Z3_API Z3_get_app_arg(Z3_context c, Z3_app a, unsigned i)
Return the i-th argument of the given application.
Z3_string Z3_API Z3_model_to_string(Z3_context c, Z3_model m)
Convert the given model into a string.
Z3_func_decl Z3_API Z3_mk_fresh_func_decl(Z3_context c, Z3_string prefix, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a fresh constant or function.
unsigned Z3_API Z3_ast_map_size(Z3_context c, Z3_ast_map m)
Return the size of the given map.
unsigned Z3_API Z3_param_descrs_size(Z3_context c, Z3_param_descrs p)
Return the number of parameters in the given parameter description set.
Z3_string Z3_API Z3_goal_to_dimacs_string(Z3_context c, Z3_goal g, bool include_names)
Convert a goal into a DIMACS formatted string. The goal must be in CNF. You can convert a goal to CNF...
Z3_ast Z3_API Z3_mk_lt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create less than.
Z3_ast Z3_API Z3_get_quantifier_no_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th no_pattern.
double Z3_API Z3_stats_get_double_value(Z3_context c, Z3_stats s, unsigned idx)
Return the double value of the given statistical data.
Z3_ast Z3_API Z3_mk_bvugt(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than.
unsigned Z3_API Z3_goal_depth(Z3_context c, Z3_goal g)
Return the depth of the given goal. It tracks how many transformations were applied to it.
Z3_ast Z3_API Z3_update_term(Z3_context c, Z3_ast a, unsigned num_args, Z3_ast const args[])
Update the arguments of term a using the arguments args. The number of arguments num_args should coin...
Z3_string Z3_API Z3_get_symbol_string(Z3_context c, Z3_symbol s)
Return the symbol name.
Z3_ast Z3_API Z3_pattern_to_ast(Z3_context c, Z3_pattern p)
Convert a Z3_pattern into Z3_ast. This is just type casting.
Z3_ast Z3_API Z3_mk_bvnot(Z3_context c, Z3_ast t1)
Bitwise negation.
Z3_ast Z3_API Z3_mk_bvurem(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned remainder.
void Z3_API Z3_mk_datatypes(Z3_context c, unsigned num_sorts, Z3_symbol const sort_names[], Z3_sort sorts[], Z3_constructor_list constructor_lists[])
Create mutually recursive datatypes.
unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f)
Return the arity (number of arguments) of the given function interpretation.
Z3_ast Z3_API Z3_mk_bvsub(Z3_context c, Z3_ast t1, Z3_ast t2)
Standard two's complement subtraction.
Z3_ast Z3_API Z3_get_algebraic_number_upper(Z3_context c, Z3_ast a, unsigned precision)
Return a upper bound for the given real algebraic number. The interval isolating the number is smalle...
Z3_ast Z3_API Z3_mk_power(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create an AST node representing arg1 ^ arg2.
Z3_ast Z3_API Z3_mk_seq_concat(Z3_context c, unsigned n, Z3_ast const args[])
Concatenate sequences.
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c, Z3_symbol name, unsigned n, Z3_symbol const enum_names[], Z3_func_decl enum_consts[], Z3_func_decl enum_testers[])
Create a enumeration sort.
unsigned Z3_API Z3_get_bv_sort_size(Z3_context c, Z3_sort t)
Return the size of the given bit-vector sort.
Z3_ast Z3_API Z3_mk_set_member(Z3_context c, Z3_ast elem, Z3_ast set)
Check for set membership.
void Z3_API Z3_ast_vector_dec_ref(Z3_context c, Z3_ast_vector v)
Decrement the reference counter of the given AST vector.
void Z3_API Z3_func_interp_dec_ref(Z3_context c, Z3_func_interp f)
Decrement the reference counter of the given Z3_func_interp object.
void Z3_API Z3_params_inc_ref(Z3_context c, Z3_params p)
Increment the reference counter of the given parameter set.
void Z3_API Z3_set_error_handler(Z3_context c, Z3_error_handler h)
Register a Z3 error handler.
Z3_ast Z3_API Z3_mk_distinct(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing distinct(args[0], ..., args[num_args-1]).
Z3_config Z3_API Z3_mk_config(void)
Create a configuration object for the Z3 context object.
void Z3_API Z3_set_param_value(Z3_config c, Z3_string param_id, Z3_string param_value)
Set a configuration parameter.
Z3_sort Z3_API Z3_mk_bv_sort(Z3_context c, unsigned sz)
Create a bit-vector type of the given size.
Z3_ast Z3_API Z3_mk_bvult(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned less than.
void Z3_API Z3_ast_map_dec_ref(Z3_context c, Z3_ast_map m)
Decrement the reference counter of the given AST map.
Z3_string Z3_API Z3_params_to_string(Z3_context c, Z3_params p)
Convert a parameter set into a string. This function is mainly used for printing the contents of a pa...
Z3_param_descrs Z3_API Z3_get_global_param_descrs(Z3_context c)
Retrieve description of global parameters.
Z3_func_decl Z3_API Z3_model_get_const_decl(Z3_context c, Z3_model m, unsigned i)
Return the i-th constant in the given model.
Z3_ast Z3_API Z3_translate(Z3_context source, Z3_ast a, Z3_context target)
Translate/Copy the AST a from context source to context target. AST a must have been created using co...
Z3_sort Z3_API Z3_get_range(Z3_context c, Z3_func_decl d)
Return the range of the given declaration.
void Z3_API Z3_global_param_set(Z3_string param_id, Z3_string param_value)
Set a global (or module) parameter. This setting is shared by all Z3 contexts.
Z3_ast_vector Z3_API Z3_model_get_sort_universe(Z3_context c, Z3_model m, Z3_sort s)
Return the finite set of distinct values that represent the interpretation for sort s.
void Z3_API Z3_func_entry_dec_ref(Z3_context c, Z3_func_entry e)
Decrement the reference counter of the given Z3_func_entry object.
unsigned Z3_API Z3_stats_size(Z3_context c, Z3_stats s)
Return the number of statistical data in s.
void Z3_API Z3_append_log(Z3_string string)
Append user-defined string to interaction log.
Z3_ast Z3_API Z3_get_quantifier_body(Z3_context c, Z3_ast a)
Return body of quantifier.
void Z3_API Z3_param_descrs_dec_ref(Z3_context c, Z3_param_descrs p)
Decrement the reference counter of the given parameter description set.
Z3_model Z3_API Z3_mk_model(Z3_context c)
Create a fresh model object. It has reference count 0.
Z3_symbol Z3_API Z3_get_decl_name(Z3_context c, Z3_func_decl d)
Return the constant declaration name as a symbol.
Z3_ast Z3_API Z3_mk_bvneg_no_overflow(Z3_context c, Z3_ast t1)
Check that bit-wise negation does not overflow when t1 is interpreted as a signed bit-vector.
Z3_string Z3_API Z3_stats_get_key(Z3_context c, Z3_stats s, unsigned idx)
Return the key (a string) for a particular statistical data.
Z3_ast Z3_API Z3_mk_bvand(Z3_context c, Z3_ast t1, Z3_ast t2)
Bitwise and.
Z3_ast_kind Z3_API Z3_get_ast_kind(Z3_context c, Z3_ast a)
Return the kind of the given AST.
Z3_ast Z3_API Z3_mk_bvsmod(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed remainder (sign follows divisor).
Z3_model Z3_API Z3_model_translate(Z3_context c, Z3_model m, Z3_context dst)
translate model from context c to context dst.
void Z3_API Z3_get_version(unsigned *major, unsigned *minor, unsigned *build_number, unsigned *revision_number)
Return Z3 version number information.
Z3_ast Z3_API Z3_mk_int2bv(Z3_context c, unsigned n, Z3_ast t1)
Create an n bit bit-vector from the integer argument t1.
void Z3_API Z3_solver_assert(Z3_context c, Z3_solver s, Z3_ast a)
Assert a constraint into the solver.
unsigned Z3_API Z3_ast_vector_size(Z3_context c, Z3_ast_vector v)
Return the size of the given AST vector.
unsigned Z3_API Z3_get_quantifier_weight(Z3_context c, Z3_ast a)
Obtain weight of quantifier.
bool Z3_API Z3_model_eval(Z3_context c, Z3_model m, Z3_ast t, bool model_completion, Z3_ast *v)
Evaluate the AST node t in the given model. Return true if succeeded, and store the result in v.
unsigned Z3_API Z3_solver_get_num_scopes(Z3_context c, Z3_solver s)
Return the number of backtracking points.
Z3_sort Z3_API Z3_get_array_sort_range(Z3_context c, Z3_sort t)
Return the range of the given array sort.
void Z3_API Z3_del_constructor_list(Z3_context c, Z3_constructor_list clist)
Reclaim memory allocated for constructor list.
Z3_ast Z3_API Z3_mk_bound(Z3_context c, unsigned index, Z3_sort ty)
Create a variable.
unsigned Z3_API Z3_get_app_num_args(Z3_context c, Z3_app a)
Return the number of argument of an application. If t is an constant, then the number of arguments is...
Z3_ast Z3_API Z3_func_entry_get_arg(Z3_context c, Z3_func_entry e, unsigned i)
Return an argument of a Z3_func_entry object.
Z3_ast Z3_API Z3_mk_eq(Z3_context c, Z3_ast l, Z3_ast r)
Create an AST node representing l = r.
void Z3_API Z3_ast_vector_inc_ref(Z3_context c, Z3_ast_vector v)
Increment the reference counter of the given AST vector.
unsigned Z3_API Z3_model_get_num_funcs(Z3_context c, Z3_model m)
Return the number of function interpretations in the given model.
void Z3_API Z3_dec_ref(Z3_context c, Z3_ast a)
Decrement the reference counter of the given AST. The context c should have been created using Z3_mk_...
Z3_ast_vector Z3_API Z3_mk_ast_vector(Z3_context c)
Return an empty AST vector.
Z3_ast Z3_API Z3_mk_empty_set(Z3_context c, Z3_sort domain)
Create the empty set.
Z3_ast Z3_API Z3_mk_repeat(Z3_context c, unsigned i, Z3_ast t1)
Repeat the given bit-vector up length i.
Z3_goal_prec Z3_API Z3_goal_precision(Z3_context c, Z3_goal g)
Return the "precision" of the given goal. Goals can be transformed using over and under approximation...
void Z3_API Z3_solver_pop(Z3_context c, Z3_solver s, unsigned n)
Backtrack n backtracking points.
void Z3_API Z3_ast_map_erase(Z3_context c, Z3_ast_map m, Z3_ast k)
Erase a key from the map.
Z3_ast Z3_API Z3_mk_int2real(Z3_context c, Z3_ast t1)
Coerce an integer to a real.
unsigned Z3_API Z3_get_index_value(Z3_context c, Z3_ast a)
Return index of de-Bruijn bound variable.
Z3_goal Z3_API Z3_mk_goal(Z3_context c, bool models, bool unsat_cores, bool proofs)
Create a goal (aka problem). A goal is essentially a set of formulas, that can be solved and/or trans...
double Z3_API Z3_get_decl_double_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the double value associated with an double parameter.
unsigned Z3_API Z3_get_ast_hash(Z3_context c, Z3_ast a)
Return a hash code for the given AST. The hash code is structural but two different AST objects can m...
Z3_symbol Z3_API Z3_get_sort_name(Z3_context c, Z3_sort d)
Return the sort name as a symbol.
void Z3_API Z3_params_validate(Z3_context c, Z3_params p, Z3_param_descrs d)
Validate the parameter set p against the parameter description set d.
Z3_func_decl Z3_API Z3_get_datatype_sort_recognizer(Z3_context c, Z3_sort t, unsigned idx)
Return idx'th recognizer.
void Z3_API Z3_global_param_reset_all(void)
Restore the value of all global (and module) parameters. This command will not affect already created...
Z3_ast Z3_API Z3_mk_gt(Z3_context c, Z3_ast t1, Z3_ast t2)
Create greater than.
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v)
Array update.
Z3_string Z3_API Z3_get_decl_rational_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the rational value, as a string, associated with a rational parameter.
void Z3_API Z3_ast_vector_push(Z3_context c, Z3_ast_vector v, Z3_ast a)
Add the AST a in the end of the AST vector v. The size of v is increased by one.
bool Z3_API Z3_is_eq_ast(Z3_context c, Z3_ast t1, Z3_ast t2)
Compare terms.
bool Z3_API Z3_is_quantifier_forall(Z3_context c, Z3_ast a)
Determine if an ast is a universal quantifier.
Z3_ast_map Z3_API Z3_mk_ast_map(Z3_context c)
Return an empty mapping from AST to AST.
Z3_ast Z3_API Z3_mk_xor(Z3_context c, Z3_ast t1, Z3_ast t2)
Create an AST node representing t1 xor t2.
Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const *args)
Map f on the argument arrays.
Z3_ast Z3_API Z3_mk_const(Z3_context c, Z3_symbol s, Z3_sort ty)
Declare and create a constant.
Z3_symbol Z3_API Z3_mk_string_symbol(Z3_context c, Z3_string s)
Create a Z3 symbol using a C string.
void Z3_API Z3_param_descrs_inc_ref(Z3_context c, Z3_param_descrs p)
Increment the reference counter of the given parameter description set.
void Z3_API Z3_stats_dec_ref(Z3_context c, Z3_stats s)
Decrement the reference counter of the given statistics object.
Z3_ast Z3_API Z3_mk_array_ext(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Create array extensionality index given two arrays with the same sort. The meaning is given by the ax...
Z3_ast Z3_API Z3_mk_re_concat(Z3_context c, unsigned n, Z3_ast const args[])
Create the concatenation of the regular languages.
Z3_ast Z3_API Z3_sort_to_ast(Z3_context c, Z3_sort s)
Convert a Z3_sort into Z3_ast. This is just type casting.
Z3_func_entry Z3_API Z3_func_interp_get_entry(Z3_context c, Z3_func_interp f, unsigned i)
Return a "point" of the given function interpretation. It represents the value of f in a particular p...
Z3_func_decl Z3_API Z3_mk_rec_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const domain[], Z3_sort range)
Declare a recursive function.
unsigned Z3_API Z3_get_ast_id(Z3_context c, Z3_ast t)
Return a unique identifier for t. The identifier is unique up to structural equality....
Z3_ast Z3_API Z3_mk_concat(Z3_context c, Z3_ast t1, Z3_ast t2)
Concatenate the given bit-vectors.
unsigned Z3_API Z3_get_quantifier_num_bound(Z3_context c, Z3_ast a)
Return number of bound variables of quantifier.
Z3_sort Z3_API Z3_get_decl_sort_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the sort value associated with a sort parameter.
Z3_constructor_list Z3_API Z3_mk_constructor_list(Z3_context c, unsigned num_constructors, Z3_constructor const constructors[])
Create list of constructors.
Z3_ast Z3_API Z3_mk_app(Z3_context c, Z3_func_decl d, unsigned num_args, Z3_ast const args[])
Create a constant or function application.
Z3_sort_kind Z3_API Z3_get_sort_kind(Z3_context c, Z3_sort t)
Return the sort kind (e.g., array, tuple, int, bool, etc).
Z3_ast Z3_API Z3_mk_bvneg(Z3_context c, Z3_ast t1)
Standard two's complement unary minus.
Z3_ast Z3_API Z3_mk_store_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const *idxs, Z3_ast v)
n-ary Array update.
Z3_sort Z3_API Z3_get_domain(Z3_context c, Z3_func_decl d, unsigned i)
Return the sort of the i-th parameter of the given function declaration.
Z3_sort Z3_API Z3_mk_bool_sort(Z3_context c)
Create the Boolean type.
void Z3_API Z3_params_set_symbol(Z3_context c, Z3_params p, Z3_symbol k, Z3_symbol v)
Add a symbol parameter k with value v to the parameter set p.
Z3_ast Z3_API Z3_ast_vector_get(Z3_context c, Z3_ast_vector v, unsigned i)
Return the AST at position i in the AST vector v.
Z3_func_decl Z3_API Z3_to_func_decl(Z3_context c, Z3_ast a)
Convert an AST into a FUNC_DECL_AST. This is just type casting.
Z3_ast Z3_API Z3_mk_set_difference(Z3_context c, Z3_ast arg1, Z3_ast arg2)
Take the set difference between two sets.
Z3_ast Z3_API Z3_mk_bvsdiv(Z3_context c, Z3_ast t1, Z3_ast t2)
Two's complement signed division.
Z3_ast Z3_API Z3_mk_bvlshr(Z3_context c, Z3_ast t1, Z3_ast t2)
Logical shift right.
Z3_ast Z3_API Z3_get_decl_ast_parameter(Z3_context c, Z3_func_decl d, unsigned idx)
Return the expression value associated with an expression parameter.
Z3_pattern Z3_API Z3_get_quantifier_pattern_ast(Z3_context c, Z3_ast a, unsigned i)
Return i'th pattern.
void Z3_API Z3_goal_dec_ref(Z3_context c, Z3_goal g)
Decrement the reference counter of the given goal.
Z3_ast Z3_API Z3_mk_not(Z3_context c, Z3_ast a)
Create an AST node representing not(a).
Z3_ast Z3_API Z3_mk_or(Z3_context c, unsigned num_args, Z3_ast const args[])
Create an AST node representing args[0] or ... or args[num_args-1].
Z3_sort Z3_API Z3_mk_array_sort(Z3_context c, Z3_sort domain, Z3_sort range)
Create an array type.
void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m)
Increment the reference counter of the given model.
Z3_ast Z3_API Z3_mk_seq_extract(Z3_context c, Z3_ast s, Z3_ast offset, Z3_ast length)
Extract subsequence starting at offset of length.
Z3_sort Z3_API Z3_mk_type_variable(Z3_context c, Z3_symbol s)
Create a type variable.
Z3_string Z3_API Z3_get_numeral_string(Z3_context c, Z3_ast a)
Return numeral value, as a decimal string of a numeric constant term.
void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value)
add a function entry to a function interpretation.
Z3_ast Z3_API Z3_mk_bvuge(Z3_context c, Z3_ast t1, Z3_ast t2)
Unsigned greater than or equal to.
Z3_string Z3_API Z3_get_numeral_binary_string(Z3_context c, Z3_ast a)
Return numeral value, as a binary string of a numeric constant term.
Z3_sort Z3_API Z3_get_quantifier_bound_sort(Z3_context c, Z3_ast a, unsigned i)
Return sort of the i'th bound variable.
void Z3_API Z3_disable_trace(Z3_string tag)
Disable tracing messages tagged as tag when Z3 is compiled in debug mode. It is a NOOP otherwise.
Z3_ast Z3_API Z3_goal_formula(Z3_context c, Z3_goal g, unsigned idx)
Return a formula from the given goal.
Z3_symbol Z3_API Z3_mk_int_symbol(Z3_context c, int i)
Create a Z3 symbol using an integer.
unsigned Z3_API Z3_func_interp_get_num_entries(Z3_context c, Z3_func_interp f)
Return the number of entries in the given function interpretation.
void Z3_API Z3_ast_map_insert(Z3_context c, Z3_ast_map m, Z3_ast k, Z3_ast v)
Store/Replace a new key, value pair in the given map.
Z3_constructor Z3_API Z3_mk_constructor(Z3_context c, Z3_symbol name, Z3_symbol recognizer, unsigned num_fields, Z3_symbol const field_names[], Z3_sort const sorts[], unsigned sort_refs[])
Create a constructor.
Z3_string Z3_API Z3_goal_to_string(Z3_context c, Z3_goal g)
Convert a goal into a string.
bool Z3_API Z3_is_eq_sort(Z3_context c, Z3_sort s1, Z3_sort s2)
compare sorts.
void Z3_API Z3_del_config(Z3_config c)
Delete the given configuration object.
double Z3_API Z3_get_numeral_double(Z3_context c, Z3_ast a)
Return numeral as a double.
void Z3_API Z3_inc_ref(Z3_context c, Z3_ast a)
Increment the reference counter of the given AST. The context c should have been created using Z3_mk_...
Z3_ast Z3_API Z3_mk_real2int(Z3_context c, Z3_ast t1)
Coerce a real to an integer.
Z3_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f)
Return the interpretation of the function f in the model m. Return NULL, if the model does not assign...
void Z3_API Z3_solver_inc_ref(Z3_context c, Z3_solver s)
Increment the reference counter of the given solver.
Z3_symbol Z3_API Z3_get_quantifier_id(Z3_context c, Z3_ast a)
Obtain id of quantifier.
Z3_ast Z3_API Z3_mk_ext_rotate_right(Z3_context c, Z3_ast t1, Z3_ast t2)
Rotate bits of t1 to the right t2 times.
Z3_string Z3_API Z3_get_numeral_decimal_string(Z3_context c, Z3_ast a, unsigned precision)
Return numeral as a string in decimal notation. The result has at most precision decimal places.
Z3_sort Z3_API Z3_get_sort(Z3_context c, Z3_ast a)
Return the sort of an AST node.
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(Z3_context c, Z3_sort t, unsigned idx_c, unsigned idx_a)
Return idx_a'th accessor for the idx_c'th constructor.
Z3_ast Z3_API Z3_mk_bvredor(Z3_context c, Z3_ast t1)
Take disjunction of bits in vector, return vector of length 1.
void Z3_API Z3_ast_map_reset(Z3_context c, Z3_ast_map m)
Remove all keys from the given map.
void Z3_API Z3_solver_reset(Z3_context c, Z3_solver s)
Remove all assertions from the solver.
bool Z3_API Z3_is_algebraic_number(Z3_context c, Z3_ast a)
Return true if the given AST is a real algebraic number.
_py2expr(a, ctx=None)
Definition z3py.py:3272
RotateRight(a, b)
Definition z3py.py:4524
_symbol2py(ctx, s)
Definition z3py.py:140
BitVecVal(val, bv, ctx=None)
Definition z3py.py:4174
BVSNegNoOverflow(a)
Definition z3py.py:4671
SetAdd(s, e)
Definition z3py.py:5136
SetSort(s)
Sets.
Definition z3py.py:5087
_coerce_exprs(a, b, ctx=None)
Definition z3py.py:1302
UGT(a, b)
Definition z3py.py:4395
is_probe(p)
Definition z3py.py:9001
SetDel(s, e)
Definition z3py.py:5147
bool is_le(Any a)
Definition z3py.py:3012
BoolSort(ctx=None)
Definition z3py.py:1824
is_bv_sort(s)
Definition z3py.py:3625
_ctx_from_ast_args(*args)
Definition z3py.py:542
RatVal(a, b, ctx=None)
Definition z3py.py:3364
_to_func_decl_ref(a, ctx)
Definition z3py.py:962
SetUnion(*args)
Definition z3py.py:5110
_valid_accessor(acc)
Datatypes.
Definition z3py.py:5207
BitVec(name, bv, ctx=None)
Definition z3py.py:4191
EmptySet(s)
Definition z3py.py:5092
BVMulNoUnderflow(a, b)
Definition z3py.py:4685
CreateDatatypes(*ds)
Definition z3py.py:5328
is_func_decl(a)
Definition z3py.py:907
get_as_array_func(n)
Definition z3py.py:6948
Distinct(*args)
Definition z3py.py:1507
RecAddDefinition(f, args, body)
Definition z3py.py:984
ToInt(a)
Definition z3py.py:3525
Implies(a, b, ctx=None)
Definition z3py.py:1918
UGE(a, b)
Definition z3py.py:4377
Ext(a, b)
Definition z3py.py:5045
_to_ast_array(args)
Definition z3py.py:554
bool is_sort(Any s)
Definition z3py.py:682
_check_bv_args(a, b)
Definition z3py.py:4336
RealSort(ctx=None)
Definition z3py.py:3304
IsSubset(a, b)
Definition z3py.py:5190
DeclareTypeVar(name, ctx=None)
Definition z3py.py:758
_get_args_ast_list(args)
Definition z3py.py:168
bool is_to_real(Any a)
Definition z3py.py:3072
_to_ref_array(ref, args)
Definition z3py.py:562
get_map_func(a)
Definition z3py.py:4853
_z3_check_cint_overflow(n, name)
Definition z3py.py:118
bool is_and(Any a)
Definition z3py.py:1754
TupleSort(name, sorts, ctx=None)
Definition z3py.py:5579
_coerce_expr_list(alist, ctx=None)
Definition z3py.py:1333
is_select(a)
Definition z3py.py:5056
SignExt(n, a)
Definition z3py.py:4540
Int(name, ctx=None)
Definition z3py.py:3395
Bools(names, ctx=None)
Definition z3py.py:1873
_probe_and(args, ctx)
Definition z3py.py:9068
Int2BV(a, num_bits)
Definition z3py.py:4150
Lambda(vs, body)
Definition z3py.py:2404
_to_param_value(val)
Definition z3py.py:178
FreshFunction(*sig)
Definition z3py.py:943
RealVector(prefix, sz, ctx=None)
Definition z3py.py:3476
BVRedOr(a)
Definition z3py.py:4629
SRem(a, b)
Definition z3py.py:4455
SortRef _sort(Context ctx, Any a)
Definition z3py.py:726
set_option(*args, **kws)
Definition z3py.py:328
ExprRef RealVar(int idx, ctx=None)
Definition z3py.py:1590
bool is_sub(Any a)
Definition z3py.py:2959
is_bv(a)
Definition z3py.py:4098
SetDifference(a, b)
Definition z3py.py:5168
bool is_arith_sort(Any s)
Definition z3py.py:2507
BitVecs(names, bv, ctx=None)
Definition z3py.py:4215
_check_same_sort(a, b, ctx=None)
Definition z3py.py:1289
bool is_mod(Any a)
Definition z3py.py:3000
BoolVector(prefix, sz, ctx=None)
Definition z3py.py:1889
_has_probe(args)
Definition z3py.py:1974
IsMember(e, s)
Definition z3py.py:5179
get_param(name)
Definition z3py.py:334
BVAddNoUnderflow(a, b)
Definition z3py.py:4643
deserialize(st)
Definition z3py.py:1207
bool is_not(Any a)
Definition z3py.py:1790
Extract(high, low, a)
Definition z3py.py:4282
Function(name, *sig)
Definition z3py.py:920
get_version()
Definition z3py.py:100
FreshConst(sort, prefix="c")
Definition z3py.py:1567
ULT(a, b)
Definition z3py.py:4359
EnumSort(name, values, ctx=None)
Definition z3py.py:5603
bool is_is_int(Any a)
Definition z3py.py:3060
_to_int_str(val)
Definition z3py.py:3321
is_algebraic_value(a)
Definition z3py.py:2921
is_bv_value(a)
Definition z3py.py:4112
BVSDivNoOverflow(a, b)
Definition z3py.py:4664
bool is_eq(Any a)
Definition z3py.py:1802
Context main_ctx()
Definition z3py.py:266
SetIntersect(*args)
Definition z3py.py:5123
simplify(a, *arguments, **keywords)
Utils.
Definition z3py.py:9135
BV2Int(a, is_signed=False)
Definition z3py.py:4127
FreshInt(prefix="x", ctx=None)
Definition z3py.py:3434
_to_ast_ref(a, ctx)
Definition z3py.py:570
_to_func_decl_array(args)
Definition z3py.py:546
disable_trace(msg)
Definition z3py.py:87
bool is_to_int(Any a)
Definition z3py.py:3087
is_map(a)
Definition z3py.py:4828
Context _get_ctx(ctx)
Definition z3py.py:287
Or(*args)
Definition z3py.py:2015
is_re(s)
Definition z3py.py:11589
args2params(arguments, keywords, ctx=None)
Definition z3py.py:5682
bool is_idiv(Any a)
Definition z3py.py:2988
Consts(names, sort)
Definition z3py.py:1552
Cond(p, t1, t2, ctx=None)
Definition z3py.py:9118
_to_pattern(arg)
Definition z3py.py:2108
RealVarVector(int n, ctx=None)
Definition z3py.py:1600
is_arith(a)
Definition z3py.py:2808
bool is_true(Any a)
Definition z3py.py:1722
bool is_false(Any a)
Definition z3py.py:1740
bool is_int(a)
Definition z3py.py:2829
If(a, b, c, ctx=None)
Definition z3py.py:1484
bool eq(AstRef a, AstRef b)
Definition z3py.py:503
is_app_of(a, k)
Definition z3py.py:1471
is_app(a)
Definition z3py.py:1368
bool is_add(Any a)
Definition z3py.py:2935
z3_error_handler(c, e)
Definition z3py.py:184
None reset_params()
Definition z3py.py:322
Reals(names, ctx=None)
Definition z3py.py:3461
is_int_value(a)
Definition z3py.py:2875
set_param(*args, **kws)
Definition z3py.py:298
is_pattern(a)
Definition z3py.py:2066
_coerce_seq(s, ctx=None)
Definition z3py.py:11250
bool is_distinct(Any a)
Definition z3py.py:1812
bool is_lt(Any a)
Definition z3py.py:3024
ULE(a, b)
Definition z3py.py:4341
is_real(a)
Definition z3py.py:2848
FullSet(s)
Definition z3py.py:5101
to_symbol(s, ctx=None)
Definition z3py.py:132
bool is_mul(Any a)
Definition z3py.py:2947
bool is_ast(Any a)
Definition z3py.py:482
_get_args(args)
Definition z3py.py:152
And(*args)
Definition z3py.py:1982
RepeatBitVec(n, a)
Definition z3py.py:4598
get_version_string()
Definition z3py.py:91
FreshReal(prefix="b", ctx=None)
Definition z3py.py:3491
Array(name, *sorts)
Definition z3py.py:4910
Concat(*args)
Definition z3py.py:4236
_reduce(func, sequence, initial)
Definition z3py.py:1326
_is_algebraic(ctx, a)
Definition z3py.py:2871
Ints(names, ctx=None)
Definition z3py.py:3408
Select(a, *args)
Definition z3py.py:4984
Const(name, sort)
Definition z3py.py:1540
is_array_sort(a)
Definition z3py.py:4784
bool is_div(Any a)
Definition z3py.py:2971
ExprRef Var(int idx, SortRef s)
Definition z3py.py:1575
BVAddNoOverflow(a, b, signed)
Definition z3py.py:4636
Real(name, ctx=None)
Definition z3py.py:3448
FreshBool(prefix="b", ctx=None)
Definition z3py.py:1904
BitVecSort(sz, ctx=None)
Definition z3py.py:4159
open_log(fname)
Definition z3py.py:122
RecFunction(name, *sig)
Definition z3py.py:966
bool is_ge(Any a)
Definition z3py.py:3036
Model(ctx=None, eval={})
Definition z3py.py:6935
BVSubNoOverflow(a, b)
Definition z3py.py:4650
bool is_gt(Any a)
Definition z3py.py:3048
is_default(a)
Definition z3py.py:4844
is_K(a)
Definition z3py.py:4815
Bool(name, ctx=None)
Definition z3py.py:1861
_is_int(v)
Definition z3py.py:76
is_const_array(a)
Definition z3py.py:4802
Sqrt(a, ctx=None)
Definition z3py.py:3560
Default(a)
Definition z3py.py:4956
_ctx_from_ast_arg_list(args, default_ctx=None)
Definition z3py.py:528
SetComplement(s)
Definition z3py.py:5158
is_as_array(n)
Definition z3py.py:6943
is_store(a)
Definition z3py.py:5069
bool is_or(Any a)
Definition z3py.py:1766
is_quantifier(a)
Definition z3py.py:2316
_mk_bin(f, a, b)
Definition z3py.py:1531
K(dom, v)
Definition z3py.py:5023
Xor(a, b, ctx=None)
Definition z3py.py:1932
Store(a, *args)
Definition z3py.py:4967
bool is_array(Any a)
Definition z3py.py:4788
mk_not(a)
Definition z3py.py:1967
is_expr(a)
Definition z3py.py:1345
_array_select(ar, arg)
Definition z3py.py:4775
is_const(a)
Definition z3py.py:1394
BoolVal(val, ctx=None)
Definition z3py.py:1842
RealVal(val, ctx=None)
Definition z3py.py:3345
bool is_implies(Any a)
Definition z3py.py:1778
z3_debug()
Definition z3py.py:70
get_full_version()
Definition z3py.py:109
IntVector(prefix, sz, ctx=None)
Definition z3py.py:3421
_coerce_expr_merge(s, a)
Definition z3py.py:1271
Context get_ctx(ctx)
Definition z3py.py:294
LShR(a, b)
Definition z3py.py:4476
ArraySort(*sig)
Definition z3py.py:4877
Map(f, *args)
Definition z3py.py:5000
is_rational_value(a)
Definition z3py.py:2899
_probe_or(args, ctx)
Definition z3py.py:9072
BVRedAnd(a)
Definition z3py.py:4622
Cbrt(a, ctx=None)
Definition z3py.py:3573
_to_expr_ref(a, ctx)
Definition z3py.py:1221
DisjointSum(name, sorts, ctx=None)
Definition z3py.py:5591
IntSort(ctx=None)
Definition z3py.py:3287
is_seq(a)
Definition z3py.py:11271
Not(a, ctx=None)
Definition z3py.py:1948
_to_sort_ref(s, ctx)
Definition z3py.py:695
enable_trace(msg)
Definition z3py.py:83
Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2383
ToReal(a)
Definition z3py.py:3505
URem(a, b)
Definition z3py.py:4434
bool is_bool(Any a)
Definition z3py.py:1704
StringVal(s, ctx=None)
Definition z3py.py:11298
IsInt(a)
Definition z3py.py:3543
_is_numeral(ctx, a)
Definition z3py.py:2867
MultiPattern(*args)
Definition z3py.py:2084
ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2365
ZeroExt(n, a)
Definition z3py.py:4570
_sort_kind(ctx, s)
Sorts.
Definition z3py.py:586
int _ast_kind(Context ctx, Any a)
Definition z3py.py:522
DatatypeSort(name, params=None, ctx=None)
Definition z3py.py:5554
BVSubNoUnderflow(a, b, signed)
Definition z3py.py:4657
UDiv(a, b)
Definition z3py.py:4413
Q(a, b, ctx=None)
Definition z3py.py:3382
Update(a, *args)
Definition z3py.py:4924
get_var_index(a)
Definition z3py.py:1438
append_log(s)
Definition z3py.py:127
is_var(a)
Definition z3py.py:1413
SortRef DeclareSort(name, ctx=None)
Definition z3py.py:730
IntVal(val, ctx=None)
Definition z3py.py:3333
BVMulNoOverflow(a, b, signed)
Definition z3py.py:4678
RotateLeft(a, b)
Definition z3py.py:4508
_mk_quantifier(is_forall, vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[])
Definition z3py.py:2330
_z3_assert(cond, msg)
Definition z3py.py:113