mirror of
https://github.com/Z3Prover/z3
synced 2025-04-27 02:45:51 +00:00
integrate lambda expressions
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
bf4edef761
commit
520ce9a5ee
139 changed files with 2243 additions and 1506 deletions
|
@ -1766,6 +1766,34 @@ class QuantifierRef(BoolRef):
|
|||
"""
|
||||
return Z3_is_quantifier_forall(self.ctx_ref(), self.ast)
|
||||
|
||||
def is_exists(self):
|
||||
"""Return `True` if `self` is an existential quantifier.
|
||||
|
||||
>>> f = Function('f', IntSort(), IntSort())
|
||||
>>> x = Int('x')
|
||||
>>> q = ForAll(x, f(x) == 0)
|
||||
>>> q.is_exists()
|
||||
False
|
||||
>>> q = Exists(x, f(x) != 0)
|
||||
>>> q.is_exists()
|
||||
True
|
||||
"""
|
||||
return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
|
||||
|
||||
def is_lambda(self):
|
||||
"""Return `True` if `self` is a lambda expression.
|
||||
|
||||
>>> f = Function('f', IntSort(), IntSort())
|
||||
>>> x = Int('x')
|
||||
>>> q = Lambda(x, f(x))
|
||||
>>> q.is_lambda()
|
||||
True
|
||||
>>> q = Exists(x, f(x) != 0)
|
||||
>>> q.is_lambda()
|
||||
False
|
||||
"""
|
||||
return Z3_is_lambda(self.ctx_ref(), self.ast)
|
||||
|
||||
def weight(self):
|
||||
"""Return the weight annotation of `self`.
|
||||
|
||||
|
@ -1973,6 +2001,26 @@ def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
|
|||
"""
|
||||
return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
|
||||
|
||||
def Lambda(vs, body):
|
||||
"""Create a Z3 lambda expression.
|
||||
|
||||
>>> f = Function('f', IntSort(), IntSort(), IntSort())
|
||||
>>> mem0 = Array('mem0', IntSort(), IntSort())
|
||||
>>> lo, hi, e, i = Ints('lo hi e i')
|
||||
>>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
|
||||
>>> mem1
|
||||
Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
|
||||
"""
|
||||
ctx = body.ctx
|
||||
if is_app(vs):
|
||||
vs = [vs]
|
||||
num_vars = len(vs)
|
||||
_vs = (Ast * num_vars)()
|
||||
for i in range(num_vars):
|
||||
## TODO: Check if is constant
|
||||
_vs[i] = vs[i].as_ast()
|
||||
return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
|
||||
|
||||
#########################################
|
||||
#
|
||||
# Arithmetic
|
||||
|
@ -5582,7 +5630,7 @@ class FuncEntry:
|
|||
>>> m = s.model()
|
||||
>>> f_i = m[f]
|
||||
>>> f_i.num_entries()
|
||||
3
|
||||
1
|
||||
>>> e = f_i.entry(0)
|
||||
>>> e.num_args()
|
||||
2
|
||||
|
@ -5600,16 +5648,16 @@ class FuncEntry:
|
|||
>>> m = s.model()
|
||||
>>> f_i = m[f]
|
||||
>>> f_i.num_entries()
|
||||
3
|
||||
1
|
||||
>>> e = f_i.entry(0)
|
||||
>>> e
|
||||
[0, 1, 10]
|
||||
[1, 2, 20]
|
||||
>>> e.num_args()
|
||||
2
|
||||
>>> e.arg_value(0)
|
||||
0
|
||||
>>> e.arg_value(1)
|
||||
1
|
||||
>>> e.arg_value(1)
|
||||
2
|
||||
>>> try:
|
||||
... e.arg_value(2)
|
||||
... except IndexError:
|
||||
|
@ -5631,14 +5679,14 @@ class FuncEntry:
|
|||
>>> m = s.model()
|
||||
>>> f_i = m[f]
|
||||
>>> f_i.num_entries()
|
||||
3
|
||||
1
|
||||
>>> e = f_i.entry(0)
|
||||
>>> e
|
||||
[0, 1, 10]
|
||||
[1, 2, 20]
|
||||
>>> e.num_args()
|
||||
2
|
||||
>>> e.value()
|
||||
10
|
||||
20
|
||||
"""
|
||||
return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
|
||||
|
||||
|
@ -5652,10 +5700,10 @@ class FuncEntry:
|
|||
>>> m = s.model()
|
||||
>>> f_i = m[f]
|
||||
>>> f_i.num_entries()
|
||||
3
|
||||
1
|
||||
>>> e = f_i.entry(0)
|
||||
>>> e.as_list()
|
||||
[0, 1, 10]
|
||||
[1, 2, 20]
|
||||
"""
|
||||
args = [ self.arg_value(i) for i in range(self.num_args())]
|
||||
args.append(self.value())
|
||||
|
@ -5693,7 +5741,7 @@ class FuncInterp(Z3PPObject):
|
|||
sat
|
||||
>>> m = s.model()
|
||||
>>> m[f]
|
||||
[0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
|
||||
[2 -> 0, else -> 1]
|
||||
>>> m[f].else_value()
|
||||
1
|
||||
"""
|
||||
|
@ -5713,9 +5761,9 @@ class FuncInterp(Z3PPObject):
|
|||
sat
|
||||
>>> m = s.model()
|
||||
>>> m[f]
|
||||
[0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
|
||||
[2 -> 0, else -> 1]
|
||||
>>> m[f].num_entries()
|
||||
3
|
||||
1
|
||||
"""
|
||||
return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
|
||||
|
||||
|
@ -5743,14 +5791,10 @@ class FuncInterp(Z3PPObject):
|
|||
sat
|
||||
>>> m = s.model()
|
||||
>>> m[f]
|
||||
[0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
|
||||
[2 -> 0, else -> 1]
|
||||
>>> m[f].num_entries()
|
||||
3
|
||||
1
|
||||
>>> m[f].entry(0)
|
||||
[0, 1]
|
||||
>>> m[f].entry(1)
|
||||
[1, 1]
|
||||
>>> m[f].entry(2)
|
||||
[2, 0]
|
||||
"""
|
||||
if idx >= self.num_entries():
|
||||
|
@ -5777,9 +5821,9 @@ class FuncInterp(Z3PPObject):
|
|||
sat
|
||||
>>> m = s.model()
|
||||
>>> m[f]
|
||||
[0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
|
||||
[2 -> 0, else -> 1]
|
||||
>>> m[f].as_list()
|
||||
[[0, 1], [1, 1], [2, 0], 1]
|
||||
[[2, 0], 1]
|
||||
"""
|
||||
r = [ self.entry(i).as_list() for i in range(self.num_entries())]
|
||||
r.append(self.else_value())
|
||||
|
@ -5891,7 +5935,7 @@ class ModelRef(Z3PPObject):
|
|||
>>> m[x]
|
||||
1
|
||||
>>> m[f]
|
||||
[1 -> 0, else -> 0]
|
||||
[else -> 0]
|
||||
"""
|
||||
if __debug__:
|
||||
_z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
|
||||
|
@ -6008,10 +6052,10 @@ class ModelRef(Z3PPObject):
|
|||
>>> m[x]
|
||||
1
|
||||
>>> m[f]
|
||||
[1 -> 0, else -> 0]
|
||||
[else -> 0]
|
||||
>>> for d in m: print("%s -> %s" % (d, m[d]))
|
||||
x -> 1
|
||||
f -> [1 -> 0, else -> 0]
|
||||
f -> [else -> 0]
|
||||
"""
|
||||
if _is_int(idx):
|
||||
if idx >= len(self):
|
||||
|
|
|
@ -959,8 +959,10 @@ class Formatter:
|
|||
ys_pp = seq3(ys, '[', ']')
|
||||
if a.is_forall():
|
||||
header = 'ForAll'
|
||||
else:
|
||||
elif a.is_exists():
|
||||
header = 'Exists'
|
||||
else:
|
||||
header = 'Lambda'
|
||||
return seq1(header, (ys_pp, body_pp))
|
||||
|
||||
def pp_expr(self, a, d, xs):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue