Section LockProtocol.
Variable server : nid.
Variable clients : seq nid.
Hypothesis Hnin : server \notin clients.
Hypothesis Huniq : uniq clients.
Definition nodes := [:: server] ++ clients.
Notation epoch := nat (only parsing).
Record server_state :=
ServerState {
outstanding : seq nid;
current_epoch : epoch;
current_holder : option nid
}.
Inductive client_state :=
| NotHeld
| Held of epoch.
Definition acquire_tag := 0.
Definition grant_tag := 1.
Definition release_tag := 2.
Definition msg_from_server ms e :=
(tag ms == grant_tag) && (tms_cont ms == [:: e]).
Definition msg_from_client ms :=
((tag ms == acquire_tag) || (tag ms == release_tag)) &&
(tms_cont ms == [::]).
Definition coh_msg pkt e :=
if from pkt == server
then to pkt \in clients /\ msg_from_server (content pkt) e
else if from pkt \in clients
then to pkt == server /\ msg_from_client (content pkt)
else False.
Definition st := ptr_nat 1.
Definition client_local_coh (cs : client_state) :=
[Pred h | h = st :-> cs].
Definition server_local_coh (ss : server_state) :=
[Pred h | h = st :-> ss].
Definition local_coh (n : nid) :=
[Pred h | valid h /\
if n == server
then exists ss, server_local_coh ss h
else n \in clients /\
exists cs, client_local_coh cs h].
Definition soup_coh : Pred soup :=
[Pred s |
valid s /\
forall m ms, find m s = Some ms -> active ms -> exists e, coh_msg ms e].

Lemma soup_coh_post_msg d m:
soup_coh (dsoup d) -> (exists e, coh_msg m e) -> soup_coh (post_msg (dsoup d) m).1.