2

(Why are not the math formulae showing correctly?)

I am performing a test over the Z3 library in Python (Collab) to see whether it knows to distinguish formulae.

The test is the following: (1) I make a quantifier elimination over a formula $phi_1$, (2) I change the formula in a way it remains semantically equivalent: for instance, $phi_1 \equiv (a<b+1)$ to $\phi_2 \equiv (a<1+b)$, (3) I test whether $phi_1=phi_2$.

To see whether $phi_1=phi_2$, I perform the following query: for all the variables, I see whether formulae imply each other. Like $\forall * . (\phi_1 \rightleftarrow \phi_2)$ Is this correct?

So, imagine I apply this on my machine:

x, t1, t2 = Reals('x t1 t2')
g = Goal()
g.add(Exists(x, And(t1 < x, x < t2)))
t = Tactic('qe')
res = t(g)

The result res is [[Not(0 <= t1 + -1*t2)]], so a semantically equivalent formula is: [[Not(0 <= -1*t2 + t1)]] Am I right?

Let us check whether [[Not(0 <= t1 + -1*t2)]] = [[Not(0 <= -1*t2 + t1)]]. So I apply the universal double-implication formula above:


w = Goal()
w.add(ForAll(t1, (ForAll(t2, And(
                                  Implies(Not(0 <= -1*t2 + t1), Not(0 <= t1 + -1*t2)),
                                  Implies(Not(0 <= t1 + -1*t2), Not(0 <= -1*t2 + t1)),                   
                        )))))
tt = Tactic('qe')
areThey = tt(w)
print (areThey)

And the result is.. [[]] I do not know how to interpret this. An optimistic approach is to think that it returns emptyness, since quantifier elimination has been capable to eliminate both quantifiers successfully (i.e. with true result).

I think this can be a problem of using a wrong tactic, or maybe Z3 does not deal OK with universal quantifiers.

However, the most probable situation is that I am probably missing something key and Z3 is clever enough to distinguish.

Any help?

Theo Deep
  • 666
  • 4
  • 15

1 Answers1

3

This just means that the quantifier-elimination tactic reduced the goal to empty-subset; i.e., it eliminated it completely. You've nothing left to do.

In general, to check if two formulas are equivalent in z3, you assert the negation of their equivalence; and see if z3 can come up with a model: If the negation is satisfiable, then that is a counter-example for the original equivalence. If you get unsat, then you conclude that the original equivalence holds for all inputs. This is how you code that in z3:

from z3 import *

t1, t2 = Reals('t1 t2')

s = Solver()
fml1 = Not(0 <= -1*t2 + t1)
fml2 = Not(0 <= t1 + -1*t2)
s.add(Not(fml1 == fml2))
print(s.check())

If you run this, you'll see:

unsat

meaning the equivalence holds.

alias
  • 28,120
  • 2
  • 23
  • 40
  • Thanks a lot! This answers my question! In any case, was my reasoning correct? I mean the forall * double-implication. – Theo Deep Nov 10 '21 at 20:49
  • 1
    z3 is an SMT solver: That is it'll try to find a model for the formula. This is why you have to negate it. So, you'd have something like `Not(ForAll([t1, t2]. fml1 == fml2))`. (Notice that bi-implication over booleans is simply equality; so you can simplify that part.) Now, if you push the negation inside, you'll see that you get: `Exists([t1, t2]. Not(fml1 == fml2))`. But a top-level declaration is equivalent to an existential, so you end up with the program I gave. To summarize, your double-implication needs a negation on top, and you can simplify by using equality. – alias Nov 10 '21 at 21:01
  • Thanks a lot! A last question: is that grouping ```ForAll([t1, t2]..)``` correct in the Z3 syntax? In case not, is there a way to do it? I mean writing ```ForAll([t1,t2]...) ``` instead of ```ForAll(t1(ForAll t2...)```. – Theo Deep Nov 10 '21 at 21:03
  • 1
    It should mean the same thing. i.e., you can group it, or stagger it without any difference. – alias Nov 10 '21 at 21:04
  • Yep, I know they mean the same semantically, but perhaps z3 did not allow, syntax-wise, to group quantified variables under the same quantifier. Anyway I have tested it and does work! – Theo Deep Nov 10 '21 at 21:07
  • 1
    yes, both are allowed. – alias Nov 10 '21 at 21:08
  • Thanks a lot, any link to 'invite for a coffee'? I have seen this way of being grateful in some posts at Stack :)) – Theo Deep Nov 10 '21 at 21:10
  • 1
    I'm not aware of any "coffee" options on stack-overflow; though that'd be cool indeed :-) Z3 stack-overflow is a small enough community that everyone tries to help each other. – alias Nov 10 '21 at 21:14