(* This server node *)
(* It's a server in protocol cal1 *)
Hypothesis  Hs1 : sv \in cs1.
(* It's a client in protocol cal2 *)
Hypothesis  Hc2 : sv \in cls2.
(* Delegate server *)
Variable sd : nid.
Hypothesis  Hs2 : sd \in cs2.
Notation loc i k := (getLocal sv (getStatelet i k)).
Notation loc1 i := (loc i l1).
Notation loc2 i := (loc i l2).
(* Delegate computation to someone else *)
Definition delegate_f := compute_f l2 f prec cs2 cls2 _ Hc2 sd.
Notation cal_ii := (ii l1 f prec cs1 cls1).
Definition receive_msg :=
with_inv cal_ii (blocking_receive_req l1 f prec cs1 cls1 _ Hs1).
Definition send_ans to args ans :=
with_inv cal_ii (send_answer l1 f prec cs1 cls1 _ Hs1 to args ans).
Definition delegating_body_spec :=
forall _ : unit,
DHT [sv, V]
(fun i =>
loc1 i = st :-> ([::]:reqs) /\
loc2 i = st :-> ([::]:reqs),
fun (r : unit) m =>
loc1 m = st :-> ([::]:reqs) /\
loc2 m = st :-> ([::]:reqs)).
Program Definition delegating_body :
delegating_body_spec := fun (_ : unit) =>
Do _ (
r <-- uinject (receive_msg);
let: (from, args) := r in
(* Delegate computations *)
ans <-- uinject (delegate_f args);
uinject (send_ans from args ans);;
ret sv V tt).

(* Specifications: *)
Lemma hook_complete_unit (c : context) : hook_complete (c, Unit).
Next Obligation.