CS195Y Lecture 23

4/13/16


Regular Expressions

(10)+ means 1 or more repetitions of the string 10. For example, 10, 1010, 101010, etc, but not “” or 101
(10)+ is equivalent to 10(10)*
The * means 0 or more repetitions
A string is “accepted” by the state machine if it is in an accepting state at the end of the string.
A finite state machine is Non Deterministic if it has more than one possible edge at some state for the same input. That is, there is some input that could take two different paths through the machine.

  1. always(colors[0] == RED || colors[1] == RED)
  2. always(eventually colors[0] == GREEN && eventually colors[1] == GREEN)

a+baᵂ
The omega means an infinite number of as.
You can’t accept this type of string in a regular finite state machine because it will never finish. Remember, a finite state machine accepts if it is in accepting state at the end of the string

Q: How can we design a state machine that handles infinite words?
A: We can’t actually run the automaton because it would never finish. But we can run it part of the way.
Pigeonhole Principle: If you have n boxes and n+1 items to put into the boxes, there must be at least one box with more than one item.
Here, we have a finite number of states, but an infinite length word. That means that we must repeat states (ie. there is a cycle).
We want to accept if as we progress through the machine, we hit an accepting state infinitely many times. This occurs when there is a cycle containing an accepting state
That is what Spin does when you run it with -a. It looks for an acceptance cycle.

Note: in Spin, you should always run both ./pan and ./pan -a. Due to optimizations, Spin will only explore paths that might lead to an acceptance cycle, so you might miss bad states (like deadlocks). This is also why you can only check one ltl property at a time.

State machine that recognizes counterexamples to property 1:
Eventually you reach a state where neither light is red

Q: How are assert statements checked?
A: They’re checked by depth-first search of the state machine and throws an error if it is violated.

Traffic Light: Version 2

Suppose one street is a busy main road and the other is a small side road. Do you really want to just arbitrarily decide when to turn the lights? No! You want to have some sort of sensor to tell whether or not there is a car waiting in each direction to decide when to turn the lights a little more intelligently.

Now our always_eventually_green ltl property is actually not desirable behavior. If no one is ever waiting in one direction, then you actually don’t want the light to turn green.

ltl always_eventually_green_2 {
    always (waiting[0] implies eventually (colors[0] == GREEN)) &&
           (waiting[1] implies eventually (colors[1] == GREEN))
}

Now let’s add a property that says “the light will stay green until the sensor fires in the other direction”

ltl change_only_when_need {
    always (colors[0] == GREEN implies colors[0] == GREEN until waiting[1])
}

a until b means that b eventually happens, but a is true until b is true.
a weakuntil b means that either a is always true, or a is true until b turns true.
In this case, we actually want weakuntil to allow for the possibility that no one is ever waiting in the other direction.

ltl change_only_when_need_2 {
    always (colors[0] == GREEN implies colors[0] == GREEN weakuntil waiting[1])
}