Lvc.RenamedApart

Require Import CSet Le.

Require Import Plus Util AllInRel Map.
Require Import Val Var Env EnvTy IL Annotation SetOperations MoreList.

Set Implicit Arguments.

Renamed-apart (formally)

Every subterm is annotated with two sets D and such that D contains all free variables of the subterm and is extactly the set of variables that occur in a binding position.
Inductive renamedApart : stmtann (set var × set var) → Prop :=
  | renamedApartExp x e s D D´´ an
    : x D
      → Exp.freeVars e D
      → renamedApart s an
      → pe (getAnn an) ({x; D}, )
      → D´´ [=] {x; }
      → renamedApart (stmtLet x e s) (ann1 (D, D´´) an)
  | renamedApartIf D Ds Dt e s t ans ant
    : Exp.freeVars e D
      → Ds Dt [=]
      → Ds Dt [=]
      → renamedApart s ans
      → renamedApart t ant
      → pe (getAnn ans) (D, Ds)
      → pe (getAnn ant) (D, Dt)
      → renamedApart (stmtIf e s t) (ann2 (D, ) ans ant)
  | renamedApartRet D e
    : Exp.freeVars e D
      → [=]
      → renamedApart (stmtReturn e) (ann0 (D, ))
  | renamedApartGoto D f Y
    : list_union (List.map Exp.freeVars Y) D
      → [=]
      → renamedApart (stmtApp f Y) (ann0 (D, ))
  | renamedApartExtern x f Y s D D´´ an
    : x D
      → list_union (List.map Exp.freeVars Y) D
      → renamedApart s an
      → pe (getAnn an) ({x; D}, )
      → D´´ [=] {x; }
      → renamedApart (stmtExtern x f Y s) (ann1 (D, D´´) an)
  | renamedApartLet D s t Ds Dt Z ans ant
    : of_list Z D [=]
      → (Ds ++ of_list Z) Dt [=]
      → Ds Dt of_list Z [=]
      → renamedApart s ans
      → pe (getAnn ans) (of_list Z D, Ds)
      → renamedApart t ant
      → pe (getAnn ant) (D, Dt)
      → unique Z
      → renamedApart (stmtFun Z s t) (ann2 (D,) ans ant).

Morphisms


Lemma renamedApart_ext s an an´
  : ann_R (@pe _ _) an an´
  → renamedApart s an
  → renamedApart s an´.
Proof.
  intros. general induction H0; simpl; invt (ann_R (@pe var _));
          invt (@pe var _); eauto using renamedApart.
  - econstructor. rewrite <- H8; eauto. rewrite <- H8; eauto.
    eapply IHrenamedApart; eauto. rewrite <- H8. rewrite (ann_R_get H9) in H2. eauto.
    rewrite <- H11. eauto.

  - econstructor; eauto. rewrite <- H7; eauto. rewrite <- H12; eauto.
    rewrite <- (ann_R_get H10). rewrite <- H7. eauto.
    rewrite <- (ann_R_get H11). rewrite <- H7. eauto.

  - econstructor; eauto. rewrite <- H5; eauto. rewrite <- H7; eauto.
  - econstructor. rewrite <- H5; eauto. rewrite <- H7; eauto.

  - econstructor. rewrite <- H8; eauto. rewrite <- H8; eauto.
    eapply IHrenamedApart; eauto. rewrite <- H8.
    rewrite <- (ann_R_get H9). eauto. rewrite <- H11; eauto.

  - econstructor; eauto. rewrite <- H8; eauto.
    rewrite <- H13; eauto.
    rewrite <- H8. rewrite <- (ann_R_get H11); eauto.
    rewrite <- H8. rewrite <- (ann_R_get H12); eauto.
Qed.

Instance renamedApart_morphism
: Proper (eq ==> (ann_R (@pe _ _)) ==> iff) renamedApart.
Proof.
  intros x s t A; subst. intros. split; intros.
  eapply renamedApart_ext; eauto.
  eapply renamedApart_ext; try symmetry; eauto.
Qed.

Relation to freeVars and occurVars

Lemma renamedApart_freeVars s an
  : renamedApart s anfreeVars s fst (getAnn an).
Proof.
  intros. general induction H; simpl; eauto.
  - rewrite H0, IHrenamedApart, H2. simpl.
    clear_all; cset_tac; intuition.
  - rewrite H, IHrenamedApart1, IHrenamedApart2. rewrite H4, H5; simpl.
    cset_tac; intuition.
  - rewrite H0, IHrenamedApart, H2; simpl. cset_tac; intuition.
  - rewrite IHrenamedApart1, IHrenamedApart2. inv H3; inv H5; simpl.
    rewrite H10, H13. cset_tac; intuition.
Qed.

