量词中的非零向量

时间:2018-05-10 18:19:55

标签: 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], 
                          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])) 

不满足公式。

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

我希望f0() > 0并约束(x0, x1) != (0, 0)

我期望的是:p0, p1 = 1, 12, 2,但我不知道如何从0, 0的可能值中删除x0, x1。< / p>

2 个答案:

答案 0 :(得分:1)

跟进Levent的回复。在第一次检查期间,Z3使用与量词一起使用的自定义决策过程。在增量模式中,它回退到不是决策程序的东西。要强制一次性解算器,请尝试以下操作:

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

答案 1 :(得分:0)

你只是把它写成量化中的含义。我想你也混淆了那里的一些变量。以下似乎可以捕捉您的意图:

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

当然,z3不能保证找到任何解决方案;虽然它似乎管理一个:

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

一旦你使用量词,所有的赌注都会被关闭,因为逻辑变得半可判断。 Z3在这里做得很好并且返回了一个解决方案,然后它就放弃了。除非你使用一些自定义决策程序,否则我认为你不能期待更好的事情。