Library Pruning

Require Export Merge.

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

Module Export SPP := SP_Merge P X V E B R Ev BEv.

Section MoreBranches.

Pruning

The pruning relation is defined as: B can be pruned to B' if B' is obtained from B by removing some branches in branching terms.

Inductive more_branches : Behaviour -> Behaviour -> Prop :=
| MB_End : more_branches End End
| MB_Send p e B B': more_branches B B' -> more_branches (p ! e; B) (p ! e; B')
| MB_Recv p x B B': more_branches B B' -> more_branches (p ? x; B) (p ? x; B')
| MB_Sel p l B B': more_branches B B' -> more_branches (p (+) l; B) (p (+) l; B')
| MB_Branching_None_None p mBl mBr : more_branches (p & mBl // mBr) (p & None // None)
| MB_Branching_None_Some p mBl Br Br' : more_branches Br Br' ->
    more_branches (p & mBl // Some Br) (p & None // Some Br')
| MB_Branching_Some_None p Bl Bl' mBr : more_branches Bl Bl' ->
    more_branches (p & Some Bl // mBr) (p & Some Bl' // None)
| MB_Branching_Some_Some p Bl Bl' Br Br' : more_branches Bl Bl' -> more_branches Br Br' ->
    more_branches (p & Some Bl // Some Br) (p & Some Bl' // Some Br')
| MB_Cond b B1 B1' B2 B2' : more_branches B1 B1' -> more_branches B2 B2' ->
    more_branches (If b Then B1 Else B2) (If b Then B1' Else B2')
| MB_Call X : more_branches (Call X) (Call X)
.

Lemma more_branches_char_1 : forall B1 B2,
  more_branches B1 B2 -> merge B1 B2 = inject B1.

Lemma more_branches_char_2 : forall B1 B2,
  merge B1 B2 = inject B1 -> more_branches B1 B2.

Lemma more_branches_char : forall B1 B2,
  more_branches B1 B2 <-> merge B1 B2 = inject B1.

Lemma merge_more_branches : forall B1 B2 B,
  merge B1 B2 = inject B -> more_branches B B1.

Lemma merge_more_branches' : forall B1 B2 B,
  merge B1 B2 = inject B -> more_branches B B2.

Lemma more_branches_refl : forall B, more_branches B B.

Lemma more_branches_refl' : forall B B', B = B' -> more_branches B B'.

Lemma more_branches_trans : forall B B' B'',
  more_branches B B' -> more_branches B' B'' -> more_branches B B''.

Local Ltac lelim X B H H':=
  elim (XUndefined_dec X); intro H;
  [ rewrite H in H'; elim (inject_not_undefined B); auto
  | rewrite Xmatch_elim in H'; auto ].

Local Ltac lelim2 X Y B H H' H'' := lelim X B H H''; lelim Y B H' H''.

Local Ltac mbsolve B B' := apply more_branches_trans with B;
  [apply merge_more_branches with B' | idtac]; auto.

Local Ltac mbsolve'' B B' := apply more_branches_trans with B;
  [apply merge_more_branches' with B' | idtac]; auto.

Local Ltac mbsolve' H := apply inject_inj in H; rewrite <- H; auto.

Lemma more_branches_merge_extend : forall B1 B2 B1' B2' B,
  more_branches B1 B1' -> more_branches B2 B2' -> merge B1 B2 = inject B ->
  exists B', merge B1' B2' = inject B' /\ more_branches B B'.

Lemma more_branches_merge : forall B B1 B2,
  more_branches B B1 -> more_branches B B2 ->
  exists B', merge B1 B2 = inject B' /\ more_branches B B'.

The same relation on extended behaviours, and corresponding lemmas.
Definition Xmore_branches XB XB' := exists B B',
  XB = inject B /\ XB' = inject B' /\ more_branches B B'.

Lemma more_branches_X : forall B B',
 more_branches B B' -> Xmore_branches (inject B) (inject B').

Lemma X_more_branches : forall B B',
 Xmore_branches (inject B) (inject B') -> more_branches B B'.

Lemma Xmore_branches_refl : forall X B, X = inject B ->
  Xmore_branches X X.

Lemma Xmore_branches_trans : forall X X' X'',
  Xmore_branches X X' -> Xmore_branches X' X'' -> Xmore_branches X X''.

Lemma Xmore_branches_merge : forall B B1 B2,
  Xmore_branches B B1 -> Xmore_branches B B2 -> Xmore_branches B (Xmerge B1 B2).

Lemma Xmore_branches_merge_extend : forall B1 B2 B1' B2' B,
  Xmore_branches B1 B1' -> Xmore_branches B2 B2' ->
  Xmerge B1 B2 = inject B ->
  Xmore_branches (Xmerge B1 B2) (Xmerge B1' B2').

Lemma Xmore_branches_char : forall B1 B2,
  Xmore_branches B1 B2 <-> (collapse B1 <> XUndefined /\ Xmerge B1 B2 = B1).

Lemma Xmerge_more_branches : forall B1 B2,
  collapse (Xmerge B1 B2) <> XUndefined -> Xmore_branches (Xmerge B1 B2) B1.

Lemma Xmerge_more_branches' : forall B1 B2,
  collapse (Xmerge B1 B2) <> XUndefined -> Xmore_branches (Xmerge B1 B2) B2.

End MoreBranches.

Definition more_branches_N (N N':Network) :=
  forall p, more_branches (N p) (N' p).

Notation "N >> N'" := (more_branches_N N N') (at level 50).

Section MoreBranchesN.

Lemma more_branches_N_refl : forall N, N >> N.

Lemma more_branches_N_refl' : forall (N N':Network),
  (N == N') -> N >> N'.

Lemma more_branches_N_trans : forall N N' N'',
  N >> N' -> N' >> N'' -> N >> N''.

Lemma SP_To_more_branches_N : forall Defs N1 s N2 s' Defs' N1' tl,
  SP_To Defs N1 s tl N2 s' -> N1' >> N1 -> (forall X, Defs X = Defs' X) ->
  exists N2', SP_To Defs' N1' s tl N2' s' /\ N2' >> N2.

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

Lemma SPP_ToStar_more_branches_N : forall P1 s P2 s' P1' tl,
  Net P1' >> Net P1 -> (forall X, Procs P1 X = Procs P1' X) ->
  (P1,s) --[tl]-->* (P2,s') ->
  exists P2', (P1',s) --[tl]-->* (P2',s') /\ Net P2' >> Net P2
  /\ forall X, Procs P1' X = Procs P2' X.

End MoreBranchesN.

End SP_Prune.