Lemma renamedApart_occurVars s an
  : renamedApart s andefinedVars s [=] snd (getAnn an).
Proof.
  intros. general induction H; simpl; eauto.
  - rewrite H3, IHrenamedApart, H2. simpl.
    clear_all; cset_tac; intuition.
  - rewrite IHrenamedApart1, IHrenamedApart2. rewrite H4, H5; simpl; eauto.
  - cset_tac; intuition; eauto.
  - cset_tac; intuition; eauto.
  - rewrite H3, IHrenamedApart, H2. simpl.
    clear_all; cset_tac; intuition.
  - rewrite IHrenamedApart1, IHrenamedApart2. rewrite H3, H5; simpl. eauto.
Qed.

Definition pminus (D´´:set var) (s:set var × set var) :=
  match s with
    | pair s (s \ D´´, )
  end.

Instance pminus_morphism
: Proper (Equal ==> (@pe _ _) ==> (@pe _ _) ) pminus.
Proof.
  unfold Proper, respectful; intros.
  inv H0; simpl; econstructor. rewrite H1, <- H. reflexivity.
  eauto.
Qed.

Instance mapAnn_pminus_morphism
  : Proper (ann_R (@pe _ _) ==> ann_R (@pe _ _)) (mapAnn (pminus )).
Proof.
  unfold Proper, respectful; intros.
  general induction H; simpl.
  - econstructor; eauto.
    + rewrite H. reflexivity.
  - econstructor; eauto.
    + rewrite H. reflexivity.
  - econstructor; eauto.
    + rewrite H. reflexivity.
Qed.

Lemma not_in_minus X `{OrderedType X} (s t: set X) x
: x s
  → x s \ t.
Proof.
  cset_tac; intuition.
Qed.

Hint Resolve not_in_minus : cset.

Lemma not_incl_minus X `{OrderedType X} (s t u: set X)
: s t
  → disj s u
  → s t \ u.
Proof.
  cset_tac; intuition.
Qed.

Hint Resolve not_incl_minus : cset.
Hint Resolve disj_1_incl disj_2_incl : cset.

Hint Extern 20 (pe ?a ?a) ⇒ reflexivity.

Lemma renamedApart_minus D an an´ s
  : disj (occurVars s) D
    → renamedApart s an
    → ann_R (@pe _ _) an´ (mapAnn (pminus D) an)
    → renamedApart s an´.
Proof.
  intros ? ? PE. general induction H0; try rewrite PE; simpl in × |- ×.
  - econstructor; eauto with cset.
    + rewrite getAnn_mapAnn. pe_rewrite.
      econstructor; eauto.
      revert H H4; unfold disj; clear_all; cset_tac; intuition.
      invc H2; eapply H1; eauto.
  - econstructor; [|eapply H0| | | | |]; eauto with cset.
    + rewrite getAnn_mapAnn. pe_rewrite; eauto.
    + rewrite getAnn_mapAnn. pe_rewrite; eauto.
  - econstructor; eauto with cset.
  - econstructor; eauto with cset.
  - econstructor; eauto with cset.
    + rewrite getAnn_mapAnn. pe_rewrite.
      econstructor; eauto.
      revert H H4; unfold disj; clear_all; cset_tac; intuition.
      invc H2; eapply H1; eauto.
  - econstructor; [| |eapply H1| | | | |]; eauto with cset.
    + change (disj (of_list Z) (D \ D0)). rewrite minus_incl; eauto.
    + rewrite getAnn_mapAnn; simpl. pe_rewrite; econstructor; eauto.
      rewrite minus_dist_union. rewrite minus_inane_set; eauto.
      eapply disj_1_incl; eauto with cset.
    + rewrite getAnn_mapAnn; simpl. pe_rewrite; constructor; eauto.
Qed.

The two annotated sets are disjoint.


Lemma renamedApart_disj s G
: renamedApart s G
  → disj (fst (getAnn G)) (snd (getAnn G)).
Proof.
  intros. general induction H; simpl.
  - rewrite H3. rewrite H2 in ×. simpl in ×.
    revert IHrenamedApart H. unfold disj.
    clear_all; cset_tac; intuition; cset_tac; eauto.
  - rewrite H4 in ×. rewrite H5 in ×. simpl in ×.
    rewrite <- H1. rewrite disj_app; eauto.
  - rewrite H0. eauto using disj_empty.
  - rewrite H0. eauto using disj_empty.
  - rewrite H3. rewrite H2 in ×. simpl in ×.
    revert IHrenamedApart H. unfold disj.
    clear_all; cset_tac; intuition; cset_tac; eauto.
  - rewrite <- H1. repeat rewrite disj_app.
    rewrite H3,H5 in *; simpl in *; eauto.
    split. split; eauto. rewrite incl_right; eauto.
    symmetry; eauto.
Qed.