init{ int i = 0; do :: i < 100 ->i++; :: break; od; printf("i = %d \n", i); }But we get stuck with this do loop. Fix? Just break on the other branch.
Suppose we wanted to make one of those fancy traffic lights that can detect when a car is waiting. In our model should we make the lights also deal with listening for cars or something else? The traffic light is already pretty busy so let's make a new proctype that will deal with sensing.
proctype Sensor(){
do
:: true -> skip
:: color[0] == RED ->
waiting =
}
Note that skip is a no op, we don't break we just don't do anything that iteration. do
:: (turn == myID && colors[myID] == RED) ->
colors[myId] = GREEN;
:: (turn == myID && colors[myID] == GREEN) ->
colors[myId] = YELLOW;
:: (turn == myID && colors[myID] == YELLOW) ->
colors[myId] = RED;
turn = turn -1;
od;
Will the assertions we have still be satisfied? Do the assertions we have still make sense?
Yes the safety properties can still be satsified, but the liveness property has some issues.
How to fix it?
ltl always_eventually_green2 {
always
(waiting[0] implies eventually (colors[0] == GREEN)) &&
(waiting[1] implies eventually (colors[1] == GREEN))
}
It doesn't work. But is there an option we could use that we didn't? Yes! We can use the f flag for fairness and now it works.
ltl change_only_when_need0 {
always (colors[0] == GREEN implies
(colors[0] == GREEN until waiting[0]))
}
Will this work? No not really... ltl change_only_when_need0 {
always (colors[0] == GREEN implies
(colors[0] == GREEN weakuntil waiting[0]))
}
And it works! And it is very fast!