Library Imp_LangTrick.ProofCompiler.ProofCompilerHelpers
From Coq Require Import String List Peano Arith Program.Equality.
From Imp_LangTrick Require Import StackLogic Imp_LangLogHoare Imp_LangTrickLanguage EnvToStack StackLanguage Imp_LangLogProp LogicProp StackLangTheorems StackLogicBase.
From Imp_LangTrick Require Import LogicTranslationBackwards StackLogicBase TranslationPure LogicTranslationAdequate LogicTrans.
From Imp_LangTrick Require Export ProofSubstitution ImpVarMapTheorems Imp_LangLogSubstAdequate.
From Imp_LangTrick Require Import Imp_LangImpHigherOrderRel ProofCompilerBase Imp_LangHoareWF Imp_LangTrickTactics Imp_LangLogicHelpers LogicPropDec Imp_LangLogPropDec Imp_LangImpHigherOrderRelTheorems.
From Imp_LangTrick Require Import FunctionWellFormed CompilerAssumptionLogicTrans FactEnvTranslator.
From Imp_LangTrick Require Import UIPList.
From Coq.Logic Require Import Eqdep_dec.
Local Open Scope string_scope.
Local Open Scope nat_scope.
Local Open Scope list_scope.
Local Open Scope imp_langtrick_scope.
Definition aimp_always_wf (func_list: list fun_Imp_Lang) (idents: list ident) (num_args: nat) (P: AbsEnv) (i: imp_Imp_Lang) (Q: AbsEnv) (fenv: fun_env) (facts : implication_env) (hl: hl_Imp_Lang P i Q facts fenv): Prop :=
hl_Imp_Lang_wf fenv func_list idents num_args P Q i facts hl.
Ltac inv_aimp_wf :=
match goal with
| [ H: aimp_always_wf ?func_list ?idents ?i |- aimp_always_wf ?func_list ?idents ?i' ] =>
unfold aimp_always_wf in *;
invs H;
eassumption
| [ H: aimp_always_wf ?func_list ?idents ?i |- _ ] =>
unfold aimp_always_wf in *;
invs H
end.
Ltac not_eq := right; intros neq; invs neq.
Lemma imp_Imp_Lang_dec :
forall (i1 i2: imp_Imp_Lang),
{i1 = i2} + {i1 <> i2}.
Proof.
induction i1; induction i2; try (left; reflexivity);
match goal with
| [ |- { ?l = ?r } + { _ } ] =>
match l with
| ?imp_lang_op _ _ _ =>
match r with
| imp_lang_op _ _ _ =>
idtac
| _ =>
not_eq; try discrim_neq
end
| ?imp_lang_op _ _ =>
match r with
| imp_lang_op _ _ =>
idtac
| _ =>
not_eq; try discrim_neq
end
| ?imp_lang_op =>
not_eq; try discrim_neq
end
end.
- pose proof (bexp_Imp_Lang_dec).
specialize (H b b0).
specialize (IHi1_1 i2_1).
specialize (IHi1_2 i2_2).
destruct IHi1_1, IHi1_2, H; try (subst; left; reflexivity); not_eq; try discrim_neq.
- specialize (IHi1 i2).
pose proof (bexp_Imp_Lang_dec).
specialize (H b b0).
destruct IHi1, H; try (subst; left; reflexivity); not_eq; try discrim_neq.
- specialize (string_dec x x0).
specialize (aexp_Imp_Lang_dec a a0).
intros.
destruct H, H0; try (subst; left; reflexivity); not_eq; try discrim_neq.
- specialize (IHi1_1 i2_1).
specialize (IHi1_2 i2_2).
destruct IHi1_1, IHi1_2; try (subst; left; reflexivity); not_eq; try discrim_neq.
Qed.
Lemma UIP_refl_bexp :
forall b: bexp_Imp_Lang,
forall H: b = b,
H = eq_refl.
Proof.
intros. symmetry. exact (@UIP_dec _ bexp_Imp_Lang_dec b b eq_refl H).
Qed.
Lemma UIP_imp_refl :
forall (i: imp_Imp_Lang)
(p: i = i),
p = eq_refl.
Proof.
intros. symmetry. exact (@UIP_dec _ imp_Imp_Lang_dec i i eq_refl p).
Qed.
From Imp_LangTrick Require Import StackLogic Imp_LangLogHoare Imp_LangTrickLanguage EnvToStack StackLanguage Imp_LangLogProp LogicProp StackLangTheorems StackLogicBase.
From Imp_LangTrick Require Import LogicTranslationBackwards StackLogicBase TranslationPure LogicTranslationAdequate LogicTrans.
From Imp_LangTrick Require Export ProofSubstitution ImpVarMapTheorems Imp_LangLogSubstAdequate.
From Imp_LangTrick Require Import Imp_LangImpHigherOrderRel ProofCompilerBase Imp_LangHoareWF Imp_LangTrickTactics Imp_LangLogicHelpers LogicPropDec Imp_LangLogPropDec Imp_LangImpHigherOrderRelTheorems.
From Imp_LangTrick Require Import FunctionWellFormed CompilerAssumptionLogicTrans FactEnvTranslator.
From Imp_LangTrick Require Import UIPList.
From Coq.Logic Require Import Eqdep_dec.
Local Open Scope string_scope.
Local Open Scope nat_scope.
Local Open Scope list_scope.
Local Open Scope imp_langtrick_scope.
Definition aimp_always_wf (func_list: list fun_Imp_Lang) (idents: list ident) (num_args: nat) (P: AbsEnv) (i: imp_Imp_Lang) (Q: AbsEnv) (fenv: fun_env) (facts : implication_env) (hl: hl_Imp_Lang P i Q facts fenv): Prop :=
hl_Imp_Lang_wf fenv func_list idents num_args P Q i facts hl.
Ltac inv_aimp_wf :=
match goal with
| [ H: aimp_always_wf ?func_list ?idents ?i |- aimp_always_wf ?func_list ?idents ?i' ] =>
unfold aimp_always_wf in *;
invs H;
eassumption
| [ H: aimp_always_wf ?func_list ?idents ?i |- _ ] =>
unfold aimp_always_wf in *;
invs H
end.
Ltac not_eq := right; intros neq; invs neq.
Lemma imp_Imp_Lang_dec :
forall (i1 i2: imp_Imp_Lang),
{i1 = i2} + {i1 <> i2}.
Proof.
induction i1; induction i2; try (left; reflexivity);
match goal with
| [ |- { ?l = ?r } + { _ } ] =>
match l with
| ?imp_lang_op _ _ _ =>
match r with
| imp_lang_op _ _ _ =>
idtac
| _ =>
not_eq; try discrim_neq
end
| ?imp_lang_op _ _ =>
match r with
| imp_lang_op _ _ =>
idtac
| _ =>
not_eq; try discrim_neq
end
| ?imp_lang_op =>
not_eq; try discrim_neq
end
end.
- pose proof (bexp_Imp_Lang_dec).
specialize (H b b0).
specialize (IHi1_1 i2_1).
specialize (IHi1_2 i2_2).
destruct IHi1_1, IHi1_2, H; try (subst; left; reflexivity); not_eq; try discrim_neq.
- specialize (IHi1 i2).
pose proof (bexp_Imp_Lang_dec).
specialize (H b b0).
destruct IHi1, H; try (subst; left; reflexivity); not_eq; try discrim_neq.
- specialize (string_dec x x0).
specialize (aexp_Imp_Lang_dec a a0).
intros.
destruct H, H0; try (subst; left; reflexivity); not_eq; try discrim_neq.
- specialize (IHi1_1 i2_1).
specialize (IHi1_2 i2_2).
destruct IHi1_1, IHi1_2; try (subst; left; reflexivity); not_eq; try discrim_neq.
Qed.
Lemma UIP_refl_bexp :
forall b: bexp_Imp_Lang,
forall H: b = b,
H = eq_refl.
Proof.
intros. symmetry. exact (@UIP_dec _ bexp_Imp_Lang_dec b b eq_refl H).
Qed.
Lemma UIP_imp_refl :
forall (i: imp_Imp_Lang)
(p: i = i),
p = eq_refl.
Proof.
intros. symmetry. exact (@UIP_dec _ imp_Imp_Lang_dec i i eq_refl p).
Qed.
There is only ever one fenv that we are using.
Axiom UIP_fun_env_refl :
forall (fenv: fun_env)
(p: fenv = fenv),
p = eq_refl.
Local Open Scope type_scope.
Lemma UIP_aexp_refl :
forall (a: aexp_Imp_Lang)
(p: a = a),
p = eq_refl.
Proof.
intros. symmetry. exact (@UIP_dec _ aexp_Imp_Lang_dec a a eq_refl p).
Qed.
Lemma UIP_fact_env :
forall (fact_env: implication_env)
(eq1 eq2: fact_env = fact_env),
eq1 = eq2.
Proof.
unfold implication_env. intros fact_env. apply UIP_to_list.
apply UIP_to_pair. unfold UIP. apply UIP_AbsEnv.
Qed.
Lemma UIP_fact_env_refl :
forall (fact_env: implication_env)
(eq: fact_env = fact_env),
eq = eq_refl.
Proof.
intros.
pose proof (UIP_AbsEnv).
exact (UIP_fact_env fact_env eq (@eq_refl _ fact_env)).
Qed.
Ltac inversion_sigma_helper H :=
let Heq := fresh "Heq" in
let Heq_rect := fresh "Heq_rect" in
inversion_sigma_on_as H ipattern:([Heq Heq_rect ]);
match goal with
| [ H' : ?l = ?l |- _ ] =>
match H' with
| Heq =>
let ltype := type of l in
match ltype with
| AbsEnv =>
specialize (UIP_AbsEnv_refl _ Heq)
| imp_Imp_Lang =>
specialize (UIP_imp_refl _ Heq)
| bexp_Imp_Lang =>
specialize (UIP_refl_bexp _ Heq)
| aexp_Imp_Lang =>
specialize (UIP_aexp_refl _ Heq)
| fun_env =>
specialize (UIP_fun_env_refl _ Heq)
| implication_env =>
specialize (UIP_fact_env_refl _ Heq)
end;
intros; subst;
simpl in *;
try (inversion_sigma_helper Heq_rect)
| _ =>
fail
end
end.
Ltac invs_aimpwf_helper H :=
let Htype := type of H in
match Htype with
| aimp_always_wf _ _ _ _ _ _ _ =>
unfold aimp_always_wf in H
| _ =>
idtac
end;
invs H;
try match goal with
| [ H' : ?l = ?r |- _ ] =>
let ltype := type of l in
match ltype with
| imp_Imp_Lang =>
match l with
| ?imp_lang_op _ _ _ =>
match r with
| imp_lang_op _ _ _ =>
idtac
| _ =>
invs H'
end
| ?imp_lang_op _ _ =>
match r with
| imp_lang_op _ _ =>
idtac
| _ =>
invs H'
end
| ?imp_lang_op =>
invs H'
end
| _ =>
fail 1
end
end;
try match goal with
| [ H' : ?p = @eq_rect ?a _ _ _ ?b ?Heq |- _ ] =>
invs Heq
;
specialize (UIP_imp_refl _ Heq) || specialize (UIP_AbsEnv_refl _ Heq)
;
intros; subst; simpl in *;
try match goal with
| [ H'' : ?p = @eq_rect ?a _ _ _ ?b ?Heq' |- _ ] =>
invs Heq'
;
specialize (UIP_imp_refl _ Heq') || specialize (UIP_AbsEnv_refl _ Heq')
;
intros; subst; simpl in *
end;
invs H';
try match goal with
| [ H' : existT _ _ _ = existT _ _ _ |- _ ] =>
inversion_sigma_helper H'
end;
try match goal with
| [ H' : existT _ _ _ = existT _ _ _ |- _ ] =>
inversion_sigma_helper H'
end
| [ H' : _ =
hl_Imp_Lang_consequence_pre ?P0 ?Q0 ?P ?Q ?i ?fenv ?hl ?aimp1 ?aimp2 ?last |- _ ] =>
invs H'
| [ H' : _ =
hl_Imp_Lang_consequence_post ?P0 ?Q0 ?P ?Q ?i ?fenv ?hl ?aimp1 ?aimp2 ?last |- _ ] =>
invs H'
end;
simpl in H.
Ltac invs_aimpwf_test :=
match goal with
| [ H' : ?l = ?r |- _ ] =>
let ltype := type of l in
match ltype with
| imp_Imp_Lang =>
match l with
| ?imp_lang_op _ _ _ =>
match r with
| imp_lang_op _ _ _ =>
idtac
| _ =>
invs H'
end
| ?imp_lang_op _ _ =>
match r with
| imp_lang_op _ _ =>
idtac
| _ =>
invs H'
end
| ?imp_lang_op =>
invs H'
end
| _ => idtac ltype; fail 1
end
end.
Lemma imp_lang_log_prop_rel_preserved_by_hl_imp_lang_post :
forall (P: AbsEnv) (i: imp_Imp_Lang) (R: AbsEnv) (func_list: list fun_Imp_Lang) (idents: list ident) (num_args: nat) (fenv: fun_env) (facts : implication_env),
forall (H: hl_Imp_Lang P i R facts fenv),
aimp_always_wf func_list idents num_args P i R fenv facts H ->
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) R.
Proof.
intros.
invs_aimpwf_helper H0; try eassumption.
unfold AbsEnv_prop_wf in H3.
unfold afalseImp_Lang.
invs H2.
invs H10.
destruct H1.
invs H1.
econstructor. eassumption. econstructor. econstructor. econstructor. eassumption.
Qed.
Lemma fun_app_well_formed_preserved_by_imp_lang_aexp_update (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(a : aexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUNassign : fun_app_imp_well_formed fenv func_list (x <- a1))
(WF' : var_map_wf_wrt_imp idents (x <- a1))
(WF : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(WFupdate : var_map_wf_wrt_aexp idents (imp_lang_aexp_update x a1 a))
(WFa : var_map_wf_wrt_aexp idents a)
(FUNa : fun_app_well_formed fenv func_list a),
fun_app_well_formed fenv func_list (imp_lang_aexp_update x a1 a).
Proof.
induction a using aexp_Imp_Lang_ind2; intros.
- simpl. constructor.
- simpl. invs FUNassign.
destruct (eqb x x0); assumption.
- simpl. assumption.
- simpl. invs FUNa. invs FUNassign. eapply var_map_wf_plus_imp_lang_forwards in WFa. destruct WFa. simpl in WFupdate.
eapply var_map_wf_plus_imp_lang_forwards in WFupdate.
destruct WFupdate as (WFupdate1 & WFupdate2).
constructor; eauto.
- simpl. invs FUNa. invs FUNassign. eapply var_map_wf_minus_imp_lang_forwards in WFa. destruct WFa. simpl in WFupdate.
eapply var_map_wf_minus_imp_lang_forwards in WFupdate.
destruct WFupdate as (WFupdate1 & WFupdate2).
constructor; eauto.
- invc FUNa. eapply var_map_wf_app_imp_lang_args_all in WFa. simpl in WFupdate.
eapply var_map_wf_app_imp_lang_args_all in WFupdate.
simpl. econstructor; eauto.
clear H5.
revert H2. revert WFa. revert WFupdate. induction H; intros.
+ simpl. econstructor; eauto.
+ simpl. simpl in WFupdate. invs WFupdate. invs WFa. invs H2.
econstructor; eauto.
+ rewrite map_length. assumption.
Qed.
Lemma fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(b : bexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WFassign : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(FUNb : fun_app_bexp_well_formed fenv func_list b)
(WFb : var_map_wf_wrt_bexp idents b)
(WFupdate : var_map_wf_wrt_bexp idents (imp_lang_bexp_update x a1 b)),
fun_app_bexp_well_formed fenv func_list (imp_lang_bexp_update x a1 b).
Proof.
induction b; intros; simpl; invs FUN_APP.
- constructor.
- constructor.
- simpl in *. eapply var_map_wf_neg_imp_lang in WFupdate; eauto.
eapply var_map_wf_neg_imp_lang in WFb; eauto.
econstructor. eapply IHb; eauto. invs FUNb. assumption.
- simpl in *. eapply var_map_wf_and_or_imp_lang_forwards in WFupdate; eauto. destruct WFupdate as (WFupdate1 & WFupdate2).
eapply var_map_wf_and_or_imp_lang_forwards in WFb; eauto. destruct WFb as (WFb1 & WFb2).
invc FUNb. rename H4 into FUNb1. rename H5 into FUNb2.
econstructor; eauto.
- simpl in *. eapply var_map_wf_and_or_imp_lang_forwards in WFupdate; eauto. destruct WFupdate as (WFupdate1 & WFupdate2).
eapply var_map_wf_and_or_imp_lang_forwards in WFb; eauto. destruct WFb as (WFb1 & WFb2).
invc FUNb. rename H4 into FUNb1. rename H5 into FUNb2.
econstructor; eauto.
- simpl in *. eapply var_map_wf_leq_imp_lang_forwards in WFupdate; eauto. destruct WFupdate as (WFupdate1 & WFupdate2).
eapply var_map_wf_leq_imp_lang_forwards in WFb; eauto. destruct WFb as (WFb1 & WFb2).
invc FUNb. rename H4 into FUNb1. rename H5 into FUNb2.
invs WFassign.
econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
Qed.
Lemma lp_aexp_fun_app_well_formed_preserved_by_transformation (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(l1: LogicProp nat aexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WF' : var_map_wf_wrt_imp idents (x <- a1))
(WF : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(H5 : prop_rel (var_map_wf_wrt_aexp idents)
(transform_prop_exprs l1
(fun a : aexp_Imp_Lang => imp_lang_aexp_update x a1 a)))
(H3 : prop_rel (var_map_wf_wrt_aexp idents) l1)
(H2 : prop_rel (fun_app_well_formed fenv func_list) l1),
prop_rel (fun_app_well_formed fenv func_list)
(transform_prop_exprs l1 (fun a : aexp_Imp_Lang => imp_lang_aexp_update x a1 a)).
Proof.
induction l1; intros.
- constructor.
- constructor.
- invc H5. invc H3. invc H2. invs FUN_APP.
constructor.
eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
- invc H5. invc H3. invc H2. invs FUN_APP. econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
- invc H5. invc H3. invc H2.
simpl. constructor; eauto.
- invc H5. invc H3. invc H2.
simpl. constructor; eauto.
- invc H5. invc H3. invc H2. invs FUN_APP. econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
- invc H5. invc H3. invc H2. econstructor. invs FUN_APP.
revert H5. revert H3. revert H4. revert H1.
induction a_list; intros.
+ constructor.
+ invc H1. invc H4. invc H3.
constructor; eauto.
eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
Qed.
Lemma lp_bexp_fun_app_bexp_well_formed_preserved_by_transformation (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(l1 : LogicProp bool bexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WFassign : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(H2 : prop_rel (var_map_wf_wrt_bexp idents) l1)
(H4 : prop_rel (var_map_wf_wrt_bexp idents)
(transform_prop_exprs l1
(fun b : bexp_Imp_Lang => imp_lang_bexp_update x a1 b)))
(H6 : prop_rel (fun_app_bexp_well_formed fenv func_list) l1),
prop_rel (fun_app_bexp_well_formed fenv func_list)
(transform_prop_exprs l1 (fun b : bexp_Imp_Lang => imp_lang_bexp_update x a1 b)).
Proof.
induction l1; intros; invc H2; invc H4; invc H6.
- constructor.
- constructor.
- constructor. eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- constructor; eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- constructor; eauto.
- constructor; eauto.
- constructor; eauto.
all: eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- constructor. revert H3. revert H2. revert H1. induction a_list; intros.
+ constructor.
+ invc H1. invc H2. invc H3. constructor; eauto.
eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
Qed.
Lemma lp_aexp_wf_preserved_by_AbsEnv_subst (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(l : LogicProp nat aexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WF' : var_map_wf_wrt_imp idents (x <- a1))
(WF : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(H5 : lp_Imp_Lang_wf func_list fenv (Imp_Lang_lp_arith l))
(H3 : prop_rel (var_map_wf_wrt_aexp idents)
(transform_prop_exprs l
(fun a : aexp_Imp_Lang => imp_lang_aexp_update x a1 a)))
(H2 : prop_rel (var_map_wf_wrt_aexp idents) l),
lp_Imp_Lang_wf func_list fenv
(Imp_LangLogSubst.subst_Imp_Lang_lp x a1 (Imp_Lang_lp_arith l)).
Proof.
induction l; intros; econstructor; invc H5.
- econstructor.
- econstructor.
- econstructor. invc H3. invc H2. invc H4.
eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eassumption.
- simpl.
invc H3. invc H2. invc H4. econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eassumption.
- simpl. invc H3. invc H2. invc H4.
econstructor; eauto; eapply lp_aexp_fun_app_well_formed_preserved_by_transformation; eauto.
- simpl. invc H3. invc H2. invc H4.
econstructor; eauto; eapply lp_aexp_fun_app_well_formed_preserved_by_transformation; eauto.
- simpl.
invc H3. invc H2. invc H4. econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eassumption.
- invc H3. invc H2. invc H4. revert H1 H3 H2.
constructor.
induction a_list; intros.
+ constructor.
+ invc H1. invc H2. invc H3. simpl. constructor.
* eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
* eapply IHa_list; eauto.
Qed.
Lemma lp_bexp_wf_preserved_by_AbsEnv_subst (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(l : LogicProp bool bexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(n_args : nat)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WFassign : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(WFlp : lp_bool_wf func_list fenv l)
(WFupdate : prop_rel (var_map_wf_wrt_bexp idents)
(transform_prop_exprs l
(fun b : bexp_Imp_Lang => imp_lang_bexp_update x a1 b)))
(WF : prop_rel (var_map_wf_wrt_bexp idents) l),
lp_Imp_Lang_wf func_list fenv (Imp_LangLogSubst.subst_Imp_Lang_lp x a1 (Imp_Lang_lp_bool l)).
Proof.
induction l; intros; constructor.
- constructor.
- constructor.
- constructor.
invc WFlp. invc WF. invc WFupdate.
rename a into b.
eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- invc WFlp. invc WFupdate. invc WF.
constructor; eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- invc WF. invc WFupdate. invc WFlp. simpl. econstructor; eauto.
eapply lp_bexp_fun_app_bexp_well_formed_preserved_by_transformation; eassumption.
eapply lp_bexp_fun_app_bexp_well_formed_preserved_by_transformation; eassumption.
- invc WFlp. invc WF. invc WFupdate. simpl. constructor; eauto.
all: eapply lp_bexp_fun_app_bexp_well_formed_preserved_by_transformation; eassumption.
- invc WFlp. invc WFupdate. invc WF.
constructor; eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- econstructor. invc WF. invc WFlp. invc WFupdate. revert H1 H2 H3.
induction a_list; intros.
+ constructor.
+ invc H1. invc H2. invc H3.
simpl; constructor.
* eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
* eapply IHa_list; eauto.
Qed.
Lemma inv_aimpwf_consequence_pre :
forall func_list idents n_args P Q P' c fenv n facts hl a imp,
aimp_always_wf func_list idents n_args P' c Q fenv facts (hl_Imp_Lang_consequence_pre P Q P' c n facts fenv hl a imp) ->
log_Imp_Lang_wf func_list fenv P /\ log_Imp_Lang_wf func_list fenv Q /\
log_Imp_Lang_wf func_list fenv P' /\
log_Imp_Lang_wf_map idents Q /\
log_Imp_Lang_wf_map idents P /\ log_Imp_Lang_wf_map idents P' /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) P /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) Q /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) P' /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) P /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) Q /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) P' /\
imp_rec_rel (var_map_wf_wrt_imp idents) c /\
hl_Imp_Lang_wf fenv func_list idents n_args P Q c facts hl.
Proof.
intros. invs H; invs H0. inversion_sigma_helper H18. intuition.
Qed.
Lemma inv_aimpwf_consequence_post :
forall func_list idents n_args P Q Q' c fenv n facts hl a imp,
aimp_always_wf func_list idents n_args P c Q' fenv facts (hl_Imp_Lang_consequence_post P Q Q' c n facts fenv hl a imp) ->
log_Imp_Lang_wf func_list fenv P /\ log_Imp_Lang_wf func_list fenv Q /\
log_Imp_Lang_wf func_list fenv Q' /\
log_Imp_Lang_wf_map idents P /\
log_Imp_Lang_wf_map idents Q /\ log_Imp_Lang_wf_map idents Q' /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) P /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) Q /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) Q' /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) P /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) Q /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) Q' /\
imp_rec_rel (var_map_wf_wrt_imp idents) c /\
hl_Imp_Lang_wf fenv func_list idents n_args P Q c facts hl.
Proof.
intros. invs H; invs H0. inversion_sigma_helper H18. subst. intuition.
Qed.
Lemma inv_aimpwf_seq:
forall i1 i2 P Q R funcs map args facts fenv hl1 hl2,
aimp_always_wf funcs map args P (i1;; i2) Q fenv facts (hl_Imp_Lang_seq P Q R facts fenv i1 i2 hl1 hl2) ->
aimp_always_wf funcs map args P i1 R fenv facts hl1 /\
aimp_always_wf funcs map args R i2 Q fenv facts hl2 /\
AbsEnv_prop_wf map R.
Proof.
intros. unfold aimp_always_wf in H. inversion H.
- inversion HSkip.
- inversion Heq.
- invs Heq. specialize (UIP_imp_refl _ Heq).
intros. subst. simpl in *. invs H0.
inversion_sigma_helper H18.
inversion_sigma_helper H19.
unfold aimp_always_wf. split; try split; try split; assumption.
- inversion heq.
- inversion Heq.
- inversion H0.
- inversion H0.
Qed.
Lemma inv_aimpwf_if:
forall i1 i2 P Q b facts fenv n_args idents func_list hl1 hl2,
aimp_always_wf func_list idents n_args P (when b then i1 else i2 done) Q fenv facts (hl_Imp_Lang_if P Q b i1 i2 facts fenv hl1 hl2) ->
aimp_always_wf func_list idents n_args (atrueImp_Lang b P) i1 Q fenv facts hl1 /\
aimp_always_wf func_list idents n_args (afalseImp_Lang b P) i2 Q fenv facts hl2.
Proof.
intros. unfold aimp_always_wf in H. inversion H.
- inversion HSkip.
- inversion Heq.
- inversion Heq.
- invs heq. specialize (UIP_imp_refl _ heq).
intros. subst. simpl in *. invs H0.
inversion_sigma_helper H13.
inversion_sigma_helper H14.
unfold aimp_always_wf. split; assumption.
- inversion Heq.
- inversion H0.
- inversion H0.
Qed.
Lemma inv_fun_app_when:
forall i1 i2 b fenv func_list,
fun_app_imp_well_formed fenv func_list (when b then i1 else i2 done) ->
fun_app_bexp_well_formed fenv func_list b /\ fun_app_imp_well_formed fenv func_list i1 /\ fun_app_imp_well_formed fenv func_list i2.
Proof.
intros. invs H. intuition.
Qed.
Lemma inv_imp_rec_rel_when : forall b idents i1 i2,
imp_rec_rel (var_map_wf_wrt_imp idents) (when b then i1 else i2 done) ->
imp_rec_rel (var_map_wf_wrt_imp idents) i1 /\ imp_rec_rel (var_map_wf_wrt_imp idents) i2 /\ var_map_wf_wrt_imp idents (when b then i1 else i2 done).
Proof.
intros. invs H. intuition.
Qed.
forall (fenv: fun_env)
(p: fenv = fenv),
p = eq_refl.
Local Open Scope type_scope.
Lemma UIP_aexp_refl :
forall (a: aexp_Imp_Lang)
(p: a = a),
p = eq_refl.
Proof.
intros. symmetry. exact (@UIP_dec _ aexp_Imp_Lang_dec a a eq_refl p).
Qed.
Lemma UIP_fact_env :
forall (fact_env: implication_env)
(eq1 eq2: fact_env = fact_env),
eq1 = eq2.
Proof.
unfold implication_env. intros fact_env. apply UIP_to_list.
apply UIP_to_pair. unfold UIP. apply UIP_AbsEnv.
Qed.
Lemma UIP_fact_env_refl :
forall (fact_env: implication_env)
(eq: fact_env = fact_env),
eq = eq_refl.
Proof.
intros.
pose proof (UIP_AbsEnv).
exact (UIP_fact_env fact_env eq (@eq_refl _ fact_env)).
Qed.
Ltac inversion_sigma_helper H :=
let Heq := fresh "Heq" in
let Heq_rect := fresh "Heq_rect" in
inversion_sigma_on_as H ipattern:([Heq Heq_rect ]);
match goal with
| [ H' : ?l = ?l |- _ ] =>
match H' with
| Heq =>
let ltype := type of l in
match ltype with
| AbsEnv =>
specialize (UIP_AbsEnv_refl _ Heq)
| imp_Imp_Lang =>
specialize (UIP_imp_refl _ Heq)
| bexp_Imp_Lang =>
specialize (UIP_refl_bexp _ Heq)
| aexp_Imp_Lang =>
specialize (UIP_aexp_refl _ Heq)
| fun_env =>
specialize (UIP_fun_env_refl _ Heq)
| implication_env =>
specialize (UIP_fact_env_refl _ Heq)
end;
intros; subst;
simpl in *;
try (inversion_sigma_helper Heq_rect)
| _ =>
fail
end
end.
Ltac invs_aimpwf_helper H :=
let Htype := type of H in
match Htype with
| aimp_always_wf _ _ _ _ _ _ _ =>
unfold aimp_always_wf in H
| _ =>
idtac
end;
invs H;
try match goal with
| [ H' : ?l = ?r |- _ ] =>
let ltype := type of l in
match ltype with
| imp_Imp_Lang =>
match l with
| ?imp_lang_op _ _ _ =>
match r with
| imp_lang_op _ _ _ =>
idtac
| _ =>
invs H'
end
| ?imp_lang_op _ _ =>
match r with
| imp_lang_op _ _ =>
idtac
| _ =>
invs H'
end
| ?imp_lang_op =>
invs H'
end
| _ =>
fail 1
end
end;
try match goal with
| [ H' : ?p = @eq_rect ?a _ _ _ ?b ?Heq |- _ ] =>
invs Heq
;
specialize (UIP_imp_refl _ Heq) || specialize (UIP_AbsEnv_refl _ Heq)
;
intros; subst; simpl in *;
try match goal with
| [ H'' : ?p = @eq_rect ?a _ _ _ ?b ?Heq' |- _ ] =>
invs Heq'
;
specialize (UIP_imp_refl _ Heq') || specialize (UIP_AbsEnv_refl _ Heq')
;
intros; subst; simpl in *
end;
invs H';
try match goal with
| [ H' : existT _ _ _ = existT _ _ _ |- _ ] =>
inversion_sigma_helper H'
end;
try match goal with
| [ H' : existT _ _ _ = existT _ _ _ |- _ ] =>
inversion_sigma_helper H'
end
| [ H' : _ =
hl_Imp_Lang_consequence_pre ?P0 ?Q0 ?P ?Q ?i ?fenv ?hl ?aimp1 ?aimp2 ?last |- _ ] =>
invs H'
| [ H' : _ =
hl_Imp_Lang_consequence_post ?P0 ?Q0 ?P ?Q ?i ?fenv ?hl ?aimp1 ?aimp2 ?last |- _ ] =>
invs H'
end;
simpl in H.
Ltac invs_aimpwf_test :=
match goal with
| [ H' : ?l = ?r |- _ ] =>
let ltype := type of l in
match ltype with
| imp_Imp_Lang =>
match l with
| ?imp_lang_op _ _ _ =>
match r with
| imp_lang_op _ _ _ =>
idtac
| _ =>
invs H'
end
| ?imp_lang_op _ _ =>
match r with
| imp_lang_op _ _ =>
idtac
| _ =>
invs H'
end
| ?imp_lang_op =>
invs H'
end
| _ => idtac ltype; fail 1
end
end.
Lemma imp_lang_log_prop_rel_preserved_by_hl_imp_lang_post :
forall (P: AbsEnv) (i: imp_Imp_Lang) (R: AbsEnv) (func_list: list fun_Imp_Lang) (idents: list ident) (num_args: nat) (fenv: fun_env) (facts : implication_env),
forall (H: hl_Imp_Lang P i R facts fenv),
aimp_always_wf func_list idents num_args P i R fenv facts H ->
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) R.
Proof.
intros.
invs_aimpwf_helper H0; try eassumption.
unfold AbsEnv_prop_wf in H3.
unfold afalseImp_Lang.
invs H2.
invs H10.
destruct H1.
invs H1.
econstructor. eassumption. econstructor. econstructor. econstructor. eassumption.
Qed.
Lemma fun_app_well_formed_preserved_by_imp_lang_aexp_update (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(a : aexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUNassign : fun_app_imp_well_formed fenv func_list (x <- a1))
(WF' : var_map_wf_wrt_imp idents (x <- a1))
(WF : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(WFupdate : var_map_wf_wrt_aexp idents (imp_lang_aexp_update x a1 a))
(WFa : var_map_wf_wrt_aexp idents a)
(FUNa : fun_app_well_formed fenv func_list a),
fun_app_well_formed fenv func_list (imp_lang_aexp_update x a1 a).
Proof.
induction a using aexp_Imp_Lang_ind2; intros.
- simpl. constructor.
- simpl. invs FUNassign.
destruct (eqb x x0); assumption.
- simpl. assumption.
- simpl. invs FUNa. invs FUNassign. eapply var_map_wf_plus_imp_lang_forwards in WFa. destruct WFa. simpl in WFupdate.
eapply var_map_wf_plus_imp_lang_forwards in WFupdate.
destruct WFupdate as (WFupdate1 & WFupdate2).
constructor; eauto.
- simpl. invs FUNa. invs FUNassign. eapply var_map_wf_minus_imp_lang_forwards in WFa. destruct WFa. simpl in WFupdate.
eapply var_map_wf_minus_imp_lang_forwards in WFupdate.
destruct WFupdate as (WFupdate1 & WFupdate2).
constructor; eauto.
- invc FUNa. eapply var_map_wf_app_imp_lang_args_all in WFa. simpl in WFupdate.
eapply var_map_wf_app_imp_lang_args_all in WFupdate.
simpl. econstructor; eauto.
clear H5.
revert H2. revert WFa. revert WFupdate. induction H; intros.
+ simpl. econstructor; eauto.
+ simpl. simpl in WFupdate. invs WFupdate. invs WFa. invs H2.
econstructor; eauto.
+ rewrite map_length. assumption.
Qed.
Lemma fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(b : bexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WFassign : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(FUNb : fun_app_bexp_well_formed fenv func_list b)
(WFb : var_map_wf_wrt_bexp idents b)
(WFupdate : var_map_wf_wrt_bexp idents (imp_lang_bexp_update x a1 b)),
fun_app_bexp_well_formed fenv func_list (imp_lang_bexp_update x a1 b).
Proof.
induction b; intros; simpl; invs FUN_APP.
- constructor.
- constructor.
- simpl in *. eapply var_map_wf_neg_imp_lang in WFupdate; eauto.
eapply var_map_wf_neg_imp_lang in WFb; eauto.
econstructor. eapply IHb; eauto. invs FUNb. assumption.
- simpl in *. eapply var_map_wf_and_or_imp_lang_forwards in WFupdate; eauto. destruct WFupdate as (WFupdate1 & WFupdate2).
eapply var_map_wf_and_or_imp_lang_forwards in WFb; eauto. destruct WFb as (WFb1 & WFb2).
invc FUNb. rename H4 into FUNb1. rename H5 into FUNb2.
econstructor; eauto.
- simpl in *. eapply var_map_wf_and_or_imp_lang_forwards in WFupdate; eauto. destruct WFupdate as (WFupdate1 & WFupdate2).
eapply var_map_wf_and_or_imp_lang_forwards in WFb; eauto. destruct WFb as (WFb1 & WFb2).
invc FUNb. rename H4 into FUNb1. rename H5 into FUNb2.
econstructor; eauto.
- simpl in *. eapply var_map_wf_leq_imp_lang_forwards in WFupdate; eauto. destruct WFupdate as (WFupdate1 & WFupdate2).
eapply var_map_wf_leq_imp_lang_forwards in WFb; eauto. destruct WFb as (WFb1 & WFb2).
invc FUNb. rename H4 into FUNb1. rename H5 into FUNb2.
invs WFassign.
econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
Qed.
Lemma lp_aexp_fun_app_well_formed_preserved_by_transformation (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(l1: LogicProp nat aexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WF' : var_map_wf_wrt_imp idents (x <- a1))
(WF : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(H5 : prop_rel (var_map_wf_wrt_aexp idents)
(transform_prop_exprs l1
(fun a : aexp_Imp_Lang => imp_lang_aexp_update x a1 a)))
(H3 : prop_rel (var_map_wf_wrt_aexp idents) l1)
(H2 : prop_rel (fun_app_well_formed fenv func_list) l1),
prop_rel (fun_app_well_formed fenv func_list)
(transform_prop_exprs l1 (fun a : aexp_Imp_Lang => imp_lang_aexp_update x a1 a)).
Proof.
induction l1; intros.
- constructor.
- constructor.
- invc H5. invc H3. invc H2. invs FUN_APP.
constructor.
eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
- invc H5. invc H3. invc H2. invs FUN_APP. econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
- invc H5. invc H3. invc H2.
simpl. constructor; eauto.
- invc H5. invc H3. invc H2.
simpl. constructor; eauto.
- invc H5. invc H3. invc H2. invs FUN_APP. econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
- invc H5. invc H3. invc H2. econstructor. invs FUN_APP.
revert H5. revert H3. revert H4. revert H1.
induction a_list; intros.
+ constructor.
+ invc H1. invc H4. invc H3.
constructor; eauto.
eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
Qed.
Lemma lp_bexp_fun_app_bexp_well_formed_preserved_by_transformation (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(l1 : LogicProp bool bexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WFassign : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(H2 : prop_rel (var_map_wf_wrt_bexp idents) l1)
(H4 : prop_rel (var_map_wf_wrt_bexp idents)
(transform_prop_exprs l1
(fun b : bexp_Imp_Lang => imp_lang_bexp_update x a1 b)))
(H6 : prop_rel (fun_app_bexp_well_formed fenv func_list) l1),
prop_rel (fun_app_bexp_well_formed fenv func_list)
(transform_prop_exprs l1 (fun b : bexp_Imp_Lang => imp_lang_bexp_update x a1 b)).
Proof.
induction l1; intros; invc H2; invc H4; invc H6.
- constructor.
- constructor.
- constructor. eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- constructor; eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- constructor; eauto.
- constructor; eauto.
- constructor; eauto.
all: eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- constructor. revert H3. revert H2. revert H1. induction a_list; intros.
+ constructor.
+ invc H1. invc H2. invc H3. constructor; eauto.
eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
Qed.
Lemma lp_aexp_wf_preserved_by_AbsEnv_subst (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(l : LogicProp nat aexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WF' : var_map_wf_wrt_imp idents (x <- a1))
(WF : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(H5 : lp_Imp_Lang_wf func_list fenv (Imp_Lang_lp_arith l))
(H3 : prop_rel (var_map_wf_wrt_aexp idents)
(transform_prop_exprs l
(fun a : aexp_Imp_Lang => imp_lang_aexp_update x a1 a)))
(H2 : prop_rel (var_map_wf_wrt_aexp idents) l),
lp_Imp_Lang_wf func_list fenv
(Imp_LangLogSubst.subst_Imp_Lang_lp x a1 (Imp_Lang_lp_arith l)).
Proof.
induction l; intros; econstructor; invc H5.
- econstructor.
- econstructor.
- econstructor. invc H3. invc H2. invc H4.
eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eassumption.
- simpl.
invc H3. invc H2. invc H4. econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eassumption.
- simpl. invc H3. invc H2. invc H4.
econstructor; eauto; eapply lp_aexp_fun_app_well_formed_preserved_by_transformation; eauto.
- simpl. invc H3. invc H2. invc H4.
econstructor; eauto; eapply lp_aexp_fun_app_well_formed_preserved_by_transformation; eauto.
- simpl.
invc H3. invc H2. invc H4. econstructor; eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eassumption.
- invc H3. invc H2. invc H4. revert H1 H3 H2.
constructor.
induction a_list; intros.
+ constructor.
+ invc H1. invc H2. invc H3. simpl. constructor.
* eapply fun_app_well_formed_preserved_by_imp_lang_aexp_update; eauto.
* eapply IHa_list; eauto.
Qed.
Lemma lp_bexp_wf_preserved_by_AbsEnv_subst (fenv : fun_env)
(func_list : list fun_Imp_Lang)
(l : LogicProp bool bexp_Imp_Lang):
forall (x : ident)
(a1 : aexp_Imp_Lang)
(idents : list ident)
(n_args : nat)
(FUN_APP : fun_app_imp_well_formed fenv func_list (x <- a1))
(WFassign : imp_rec_rel (var_map_wf_wrt_imp idents) (x <- a1))
(WFlp : lp_bool_wf func_list fenv l)
(WFupdate : prop_rel (var_map_wf_wrt_bexp idents)
(transform_prop_exprs l
(fun b : bexp_Imp_Lang => imp_lang_bexp_update x a1 b)))
(WF : prop_rel (var_map_wf_wrt_bexp idents) l),
lp_Imp_Lang_wf func_list fenv (Imp_LangLogSubst.subst_Imp_Lang_lp x a1 (Imp_Lang_lp_bool l)).
Proof.
induction l; intros; constructor.
- constructor.
- constructor.
- constructor.
invc WFlp. invc WF. invc WFupdate.
rename a into b.
eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- invc WFlp. invc WFupdate. invc WF.
constructor; eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- invc WF. invc WFupdate. invc WFlp. simpl. econstructor; eauto.
eapply lp_bexp_fun_app_bexp_well_formed_preserved_by_transformation; eassumption.
eapply lp_bexp_fun_app_bexp_well_formed_preserved_by_transformation; eassumption.
- invc WFlp. invc WF. invc WFupdate. simpl. constructor; eauto.
all: eapply lp_bexp_fun_app_bexp_well_formed_preserved_by_transformation; eassumption.
- invc WFlp. invc WFupdate. invc WF.
constructor; eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
- econstructor. invc WF. invc WFlp. invc WFupdate. revert H1 H2 H3.
induction a_list; intros.
+ constructor.
+ invc H1. invc H2. invc H3.
simpl; constructor.
* eapply fun_app_bexp_well_formed_preserved_by_imp_lang_bexp_update; eassumption.
* eapply IHa_list; eauto.
Qed.
Lemma inv_aimpwf_consequence_pre :
forall func_list idents n_args P Q P' c fenv n facts hl a imp,
aimp_always_wf func_list idents n_args P' c Q fenv facts (hl_Imp_Lang_consequence_pre P Q P' c n facts fenv hl a imp) ->
log_Imp_Lang_wf func_list fenv P /\ log_Imp_Lang_wf func_list fenv Q /\
log_Imp_Lang_wf func_list fenv P' /\
log_Imp_Lang_wf_map idents Q /\
log_Imp_Lang_wf_map idents P /\ log_Imp_Lang_wf_map idents P' /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) P /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) Q /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) P' /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) P /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) Q /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) P' /\
imp_rec_rel (var_map_wf_wrt_imp idents) c /\
hl_Imp_Lang_wf fenv func_list idents n_args P Q c facts hl.
Proof.
intros. invs H; invs H0. inversion_sigma_helper H18. intuition.
Qed.
Lemma inv_aimpwf_consequence_post :
forall func_list idents n_args P Q Q' c fenv n facts hl a imp,
aimp_always_wf func_list idents n_args P c Q' fenv facts (hl_Imp_Lang_consequence_post P Q Q' c n facts fenv hl a imp) ->
log_Imp_Lang_wf func_list fenv P /\ log_Imp_Lang_wf func_list fenv Q /\
log_Imp_Lang_wf func_list fenv Q' /\
log_Imp_Lang_wf_map idents P /\
log_Imp_Lang_wf_map idents Q /\ log_Imp_Lang_wf_map idents Q' /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) P /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) Q /\
AbsEnv_prop_rel (var_map_wf_wrt_aexp idents) (var_map_wf_wrt_bexp idents) Q' /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) P /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) Q /\
AbsEnv_prop_rel (all_params_ok_aexp n_args) (all_params_ok_bexp n_args) Q' /\
imp_rec_rel (var_map_wf_wrt_imp idents) c /\
hl_Imp_Lang_wf fenv func_list idents n_args P Q c facts hl.
Proof.
intros. invs H; invs H0. inversion_sigma_helper H18. subst. intuition.
Qed.
Lemma inv_aimpwf_seq:
forall i1 i2 P Q R funcs map args facts fenv hl1 hl2,
aimp_always_wf funcs map args P (i1;; i2) Q fenv facts (hl_Imp_Lang_seq P Q R facts fenv i1 i2 hl1 hl2) ->
aimp_always_wf funcs map args P i1 R fenv facts hl1 /\
aimp_always_wf funcs map args R i2 Q fenv facts hl2 /\
AbsEnv_prop_wf map R.
Proof.
intros. unfold aimp_always_wf in H. inversion H.
- inversion HSkip.
- inversion Heq.
- invs Heq. specialize (UIP_imp_refl _ Heq).
intros. subst. simpl in *. invs H0.
inversion_sigma_helper H18.
inversion_sigma_helper H19.
unfold aimp_always_wf. split; try split; try split; assumption.
- inversion heq.
- inversion Heq.
- inversion H0.
- inversion H0.
Qed.
Lemma inv_aimpwf_if:
forall i1 i2 P Q b facts fenv n_args idents func_list hl1 hl2,
aimp_always_wf func_list idents n_args P (when b then i1 else i2 done) Q fenv facts (hl_Imp_Lang_if P Q b i1 i2 facts fenv hl1 hl2) ->
aimp_always_wf func_list idents n_args (atrueImp_Lang b P) i1 Q fenv facts hl1 /\
aimp_always_wf func_list idents n_args (afalseImp_Lang b P) i2 Q fenv facts hl2.
Proof.
intros. unfold aimp_always_wf in H. inversion H.
- inversion HSkip.
- inversion Heq.
- inversion Heq.
- invs heq. specialize (UIP_imp_refl _ heq).
intros. subst. simpl in *. invs H0.
inversion_sigma_helper H13.
inversion_sigma_helper H14.
unfold aimp_always_wf. split; assumption.
- inversion Heq.
- inversion H0.
- inversion H0.
Qed.
Lemma inv_fun_app_when:
forall i1 i2 b fenv func_list,
fun_app_imp_well_formed fenv func_list (when b then i1 else i2 done) ->
fun_app_bexp_well_formed fenv func_list b /\ fun_app_imp_well_formed fenv func_list i1 /\ fun_app_imp_well_formed fenv func_list i2.
Proof.
intros. invs H. intuition.
Qed.
Lemma inv_imp_rec_rel_when : forall b idents i1 i2,
imp_rec_rel (var_map_wf_wrt_imp idents) (when b then i1 else i2 done) ->
imp_rec_rel (var_map_wf_wrt_imp idents) i1 /\ imp_rec_rel (var_map_wf_wrt_imp idents) i2 /\ var_map_wf_wrt_imp idents (when b then i1 else i2 done).
Proof.
intros. invs H. intuition.
Qed.
Definition to make the following lemmas agnostic to whether the
function is afalseImp_Lang/afalsestk or atrueImp_Lang/atruestk.
Local Definition isAfalseOrAtrue (afalsetrueImp_Lang: bexp_Imp_Lang -> AbsEnv -> AbsEnv) (afalsetruestk: bexp_stack -> AbsState -> AbsState): Prop :=
(afalsetrueImp_Lang = afalseImp_Lang /\ afalsetruestk = afalsestk) \/ (afalsetrueImp_Lang = atrueImp_Lang /\ afalsetruestk = atruestk).
Lemma absand_distribution :
forall (s1 s2 s3: AbsState) (fenv: fun_env_stk) (stk: stack),
absstate_match_rel
(AbsAnd (AbsAnd s1 s2) s3) fenv stk <->
absstate_match_rel (AbsAnd (AbsAnd s1 s3) (AbsAnd s2 s3)) fenv stk.
Proof.
split; intros; invs H.
- invs H2. constructor; constructor; auto.
- invs H2. constructor; auto. constructor; auto.
invs H5. auto.
Qed.
Lemma absor_distribution :
forall (s1 s2 s3: AbsState) (fenv: fun_env_stk) (stk: stack),
absstate_match_rel (AbsAnd (AbsOr s1 s2) s3) fenv stk <->
absstate_match_rel (AbsOr (AbsAnd s1 s3) (AbsAnd s2 s3)) fenv stk.
Proof.
split; intros; invs H.
- invs H2.
+ econstructor; econstructor; eassumption.
+ eapply RelAbsOrRight. econstructor; eassumption.
- invs H4. econstructor.
+ econstructor. eassumption.
+ eassumption.
- invs H4. econstructor.
+ eapply RelAbsOrRight. eassumption.
+ eassumption.
Qed.
Lemma absor_dissolution :
forall (s1 s2: AbsState) (fenv: fun_env_stk) (stk: stack),
absstate_match_rel (AbsOr s1 s2) fenv stk <->
(absstate_match_rel s1 fenv stk \/ absstate_match_rel s2 fenv stk).
Proof.
split; intros; invs H.
- left. assumption.
- right. assumption.
- econstructor. assumption.
- eapply RelAbsOrRight. assumption.
Qed.
Lemma absand_dissolution :
forall (s1 s2: AbsState) (fenv: fun_env_stk) (stk: stack),
absstate_match_rel (AbsAnd s1 s2) fenv stk <->
(absstate_match_rel s1 fenv stk /\ absstate_match_rel s2 fenv stk).
Proof.
split; intros; invs H; intuition. constructor; auto.
Qed.
Ltac absand_destruct H :=
eapply absand_dissolution in H; destruct H.
(afalsetrueImp_Lang = afalseImp_Lang /\ afalsetruestk = afalsestk) \/ (afalsetrueImp_Lang = atrueImp_Lang /\ afalsetruestk = atruestk).
Lemma absand_distribution :
forall (s1 s2 s3: AbsState) (fenv: fun_env_stk) (stk: stack),
absstate_match_rel
(AbsAnd (AbsAnd s1 s2) s3) fenv stk <->
absstate_match_rel (AbsAnd (AbsAnd s1 s3) (AbsAnd s2 s3)) fenv stk.
Proof.
split; intros; invs H.
- invs H2. constructor; constructor; auto.
- invs H2. constructor; auto. constructor; auto.
invs H5. auto.
Qed.
Lemma absor_distribution :
forall (s1 s2 s3: AbsState) (fenv: fun_env_stk) (stk: stack),
absstate_match_rel (AbsAnd (AbsOr s1 s2) s3) fenv stk <->
absstate_match_rel (AbsOr (AbsAnd s1 s3) (AbsAnd s2 s3)) fenv stk.
Proof.
split; intros; invs H.
- invs H2.
+ econstructor; econstructor; eassumption.
+ eapply RelAbsOrRight. econstructor; eassumption.
- invs H4. econstructor.
+ econstructor. eassumption.
+ eassumption.
- invs H4. econstructor.
+ eapply RelAbsOrRight. eassumption.
+ eassumption.
Qed.
Lemma absor_dissolution :
forall (s1 s2: AbsState) (fenv: fun_env_stk) (stk: stack),
absstate_match_rel (AbsOr s1 s2) fenv stk <->
(absstate_match_rel s1 fenv stk \/ absstate_match_rel s2 fenv stk).
Proof.
split; intros; invs H.
- left. assumption.
- right. assumption.
- econstructor. assumption.
- eapply RelAbsOrRight. assumption.
Qed.
Lemma absand_dissolution :
forall (s1 s2: AbsState) (fenv: fun_env_stk) (stk: stack),
absstate_match_rel (AbsAnd s1 s2) fenv stk <->
(absstate_match_rel s1 fenv stk /\ absstate_match_rel s2 fenv stk).
Proof.
split; intros; invs H; intuition. constructor; auto.
Qed.
Ltac absand_destruct H :=
eapply absand_dissolution in H; destruct H.