module language/lights open util/ordering[LightState] sig Colour {} one sig Red, Yellow, Green extends Colour {} fun colourSequence (): Colour -> Colour { Colour <: iden + Red->Green + Green->Yellow + Yellow->Red } sig Street {} sig Light {street: Street} sig LightState {colour: Light -> one Colour} {all l, l': Light | l.street = l'.street => l.colour = l'.colour} sig Junction {lights: set Light} fact {lights: Junction lone -> Light} fun redLights (s: LightState): set Light {s.colour.Red} pred mostlyRed (s: LightState, j: Junction) { lone j.lights - redLights(s) } pred trans (s, s': LightState, j: Junction) { lone x: j.lights | s.colour[x] != s'.colour[x] all x: j.lights | let step = s.colour[x]-> s'.colour[x] { step in Red->(Colour-Red) => j.lights in redLights(s) } } /* pred traces () { all s: LightState - last () | all j: Junction | trans (s, next (s), j) } run traces for exactly 2 Junction, exactly 2 Street, 3 Colour, 5 LightState, exactly 4 Light */ assert Safe { all s, s': LightState, j: Junction | mostlyRed (s, j) and trans (s, s', j) => mostlyRed (s', j) } check Safe for 3 but exactly 2 Junction, 2 Street assert ColourSequenceDeterministic { all c: Colour | lone c.colourSequence () } check ColourSequenceDeterministic