此代码仅运行i=4
,但如果位置未初始化,则会运行i=19
?????
location=BoolVal(False)
位置已在此处初始化
from z3 import *
x,t,t1,t2,x_next=Reals ('x t t1 t2 x_next')
location,location_next=Bools('location location_next')
x=20
#t1=0
t=0
location=BoolVal(False)
#set_option(precision=10)
k=20
for i in range(k):
s=Solver()
s.add(Or(And((10*x_next)>=(3*t1)-(3*t2)+(10*x),(10*x_next)<=(10*x)-(t2-t1),x_next>=18,(t2-t1)>0,Not(location_next)),
And((10*x_next)>=(t2-t1)+(10*x),(5*x_next)<=(5*x)+(t2-t1),x_next<=22,(t2-t1)>0,location_next)),
location_next==If(And(Not(location),x_next<19),True,If(And(location,x_next>21),False,location)))
print i
print s.check()
if s.check()==unsat:
break
m=s.model()
x=m[x_next]
#t1=m[t2]
print m[x_next].as_decimal(10)
答案 0 :(得分:2)
简短的回答是:在迭代4中,您在命令s.add(...)
中添加的公式是不可满足的。
在迭代4的开始,我们x
是19
而location
是False
。
通过替换公式中的x
和location
,我们得到了:
[Or(And(10*x_next >= 3*t1 - 3*t2 + 190,
10*x_next <= 190 - t2 + t1,
x_next >= 18,
t2 - t1 > 0,
Not(location_next)),
And(10*x_next >= t2 - t1 + 190,
5*x_next <= 95 + t2 - t1,
x_next <= 22,
t2 - t1 > 0,
location_next)),
location_next ==
If(And(Not(False), x_next < 19),
True,
If(And(False, x_next > 21), False, False))]
在简化上述公式后,我们有:
[Or(And(10*x_next >= 190 + 3*t1 - 3*t2,
10*x_next <= 190 - t2 + t1,
x_next >= 18,
t2 - t1 > 0,
Not(location_next)),
And(10*x_next >= 190 + t2 - t1,
5*x_next <= 95 + t2 - t1,
x_next <= 22,
t2 - t1 > 0,
location_next)),
location_next == x_next < 19]
为了表明此公式的不可靠性,让我们考虑以下两种情况:location_next
为True,或location_next
为False。
location_next
为True。然后,x_next < 19
也必须为True。而且,Or
的第一个参数是假的。因此,只有当我们可以使第二个参数为True时,公式才是可满足的。情况并非如此,因为以下内容是不可满足的:
10*x_next >= 190 + t2 - t1, 5*x_next <= 95 + t2 - t1, x_next < 19
前两个不等式意味着x_next >= 19
。
location_next
是假的。然后x_next >= 19
必须为True。通过类似的论证,只有当我们能够使Or
为真的第一个参数时,公式才是可满足的。这也是不可能的,因为以下是不可满足的:
10*x_next <= 190 - t2 + t1, t2 - t1 > 0, 19 <= x_next
前两个不等式意味着x_next < 19
。
备注:您未在循环结束时使用location
更新location_next
的值。您为x
执行此操作,但不为location
执行此操作。这是一个正交问题。我期待着如下声明:
location=m[location_next]