Asynchronous Interface
Asynchronous Interface
I wanted to investigate the state transition relation for the asynchronous interface Leslie Lamport described in his book Specifying Systems.
module async_interface
I won’t need sophisticated operators—only the diversity relation from my relmath
repo.
open relmath/ops
Onto the model.
Signature
People are mainly used to describing transitions between states. I am biased towards modal logic, so I will call my “state” signature W
after “World”.
sig W {
, Next: set W
, ack
, rdy: Flag
, val: Data
}
We can simulate the set 2
with an up
and a down
flag. (We could have used zero
and one
just as easily).
enum Flag { up, down }
Lamport points out the nature of the data being transmitted isn’t essential. We express the same lack of emphasis by using a signature with no relations we call Data
.
sig Data {}
Identity
Two states (sorry, Worlds) are the same when they share the same ack
, rdy
, and val
values.
fact {
id[W]
= ack.~ack
& rdy.~rdy
& val.~val
}
I’ve done it this way because I want to highlight that an accessibility relation can always take us right back to where we started.
Transitions
Lamport describes two transition relations: Send and Receive. He specifies them using TLA+. I present a pointfree translation of each below. One thing to notice is that many TLA practitioners complain about how Alloy burdens the modeller by not having an UNCHANGED
keyword. That might be a problem when working with pointwise specifications, but it isn’t so much of an issue when working pointfree. If you want to say that an attribute remains unchanged by a transition, you intersect with that attribute’s kernel, e.g. rdy.~rdy
.
Send
What I found particularly entertaining about Send
is that it can be expressed using composition. Its enabling condition (that ack
and rdy
have the same value) is described using a coreflexive.
fun Send : W->W {
(id[W] & (ack.~rdy)).(
rdy.(di[Flag]).~rdy
& ack.~ack
)
}
Rcv
Rcv
is very similar to Send
and is the only place in this specification where I have to use the diversity relation, i.e. the complement of the identity. I use it to express the enabling condition that ack
and rdy
must differ. Again the whole relation is expressed compositionally.
fun Rcv : W->W {
(id[W] & ack.(di[Flag]).~rdy).(
ack.(di[Flag]).~ack
& val.~val
& rdy.~rdy
)
}
Next
The Next
relation is defined as the union of the Send
and Rcv
relations.
fact { Next = Send + Rcv }
Stuttering might be accommodated by further adding the identity.
Visualisation
Now we can run the model and get a bird’s eye view of how this asynchronous interface might behave.
run {} for 10 but exactly 5 Data
I recommend adjusting your theme to use attributes instead of arcs for the rdy
, ack
, and val
relations.