type bit = {zero,one}
type univ
module intf(sndr,rcvr) = {
individual state : bit
relation pending
init state = one & ~pending
action put(v : bit) = {
assert ~pending & v ~= state;
state := v;
pending := true
}
mixin put before rcvr:put
action get(v : bit) = {
assert pending & v = state;
pending := false
}
mixin get before sndr:get
}
module channel(sndr,rcvr) = {
individual state : bit
relation put_pending
relation get_pending
init ~put_pending & ~get_pending & state = one
action get(v : bit) = {
get_pending := true;
state := v
}
action put(v : bit) = {
put_pending := true;
state := v
}
action step = {
if * {
assume get_pending;
get_pending := false;
call sndr:get(state)
}
else {
assume put_pending;
put_pending := false;
call rcvr:put(state)
}
}
}
module sender(rcvr) = {
individual state : bit
relation pending
init ~pending & state = one
action get(v : bit) = {
pending := false
}
action step(v : bit) = {
assume ~pending;
assume v ~= state;
pending := true;
state := v;
call rcvr:put(v)
}
}
module receiver(sndr) = {
individual state : bit
relation pending
init ~pending
action put(v : bit) = {
pending := true;
state := v
}
action step = {
assume pending;
call sndr:get(state);
call sndr:get(zero);
pending := false
}
}
instantiate s : sender(c)
instantiate c : channel(s,r)
instantiate r : receiver(c)
export s:step
export c:step
export r:step
instantiate sc : intf(s,c)
instantiate sr : intf(c,r)
isolate iso_s = s with sc
isolate iso_c = c with sc,sr
isolate iso_r = r with sr