0

I posted a related question, but then I think it was not very clear. I would like to rephrase the problem like this:

Two formulas a1 == a + b (1) and a1 == b (2) are equivalent if a == 0. Given these formulas (1) and (2), how can I use Z3 python to find out this required condition (a == 0) so the above formulas become equivalent?

I suppose that a1, a and b are all in the format of BitVecs(32).

Edit: I came up with the code like this:

from z3 import *

a, b = BitVecs('a b', 32)
a1 = BitVec('a1', 32)
s = Solver()
s.add(ForAll(b, a + b == b))
if s.check() == sat:
    print 'a =', s.model()[a]
else:
    print 'Not Equ'

The output is: a = 0, as expected.

However, when I modified the code a bit to use two formulas, it doesnt work anymore:

from z3 import *

a, b = BitVecs('a b', 32)
a1 = BitVec('a1', 32)

f = True
f = And(f, a1 == a * b)

g = True
g = And(g, a1 == b)

s = Solver()
s.add(ForAll(b, f == g))
if s.check() == sat:
    print 'a =', s.model()[a]
else:
    print 'Not Equ'

The output now is different: a = 1314914305

So the questions are:

(1) Why the second code produces different (wrong) result?

(2) Is there any way to do this without using ForAll (or quantifier) at all?

Thanks

Community
  • 1
  • 1
user311703
  • 1,113
  • 2
  • 14
  • 25
  • If you already open a new question instead of improving your previous one, at least provide a link to the latter. – Malte Schwerhoff Jun 14 '13 at 16:17
  • i think opening the new question is less confused than modifying the old one. i added the link. thanks. – user311703 Jun 14 '13 at 16:45
  • The 2nd code piece produces a different result because the solver can _choose_ the value of a1 to make the two formulas evaluate the same - which it does. You would need to quantify over a1 as well to prevent that from happening. – Vladimir Klebanov Jun 15 '13 at 16:12
  • Vladimir, this seems to fix my problem! Do you have any idea to avoid `ForAll` quantifier for this problem? Thanks! – user311703 Jun 15 '13 at 16:14

1 Answers1

0

The two codes produce the same correct answer a = 0. You have a typo: you are writing a1 = a*b and it must be a1 = a + b . Do you agree?

Possible code without using ForAll:

a, b = BitVecs('a b', 32)
a1 = BitVec('a1', 32)
s = Solver()
s.add(a + b == b)
if s.check() == sat:
print 'a =', s.model()[a]
else:
print 'Not Equ'
s1 = Solver()
s1.add(a==0, Not(a + b == b))
print s1.check()

Output:

a = 0
unsat
Juan Ospina
  • 1,317
  • 1
  • 7
  • 15
  • Juan, indeed I had a typo, but then the question is: why the result is `a = 1314914305`, but not `a = 1`? (since with a * b == b with every 'b', we should have a == 1). – user311703 Jun 15 '13 at 14:48
  • Juan, the second problem with your solution is that: the s.check() produces a model, but that model may not be true for all values of `b`. What I want is to find `a` so that `a + b == b` with every `b`, so I dont think I can avoid `ForAll`. Correct me if I am wrong, though. Thanks – user311703 Jun 15 '13 at 15:51
  • As you can see, the first solver obtains the value a =0 and then the second solver generates the output "unsat" and then a + b = b with every b when a = 0. Do you agree? – Juan Ospina Jun 15 '13 at 16:33
  • Juan, as I said the model might give different value (a != 0), so I dont think your is correct. The answer of Vladimir seems to be the best to me. – user311703 Jun 15 '13 at 16:42