0

I want to verify a formula of the form:

Exists p . ForAll x != 0 . f(x, p) > 0 and g(x, p) < 0

All variables are reals.

As suggested here, I add this list to the solver:

[ForAll([x0, x1],
    Implies(Or(x0 != 0, x1 != 0),
        And(P0*x0*x0 + P1*x0*x1 + P2*x0*x1 + P3*x1*x1 > 0,
            -2*P0*x0*x1 + P1*x0*x0 - P1*x0*x1 - P1*x1*x1 + P2*x0*x0 - P2*x0*x1 - P2*x1*x1 + 2*P3*x0*x1 - 2*P3*x1*x1 < 0
            )
        )
    )
]

The solver with the above formula returns unsat. A possible solution is for P to be [[1.5, -0.5], [-0.5, 1]] and in fact, by substituting those values, the formula is satisfied:

And(3/2*x0*x0 - 1*x0*x1 + x1*x1 > 0,
    -1*x0*x0 - 1*x1*x1 < 0)

Is there a way to actually compute such a p? If it's hard for z3, is there any alternative for this problem?

nyuw
  • 13
  • 2

1 Answers1

0

When you say 'Exists' followed by 'Forall', then you are saying that the formula should be true for every such x0, x1. And Z3 is telling you that is simply not the case.

If you are interested in finding one such P, and corresponding x values, simply drop the quantification and make everything a top-level variable:

from z3 import *

def f(x0, x1, P0, P1, P2, P3):
    return P0*x0*x0 + P1*x0*x1 + P2*x0*x1 + P3*x1*x1

def g(x0, x1, P0, P1, P2, P3):
    return -2*P0*x0*x1 + P1*x0*x0 - P1*x0*x1 - P1*x1*x1 + P2*x0*x0 - P2*x0*x1 - P2*x1*x1 + 2*P3*x0*x1 - 2*P3*x1*x1

p0, p1, p2, p3  = Reals('p0 p1 p2 p3')

x0, x1 = Reals('x0 x1')
fmls = [Implies(Or(x0 != 0, x1 != 0), And(f(x0, x1, p0, p1, p2, p3) > 0, g(x0, x1, p0, p1, p2, p3) < 0))]

while True:
    s = Solver()
    s.add(fmls)
    res = s.check()
    print res
    if res == sat:
        m = s.model()
        print m
        fmls += [Or(p0 != m[p0], p1 != m[p1])]
    else:
       print "giving up"
       break

When I run this, I get:

sat
[x0 = 1/8, p0 = -1/2, p1 = -1/2, x1 = 1/2, p2 = 1, p3 = 1]

and many others; which is I believe what you're after.

Note that you can also do some programming to get rid of the existential quantification depending on where you are; i.e., start with the quantified version, if you get an unsat, then switch to a new solver and use the unquantified version to automate this process. Of course, this is just programming and doesn't really have anything to do with z3 at this point.

alias
  • 28,120
  • 2
  • 23
  • 40
  • I'm really interested in finding a `P` for which all nonzero reals satisfy the formula; that `P` exists, because the one in the first post satisfy the formula for all nonzero reals – nyuw May 18 '18 at 10:53
  • Also, when you say: "And Z3 is telling you that is simply not the case", then Z3 is wrong, because of that example. And introducing the values makes Z3's result be `sat` – nyuw May 20 '18 at 14:25
  • @nyuw I didn't study the expression, but if you do believe Z3 is wrong, then that would be a rather serious bug that should be reported. (This is a soundness issue, and developers should know about it!) I'd encourage you to report it at their issue tracker: https://github.com/Z3Prover/z3/issues – alias May 20 '18 at 15:54
  • @nyuw I've since looked at the expressions in more detail, and I think you're right that Z3 seems to be saying `unsat` for no good reason. Unless there's some other gotcha, this might very well be a bug. Please report this at their issues page. (Or I can do the same, let me know.) – alias May 21 '18 at 00:27
  • I've created an issue; please let me know if you think it's properly written. I also wasn't exactly sure why I had to drop the `Exists` quantifier at the beginning (ref. my previous question); but even by adding it again, some of the values for `P` are wrong (?) or they don't work if hard coded (as I said in the issue). Let me know – nyuw May 21 '18 at 10:09
  • @nyuw The bug is now fixed: https://github.com/Z3Prover/z3/issues/1637 If you do a build off of github (or wait for the nightly builds to come out), I think you'll find it now works as expected. – alias May 23 '18 at 03:17
  • @nyuw It would be good to close the bug (https://github.com/Z3Prover/z3/issues/1637) if this is all working as expected now. – alias May 24 '18 at 14:37
  • I just wanted to test it a bit more. Thank you so much :) – nyuw May 25 '18 at 12:35