i am looking for some code examples using theory of array in Z3 python, but cannot find any.
please could somebody provide some code examples?
thanks!
Here is an example showing array declarations and accessing items by indices http://rise4fun.com/Z3Py/7jAj:
x = Int('x')
a = Array('a', IntSort(), BoolSort())
b = Array('b', IntSort(), BoolSort())
c = Array('c', BoolSort(), BoolSort())
e = ForAll(x, Or(Not(a[x]), c[b[x]]))
print e
solver = Solver()
solver.add(e)
c = solver.check()
print c
Here is another example using Select and Store on array theory http://rise4fun.com/Z3Py/2CAn:
x = Int('x')
y = Int('y')
a = Array('a', IntSort(), IntSort())
s = Solver()
s.add(Select(a, x) == x, Store(a, x, y) == a)
print s.check()
print s.model()
That said, there are a few array examples floating around StackOverflow. You can try to search on the site using "z3py array" keyword for more information.
Related
I have the following formula and Python code trying to find the largest n satisfying some property P:
x, u, n, n2 = Ints('x u n n2')
def P(u):
return Implies(And(2 <= x, x <= u), And(x >= 1, x <= 10))
nIsLargest = ForAll(n2, Implies(P(n2), n2 <= n))
exp = ForAll(x, And(P(n), nIsLargest))
s = SolverFor("LIA")
s.reset()
s.add(exp)
print(s.check())
if s.check() == sat:
print(s.model())
My expectation was that it would return n=10, yet Z3 returns unsat. What am I missing?
You're using the optimization API incorrectly; and your question is a bit confusing since your predicate P has a free variable x: Obviously, the value that maximizes it will depend on both x and u.
Here's a simpler example that can get you started, showing how to use the API correctly:
from z3 import *
def P(x):
return And(x >= 1, x <= 10)
n = Int('n')
opt = Optimize()
opt.add(P(n))
maxN = opt.maximize(n)
r = opt.check()
print(r)
if r == sat:
print("maxN =", maxN.value())
This prints:
sat
maxN = 10
Hopefully you can take this example and extend it your use case.
I'm trying to understand traversing quantified formula in z3 (i'm using z3py). Have no idea how to pickup the quantified variables. For example in code shown below i'm trying to print the same formula and getting error.
from z3 import *
def traverse(e):
if is_quantifier(e):
var_list = []
if e.is_forall():
for i in range(e.num_vars()):
var_list.append(e.var_name(i))
return ForAll (var_list, traverse(e.body()))
x, y = Bools('x y')
fml = ForAll(x, ForAll (y, And(x,y)))
same_formula = traverse( fml )
print same_formula
With little search i got to know that z3 uses De Bruijn index and i have to get something like Var(1, BoolSort()). I can think of using var_sort() but how to get the formula to return the variable correctly. Stuck here for some time.
var_list is a list of strings, but ForAll expects a list of constants. Also, traverse should return e when it's not a quantifier. Here's a modified example:
from z3 import *
def traverse(e):
if is_quantifier(e):
var_list = []
if e.is_forall():
for i in range(e.num_vars()):
c = Const(e.var_name(i) + "-traversed", e.var_sort(i))
var_list.append(c)
return ForAll (var_list, traverse(e.body()))
else:
return e
x, y = Bools('x y')
fml = ForAll(x, ForAll (y, And(x,y)))
same_formula = traverse( fml )
print(same_formula)
I have this code in Z3 python:
x = Bool('x')
y = Bool('y')
z = Bool('z')
z == (x xor y)
s = Solver()
s.add(z == True)
print s.check()
But this code reports below error when running:
c.py(4): error: invalid syntax
If I replace xor with and, there is no problem. So this means XOR is not supported?
You should use Xor(a, b). Moreover, to create the Z3 expression that represents the formula a and b, we must use And(a, b). In Python, we can't overload the operators and and or.
Here is an example with the Xor (available online at rise4fun).
x = Bool('x')
y = Bool('y')
z = Xor(x, y)
s = Solver()
s.add(z)
print s.check()
print s.model()
Solver.model() sometimes returns an assignment with a seemingly-needless Var(), whereas I was (perhaps naively) expecting Solver.model() to always return a concrete value for each variable. For example:
#!/usr/bin/python
import z3
x, y = z3.Ints('x y')
a = z3.Array('a', z3.IntSort(), z3.IntSort())
e = z3.Not(z3.Exists([x], z3.And(x != y, a[x] == a[y])))
solver = z3.Solver()
solver.add(e)
print solver.check()
print solver.model()
produces
sat
[k!1 = 0,
a = [else -> k!5!7(k!6(Var(0)))],
y = 1,
k!5 = [else -> k!5!7(k!6(Var(0)))],
k!5!7 = [1 -> 3, else -> 2],
k!6 = [1 -> 1, else -> 0]]
What's going on here? Is Var(0) in a's "else" referring to the 0th argument to the a array, meaning a[i] = k!5!7[k!6[i]]? Is it possible to get a concrete satisfying assignment for a out of Z3, such as a = [1 -> 1, else -> 0]?
This is the intended output. The interpretation for functions and arrays should be viewed as function definitions. Keep in mind that the assertion
z3.Not(z3.Exists([x], z3.And(x != y, a[x] == a[y])))
is essentially a universal quantifier. For quantifier free problems, Z3 does generate the "concrete assignments" suggested in your post. However, this kind of representation is not expressive enough. In the end of the message, I attached an example that cannot be encoded using "concrete assignments".
The following post has additional information about how models are encoded in Z3.
understanding the z3 model
You can find more details regarding the encoding used by Z3 at http://rise4fun.com/Z3/tutorial/guide
Here is an example that produces a model that can't be encoded using "concrete" assignments (available online at http://rise4fun.com/Z3Py/eggh):
a = Array('a', IntSort(), IntSort())
i, j = Ints('i j')
solver = Solver()
x, y = Ints('x y')
solver.add(ForAll([x, y], Implies(x <= y, a[x] <= a[y])))
solver.add(a[i] != a[j])
print solver.check()
print solver.model()
I have simple Z3 python code like below. I expect the "print" line will return me "y" which was stored in the line above it. Instead, I got back "A[x]" as result.
I = IntSort()
A = Array('A', I, I)
x = Int('x')
y = Int('y')
Store(A, x, y)
print Select(A,x)
Why does not Select() return the value stored by Store()?
Thanks.
There are two things to note:
First:
When you write
Store(A, x, y)
You create a term with three arguments , A, x, and y.
There is no side-effect to A.
You can create a name for this term by writing
B = Store(A,x,y)
Second:
Z3 does not simplify terms unless you want it to.
The python API exposes a simplification function called simplify.
You can obtain the reduced term by calling the simplifier.
The example is:
I = IntSort()
A = Array('A', I, I)
x = Int('x')
y = Int('y')
B = Store(A, x, y)
print Select(B,x)
print simplify (Select(B,x))