Library Substitutivity

Require Export Omega Coq.Setoids.Setoid List Util AutoIndTac Base Equivalences.

Set Implicit Arguments.
Unset Printing Records.

Require Import Autosubst.

Inversion lemmas for substitution


Fact inv_subst_Eps s sigma
  : s.[sigma] = CFPEps( x, s = CFPVar x sigma x = CFPEps) s = CFPEps.
Proof.
  intros. general induction s.
  - right. reflexivity.
  - left. x. split; eauto.
Qed.

Fact inv_subst_Var s sigma y
  : s.[sigma] = CFPVar y
    → ( x, s = CFPVar x sigma x = CFPVar y).
Proof.
  intros. general induction s.
   x. split; eauto.
Qed.

Fact inv_subst_Seq s t1 t2 sigma
  : s.[sigma] = CFPSeq t1 t2
    → ( x, s = CFPVar x sigma x = CFPSeq t1 t2)
        ( s1 s2, t1 = s1.[sigma] t2 = s2.[sigma] s = CFPSeq s1 s2).
Proof.
  intros. general induction s.
  - right. s1, s2. repeat split; eauto.
  - left. x. split; eauto.
Qed.

Fact inv_subst_Choice s t1 t2 sigma
  : s.[sigma] = CFPChoice t1 t2
    → ( x, s = CFPVar x sigma x = CFPChoice t1 t2)
        ( s1 s2, t1 = s1.[sigma] t2 = s2.[sigma] s = CFPChoice s1 s2).
Proof.
  intros. general induction s.
  - right. s1, s2. repeat split; eauto.
  - left. x. split; eauto.
Qed.

