diff options
author | Jason Gross <jgross@mit.edu> | 2017-03-14 14:05:55 -0400 |
---|---|---|
committer | Jason Gross <jgross@mit.edu> | 2017-03-14 14:05:55 -0400 |
commit | 7a3740e056dcd0ca644eea443d7d87fb72df5aee (patch) | |
tree | 6ba47ad5dd97c516acd2ec15f433f3512bee12a3 | |
parent | 144354f092b18d4293e0c214fc095a9fcee35453 (diff) |
Add ContextProperties
-rw-r--r-- | _CoqProject | 1 | ||||
-rw-r--r-- | src/Reflection/Named/ContextProperties.v | 346 |
2 files changed, 347 insertions, 0 deletions
diff --git a/_CoqProject b/_CoqProject index f40db4cb2..74cf1a3be 100644 --- a/_CoqProject +++ b/_CoqProject @@ -154,6 +154,7 @@ src/Reflection/WfReflectiveGen.v src/Reflection/Named/Compile.v src/Reflection/Named/ContextDefinitions.v src/Reflection/Named/ContextOn.v +src/Reflection/Named/ContextProperties.v src/Reflection/Named/DeadCodeElimination.v src/Reflection/Named/EstablishLiveness.v src/Reflection/Named/FMapContext.v diff --git a/src/Reflection/Named/ContextProperties.v b/src/Reflection/Named/ContextProperties.v new file mode 100644 index 000000000..ace3a1115 --- /dev/null +++ b/src/Reflection/Named/ContextProperties.v @@ -0,0 +1,346 @@ +Require Import Coq.Logic.Eqdep_dec. +Require Import Crypto.Util.FixCoqMistakes. +Require Import Crypto.Reflection.Syntax. +Require Import Crypto.Reflection.Relations. +Require Import Crypto.Reflection.SmartMap. +Require Import Crypto.Reflection.Named.Syntax. +Require Import Crypto.Reflection.Named.ContextDefinitions. +Require Import Crypto.Util.PointedProp. +Require Import Crypto.Util.Logic. +Require Import Crypto.Util.Option. +Require Import Crypto.Util.Sigma. +Require Import Crypto.Util.Tactics.SplitInContext. +Require Import Crypto.Util.Tactics.DestructHead. +Require Import Crypto.Util.Tactics.BreakMatch. +Require Import Crypto.Util.Tactics.RewriteHyp. + +Section with_context. + Context {base_type_code Name var} (Context : @Context base_type_code Name var) + (base_type_code_dec : forall x y : base_type_code, {x = y} + {x <> y}) + (Name_dec : forall x y : Name, {x = y} + {x <> y}) + (ContextOk : ContextOk Context). + + Local Notation find_Name := (@find_Name base_type_code Name Name_dec). + Local Notation cast_if_eq := (@cast_if_eq base_type_code base_type_code_dec). + Local Notation find_Name_and_val := (@find_Name_and_val base_type_code Name base_type_code_dec Name_dec). + + Let base_type_UIP_refl : forall t (p : t = t :> base_type_code), p = eq_refl. + Proof. + intro; apply K_dec; intros; [ | reflexivity ]. + edestruct base_type_code_dec; eauto. + Defined. + + Lemma lookupb_eq_cast + : forall (ctx : Context) n t t' (pf : t = t'), + lookupb ctx n t' = option_map (fun v => eq_rect _ var v _ pf) (lookupb ctx n t). + Proof. + intros; subst; edestruct lookupb; reflexivity. + Defined. + Lemma lookupb_extendb_eq + : forall (ctx : Context) n t t' (pf : t = t') v, + lookupb (extendb ctx n (t:=t) v) n t' = Some (eq_rect _ var v _ pf). + Proof. + intros; subst; apply lookupb_extendb_same; assumption. + Defined. + + Local Ltac fin_t_step := + solve [ reflexivity ]. + Local Ltac fin_t_late_step := + solve [ tauto + | congruence + | eauto + | exfalso; eauto ]. + Local Ltac inversion_step := + first [ progress subst + | progress inversion_option + | progress inversion_sigma + | progress destruct_head' and + | match goal with + | [ H : ?t = ?t :> base_type_code |- _ ] + => pose proof (base_type_UIP_refl t H); subst H + end + | progress split_and ]. + Local Ltac rewrite_lookupb_extendb_step := + first [ rewrite lookupb_extendb_different by congruence + | rewrite lookupb_extendb_same + | rewrite lookupb_extendb_wrong_type by assumption ]. + Local Ltac misc_t_step := + first [ progress intros + | match goal with + | [ H : ?x = ?x -> _ |- _ ] => specialize (H eq_refl) + end + | progress simpl in * ]. + Local Ltac break_t_step := + first [ progress break_innermost_match_step + | progress unfold cast_if_eq in * + | match goal with + | [ H : context[match _ with _ => _ end] |- _ ] + => revert H; progress break_innermost_match_step + | [ |- _ /\ _ ] => split + | [ |- _ <-> _ ] => split + end + | progress destruct_head' or ]. + Local Ltac myfold_in_star c := + let c' := (eval cbv [interp_flat_type] in c) in + change c' with c in *. + Local Ltac refolder_t_step := + first [ progress myfold_in_star (@interp_flat_type base_type_code var) + | progress myfold_in_star (@interp_flat_type base_type_code (fun _ => Name)) + | match goal with + | [ var : base_type_code -> Type |- _ ] + => progress myfold_in_star (@interp_flat_type base_type_code var) + + end ]. + Local Ltac rewriter_t_step := + first [ match goal with + | [ H : _ |- _ ] => rewrite H by (assumption || congruence) + | [ H : _ |- _ ] => etransitivity; [ | rewrite H by (assumption || congruence); reflexivity ] + | [ H : ?x = Some _, H' : context[?x] |- _ ] => rewrite H in H' + | [ H : ?x = None, H' : context[?x] |- _ ] => rewrite H in H' + | [ H : ?x = ?a :> option _, H' : ?x = ?b :> option _ |- _ ] + => assert (a = b) + by (transitivity x; [ symmetry | ]; assumption); + clear H' + | _ => progress autorewrite with ctx_db in * + end ]. + Local Ltac t_step := + first [ fin_t_step + | inversion_step + | rewrite_lookupb_extendb_step + | misc_t_step + | break_t_step + | refolder_t_step + | rewriter_t_step + | fin_t_late_step ]. + Local Ltac t := repeat t_step. + + Lemma lookupb_extend (ctx : Context) + T N t n v + : lookupb (extend ctx N (t:=T) v) n t + = find_Name_and_val t n N v (lookupb ctx n t). + Proof. revert ctx; induction T; t. Qed. + + Lemma find_Name_and_val_Some_None + {var' var''} + {t n T N} + {x : interp_flat_type var' T} + {y : interp_flat_type var'' T} + {default default' v} + (H0 : @find_Name_and_val var' t n T N x default = Some v) + (H1 : @find_Name_and_val var'' t n T N y default' = None) + : default = Some v /\ default' = None. + Proof. + revert dependent default; revert dependent default'; induction T; t. + Qed. + + Lemma find_Name_and_val_default_to_None + {var'} + {t n T N} + {x : interp_flat_type var' T} + {default} + (H : @find_Name n T N <> None) + : @find_Name_and_val var' t n T N x default + = @find_Name_and_val var' t n T N x None. + Proof. revert default; induction T; t. Qed. + Hint Rewrite @find_Name_and_val_default_to_None using congruence : ctx_db. + + Lemma find_Name_and_val_different + {var'} + {t n T N} + {x : interp_flat_type var' T} + {default} + (H : @find_Name n T N = None) + : @find_Name_and_val var' t n T N x default = default. + Proof. revert default; induction T; t. Qed. + Hint Rewrite @find_Name_and_val_different using assumption : ctx_db. + + Lemma find_Name_and_val_wrong_type_iff + {var'} + {t t' n T N} + {x : interp_flat_type var' T} + {default} + (H : @find_Name n T N = Some t') + : t <> t' + <-> @find_Name_and_val var' t n T N x default = None. + Proof. split; revert default; induction T; t. Qed. + Lemma find_Name_and_val_wrong_type + {var'} + {t t' n T N} + {x : interp_flat_type var' T} + {default} + (H : @find_Name n T N = Some t') + (Ht : t <> t') + : @find_Name_and_val var' t n T N x default = None. + Proof. eapply find_Name_and_val_wrong_type_iff; eassumption. Qed. + Hint Rewrite @find_Name_and_val_wrong_type using congruence : ctx_db. + + Lemma find_Name_find_Name_and_val_wrong {var' n t' T V N} + : find_Name n N = Some t' + -> @find_Name_and_val var' t' n T N V None = None + -> False. + Proof. induction T; t. Qed. + + Lemma find_Name_and_val_None_iff + {var'} + {t n T N} + {x : interp_flat_type var' T} + {default} + : (@find_Name n T N <> Some t + /\ (@find_Name n T N <> None \/ default = None)) + <-> @find_Name_and_val var' t n T N x default = None. + Proof. + destruct (@find_Name n T N) eqn:?; unfold not; t; + try solve [ eapply find_Name_and_val_wrong_type; [ eassumption | congruence ] + | eapply find_Name_find_Name_and_val_wrong; eassumption + | left; congruence ]. + Qed. + + Lemma find_Name_and_val_split + {var' t n T N V default} + : @find_Name_and_val var' t n T N V default + = match @find_Name n T N with + | Some t' => match base_type_code_dec t t' with + | left _ => @find_Name_and_val var' t n T N V None + | right _ => None + end + | None => default + end. + Proof. + t; erewrite find_Name_and_val_wrong_type by solve [ eassumption | congruence ]; reflexivity. + Qed. + Local Ltac find_Name_and_val_default_to_None_step := + match goal with + | [ H : context[find_Name_and_val _ _ _ _ ?default] |- _ ] + => lazymatch default with None => fail | _ => idtac end; + rewrite (find_Name_and_val_split (default:=default)) in H + end. + Local Ltac find_Name_and_val_default_to_None := repeat find_Name_and_val_default_to_None_step. + + Lemma find_Name_SmartFlatTypeMapInterp2_None_iff {var' n f T V N} + : @find_Name n (SmartFlatTypeMap f (t:=T) V) + (SmartFlatTypeMapInterp2 (var':=var') (fun _ _ (n' : Name) => n') V N) = None + <-> find_Name n N = None. + Proof. + split; + (induction T; + [ | | specialize (IHT1 (fst V) (fst N)); + specialize (IHT2 (snd V) (snd N)) ]); + t. + Qed. + Hint Rewrite @find_Name_SmartFlatTypeMapInterp2_None_iff : ctx_db. + Lemma find_Name_SmartFlatTypeMapInterp2_None {var' n f T V N} + : @find_Name n (SmartFlatTypeMap f (t:=T) V) + (SmartFlatTypeMapInterp2 (var':=var') (fun _ _ (n' : Name) => n') V N) = None + -> find_Name n N = None. + Proof. apply find_Name_SmartFlatTypeMapInterp2_None_iff. Qed. + Hint Rewrite @find_Name_SmartFlatTypeMapInterp2_None using eassumption : ctx_db. + Lemma find_Name_SmartFlatTypeMapInterp2_None' {var' n f T V N} + : find_Name n N = None + -> @find_Name n (SmartFlatTypeMap f (t:=T) V) + (SmartFlatTypeMapInterp2 (var':=var') (fun _ _ (n' : Name) => n') V N) = None. + Proof. apply find_Name_SmartFlatTypeMapInterp2_None_iff. Qed. + Lemma find_Name_SmartFlatTypeMapInterp2_None_Some_wrong {var' n f T V N v} + : @find_Name n (SmartFlatTypeMap f (t:=T) V) + (SmartFlatTypeMapInterp2 (var':=var') (fun _ _ (n' : Name) => n') V N) = None + -> find_Name n N = Some v + -> False. + Proof. + intro; erewrite find_Name_SmartFlatTypeMapInterp2_None by eassumption; congruence. + Qed. + Local Hint Resolve @find_Name_SmartFlatTypeMapInterp2_None_Some_wrong. + + Lemma find_Name_SmartFlatTypeMapInterp2 {var' n f T V N} + : @find_Name n (SmartFlatTypeMap f (t:=T) V) + (SmartFlatTypeMapInterp2 (var':=var') (fun _ _ (n' : Name) => n') V N) + = match find_Name n N with + | Some t' => match find_Name_and_val t' n N V None with + | Some v => Some (f t' v) + | None => None + end + | None => None + end. + Proof. + induction T; + [ | | specialize (IHT1 (fst V) (fst N)); + specialize (IHT2 (snd V) (snd N)) ]. + { t. } + { t. } + { repeat first [ fin_t_step + | inversion_step + | rewrite_lookupb_extendb_step + | misc_t_step + | refolder_t_step ]. + repeat match goal with + | [ |- context[match @find_Name ?n ?T ?N with _ => _ end] ] + => destruct (@find_Name n T N) eqn:? + | [ H : context[match @find_Name ?n ?T ?N with _ => _ end] |- _ ] + => destruct (@find_Name n T N) eqn:? + end; + repeat first [ fin_t_step + | rewriter_t_step + | fin_t_late_step ]. } + Qed. + + Lemma find_Name_and_val__SmartFlatTypeMapInterp2__SmartFlatTypeMapUnInterp__Some_Some_alt + {var' var'' var''' t b n f g T V N X v v'} + (Hfg + : forall (V : var' t) (X : var'' (f t V)) (H : f t V = f t b), + g t b (eq_rect (f t V) var'' X (f t b) H) = g t V X) + : @find_Name_and_val + var'' (f t b) n (SmartFlatTypeMap f (t:=T) V) + (SmartFlatTypeMapInterp2 (var':=var') (fun _ _ (n' : Name) => n') V N) X None = Some v + -> @find_Name_and_val + var''' t n T N (SmartFlatTypeMapUnInterp (f:=f) g X) None = Some v' + -> g t b v = v'. + Proof. + induction T; + [ | | specialize (IHT1 (fst V) (fst N) (fst X)); + specialize (IHT2 (snd V) (snd N) (snd X)) ]; + repeat first [ find_Name_and_val_default_to_None_step + | t_step + | match goal with + | [ H : _ |- _ ] + => progress rewrite find_Name_and_val_different in H + by solve [ congruence + | apply find_Name_SmartFlatTypeMapInterp2_None'; assumption ] + end ]. + Qed. + + Lemma find_Name_and_val__SmartFlatTypeMapInterp2__SmartFlatTypeMapUnInterp__Some_Some + {var' var'' var''' t b n f g T V N X v v'} + : @find_Name_and_val + var'' (f t b) n (SmartFlatTypeMap f (t:=T) V) + (SmartFlatTypeMapInterp2 (var':=var') (fun _ _ (n' : Name) => n') V N) X None = Some v + -> @find_Name_and_val + _ t n T N V None = Some b + -> @find_Name_and_val + var''' t n T N (SmartFlatTypeMapUnInterp (f:=f) g X) None = Some v' + -> g t b v = v'. + Proof. + induction T; + [ | | specialize (IHT1 (fst V) (fst N) (fst X)); + specialize (IHT2 (snd V) (snd N) (snd X)) ]; + repeat first [ find_Name_and_val_default_to_None_step + | t_step + | match goal with + | [ H : _ |- _ ] + => progress rewrite find_Name_and_val_different in H + by solve [ congruence + | apply find_Name_SmartFlatTypeMapInterp2_None'; assumption ] + end ]. + Qed. + + Lemma interp_flat_type_rel_pointwise__find_Name_and_val + {var' var'' t n T N x y R v0 v1} + (H0 : @find_Name_and_val var' t n T N x None = Some v0) + (H1 : @find_Name_and_val var'' t n T N y None = Some v1) + (HR : interp_flat_type_rel_pointwise R x y) + : R _ v0 v1. + Proof. + induction T; + [ | | specialize (IHT1 (fst N) (fst x) (fst y)); + specialize (IHT2 (snd N) (snd x) (snd y)) ]; + repeat first [ find_Name_and_val_default_to_None_step + | t_step ]. + Qed. +End with_context. |