open util/ordering[Time]
sig Time {
turn: one Light
}
abstract sig Color {}
one sig Red, Yellow, Green extends Color {}
abstract sig Light {
myColor: Time -> one Color
}
one sig Light1, Light2 extends Light {}
fact init {
Light1.myColor[first] = Red
Light2.myColor[first] = Red
}
fact traces {
all t: Time - last | { -- every prestate
let other = Light - t.turn | {
other.myColor[t.next] = other.myColor[t]
t.turn.myColor[t] = Red => {
t.turn.myColor[t.next] = Green
t.turn = t.next.turn
}
t.turn.myColor[t] = Yellow => {
t.turn.myColor[t.next] = Red
other = t.next.turn
}
t.turn.myColor[t] = Green => {
t.turn.myColor[t.next] = Yellow
t.turn = t.next.turn
}
}
}
}
run {} for 3 Color, 2 Light, 5 Time
/*
pred candidate1 {
Light.myColor.Red = Time
}
pred candidate2 {
all t: Time |
some l: Light |
l.myColor[t] = Red
}
check equiv { --alwaysOneRed {
candidate1 iff candidate2
} for 3 Color, 2 Light, 10 Time
*/
check alwaysOneRed {
Light.myColor.Red = Time
} for 3 Color, 2 Light, 10 Time
check alwaysTurnGreenEventually {
all l: Light |
all t: Time | {
l.myColor[t] = Red implies
some t2: t.^next | {
l.myColor[t2] = Green
}
}
} for 3 Color, 2 Light, 100 Time
-- uh oh!