我想找到一个表达式e
对所有 x 都为真的最大间隔。编写此类公式的方法应该是:Exists d : ForAll x in (-d,d) . e and ForAll x not in (-d,d) . !e
。
为了得到这样的d
,Z3 中f
的公式(查看上面的公式(可能如下:
from __future__ import division
from z3 import *
x = Real('x')
delta = Real('d')
s = Solver()
e = And(1/10000*x**2 > 0, 1/5000*x**3 + -1/5000*x**2 < 0)
f = ForAll(x,
And(Implies(And(delta > 0,
-delta < x, x < delta,
x != 0),
e),
Implies(And(delta > 0,
Or(x > delta, x < -delta),
x != 0),
Not(e))
)
)
s.add(Not(f))
s.check()
print s.model()
其中输出[d = 1/4]
.
为了检查它,我设置了delta = RealVal('1/4')
,从f
中删除ForAll
量词,我得到x = 1/2
。我用1/2
替换delta
并得到3/4
,然后7/8
等等。绑定应1
。我可以让 Z3 立即输出吗?
如果你自己做数学,你可以看到解决方案是x != 0, x < 1
.或者你可以简单地让 Wolfram Alpha 为你做这件事。所以,没有这样的delta
.
您遇到的问题是您断言:
s.add(Not(f))
这就把x
的普遍量化变成了存在主义的;要求z3
找到一个delta
,这样就有一些符合要求的x。(也就是说,你否定了你的整个公式。相反,您应该执行以下操作:
s.add(delta > 0, f)
这也确保了delta
是积极的。通过该更改,z3 将正确响应:
unsat
(然后你会得到一个错误,调用s.model()
,你应该只在上一个调用s.check()
返回sat
时调用s.model()
。