Fact inv_subst_Fix s t sigma
  : s.[sigma] = CFPFix t
    → ( x, s = CFPVar x sigma x = CFPFix t)
        ( s', t = s'.[up sigma] s = CFPFix s').
Proof.
  intros. general induction s.
  - right. s. repeat split; eauto.
  - left. x. split; eauto.
Qed.

Altenative trace predicate for programs under substitution


Inductive TCsubst : cfp → (varcfp) → traceProp :=
| TCsubstPartial s sigma
  : TCsubst s sigma P
| TCsubstTotal sigma
  : TCsubst CFPEps sigma T
| TCsubstVar x xi sigma
  : TC (sigma x) xiTCsubst (CFPVar x) sigma xi
| TCsubstSeq s t xi1 xi2 sigma
  : TCsubst s sigma xi1TCsubst t sigma xi2TCsubst (CFPSeq s t) sigma (concat xi1 xi2)
| TCsubstChoiceLeft s t xi sigma
  : TCsubst s sigma xiTCsubst (CFPChoice s t) sigma xi
| TCsubstChoiceRight s t xi sigma
  : TCsubst t sigma xiTCsubst (CFPChoice s t) sigma xi
| TCsubstFix s xi sigma
  : TCsubst (s.[CFPFix s /]) sigma xiTCsubst (CFPFix s) sigma xi.

Correctness of TCsubst


Lemma TC_TCsubst s sigma xi
  : TC s.[sigma] xiTCsubst s sigma xi.
Proof.
  intros. general induction H; eauto using TCsubst.
  - symmetry in Heqc. apply inv_subst_Eps in Heqc. destruct Heqc as [[x [H1 H2]] | H3].
    + rewrite H1. constructor. rewrite H2. constructor.
    + rewrite H3. constructor.
  - symmetry in Heqc. apply inv_subst_Var in Heqc. destruct Heqc as [y [H1 H2]].
    rewrite H1. constructor. rewrite H2. constructor.
  - symmetry in Heqc. apply inv_subst_Var in Heqc. destruct Heqc as [y [H1 H2]].
    rewrite H1. constructor. rewrite H2. constructor.
  - symmetry in Heqc. apply inv_subst_Seq in Heqc.
    destruct Heqc as [[x [H1 H2]] |[s1 [s2 [H3 [H4 H5]]]]].
    + rewrite H1. constructor. rewrite H2. constructor; eauto.
    + rewrite H5. constructor; eauto.
  - symmetry in Heqc. apply inv_subst_Choice in Heqc.
    destruct Heqc as [[x [H1 H2]] |[s1 [s2 [H3 [H4 H5]]]]].
    + rewrite H1. constructor. rewrite H2. constructor; eauto.
    + rewrite H5. constructor; eauto.
  - symmetry in Heqc. apply inv_subst_Choice in Heqc.
    destruct Heqc as [[x [H1 H2]] |[s1 [s2 [H3 [H4 H5]]]]].
    + rewrite H1. constructor. rewrite H2. constructor 7; eauto.
    + rewrite H5. eauto using TCsubst.
  - symmetry in Heqc. apply inv_subst_Fix in Heqc.
    destruct Heqc as [[x [H1 H2]]| [s' [H3 H4]]].
    + rewrite H1. constructor. rewrite H2. eauto using TC.
    + rewrite H4. constructor. apply IHTC.
      rewrite H3. asimpl. eauto.
Qed.

Lemma TCsubst_TC s sigma xi
  : TCsubst s sigma xiTC s.[sigma] xi.
Proof.
  intros. general induction H; eauto using TC.
  asimpl in IHTCsubst. constructor. asimpl. eauto.
Qed.

Trace substitution


Inductive substT : trace → (varcfp) → traceProp :=
| SubstTT sigma
  : substT T sigma T
| SubstTP sigma
  : substT P sigma P
| SubstTV sigma x xi xi' my
  : TC (sigma x) xi'
    → substT xi sigma my
    → substT (V x xi) sigma (concat xi' my).

Correctness of trace substitution


Fact substT_total xi sigma
  : my, substT xi sigma my.
Proof.
  general induction xi.
  - P. eauto using substT.
  - T. eauto using substT.
  - destruct (IHxi sigma) as [my A].
     (concat P my). constructor; eauto using TC.
Qed.

Fact substT_concat_compose xi1 xi2 my1 my2 sigma
  : substT xi1 sigma my1
    → substT xi2 sigma my2
    → substT (concat xi1 xi2) sigma (concat my1 my2).
Proof.
  intros. general induction H; simpl; eauto using substT.
  rewrite concat_assoc. constructor; eauto.
Qed.

Fact substT_concat_decompose xi1 xi2 my sigma
  : substT (concat xi1 xi2) sigma my
    → my1 my2, substT xi1 sigma my1
                        substT xi2 sigma my2
                        my = concat my1 my2.
Proof.
  general induction xi1; simpl in H.
  - P. inv H.
    destruct (substT_total xi2 sigma) as [my2 A].
     my2.
    repeat split; eauto using substT.
  - simpl in H. T, my.
    split; eauto using substT.
  - simpl in H. inv H.
    specialize (IHxi1 xi2 my0 sigma H5).
    destruct IHxi1 as [my1 [my2 [A [B C]]]].
     (concat xi' my1), my2.
    repeat split; eauto using substT.
    rewrite C. rewrite concat_assoc. eauto.
Qed.

Lemma subst_trace_construct s xi sigma my
  : TC s xisubstT xi sigma myTC s.[sigma] my.
Proof.
  intros. general induction H; asimpl; eauto using TC.
  - inv H0. constructor.
  - inv H0. asimpl. constructor.
  - inv H0. asimpl. inv H5.
    apply trace_concat_P. eauto.
  - inv H0. asimpl. inv H5.
    rewrite <- concat_T_iden_right. eauto.
  - asimpl. apply substT_concat_decompose in H1.
    destruct H1 as [my1 [my2 [A [B C]]]].
    rewrite C. constructor; eauto.
  - asimpl. constructor. asimpl.
    rewrite <- subst_Fix_distribute. eauto.
Qed.

Lemma subst_trace_deconstruct s my sigma
  : TC s.[sigma] my xi, TC s xi substT xi sigma my.
Proof.
  intros. apply TC_TCsubst in H. general induction H.
  - P. split; eauto using TC, substT.
  - T. split; eauto using TC, substT.
  - (V x T). split; eauto using TC.
    rewrite concat_T_iden_right.
    eauto using substT.
  - destruct IHTCsubst1 as [xiA [A1 A2]].
    destruct IHTCsubst2 as [xiB [B1 B2]].
     (concat xiA xiB). split; eauto using TC, substT_concat_compose.
  - destruct IHTCsubst as [xiA [A1 A2]].
     xiA. split; eauto using TC.
  - destruct IHTCsubst as [xiA [A1 A2]].
     xiA. split; eauto using TC.
  - destruct IHTCsubst as [xiA [A1 A2]].
     xiA. split; eauto using TC.
Qed.

Substitutivity of the trace semantics


Lemma subst_tracesubsumption_preserve s t xi sigma
  : ( xi, TC s xiTC t xi) → TC s.[sigma] xiTC t.[sigma] xi.
Proof.
  intros. apply subst_trace_deconstruct in H0.
  destruct H0 as [xi1 [A B]].
  apply H in A.
  apply subst_trace_construct with (xi:= xi1); eauto.
Qed.

Lemma substitutivity1 s t sigma
  : s =T ts.[sigma] =T t.[sigma].
Proof.
  intros. split; intros.
  - apply subst_tracesubsumption_preserve with (s:= s); eauto.
    intros. apply H. eauto.
  - apply subst_tracesubsumption_preserve with (s:= t); eauto.
    intros. apply H. eauto.
Qed.

Lemma subst_subsumption_transfer s sigma1 sigma2 xi
  : ( x xi, TC (sigma1 x) xiTC (sigma2 x) xi)
    → TC s.[sigma1] xiTC s.[sigma2] xi.
Proof.
  intros. apply TC_TCsubst in H0. general induction H0; eauto using TC.
  constructor. asimpl.
  rewrite <- subst_Fix_distribute. eauto.
Qed.

Lemma substitutivity2 s sigma1 sigma2
  : ( x, sigma1 x =T sigma2 x) → s.[sigma1] =T s.[sigma2].
Proof.
  intros. split; intros.
  - apply subst_subsumption_transfer with (sigma1:= sigma1); eauto.
    intros. apply H. eauto.
  - apply subst_subsumption_transfer with (sigma1:= sigma2); eauto.
    intros. apply H. eauto.
Qed.

Theorem substitutivity sigma1 sigma2 s t
  : ( x, sigma1 x =T sigma2 x) → s =T ts.[sigma1] =T t.[sigma2].
Proof.
  intros. rewrite substitutivity2; eauto.
  rewrite substitutivity1; eauto. reflexivity.
Qed.