我想验证表单的公式:
Exists p . ForAll x != 0 . f(x, p) > 0 and g(x, p) < 0
所有变量都是实数。
根据建议here,我将此列表添加到求解器:
[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
)
)
)
]
具有上述公式的求解器返回unsat
。一个可能的解决方案是P
为[[1.5, -0.5], [-0.5, 1]]
,事实上,通过替换这些值,公式得到满足:
And(3/2*x0*x0 - 1*x0*x1 + x1*x1 > 0,
-1*x0*x0 - 1*x1*x1 < 0)
有没有办法真正计算出这样的p
?如果z3很难,那么这个问题还有其他选择吗?
答案 0 :(得分:0)
如果您说'存在'后跟'Forall',那么您说每个x0
,x1
的公式都应该为真。并且Z3告诉你事实并非如此。
如果您有兴趣找到一个这样的P
和相应的x
值,只需删除量化并使所有内容成为顶级变量:
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
当我跑步时,我得到:
sat
[x0 = 1/8, p0 = -1/2, p1 = -1/2, x1 = 1/2, p2 = 1, p3 = 1]
和其他许多人;我相信你所追求的是什么。
请注意,您还可以根据自己的位置进行一些编程以消除存在量化;即,从量化版本开始,如果得到unsat
,则切换到新的求解器并使用未量化的版本自动执行此过程。当然,这只是编程,并且在这一点上与z3没有任何关系。