CS195Y Lecture 26

4/10/2017


Model Checking 3

Back to the traffic light

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.
Note that when we run this the numbers are pretty low because randomness this way biases towards the starting value since it's a 50/50 chnace that we break at each iteration.

To do this quick and easy for small ranges by using select(i: low..high)

Some other ideas for reducing the bias:
Make other branches that do different things
Make other branches that do the same thing

If you really need a uniform distribrution you should probably use another programming language.

Back to the traffic light

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.

Now how do we need to modify the traffic light code?

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.

But why do we have sensors in the first place? So that more important roads can get to go more often than less important roads. Basically, we only want to change color in the interest of sombody waiting.

How can we assert this? There's a new ltl operator we cam use!
ltl change_only_when_need0 {
  always (colors[0] == GREEN implies
      (colors[0] == GREEN until waiting[0]))
}
Will this work? No not really...
This would work if there were always cars coming but the way we have it (using strong until) it'll fail. So we want the weak until which looks like.
ltl change_only_when_need0 {
  always (colors[0] == GREEN implies
      (colors[0] == GREEN weakuntil waiting[0]))
}
And it works! And it is very fast!