Section CalculatorProtocol.
Definition input := seq nat.
(* Partially defined function, e.g., addition or multiplication require precisely two arguments *)
Variable f : input -> option nat.
Variable prec : input -> bool.
Hypothesis prec_valid :
forall i, prec i -> exists v, f i = Some v.
(* Calculator nodes *)
Variable cs: seq nid.
Variable cls : seq nid.
(* All nodes *)
Notation nodes := (cs ++ cls).
(* All nodes are unique *)
Hypothesis Huniq : uniq nodes.
(* Protocol:  - "Clients" can send messages with requests as long as the request satisfies the precondition prec.  - "Clients" can receive messages from "servers" (i.e., calculators).  - "Servers" can receive messages as long as they satisfy the precondition and record the sender and the arguments in the permission list.  - "Servers" can respond to clients accordingly, given that the result satisfies the arguments.  *)
(* Defining state-space *)
(* Calculator server state *)
Definition st := ptr_nat 1.
(* Calculator state: - client node id - server node id - client-provided id (e.g., hash of the input) - client input *)
Definition perm := (nid * nat * (seq nat))%type.
Definition cstate := seq perm.
Definition all_valid (s : cstate) := all (fun e => prec e.2) s.
(* Local state coherence *)
Definition localCoh (n : nid) : Pred heap :=
[Pred h | exists (s : cstate), h = st :-> s /\ all_valid s].
(* Tags *)
Definition req : nat := 0.
Definition resp : nat := 1.
Definition tags := [:: req; resp].
(* Coherent messages *)
Definition cohMsg (ms: msg TaggedMessage) : Prop :=
let body := content ms in
if tag body == resp then
[/\ from ms \in cs, to ms \in cls &
exists v args, tms_cont body = [:: v] ++ args]
else [/\ tag body == req,
from ms \in cls, to ms \in cs &
exists args,
tms_cont body = args /\
prec args].
Definition soupCoh : Pred soup :=
[Pred s | valid s /\ forall m ms, find m s = Some ms -> cohMsg ms].
Definition calcoh d : Prop :=
let: dl := dstate d in
let: ds := dsoup d in
[/\ soupCoh ds, dom dl =i nodes,
valid dl &
forall n, n \in nodes -> localCoh n (getLocal n d)].
(****************************************************)
(********* Getter lemmas for local state ************)
(****************************************************)
Definition getSt n d (C : CalCoh d) : cstate :=
match find st (getLocal n d) as f return _ = f -> _ with
Some v => fun epf => icast (sym_eq (cohSt C epf)) (dyn_val v)
| _ => fun epf => [::]
end (erefl _).

Lemma getStE n i j C C' (pf : n \in nodes) :
getLocal n j = getLocal n i ->
@getSt n j C' = @getSt n i C.