Nonzero vector in quantifier

▼魔方 西西 提交于 2019-12-02 08:03:42

问题


I want to verify a formula of the form:

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

An implementation (that isn't working) is the following:

def f0(x0, x1, x, y):
    return x1 ** 2 * y + x0 ** 2 * x

s = Solver()
x0, x1 = Reals('x0 x1')
p0, p1 = Reals('p0 p1')

s.add(Exists([p0, p1], 
                ForAll([x0, x1], 
                          f0(x0, x1, p0, p1) > 0
                      )
            ))
#s.add(Or(x0 != 0, x1 != 0))

while s.check() == sat:
    m = s.model()
    m.evaluate(x0, model_completion=True)
    m.evaluate(x1, model_completion=True)
    m.evaluate(p0, model_completion=True)
    m.evaluate(p1, model_completion=True)
    print m
    s.add(Or(x0 != m[x0], x1 != m[x1])) 

The formula isn't satisfied.

With f0() >= 0, the only output is (0, 0).

I want to have f0() > 0 and constrain (x0, x1) != (0, 0).

Something I'd expect is: p0, p1 = 1, 1 or 2, 2 for instance, but I don't know how to remove 0, 0 from the possible values for x0, x1.


回答1:


Following up on Levent's reply. During the first check, Z3 uses a custom decision procedure that works with the quantifiers. In incremental mode it falls back to something that isn't a decision procedure. To force the one-shot solver try the following:

from z3 import *

def f0(x0, x1, x, y):
    return x1 * x1 * y + x0 * x0 * x

p0, p1 = Reals('p0 p1')

x0, x1 = Reals('x0 x1')
fmls = [ForAll([x0, x1], Implies(Or(x0 != 0, x1 != 0), f0(x0, x1, p0, p1) > 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



回答2:


You'd simply write that as an implication inside the quantification. I think you're also mixing up some of the variables in there. The following seems to capture your intent:

from z3 import *

def f0(x0, x1, x, y):
    return x1 * x1 * y + x0 * x0 * x

s = Solver()
p0, p1 = Reals('p0 p1')

x0, x1 = Reals('x0 x1')
s.add(ForAll([x0, x1], Implies(Or(x0 != 0, x1 != 0), f0(x0, x1, p0, p1) > 0)))

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

Of course, z3 isn't guaranteed to find you any solutions; though it seems to manage one:

$ python a.py
sat
[p1 = 1, p0 = 1]
unknown
giving up

Once you use quantifiers all bets are off, as the logic becomes semi-decidable. Z3 is doing a good job here and returning one solution, and then it's giving up. I don't think you can expect anything better, unless you use some custom decision procedures.



来源:https://stackoverflow.com/questions/50279196/nonzero-vector-in-quantifier

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!