package TL2 (sysTL, TL) where { -- Simple model of a traffic light -- Version 2: add a specific time delay for each state -- We'll use an integer register to count time (seconds) interface TL = { }; data TLstates = AllRed | GreenNS | AmberNS | GreenE | AmberE | GreenW | AmberW deriving (Eq, Bits); -- Assume the clock ticks every second -- Assume that no delay is greater than 32 seconds (5-bits) type Time32 = UInt 5; sysTL :: Module TL; sysTL = module { state :: Reg TLstates; state <- mkReg AllRed; next_green :: Reg TLstates; next_green <- mkReg GreenNS; secs :: Reg Time32; secs <- mkReg 0; let { allRedDelay :: Time32; allRedDelay = 2; amberDelay :: Time32; amberDelay = 4; ns_green_delay :: Time32; ns_green_delay = 20; ew_green_delay :: Time32; ew_green_delay = 10; }; interface { -- Empty interface }; addRules $ rules { "wait": when True ==> secs := secs + 1 } +> rules { "fromAllRed": when (state == AllRed) && ((secs + 1) >= allRedDelay) ==> action { state := next_green; secs := 0; } ; "fromGreenNS": when (state == GreenNS) && ((secs + 1) >= ns_green_delay) ==> action { state := AmberNS; secs := 0; }; "fromAmberNS": when (state == AmberNS) && ((secs + 1) >= amberDelay) ==> action { state := AllRed; secs := 0; next_green := GreenE; }; "fromGreenE": when (state == GreenE) && ((secs + 1) >= ew_green_delay) ==> action { state := AmberE; secs := 0; }; "fromAmberE": when (state == AmberE) && ((secs + 1) >= amberDelay) ==> action { state := AllRed; secs := 0; next_green := GreenW; }; "fromGreenW": when (state == GreenW) && ((secs + 1) >= ew_green_delay) ==> action { state := AmberW; secs := 0; }; "fromAmberW": when (state == AmberW) && ((secs + 1) >= amberDelay) ==> action { state := AllRed; secs := 0; next_green := GreenNS; }; } } }