量词中的非零向量
Nonzero vector in quantifier
我想验证以下形式的公式:
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, 1
或 2, 2
,但我不知道如何从 x0, x1
的可能值中删除 0, 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 在这里做得很好并返回一个解决方案,然后它放弃了。我不认为你可以期待更好的东西,除非你使用一些自定义决策程序。
正在跟进 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
我想验证以下形式的公式:
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, 1
或 2, 2
,但我不知道如何从 x0, x1
的可能值中删除 0, 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 在这里做得很好并返回一个解决方案,然后它放弃了。我不认为你可以期待更好的东西,除非你使用一些自定义决策程序。
正在跟进 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