Library EPP

Require Export CC.
Require Export Pruning.

Local Open Scope nat_scope.

Module EPPBase (P X V E B R:DecType) (Ev:Eval E X V V) (BEv:Eval B X V Bool).

Module PR := DecProd R P.

Module Export CCBase := CCBase P X V E B R Ev BEv.
Module Export SP_EPP := SP_Prune P X V E B PR Ev BEv.

Ltac sup := unfold set_union_pid; rewrite set_union_iff; auto.

Section EPP.

EndPoint projection

First step: returns an XBehaviour, possibly with XUndefined subcomponents.
Fixpoint bproj (Defs:DefSet) (C:Choreography) (r:Pid) : XBehaviour :=
match C with
| CCBase.End => XEnd
| p#e --> q$x;; C' => if Pid_dec p r
                               then XSend q e (bproj Defs C' r)
                               else if Pid_dec q r
                                    then XRecv p x (bproj Defs C' r)
                                    else bproj Defs C' r
| p --> q[left];; C' => if Pid_dec p r
                               then XSel q left (bproj Defs C' r)
                               else if Pid_dec q r
                                    then XBranching p (Some (bproj Defs C' r)) None
                                    else bproj Defs C' r
| p --> q[right];; C' => if Pid_dec p r
                               then XSel q right (bproj Defs C' r)
                               else if Pid_dec q r
                                    then XBranching p None (Some (bproj Defs C' r))
                                    else bproj Defs C' r
| If p ?? b Then C1 Else C2 => if Pid_dec p r
                               then XCond b (bproj Defs C1 r) (bproj Defs C2 r)
                               else Xmerge (bproj Defs C1 r) (bproj Defs C2 r)
| CCBase.Call X => if In_dec P.eq_dec r (fst (Defs X))
                               then XCall (X,r)
                               else XEnd
| RT_Call X ps C' => if In_dec P.eq_dec r ps
                               then XCall (X,r)
                               else bproj Defs C' r
end.

Second step: collapse all undefined behaviours.
Definition epp_list (Defs:DefSet) (C:Choreography) (ps:list Pid) : list (Pid * XBehaviour) :=
  map (fun p => (p, collapse (bproj Defs C p))) ps.

Definitions of projectability at all different levels.
Definition projectable_C Defs ps C :=
  Forall (fun X => snd X <> XUndefined) (epp_list Defs C ps).

Definition projectable_D Xs Defs :=
  Forall (fun X => projectable_C Defs (fst (Defs X)) (snd (Defs X)) ) Xs.

Definition projectable Xs ps P :=
  projectable_C (Procedures P) ps (Main P) /\
  projectable_D Xs (Procedures P) /\
  (forall p, In p (CCC_pn (Main P) (fun _ => nil)) -> In p ps) /\
  (forall p X, In X Xs -> In p (fst (Procedures P X)) -> In p ps) /\
  (forall p X, In X Xs -> In p (CCC_pn (snd (Procedures P X)) (fun _ => nil)) -> In p ps).

Not decidable, but in practice easy to compute. Maybe we want to compute ps from Xs?
For simplifying future definitions.
Now we can define EPP, again in a layered manner. Definitions are interactive because of the absurd cases.
Auxiliary results about behaviour projection.
Lemma bproj_not_In : forall Defs r C,
  ~In r (CCC_pn C (fun X => fst (Defs X))) -> bproj Defs C r = XEnd.

Lemma bproj_Call_In : forall Defs C p X, bproj Defs C p = XCall (X, p) ->
  consistent (fun X => fst (Defs X)) C -> In p (fst (Defs X)).

Lemma bproj_disjoint : forall Defs e C p, ~In p (eta_pn e) ->
  bproj Defs (e;; C) p = bproj Defs C p.

Proof irrelevance for EPP.
Lemma epp_C_wd : forall Defs C ps H H',
  (epp_C Defs ps C H) == (epp_C Defs ps C H').

Lemma epp_C_out : forall Defs C ps H p, ~In p ps ->
  epp_C Defs ps C H p = End.

Lemma epp_C_out' : forall Defs ps C HC p,
  ~In p (CCC_pn C (fun X => fst (Defs X))) -> epp_C Defs ps C HC p = End.

Lemma epp_C_char : forall Xs ps Defs C HP HC,
  (Net (epp Xs ps {| Procedures := Defs; Main := C |} HP))
    == (epp_C Defs ps C HC).

Lemma epp_C_char' : forall Xs ps Defs C HP p, In p ps ->
  bproj Defs C p = inject (Net (epp Xs ps {| Procedures := Defs; Main := C |} HP) p).

Lemma epp_C_bproj : forall Defs ps C HC p, In p ps ->
  bproj Defs C p = inject (epp_C Defs ps C HC p).

Lemma epp_D_wd : forall Xs Defs H H' X, epp_D Xs Defs H X = epp_D Xs Defs H' X.

Lemma epp_D_char : forall Xs ps Defs C HP HD X p,
  Procs (epp Xs ps {| Procedures := Defs; Main := C |} HP) (X,p)
  = epp_D Xs Defs HD (X,p).

Lemma epp_D_char' : forall Xs ps Defs C HP X p,
  In X Xs -> set_incl_pid (CCC_pn (snd (Defs X)) (fun Y => fst (Defs Y))) (fst (Defs X)) ->
  bproj Defs (snd (Defs X)) p = inject (Procs (epp Xs ps {| Procedures := Defs; Main := C |} HP) (X,p)).

Lemma epp_D_char'' : forall Xs ps Defs C HP X p HX, In X Xs ->
   Procs (epp Xs ps {| Procedures := Defs; Main := C |} HP) (X, p) =
   epp_C Defs (fst (Defs X)) (snd (Defs X)) HX p.

Lemma epp_out : forall Xs ps Defs C HP p, ~In p ps ->
  Net (epp Xs ps {| Procedures := Defs; Main := C |} HP) p = End.

Sanity checks: EPP works as defined informally in the paper.
Lemma epp_C_Com_p : forall Defs ps C p e q x HC HC', In p ps ->
  epp_C Defs ps (p#e-->q$x;;C) HC p = q!e; epp_C Defs ps C HC' p.

Lemma epp_C_Com_q : forall Defs ps C p e q x HC HC', p <> q -> In q ps ->
  epp_C Defs ps (p#e-->q$x;;C) HC q = p ? x; epp_C Defs ps C HC' q.

Lemma epp_C_Com_r : forall Defs ps C p e q x HC HC' r, p <> r -> q <> r ->
  epp_C Defs ps (p#e-->q$x;;C) HC r = epp_C Defs ps C HC' r.

Lemma epp_C_Sel_p : forall Defs ps C p q l HC HC', In p ps ->
  epp_C Defs ps (p-->q[l];;C) HC p = q(+)l; epp_C Defs ps C HC' p.

Lemma epp_C_Sel_ql : forall Defs ps C p q HC HC', p <> q -> In q ps ->
  epp_C Defs ps (p-->q[left];;C) HC q = p & Some (epp_C Defs ps C HC' q) // None.

Lemma epp_C_Sel_qr : forall Defs ps C p q HC HC', p <> q -> In q ps ->
  epp_C Defs ps (p-->q[right];;C) HC q = p & None // Some (epp_C Defs ps C HC' q).

Lemma epp_C_Sel_r : forall Defs ps C p q l HC HC' r, p <> r -> q <> r ->
  epp_C Defs ps (p-->q[l];;C) HC r = epp_C Defs ps C HC' r.

Lemma epp_C_Cond_p : forall Defs ps p b C1 C2 HC HC1 HC2, In p ps ->
  epp_C Defs ps (If p ?? b Then C1 Else C2) HC p
  = If b Then (epp_C Defs ps C1 HC1 p) Else (epp_C Defs ps C2 HC2 p).

Lemma epp_C_Cond_r : forall Defs ps p b C1 C2 HC HC1 HC2 r, p <> r ->
  inject (epp_C Defs ps (If p ?? b Then C1 Else C2) HC r)
  = merge (epp_C Defs ps C1 HC1 r) (epp_C Defs ps C2 HC2 r).


Lemma epp_C_Call : forall Defs ps X p HC, In p ps -> In p (fst (Defs X)) ->
  epp_C Defs ps (CCBase.Call X) HC p = Call (X,p).

Lemma epp_C_Call_out : forall Defs ps X p HC, ~In p (fst (Defs X)) ->
  epp_C Defs ps (CCBase.Call X) HC p = End.

Lemma epp_C_RT_Call : forall Defs ps X p ps' C HC, In p ps -> In p ps' ->
  epp_C Defs ps (RT_Call X ps' C) HC p = Call (X,p).

Lemma epp_C_RT_Call_out : forall Defs ps X p ps' C HC HC', ~In p ps' ->
  epp_C Defs ps (RT_Call X ps' C) HC p = epp_C Defs ps C HC' p.

Lemma epp_C_End : forall Defs ps p HC,
  epp_C Defs ps CCBase.End HC p = End.

Strange characterizations lemmas for branching.
Strange inversion lemmas for conditionals.
Lemma epp_C_Cond_Send_inv : forall Defs ps p b C1 C2 HC HC1 HC2 r q e B,
  epp_C Defs ps (If p ?? b Then C1 Else C2) HC r = q ! e; B ->
  exists B1 B2, epp_C Defs ps C1 HC1 r = q ! e; B1
  /\ epp_C Defs ps C2 HC2 r = q ! e; B2 /\ merge B1 B2 = inject B.

Lemma epp_C_Cond_Recv_inv : forall Defs ps p b C1 C2 HC HC1 HC2 r q x B,
  epp_C Defs ps (If p ?? b Then C1 Else C2) HC r = q ? x; B ->
  exists B1 B2, epp_C Defs ps C1 HC1 r = q ? x; B1
  /\ epp_C Defs ps C2 HC2 r = q ? x; B2 /\ merge B1 B2 = inject B.

Lemma epp_C_Cond_Sel_inv : forall Defs ps p b C1 C2 HC HC1 HC2 r q l B,
  epp_C Defs ps (If p ?? b Then C1 Else C2) HC r = q (+) l; B ->
  exists B1 B2, epp_C Defs ps C1 HC1 r = q (+) l; B1
  /\ epp_C Defs ps C2 HC2 r = q (+) l; B2 /\ merge B1 B2 = inject B.

Lemma epp_C_Cond_Branching_l_inv : forall Defs ps p b C1 C2 HC HC1 HC2 r q B,
  epp_C Defs ps (If p ?? b Then C1 Else C2) HC r = q & Some B // None ->
  exists B1 B2, epp_C Defs ps C1 HC1 r = q & Some B1 // None
  /\ epp_C Defs ps C2 HC2 r = q & Some B2 // None /\ merge B1 B2 = inject B.

Lemma epp_C_Cond_Branching_r_inv : forall Defs ps p b C1 C2 HC HC1 HC2 r q B,
  epp_C Defs ps (If p ?? b Then C1 Else C2) HC r = q & None // Some B ->
  exists B1 B2, epp_C Defs ps C1 HC1 r = q & None // Some B1
  /\ epp_C Defs ps C2 HC2 r = q & None // Some B2 /\ merge B1 B2 = inject B.

Lemma epp_C_Cond_Cond_inv : forall Defs ps p b b' C1 C2 HC HC1 HC2 r Bt Be,
  epp_C Defs ps (If p ?? b Then C1 Else C2) HC r = If b' Then Bt Else Be ->
  p <> r -> exists B1t B1e B2t B2e,
    epp_C Defs ps C1 HC1 r = If b' Then B1t Else B1e
    /\ epp_C Defs ps C2 HC2 r = If b' Then B2t Else B2e
    /\ merge B1t B2t = inject Bt /\ merge B1e B2e = inject Be.

End EPP.

Section Projectability.

Properties of projectability

All variants of parameterized projectability are decidable.
Inversion lemmas for projectability.
The corresponding lemmas for RT_Call do not hold. Therefore, projectability is not preserved by reductions, so we need an auxiliary notion.
Fixpoint strongly_projectable Defs (C:Choreography) (r:Pid) : Prop :=
match C with
| eta;; C' => strongly_projectable Defs C' r
| If p ?? b Then C1 Else C2 => strongly_projectable Defs C1 r
     /\ strongly_projectable Defs C2 r
     /\ collapse (bproj Defs C r) <> XUndefined
| RT_Call X ps C => strongly_projectable Defs C r /\
     (forall p, In p ps -> In p (fst (Defs X))
          /\ Xmore_branches (bproj Defs (snd (Defs X)) p) (bproj Defs C p))
| _ => True
end.

Lemma strongly_projectable_C : forall Defs C r,
  strongly_projectable Defs C r -> collapse (bproj Defs C r) <> XUndefined.

Lemma strongly_projectable_C' : forall Defs C ps,
  (forall r, In r ps -> strongly_projectable Defs C r) -> projectable_C Defs ps C.

Lemma initial_strongly_projectable : forall C, initial C ->
  forall Defs ps, projectable_C Defs ps C ->
  forall r, In r ps -> strongly_projectable Defs C r.

Lemma initial_strongly_projectable' : forall Defs C r, initial C ->
  ~In r (CCC_pn C (fun X => fst (Defs X))) -> strongly_projectable Defs C r.

Inversion lemmas for strong projectability.
Inversion lemmas about program projectability.
Miscellaneous.

The EPP Theorem

Lemmas about reduction and projection.

Lemma CCC_To_bproj_Com_p : forall Defs C s C' s' p q v x,
  strongly_projectable Defs C p ->
  CCC_To Defs C s (CCBase.TL.R_Com p v q x) C' s' ->
  exists e Bp, bproj Defs C p = XSend q e Bp /\ bproj Defs C' p = Bp
    /\ v = eval_on_state e s p.

Lemma CCC_To_bproj_Com_q : forall Defs C s C' s' p q v x,
  strongly_projectable Defs C q ->
  CCC_To Defs C s (CCBase.TL.R_Com p v q x) C' s' -> p <> q ->
  exists Bq, bproj Defs C q = XRecv p x Bq /\ bproj Defs C' q = Bq.

Lemma CCC_To_bproj_Com_r : forall Defs C s C' s' p q v x r,
  strongly_projectable Defs C r ->
  CCC_To Defs C s (CCBase.TL.R_Com p v q x) C' s' ->
  p <> r -> q <> r -> bproj Defs C' r = bproj Defs C r.

Lemma CCC_To_bproj_Sel_p : forall Defs C s C' s' p q l,
  strongly_projectable Defs C p ->
  CCC_To Defs C s (CCBase.TL.R_Sel p q l) C' s' ->
  exists Bp, bproj Defs C p = XSel q l Bp /\ bproj Defs C' p = Bp.

Lemma CCC_To_bproj_Sel_ql : forall Defs C s C' s' p q,
  strongly_projectable Defs C q ->
  CCC_To Defs C s (CCBase.TL.R_Sel p q left) C' s' -> p <> q ->
  exists Bq, bproj Defs C q = XBranching p (Some Bq) None /\ bproj Defs C' q = Bq.

Lemma CCC_To_bproj_Sel_qr : forall Defs C s C' s' p q,
  strongly_projectable Defs C q ->
  CCC_To Defs C s (CCBase.TL.R_Sel p q right) C' s' -> p <> q ->
  exists Bq, bproj Defs C q = XBranching p None (Some Bq) /\ bproj Defs C' q = Bq.

Lemma CCC_To_bproj_Sel_r : forall Defs C s C' s' p q l r,
  strongly_projectable Defs C r ->
  CCC_To Defs C s (CCBase.TL.R_Sel p q l) C' s' ->
  p <> r -> q <> r -> bproj Defs C' r = bproj Defs C r.

Lemma CCC_To_bproj_Cond_p : forall Defs C s C' s' p,
  strongly_projectable Defs C p ->
  CCC_To Defs C s (CCBase.TL.R_Cond p) C' s' ->
  exists b Bt Be, bproj Defs C p = XCond b Bt Be
    /\ (CCBase.beval_on_state b s p = true -> bproj Defs C' p = Bt)
    /\ (CCBase.beval_on_state b s p = false -> bproj Defs C' p = Be).

Lemma CCC_To_bproj_Cond_r : forall Defs C s C' s' p r,
  strongly_projectable Defs C r ->
  CCC_To Defs C s (CCBase.TL.R_Cond p) C' s' ->
  p <> r -> Xmore_branches (bproj Defs C r) (bproj Defs C' r).

Lemma CCC_To_bproj_Call_p : forall Defs C s C' s' p X Xs,
  strongly_projectable Defs C p ->
  (forall Y, In Y Xs -> strongly_projectable Defs (snd (Defs Y)) p) ->
  (forall Y, set_incl_pid (CCC_pn (snd (Defs Y)) (fun X => fst (Defs X))) (fst (Defs Y))) ->
  In X Xs ->
  CCC_To Defs C s (CCBase.TL.R_Call X p) C' s' ->
  bproj Defs C p = XCall (X,p) /\ Xmore_branches (bproj Defs (snd (Defs X)) p) (bproj Defs C' p).

Lemma CCC_To_bproj_Call_r : forall Defs C s C' s' p X r,
  (forall X, set_incl_pid (CCC_pn (snd (Defs X)) (fun Y => fst (Defs Y))) (fst (Defs X))) ->
  CCC_To Defs C s (CCBase.TL.R_Call X p) C' s' ->
  p <> r -> bproj Defs C' r = bproj Defs C r.

Lemma CCC_To_bproj_disjoint : forall Defs C s tl C' s' ps p,
  (forall X, set_incl_pid (CCC_pn (snd (Defs X)) (fun Y => fst (Defs Y))) (fst (Defs X))) ->
  (forall r, In r ps -> strongly_projectable Defs C r) -> In p ps ->
  CCBase.TL.disjoint_p_rl p tl -> CCC_To Defs C s tl C' s' ->
  Xmore_branches (bproj Defs C p) (bproj Defs C' p).

Projectability of well-formed programs is preserved by reductions.
Lemma CCC_To_projectable_C_Com : forall Defs ps C s C' s' p v q x,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  CCC_To Defs C s (CCBase.TL.R_Com p v q x) C' s' ->
  projectable_C Defs ps C'.

Lemma CCC_To_projectable_C_Sel : forall Defs ps C s C' s' p q l,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  CCC_To Defs C s (CCBase.TL.R_Sel p q l) C' s' ->
  projectable_C Defs ps C'.

Lemma CCC_To_projectable_C_Cond : forall Defs ps C s C' s' p,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  CCC_To Defs C s (CCBase.TL.R_Cond p) C' s' ->
  projectable_C Defs ps C'.

Lemma CCC_To_projectable_C_Call : forall Defs ps C s C' s' X p Xs,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p Y, In p ps -> In Y Xs -> strongly_projectable Defs (snd (Defs Y)) p) ->
  (forall Y, set_incl_pid (CCC_pn (snd (Defs Y)) (fun Z => fst (Defs Z))) (fst (Defs Y))) ->
  In X Xs -> CCC_To Defs C s (CCBase.TL.R_Call X p) C' s' ->
  projectable_C Defs ps C'.

Lemma CCC_To_projectable_C : forall Defs ps C s C' s' t Xs,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p Y, In p ps -> In Y Xs -> strongly_projectable Defs (snd (Defs Y)) p) ->
  (forall Y, set_incl_pid (CCC_pn (snd (Defs Y)) (fun Z => fst (Defs Z))) (fst (Defs Y))) ->
  (forall p X, In X Xs -> In p (fst (Defs X)) -> In p ps) ->
  within_Xs Xs C -> CCC_To Defs C s t C' s' -> projectable_C Defs ps C'.

Lemma CCC_To_projectable : forall P Xs ps,
  Program_WF Xs P -> well_ann P -> projectable Xs ps P ->
  (forall p, In p ps -> strongly_projectable (Procedures P) (Main P) p) ->
  (forall p, In p (CCC_pn (Main P) (Vars P)) -> In p ps) ->
  (forall p X, In X Xs -> In p (Vars P X) -> In p ps) ->
  forall s tl P' s', ((P,s) --[tl]--> (P',s'))%CC -> projectable Xs ps P'.

Strong projectability of well-formed programs is preserved by reductions: this is needed for chaining applications of the EPP theorem.
Lemma CCC_To_strongly_projectable_Com : forall Defs C s C' s' ps p v q x r,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  In r ps ->
  CCC_To Defs C s (CCBase.TL.R_Com p v q x) C' s' ->
  strongly_projectable Defs C' r.

Lemma CCC_To_strongly_projectable_Sel : forall Defs C s C' s' ps p q l r,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  In r ps ->
  CCC_To Defs C s (CCBase.TL.R_Sel p q l) C' s' ->
  strongly_projectable Defs C' r.

Lemma CCC_To_strongly_projectable_Cond : forall Defs C s C' s' ps p r,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  In r ps ->
  CCC_To Defs C s (CCBase.TL.R_Cond p) C' s' ->
  strongly_projectable Defs C' r.

Lemma CCC_To_strongly_projectable_Call : forall Defs C s C' s' ps p X r Xs,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p Y, In p ps -> In Y Xs -> strongly_projectable Defs (snd (Defs Y)) p) ->
  (forall Y, set_incl_pid (CCC_pn (snd (Defs Y)) (fun Z => fst (Defs Z))) (fst (Defs Y))) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  In r ps -> In X Xs ->
  CCC_To Defs C s (CCBase.TL.R_Call X p) C' s' ->
  strongly_projectable Defs C' r.

Lemma CCC_To_strongly_projectable : forall Defs ps C s C' s' t Xs,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  (forall p Y, In p ps -> In Y Xs -> strongly_projectable Defs (snd (Defs Y)) p) ->
  (forall Y, set_incl_pid (CCC_pn (snd (Defs Y)) (fun Z => fst (Defs Z))) (fst (Defs Y))) ->
  (forall p X, In X Xs -> In p (fst (Defs X)) -> In p ps) ->
  within_Xs Xs C -> CCC_To Defs C s t C' s' ->
  forall p, In p ps -> strongly_projectable Defs C' p.

Lemma CCP_To_strongly_projectable : forall P Xs ps,
  Program_WF Xs P -> well_ann P -> projectable Xs ps P ->
  (forall p, In p ps -> strongly_projectable (Procedures P) (Main P) p) ->
  (forall p, In p (CCC_pn (Main P) (Vars P)) -> In p ps) ->
  (forall p X, In X Xs -> In p (Vars P X) -> In p ps) ->
  forall s tl P' s', ((P,s) --[tl]--> (P',s'))%CC ->
  forall p, In p ps -> strongly_projectable (Procedures P') (Main P') p.

Completeness

The completeness part of the EPP theorem.
Lemma EPP_Complete : forall P Xs ps,
  Program_WF Xs P -> well_ann P -> forall (HP:projectable Xs ps P),
  (forall p, In p ps -> strongly_projectable (Procedures P) (Main P) p) ->
  (forall p, In p (CCC_pn (Main P) (Vars P)) -> In p ps) ->
  (forall p X, In X Xs -> In p (Vars P X) -> In p ps) ->
  forall s tl P' s', ((P,s) --[tl]--> (P',s'))%CC ->
  exists N tl', (epp Xs ps P HP,s) --[tl']--> (N,s')
    /\ Procs N = Procs (epp Xs ps P HP)
    /\ forall H, Net N >> Net (epp Xs ps P' H).

Lemma EPP_Complete' : forall P Xs ps,
  Program_WF Xs P -> well_ann P -> forall (HP:projectable Xs ps P),
  initial (Main P) ->
  (forall p, In p (CCC_pn (Main P) (Vars P)) -> In p ps) ->
  (forall p X, In X Xs -> In p (Vars P X) -> In p ps) ->
  forall s tl P' s', ((P,s) --[tl]-->* (P',s'))%CC ->
  exists N tl', (epp Xs ps P HP,s) --[tl']-->* (N,s')
  /\ forall H, Net N >> Net (epp Xs ps P' H).

Soundness of EPP

Soundness is proven by case analysis on the label of the reduction, and then by induction on the choreography. We split the proofs for each label in separate results, as we get some stronger statements.

Definition SP_eq (P P':Program) : Prop :=
  forall X, Procs P X = Procs P' X /\ (Net P == Net P').

Lemma SP_To_bproj_Com : forall Defs Defs' ps C HC s N' s' p x q v,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  SP_To Defs' (epp_C Defs ps C HC) s (R_Com p v q x) N' s' ->
  exists C', CCC_To Defs C s (CCBase.TL.R_Com p v q x) C' s'
  /\ forall HC', N' == (epp_C Defs ps C' HC').

Lemma SP_To_bproj_Sel_l : forall Defs Defs' ps C HC s N' s' p q,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  SP_To Defs' (epp_C Defs ps C HC) s (R_Sel p q left) N' s' ->
  exists C', CCC_To Defs C s (CCBase.TL.R_Sel p q left) C' s'
  /\ forall HC', N' == (epp_C Defs ps C' HC').

Lemma SP_To_bproj_Sel_r : forall Defs Defs' ps C HC s N' s' p q,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  SP_To Defs' (epp_C Defs ps C HC) s (R_Sel p q right) N' s' ->
  exists C', CCC_To Defs C s (CCBase.TL.R_Sel p q right) C' s'
  /\ forall HC', N' == (epp_C Defs ps C' HC').

Lemma SP_To_bproj_Cond : forall Defs Defs' ps C HC s N' s' p,
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  SP_To Defs' (epp_C Defs ps C HC) s (R_Cond p) N' s' ->
  exists C', CCC_To Defs C s (CCBase.TL.R_Cond p) C' s'
  /\ forall HC', N' >> (epp_C Defs ps C' HC').

Lemma SP_To_bproj_Call : forall Defs Defs' ps C HC s N' s' p X Xs,
  Choreography_WF C -> within_Xs Xs C -> In X Xs ->
  (forall p, In p ps -> strongly_projectable Defs C p) ->
  (forall p, In p (CCC_pn C (fun X => fst (Defs X))) -> In p ps) ->
  (forall p HX, Defs' (X,p) = epp_C Defs ps (snd (Defs X)) HX p) ->
  (forall p X, In p (CCC_pn (snd (Defs X)) (fun Y => fst (Defs Y))) -> In p (fst (Defs X))) ->
  (forall X, In X Xs -> projectable_C Defs ps (snd (Defs X))) ->
  (forall X, In X Xs -> initial (snd (Defs X))
    /\ forall p, In p (fst (Defs X)) -> In p ps) ->
  SP_To Defs' (epp_C Defs ps C HC) s (R_Call (X,p) p) N' s' ->
  exists C', CCC_To Defs C s (CCBase.TL.R_Call X p) C' s'
  /\ forall HC', N' >> epp_C Defs ps C' HC'.

Lemma SP_To_bproj_Call_name : forall Defs Defs' ps C HC s N' s' p X,
  SP_To Defs' (epp_C Defs ps C HC) s (R_Call X p) N' s' ->
  exists Y, X = (Y,p) /\ X_Free Y C.

Lemma EPP_Sound : forall P Xs ps,
  Program_WF Xs P -> well_ann P -> forall (HP:projectable Xs ps P),
  (forall p, In p ps -> strongly_projectable (Procedures P) (Main P) p) ->
  (forall p, In p (CCC_pn (Main P) (Vars P)) -> In p ps) ->
  (forall p X, In X Xs -> In p (Vars P X) -> In p ps) ->
  forall s tl N' s', (epp Xs ps P HP,s) --[tl]-->(N',s') ->
  exists P' tl', ((P,s) --[tl']--> (P',s'))%CC /\
    forall H, Net N' >> Net (epp Xs ps P' H).

Lemma SP_To_more_branches_N : forall Defs N1 s N2 s' tl Defs' ps C HC,
  N1 >> epp_C Defs' ps C HC -> SP_To Defs N1 s tl N2 s' ->
  exists N2', SP_To Defs (epp_C Defs' ps C HC) s tl N2' s' /\ N2 >> N2'.

Lemma SPP_To_more_branches_N : forall P1 s P2 s' tl Xs ps P HP,
  (forall X, Procs P1 X = Procs (epp Xs ps P HP) X) ->
  Net P1 >> Net (epp Xs ps P HP) -> (P1,s) --[tl]--> (P2,s') ->
  exists P2', (epp Xs ps P HP,s) --[tl]--> (P2',s') /\ Net P2 >> Net P2'
  /\ forall X, Procs P2 X = Procs P2' X.

Generalizing the last result to -->* already requires the EPP Theorem.

Lemma SPP_ToStar_more_branches_N : forall P1 s P2 s' tl Xs ps P,
  Program_WF Xs P -> well_ann P -> forall (HP:projectable Xs ps P),
  (forall p, In p ps -> strongly_projectable (Procedures P) (Main P) p) ->
  (forall p, In p (CCC_pn (Main P) (Vars P)) -> In p ps) ->
  (forall p X, In X Xs -> In p (Vars P X) -> In p ps) ->
  (forall X, Procs P1 X = Procs (epp Xs ps P HP) X) ->
  Net P1 >> Net (epp Xs ps P HP) -> (P1,s) --[tl]-->* (P2,s') ->
  exists P2', (epp Xs ps P HP,s) --[tl]-->* (P2',s') /\ Net P2 >> Net P2'
  /\ forall X, Procs P2 X = Procs P2' X.

Lemma EPP_Sound' : forall P Xs ps,
  Program_WF Xs P -> well_ann P -> forall (HP:projectable Xs ps P),
  (forall p, In p ps -> strongly_projectable (Procedures P) (Main P) p) ->
  (forall p, In p (CCC_pn (Main P) (Vars P)) -> In p ps) ->
  (forall p X, In X Xs -> In p (Vars P X) -> In p ps) ->
  forall s tl P' s', (epp Xs ps P HP,s) --[tl]-->* (P',s') ->
  exists P'' tl', ((P,s) --[tl']-->* (P'',s'))%CC /\
    forall H, Net P' >> Net (epp Xs ps P'' H).

End EPP_Theorem.

End EPPBase.