----------------------------------------------------------------------
-- This is an implementation of a simple traffic light system with one 
-- (bi-directional) car lane and one pedestrian crossing. 
--
--                            ooo
--       ------------------==-------------------
--                         ==
--                         ==
--       ------------------==-------------------
--                    ooo
--
-- Using the simulator, try to find problems in the implementation. 
----------------------------------------------------------------------

node TrafficLight3( Button : bool )
returns ( Red, Yellow, Green, Walk, DontWalk : bool );

var Phase, prePhase : int;
let
  prePhase = 0 -> pre Phase;
  Phase    = if Button and (false -> pre(DontWalk)) and prePhase = 0
               then 1
               else if prePhase > 0 and prePhase < 10
                      then prePhase+1
                      else 0;
  
  Green    = Phase = 0;
  Yellow   = Phase = 1;
  Red      = Phase > 1;
  
  Walk     = Phase > 2 and Phase < 10;
  DontWalk = not Walk;
tel

----------------------------------------------------------------------
-- A synchronous observer that checks a number of safety properties 
-- for the TrafficLight.
--
-- Try to prove them using Kind 2.
-- If a property is falsifiable, inspect the counter example
-- and try to fix the bug.
-- 
-- Try to specify additional properties and verify these. Avoid  
-- redundancies in your properties if you can.
----------------------------------------------------------------------

node ReqTrafficLight3( Button : bool )
returns (R1, R2, R3, R4, R5, R6, R7, R8, R9, R10: bool);

var  CarsAllowed, Red, Yellow, Green, Walk, DontWalk : bool;
let
  (Red, Yellow, Green, Walk, DontWalk) = TrafficLight3(Button);
  CarsAllowed = Green or Yellow;

  R1 = not (CarsAllowed and Walk);
  R2 = not (Red and Green);
  R3 = Red or Yellow or Green;
  R4 = Walk => Red;
  R5 = Walk xor DontWalk;
  R6 = true -> not (Red and pre Green);
  R7 = true -> not (Walk and pre CarsAllowed);
  R8 = true -> not (CarsAllowed and pre Walk);
  R9 = true -> not (Yellow and pre Yellow);
  R10 = true -> (pre Red and not Red) => Green;
tel