Definition cn_send_trans :=
SendTrans cn_safe_coh cn_safe_in cn_safe_def cn_step_coh.
End CoordinatorGenericSendTransitions.
Section CoordinatorSendTransitions.
(* Send-Prep transition *)
Definition send_prep_prec (p : CStateT) to (m : payload) :=
(exists n, p = (n, CInit) /\ exists d, m = n :: d) \/
exists n d ps, [/\ p = (n, CSentPrep d ps), m = n :: d & to \notin ps].
Program Definition cn_send_prep_trans : send_trans TPCCoh :=
@cn_send_trans prep_req send_prep_prec _.
Next Obligation.
case: H=>/eqP->H; rewrite /cohMsg eqxx; split=>//=.
case: H0; first by case=>n[->{s}][d->{m}]/=; eexists _.
by case=>n[d][ps][->{s}]->; eexists _.
Qed.
(* Send-Commit transition *)
Definition send_commit_prec (p :  CStateT) to (m : payload) :=
(exists n d res,
[/\ p = (n, CWaitPrepResponse d res), m = [::n],
perm_eq (map fst res) pts & all (fun r => r) (map snd res)])
\/ exists n d ps, [/\ p = (n, CSentCommit d ps), m = [::n] & to \notin ps].
Program Definition cn_send_commit_trans : send_trans TPCCoh :=
@cn_send_trans commit_req send_commit_prec _.
Next Obligation.
case: H=>/eqP->H; rewrite /cohMsg eqxx; split=>//=.
case: H0; by case=>n[d][res][->{s}]/=->.
Qed.
(* Send-Abort transition *)
Definition send_abort_prec (p : CStateT) to (m : payload) :=
(exists n d res,
[/\ p = (n, CWaitPrepResponse d res), m = [::n],
perm_eq (map fst res) pts & has (fun r => negb r) (map snd res)]) \/
exists n d ps, [/\ p = (n, CSentAbort d ps), m = [::n] & to \notin ps].
Program Definition cn_send_abort_trans : send_trans TPCCoh :=
@cn_send_trans abort_req send_abort_prec _.
Next Obligation.
case: H=>/eqP->H; rewrite /cohMsg eqxx; split=>//=.
by case:H0;move=>[n][d][res][->{s}]/=->.
Qed.
End CoordinatorSendTransitions.
Section CoordinatorGenericReceiveTransitions.
Notation coh := TPCCoh.
(* Send-prepare *)
Variable rc_tag : ttag.
Variable rc_wf : forall d, coh d -> nid -> nid -> TaggedMessage -> bool.
Definition rc_step : receive_step_t coh :=
fun this (from : nid) (m : seq nat) d (pf : coh d) (pt : this \in nodes) =>
if (this == cn)
then let s := getStC pf in
let l := @getStL this d pf pt in
mkLocal (cstep_recv s from rc_tag m l)
else getLocal this d.

(* Specifications: *)
Lemma rc_step_coh : r_step_coh_t rc_wf rc_tag rc_step.
Definition rc_recv_trans := ReceiveTrans rc_step_coh.