Z3 量词中的非零向量

Z3 量词中的非零向量,z3,solver,z3py,Z3,Solver,Z3py,我想验证以下表单的公式: Exists p . ForAll x != 0 . f(x, p) > 0 实现(不起作用)如下所示: 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],

我想验证以下表单的公式:

Exists p . ForAll x != 0 . f(x, p) > 0
实现(不起作用)如下所示:

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])) 
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
这个公式不符合要求

f0()>=0
时,唯一的输出是
(0,0)

我想要
f0()>0
和约束
(x0,x1)!=(0,0)


我所期望的是:
p0,p1=1,1
2,2
,例如,但我不知道如何从
x0,x1
的可能值中删除
0,0
,,您只需将其作为一种含义写入量化中即可。我想你也把一些变量弄混了。以下内容似乎抓住了您的意图:

从z3导入*
def f0(x0,x1,x,y):
返回x1*x1*y+x0*x0*x
s=解算器()
p0,p1=Reals('p0 p1')
x0,x1=Reals('x0-x1')
s、 加法(对于所有([x0,x1],意味着(或(x0!=0,x1!=0),f0(x0,x1,p0,p1)>0)))
尽管如此:
res=s.check()
打印资源
如果res==sat:
m=s.模型()
打印m
s、 加(或(p0!=m[p0],p1!=m[p1]))
其他:
打印“放弃”
打破
当然,z3不能保证为您找到任何解决方案;虽然它似乎管理一个:

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

一旦你使用了量词,所有的赌注都被取消了,因为逻辑变得半可判定。Z3在这里做得很好,返回了一个解决方案,然后就放弃了。我不认为你能期待更好的结果,除非你使用一些定制的决策程序。

跟进Levent的回复。在第一次检查期间,Z3使用一个自定义的决策过程,该过程与量词一起工作。在增量模式下,它会退回到非决策过程。若要强制单发解算器,请尝试以下操作:

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

太酷了!我没有意识到增量模式切换到了另一个解算器。很高兴知道!谢谢当某对
x0,x1
为假时,我是否可以得到一个反例?