// Two different events with the same receiver imply they occurred at different times
e.receiver = e2.receiver and e != e2 implies e.pre != e2.pre
}
}
fact noStateTransfersToSelf {
all ste:StateTransferEvent {
ste.sender != ste.receiver
}
}
fact noDuplicateStateTransferEvents {
all ste,ste2:StateTransferEvent {
// Two state transfer events with the same nodes imply that they occurred at different times
ste.sender = ste2.sender and ste.receiver = ste2.receiver and ste != ste2 implies ste.pre != ste2.pre
}
}
--- Trace (time invariant)
fact trace {
all t:Time - last | let t' = t.next {
all n:Node {
// A node in (pre.t).receiver means it is being pointed to by some event that will happen over the next time step
n in (pre.t).receiver implies n.state.t' != n.state.t and n.sequenceNumber.t' != n.sequenceNumber.t // A node which receives some sort of event at time t causes it to change state
else n.state.t' = n.state.t and n.sequenceNumber.t' = n.sequenceNumber.t // Otherwise, it does not change state
}
}
}
--- Things we might like to be true, but are not always true
pred atLeastOneEvent {
#Event >= 1
}
pred allNodesStartAtSameStateAndSequenceNumber {
all n,n2:Node {
n.state.first = n2.state.first and n.sequenceNumber.first = n2.sequenceNumber.first
}
}
pred noStateChangeEventsAtEnd {
no e:StateChangeEvent {
e.post = last
}
}
--- Demonstration (Alloy will try to satisfy this)
pred show {
atLeastOneEvent
}
run show
--- Assertions (Alloy will try to break these)
assert allNodesConsistentAtEnd {
allNodesStartAtSameStateAndSequenceNumber implies
all n,n2:Node {
// At the end of a sequence (last) all nodes with the same sequence number have the same state