How to use substitute method in Z3 to replace a variable to True its not working and it replaces with ζ1 and also simplify method doesn't work? - z3

This is the following code . I also tried to convert it into Bool and BoolRef but here also it didn't work:-
print(A)
substitute(A, (Var[0], Bool(True) )) # where Var[0] = x_0_2
Output:-
And(And(And(And(x_0_3, Not(x_0_2)), Not(x_0_1)), Not(x_0_0)),
And(And(And(x_1_3 == x_0_0, x_1_2 == x_0_3),
x_1_1 == x_0_2),
x_1_0 == x_0_1))
x_0_3 ∧ ¬ζ1 ∧ ¬x_0_1 ∧ ¬x_0_0 ∧ x_1_3 = x_0_0 ∧ x_1_2 = x_0_3 ∧ x_1_1 = ζ1 ∧ x_1_0 = x_0_1

Stack-overflow works the best if you post code that people can run on their own; without seeing other parts of what you are doing it's impossible for other people to figure out what else might cause issues in your code.
Having said that, here's how you'd substitute True for a variable:
from z3 import *
x, y = Bools('x y')
expr = And(x, Or(y, And(x, y)))
print expr
expr2 = substitute(expr, (x, BoolVal(True)))
print expr2
print simplify(expr2)
When I run this, I get:
And(x, Or(y, And(x, y)))
And(True, Or(y, And(True, y)))
y
which shows the effect of the substitution and the further simplification of the expression. Note the use of the term BoolVal(True) to get access to the constant value True as a boolean expression.

Related

A model of a simple formula 'Exists([y],ForAll([x],Phi))' should be 'y=2' but Z3 it is returning '[]'

Note the following Z3-Py code:
x, y = Ints('x y')
negS0= (x >= 2)
s1 = (y > 1)
s2 = (y <= x)
s = Solver()
phi = Exists([y],ForAll([x], Implies(negS0, And(s1,s2))))
s.add(phi)
print(s.check())
print(s.model())
This prints:
sat
[]
My question is: why is the model empty? I mean, I think y=2 should be a model...
Note that the same result happens with x and y being Real.
z3 will not include any quantified variable (in your case neither y nor x) in its model. Note that you cannot put x in a model anyhow, because the formula is true for all x: That's the meaning of universal quantification. For the outer-most existentials (like your y), z3 can indeed print the model value for that, but it chooses not to do so since it can be confusing: Imagine you had a phi2, which also had an outer-most existential named y: How would you know which y it would be that it prints in the model?
So, z3 keeps things simple and simply prints the top-level declared variables in the model. And since a top-level declaration is equivalent to an outermost existential, you can simply drop it:
from z3 import *
x, y = Ints('x y')
negS0= (x >= 2)
s1 = (y > 1)
s2 = (y <= x)
s = Solver()
phi = ForAll([x], Implies(negS0, And(s1,s2)))
s.add(phi)
print(s.check())
print(s.model())
This prints:
sat
[y = 2]
like you predicted. Note that this y is unambiguous, since it's declared at the top-level. (Of course, you can redefine it to be something else due to the loosely typed nature of Python bindings and still get yourself confused, but that's a different discussion.)

How to check in Z3py whether the expression contains a specific variable or expression?

I'm using z3py, how do I check whether an expression contains a given variable or expression? For example,
x = Int('x')
expr = x + 1
So, expr should contains variable x.
I've checked the z3.py source code, but I didn't find a solution. Any idea? Thanks.
You can write a simple recursive descent walk over the expression:
from z3 import *
def contains(x, e):
return x.__repr__() == e.__repr__() or any([contains(x, c) for c in e.children()])
x, y, z = Ints('x y z')
expr = x + 2 * y
print(contains(x, expr))
print(contains(y, expr))
print(contains(z, expr))
print(contains(x+2, expr))
print(contains(2*y, expr))
print(contains(y*2, expr))
print(contains(1, IntVal(2)))
print(contains(1, IntVal(1)))
print(contains(x, x))
print(contains(x, y))
This prints:
True
True
False
False
True
False
False
True
True
False
However, I should caution that in typical z3 programming you already know what your variables are. (After all, you have to declare them explicitly!) So, unless you're writing some high-level library code, you should simply keep track of what variables you have and just check in this list. Recursive-descents like this can be expensive for large expressions.

Understanding quantifier traversing in Z3

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)

Z3Python: ForAll causes my code hangup, or returns Unsat, why?

I am still struggling with the problem of findiong a value so that a * b == b with all value of b. The expected result is a == 1. I have two solutions below.
(A) I implemented this with ForAll quantifier in below code (correct me if there is a solution without using any quantifier). The idea is to prove f and g are equivalent.
from z3 import *
a, b, a1, tmp1 = BitVecs('a b a1 tmp1', 32)
f = True
f = And(f, tmp1 == b)
f = And(f, a1 == a * tmp1)
g= True
g = And(g, a1 == b)
s = Solver()
s.add(ForAll([b, tmp1, a1], f == g))
if s.check() == sat:
print 'a =', s.model()[a]
else:
print 'Unsat'
However, this simple code runs forever without giving back result. I think that is because of the ForAll. Any idea on how to fix the problem?
(B) I tried again with another version. This time I dont prove two formulas to be equivalent, but put them all into one formula f. Logically, I think this is true, but please correct me if I am wrong here:
from z3 import *
a, b, a1, tmp = BitVecs('a b a1 tmp', 32)
f = True
f = And(f, tmp == b)
f = And(f, a1 == a * tmp)
f = And(f, a1 == b)
s = Solver()
s.add(ForAll([b, a1], f))
if s.check() == sat:
print 'a =', s.model()[a]
else:
print 'Unsat'
This time the code does not hang, but immediately returns 'Unsat'. Any idea on how to fix this?
Thanks a lot.
The direct formulation of your problem provides the answer you were expecting: http://rise4fun.com/Z3Py/N07sW
The versions you propose use auxiliary variables, a1, tmp, tmp1 and you
use universal quantification over these variables. This does not correspond
to the formula you intended.

z3python: no XOR operator?

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()

Resources