The following code terminates after 8 iterations (while it should iterate 14 times) why?
The code encodes a linear hybrid automata, it should run for the designated number of iterations but doesn’t.
from z3 import *
x,t,t1,t2,x_next=Reals ('x t t1 t2 x_next')
location=[None]
location='off'
x=20
t1=0
s=Solver()
#set_option(precision=10)
k=14
for i in range(k):
print location
if location=='off':
s.add((10*x_next)>=(3*t1)-(3*t2)+(10*x),(10*x_next)<=(10*x)-(t2-t1),x_next>=18,(t2-t1)>0)
elif location=='on':
s.add(10*x_next>=(t2-t1)+(10*x),(5*x_next)<=(5*x)+(t2-t1),x_next<=22,(t2-t1)>0)
if [location=='off' and x_next<19] :
location='on'
elif [location=='on' and x_next>21]:
location='off'
if s.check()==unsat:
break
m=s.model()
#print s.check()
print i
print location
print s.model()
print "value of x_next"
print m[x_next].as_decimal(10)
x=m[x_next]
t1=m[t2]
The program stops because the set of assertions is unsatisfiable after iteration 8, and in your loop you have the statements:
In the first iteration you add the assertion:
In the last iteration, you add:
where, the command
Q(a, b)is used to create the rational numbera/b.That is,
t1is40/3andxis56/3at iteration 8.The three assertions above are unsatisfiable. The first two imply that
t2 <= 40/3, and the lastt2 > 40/3.BTW, the following statement seems to be incorrect. That is, I do not believe it reflects your intention. Note that, this is orthogonal problem.
The expression
x_next<19does not evaluate toTrueorFalse. It creates the Z3 (symbolic) expressionx_next < 19. I believe, you want to evaluate whether this expression is true in a modelm. If that is the case, you should write:The command
m.evaluate(t)evaluates the expressiontin the modelm. The result is a Z3 expression. The functionis_true(t)returnsTrueiftis the Z3 expression true.