From e0c9b5f803e63a91922cc0724119d39da0f24379 Mon Sep 17 00:00:00 2001 From: Jason Gross Date: Thu, 4 Apr 2019 15:51:20 -0400 Subject: Add UnderLets flat_map interp proofs,other changes Also remove a rewrite rule using cast from the non-cast arith rules, regenerate the .out files, add ident.gets_inlined for eventual use in the rewriter, and generalize the rewrite rule lemmas over cast_out_of_range so that we can actually make use of their proofs for interp. --- src/UnderLetsProofs.v | 367 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 283 insertions(+), 84 deletions(-) (limited to 'src/UnderLetsProofs.v') diff --git a/src/UnderLetsProofs.v b/src/UnderLetsProofs.v index 54aee6d76..ccb872a44 100644 --- a/src/UnderLetsProofs.v +++ b/src/UnderLetsProofs.v @@ -501,88 +501,62 @@ Module Compilers. Qed. End with_var2. - Section for_interp. + Section for_interp2. Context {base_interp : base_type -> Type} - (ident_interp : forall t, ident t -> type.interp base_interp t). - - Local Notation UnderLets := (@UnderLets (type.interp base_interp)). + (ident_interp : forall t, ident t -> type.interp base_interp t) + {var : type -> Type}. - Fixpoint interp {T} (v : UnderLets T) : T - := match v with - | Base v => v - | UnderLet A x f => let xv := expr.interp ident_interp x in - @interp _ (f xv) - end. - - Fixpoint interp_related {T1 T2} (R : T1 -> T2 -> Prop) (e : UnderLets T1) (v2 : T2) : Prop + Fixpoint interp_related_gen {T1 T2} (R' : forall t, var t -> type.interp base_interp t -> Prop) (R : T1 -> T2 -> Prop) (e : @UnderLets var T1) (v2 : T2) : Prop := match e with | Base v1 => R v1 v2 | UnderLet t e f (* combine the App rule with the Abs rule *) => exists fv ev, - expr.interp_related ident_interp e ev + expr.interp_related_gen ident_interp R' e ev /\ (forall x1 x2, - x1 == x2 - -> @interp_related T1 T2 R (f x1) (fv x2)) + R' _ x1 x2 + -> @interp_related_gen T1 T2 R' R (f x1) (fv x2)) /\ fv ev = v2 end. - Lemma interp_splice {A B} (x : UnderLets A) (e : A -> UnderLets B) - : interp (splice x e) = interp (e (interp x)). - Proof. induction x; cbn [splice interp]; eauto. Qed. - - Lemma interp_splice_list {A B} (x : list (UnderLets A)) (e : list A -> UnderLets B) - : interp (splice_list x e) - = interp (e (List.map interp x)). - Proof. - revert e; induction x as [|x xs IHx]; intros; cbn [splice_list interp List.map]; [ reflexivity | ]. - rewrite interp_splice, IHx; reflexivity. - Qed. - - Lemma interp_to_expr {t} (x : UnderLets (expr t)) - : expr.interp ident_interp (to_expr x) = expr.interp ident_interp (interp x). - Proof. induction x; cbn [expr.interp interp to_expr]; cbv [LetIn.Let_In]; eauto. Qed. - - Lemma interp_of_expr {t} (x : expr t) - : expr.interp ident_interp (interp (of_expr x)) = expr.interp ident_interp x. - Proof. induction x; cbn [expr.interp interp of_expr]; cbv [LetIn.Let_In]; eauto. Qed. - - Lemma to_expr_interp_related_iff {t e v} - : interp_related (expr.interp_related ident_interp (t:=t)) e v - <-> expr.interp_related ident_interp (UnderLets.to_expr e) v. + Lemma to_expr_interp_related_gen_iff (R : forall t, var t -> type.interp base_interp t -> Prop) {t e v} + : interp_related_gen R (expr.interp_related_gen ident_interp R (t:=t)) e v + <-> expr.interp_related_gen ident_interp R (UnderLets.to_expr e) v. Proof using Type. - revert v; induction e; cbn [UnderLets.to_expr interp_related expr.interp_related]; try reflexivity. + revert v; induction e; cbn [UnderLets.to_expr interp_related_gen expr.interp_related_gen]; try reflexivity. setoid_rewrite H. reflexivity. Qed. - Global Instance interp_related_Proper_iff {T1 T2} - : Proper (pointwise_relation _ (pointwise_relation _ iff) ==> eq ==> eq ==> iff) (@interp_related T1 T2) | 10. + Global Instance interp_related_gen_Proper_iff {T1 T2 R} + : Proper (pointwise_relation _ (pointwise_relation _ iff) ==> eq ==> eq ==> iff) (@interp_related_gen T1 T2 R) | 10. Proof using Type. cbv [pointwise_relation respectful Proper]. intros R1 R2 HR x y ? x' y' H'; subst y y'. - revert x'; induction x; [ apply HR | ]; cbn [interp_related]. + revert x'; induction x; [ apply HR | ]; cbn [interp_related_gen]. setoid_rewrite H; reflexivity. Qed. - Lemma splice_interp_related_iff {A B T R x e} {v : T} - : interp_related R (@UnderLets.splice _ ident _ A B x e) v - <-> interp_related - (fun xv => interp_related R (e xv)) + Lemma splice_interp_related_gen_iff {A B T R' R x e} {v : T} + : interp_related_gen R' R (@UnderLets.splice _ ident _ A B x e) v + <-> interp_related_gen + R' + (fun xv => interp_related_gen R' R (e xv)) x v. Proof using Type. - revert v; induction x; cbn [UnderLets.splice interp_related]; [ reflexivity | ]. + revert v; induction x; cbn [UnderLets.splice interp_related_gen]; [ reflexivity | ]. match goal with H : _ |- _ => setoid_rewrite H end. reflexivity. Qed. - Lemma splice_list_interp_related_iff_gen {A B T R x e1 e2 base} {v : T} + Lemma splice_list_interp_related_gen_iff_gen {A B T R' R x e1 e2 base} {v : T} (He1e2 : forall ls', e1 ls' = e2 (base ++ ls')) - : interp_related R (@UnderLets.splice_list _ ident _ A B x e1) v + : interp_related_gen R' R (@UnderLets.splice_list _ ident _ A B x e1) v <-> list_rect (fun _ => list _ -> _ -> Prop) - (fun ls v => interp_related R (e2 ls) v) + (fun ls v => interp_related_gen R' R (e2 ls) v) (fun x xs recP ls v - => interp_related + => interp_related_gen + R' (fun x' v => recP (ls ++ [x']) v) x v) @@ -590,22 +564,23 @@ Module Compilers. base v. Proof using Type. - revert base v e1 e2 He1e2; induction x as [|? ? IHx]; cbn [UnderLets.splice_list interp_related list_rect]; intros. + revert base v e1 e2 He1e2; induction x as [|? ? IHx]; cbn [UnderLets.splice_list interp_related_gen list_rect]; intros. { intros; rewrite He1e2, ?app_nil_r; reflexivity. } - { setoid_rewrite splice_interp_related_iff. - apply interp_related_Proper_iff; [ | reflexivity.. ]; cbv [pointwise_relation]; intros. + { setoid_rewrite splice_interp_related_gen_iff. + apply interp_related_gen_Proper_iff; [ | reflexivity.. ]; cbv [pointwise_relation]; intros. specialize (fun v => IHx (base ++ [v])). setoid_rewrite IHx; [ reflexivity | ]. intros; rewrite He1e2, <- ?app_assoc; reflexivity. } Qed. - Lemma splice_list_interp_related_iff {A B T R x e} {v : T} - : interp_related R (@UnderLets.splice_list _ ident _ A B x e) v + Lemma splice_list_interp_related_gen_iff {A B T R' R x e} {v : T} + : interp_related_gen R' R (@UnderLets.splice_list _ ident _ A B x e) v <-> list_rect (fun _ => list _ -> _ -> Prop) - (fun ls v => interp_related R (e ls) v) + (fun ls v => interp_related_gen R' R (e ls) v) (fun x xs recP ls v - => interp_related + => interp_related_gen + R' (fun x' v => recP (ls ++ [x']) v) x v) @@ -613,19 +588,19 @@ Module Compilers. nil v. Proof using Type. - apply splice_list_interp_related_iff_gen; reflexivity. + apply splice_list_interp_related_gen_iff_gen; reflexivity. Qed. - Lemma splice_interp_related_of_ex {A B T T' RA RB x e} {v : T} + Lemma splice_interp_related_gen_of_ex {A B T T' R' RA RB x e} {v : T} : (exists ev (xv : T'), - interp_related RA x xv + interp_related_gen R' RA x xv /\ (forall x1 x2, RA x1 x2 - -> interp_related RB (e x1) (ev x2)) + -> interp_related_gen R' RB (e x1) (ev x2)) /\ ev xv = v) - -> interp_related RB (@UnderLets.splice _ ident _ A B x e) v. + -> interp_related_gen R' RB (@UnderLets.splice _ ident _ A B x e) v. Proof using Type. - revert e v; induction x; cbn [interp_related UnderLets.splice]; intros. + revert e v; induction x; cbn [interp_related_gen UnderLets.splice]; intros. all: repeat first [ progress destruct_head'_ex | progress destruct_head'_and | progress subst @@ -635,21 +610,21 @@ Module Compilers. end ]. do 2 eexists; repeat apply conj; [ eassumption | | ]; intros. { match goal with H : _ |- _ => apply H; clear H end. - do 2 eexists; repeat apply conj; now eauto. } + do 2 eexists; repeat apply conj; try now eauto. } { reflexivity. } Qed. - Lemma splice_list_interp_related_of_ex {A B T T' RA RB x e} {v : T} + Lemma splice_list_interp_related_gen_of_ex {A B T T' R' RA RB x e} {v : T} : (exists ev (xv : list T'), - List.Forall2 (interp_related RA) x xv + List.Forall2 (interp_related_gen R' RA) x xv /\ (forall x1 x2, List.length x2 = List.length xv -> List.Forall2 RA x1 x2 - -> interp_related RB (e x1) (ev x2)) + -> interp_related_gen R' RB (e x1) (ev x2)) /\ ev xv = v) - -> interp_related RB (@UnderLets.splice_list _ ident _ A B x e) v. + -> interp_related_gen R' RB (@UnderLets.splice_list _ ident _ A B x e) v. Proof using Type. - revert e v; induction x as [|x xs IHxs]; cbn [interp_related UnderLets.splice_list]; intros. + revert e v; induction x as [|x xs IHxs]; cbn [interp_related_gen UnderLets.splice_list]; intros. all: repeat first [ progress destruct_head'_ex | progress destruct_head'_and | progress cbn [List.length] in * @@ -665,7 +640,7 @@ Module Compilers. | [ H : forall l1 l2, length l2 = S (length _) -> Forall2 _ l1 l2 -> _ |- _ ] => specialize (fun l ls l' ls' (pf0 : length _ = _) pf1 pf2 => H (cons l ls) (cons l' ls') (f_equal S pf0) (Forall2_cons _ _ pf1 pf2)) end. - eapply splice_interp_related_of_ex; do 2 eexists; repeat apply conj; + eapply splice_interp_related_gen_of_ex; do 2 eexists; repeat apply conj; intros; [ eassumption | | ]. { eapply IHxs. do 2 eexists; repeat apply conj; intros; @@ -675,6 +650,207 @@ Module Compilers. { reflexivity. } Qed. + Lemma list_rect_interp_related_gen {A B Pnil Pcons ls B' Pnil' Pcons' ls' R' R} + (Hnil : interp_related_gen R' R Pnil Pnil') + (Hcons : forall x x', + expr.interp_related_gen ident_interp R' x x' + -> forall l l', + List.Forall2 (expr.interp_related_gen ident_interp R') l l' + -> forall rec rec', + interp_related_gen R' R rec rec' + -> interp_related_gen R' R (Pcons x l rec) (Pcons' x' l' rec')) + (Hls : List.Forall2 (expr.interp_related_gen ident_interp R' (t:=A)) ls ls') + : interp_related_gen + R' R + (list_rect + (fun _ : list _ => UnderLets _ B) + Pnil + Pcons + ls) + (list_rect + (fun _ : list _ => B') + Pnil' + Pcons' + ls'). + Proof using Type. induction Hls; cbn [list_rect] in *; auto. Qed. + + Lemma list_rect_arrow_interp_related_gen {A B C Pnil Pcons ls x B' C' Pnil' Pcons' ls' x' R'' R} + {R' : B -> B' -> Prop} + (Hnil : forall x x', R' x x' -> interp_related_gen R'' R (Pnil x) (Pnil' x')) + (Hcons : forall x x', + expr.interp_related_gen ident_interp R'' x x' + -> forall l l', + List.Forall2 (expr.interp_related_gen ident_interp R'') l l' + -> forall rec rec', + (forall v v', R' v v' -> interp_related_gen R'' R (rec v) (rec' v')) + -> forall v v', + R' v v' + -> interp_related_gen R'' R (Pcons x l rec v) (Pcons' x' l' rec' v')) + (Hls : List.Forall2 (expr.interp_related_gen ident_interp R'' (t:=A)) ls ls') + (Hx : R' x x') + : interp_related_gen + R'' R + (list_rect + (fun _ : list _ => B -> UnderLets _ C) + Pnil + Pcons + ls + x) + (list_rect + (fun _ : list _ => B' -> C') + Pnil' + Pcons' + ls' + x'). + Proof using Type. revert x x' Hx; induction Hls; cbn [list_rect] in *; auto. Qed. + + Lemma nat_rect_interp_related_gen {A PO PS n A' PO' PS' n' R' R} + (Hnil : interp_related_gen R' R PO PO') + (Hcons : forall n rec rec', + interp_related_gen R' R rec rec' + -> interp_related_gen R' R (PS n rec) (PS' n rec')) + (Hn : n = n') + : interp_related_gen + R' R + (nat_rect (fun _ => UnderLets _ A) PO PS n) + (nat_rect (fun _ => A') PO' PS' n'). + Proof using Type. subst n'; induction n; cbn [nat_rect] in *; auto. Qed. + + Lemma nat_rect_arrow_interp_related_gen {A B PO PS n x A' B' PO' PS' n' x' R'' R} + {R' : A -> A' -> Prop} + (Hnil : forall x x', R' x x' -> interp_related_gen R'' R (PO x) (PO' x')) + (Hcons : forall n rec rec', + (forall x x', R' x x' -> interp_related_gen R'' R (rec x) (rec' x')) + -> forall x x', + R' x x' + -> interp_related_gen R'' R (PS n rec x) (PS' n rec' x')) + (Hn : n = n') + (Hx : R' x x') + : interp_related_gen + R'' R + (nat_rect (fun _ => A -> UnderLets _ B) PO PS n x) + (nat_rect (fun _ => A' -> B') PO' PS' n' x'). + Proof using Type. subst n'; revert x x' Hx; induction n; cbn [nat_rect] in *; auto. Qed. + + Lemma interp_related_gen_Proper_impl_same_UnderLets {A B B' R' R1 R2 e v f} + (HR : forall e v, (R1 e v : Prop) -> (R2 e (f v) : Prop)) + : @interp_related_gen A B R' R1 e v + -> @interp_related_gen A B' R' R2 e (f v). + Proof using Type. + revert f v HR; induction e; cbn [interp_related_gen]; [ now eauto | ]; intros F v HR H'. + destruct H' as [fv H']; exists (fun ev => F (fv ev)). + repeat first [ let x := fresh "x" in destruct H' as [x H']; exists x + | let x := fresh "x" in intro x; specialize (H' x) + | let H := fresh "H" in destruct H' as [H H']; split; [ exact H || now subst | ] + | let H := fresh "H" in destruct H' as [H' H]; split; [ | exact H || now subst ] ]. + auto. + Qed. + End for_interp2. + + Section for_interp. + Context {base_interp : base_type -> Type} + (ident_interp : forall t, ident t -> type.interp base_interp t). + + Local Notation UnderLets := (@UnderLets (type.interp base_interp)). + + Fixpoint interp {T} (v : UnderLets T) : T + := match v with + | Base v => v + | UnderLet A x f => let xv := expr.interp ident_interp x in + @interp _ (f xv) + end. + + Definition interp_related {T1 T2} (R : T1 -> T2 -> Prop) (e : UnderLets T1) (v2 : T2) : Prop + := @interp_related_gen base_interp ident_interp _ T1 T2 (fun t => type.eqv) R e v2. + + Lemma interp_splice {A B} (x : UnderLets A) (e : A -> UnderLets B) + : interp (splice x e) = interp (e (interp x)). + Proof. induction x; cbn [splice interp]; eauto. Qed. + + Lemma interp_splice_list {A B} (x : list (UnderLets A)) (e : list A -> UnderLets B) + : interp (splice_list x e) + = interp (e (List.map interp x)). + Proof. + revert e; induction x as [|x xs IHx]; intros; cbn [splice_list interp List.map]; [ reflexivity | ]. + rewrite interp_splice, IHx; reflexivity. + Qed. + + Lemma interp_to_expr {t} (x : UnderLets (expr t)) + : expr.interp ident_interp (to_expr x) = expr.interp ident_interp (interp x). + Proof. induction x; cbn [expr.interp interp to_expr]; cbv [LetIn.Let_In]; eauto. Qed. + + Lemma interp_of_expr {t} (x : expr t) + : expr.interp ident_interp (interp (of_expr x)) = expr.interp ident_interp x. + Proof. induction x; cbn [expr.interp interp of_expr]; cbv [LetIn.Let_In]; eauto. Qed. + + Lemma to_expr_interp_related_iff {t e v} + : interp_related (expr.interp_related ident_interp (t:=t)) e v + <-> expr.interp_related ident_interp (UnderLets.to_expr e) v. + Proof using Type. apply to_expr_interp_related_gen_iff. Qed. + + Global Instance interp_related_Proper_iff {T1 T2} + : Proper (pointwise_relation _ (pointwise_relation _ iff) ==> eq ==> eq ==> iff) (@interp_related T1 T2) | 10. + Proof using Type. apply interp_related_gen_Proper_iff. Qed. + + Lemma splice_interp_related_iff {A B T R x e} {v : T} + : interp_related R (@UnderLets.splice _ ident _ A B x e) v + <-> interp_related + (fun xv => interp_related R (e xv)) + x v. + Proof using Type. apply splice_interp_related_gen_iff. Qed. + + Lemma splice_list_interp_related_iff_gen {A B T R x e1 e2 base} {v : T} + (He1e2 : forall ls', e1 ls' = e2 (base ++ ls')) + : interp_related R (@UnderLets.splice_list _ ident _ A B x e1) v + <-> list_rect + (fun _ => list _ -> _ -> Prop) + (fun ls v => interp_related R (e2 ls) v) + (fun x xs recP ls v + => interp_related + (fun x' v => recP (ls ++ [x']) v) + x + v) + x + base + v. + Proof using Type. now apply splice_list_interp_related_gen_iff_gen. Qed. + + Lemma splice_list_interp_related_iff {A B T R x e} {v : T} + : interp_related R (@UnderLets.splice_list _ ident _ A B x e) v + <-> list_rect + (fun _ => list _ -> _ -> Prop) + (fun ls v => interp_related R (e ls) v) + (fun x xs recP ls v + => interp_related + (fun x' v => recP (ls ++ [x']) v) + x + v) + x + nil + v. + Proof using Type. apply splice_list_interp_related_gen_iff. Qed. + + Lemma splice_interp_related_of_ex {A B T T' RA RB x e} {v : T} + : (exists ev (xv : T'), + interp_related RA x xv + /\ (forall x1 x2, + RA x1 x2 + -> interp_related RB (e x1) (ev x2)) + /\ ev xv = v) + -> interp_related RB (@UnderLets.splice _ ident _ A B x e) v. + Proof using Type. apply splice_interp_related_gen_of_ex. Qed. + + Lemma splice_list_interp_related_of_ex {A B T T' RA RB x e} {v : T} + : (exists ev (xv : list T'), + List.Forall2 (interp_related RA) x xv + /\ (forall x1 x2, + List.length x2 = List.length xv + -> List.Forall2 RA x1 x2 + -> interp_related RB (e x1) (ev x2)) + /\ ev xv = v) + -> interp_related RB (@UnderLets.splice_list _ ident _ A B x e) v. + Proof using Type. apply splice_list_interp_related_gen_of_ex. Qed. + Lemma list_rect_interp_related {A B Pnil Pcons ls B' Pnil' Pcons' ls' R} (Hnil : interp_related R Pnil Pnil') (Hcons : forall x x', @@ -697,7 +873,7 @@ Module Compilers. Pnil' Pcons' ls'). - Proof using Type. induction Hls; cbn [list_rect] in *; auto. Qed. + Proof using Type. now apply list_rect_interp_related_gen. Qed. Lemma list_rect_arrow_interp_related {A B C Pnil Pcons ls x B' C' Pnil' Pcons' ls' x' R} {R' : B -> B' -> Prop} @@ -727,7 +903,7 @@ Module Compilers. Pcons' ls' x'). - Proof using Type. revert x x' Hx; induction Hls; cbn [list_rect] in *; auto. Qed. + Proof using Type. eapply list_rect_arrow_interp_related_gen; now eauto. Qed. Lemma nat_rect_interp_related {A PO PS n A' PO' PS' n' R} (Hnil : interp_related R PO PO') @@ -739,7 +915,7 @@ Module Compilers. R (nat_rect (fun _ => UnderLets A) PO PS n) (nat_rect (fun _ => A') PO' PS' n'). - Proof using Type. subst n'; induction n; cbn [nat_rect] in *; auto. Qed. + Proof using Type. now apply nat_rect_interp_related_gen. Qed. Lemma nat_rect_arrow_interp_related {A B PO PS n x A' B' PO' PS' n' x' R} {R' : A -> A' -> Prop} @@ -755,21 +931,13 @@ Module Compilers. R (nat_rect (fun _ => A -> UnderLets B) PO PS n x) (nat_rect (fun _ => A' -> B') PO' PS' n' x'). - Proof using Type. subst n'; revert x x' Hx; induction n; cbn [nat_rect] in *; auto. Qed. + Proof using Type. eapply nat_rect_arrow_interp_related_gen; now eauto. Qed. Lemma interp_related_Proper_impl_same_UnderLets {A B B' R1 R2 e v f} (HR : forall e v, (R1 e v : Prop) -> (R2 e (f v) : Prop)) : @interp_related A B R1 e v -> @interp_related A B' R2 e (f v). - Proof using Type. - revert f v HR; induction e; cbn [interp_related]; [ now eauto | ]; intros F v HR H'. - destruct H' as [fv H']; exists (fun ev => F (fv ev)). - repeat first [ let x := fresh "x" in destruct H' as [x H']; exists x - | let x := fresh "x" in intro x; specialize (H' x) - | let H := fresh "H" in destruct H' as [H H']; split; [ exact H || now subst | ] - | let H := fresh "H" in destruct H' as [H' H]; split; [ | exact H || now subst ] ]. - auto. - Qed. + Proof using Type. now apply interp_related_gen_Proper_impl_same_UnderLets. Qed. End for_interp. Section for_interp2. @@ -790,6 +958,37 @@ Module Compilers. eassumption. Qed. End for_interp2. + + Section with_var2_for_interp. + Context {base_interp : base_type -> Type} + {ident_interp : forall t, ident t -> type.interp base_interp t} + {var1 var2 : type -> Type}. + + Lemma flat_map_interp_related_iff + {T1 T2} f f' R'' R' R e v + (Hf : forall t e v, expr.interp_related_gen ident_interp R'' e v -> interp_related_gen ident_interp R' (expr.interp_related_gen ident_interp R') (f t e) v) + (Hf' : forall t e v, R' t e v -> R'' t (f' t e) v) + (He : @interp_related_gen _ ident_interp _ _ _ R'' R e v) + : @interp_related_gen + _ ident_interp _ _ T2 R' R + (@flat_map _ ident var1 ident var2 f f' T1 e) + v. + Proof using Type. + revert dependent v; induction e as [|? ? ? IHe]; cbn [flat_map interp_related_gen] in *; intros; [ assumption | ]. + repeat first [ progress destruct_head'_ex + | progress destruct_head'_and + | progress subst + | eapply splice_interp_related_gen_of_ex; do 2 eexists; repeat apply conj; + [ eapply Hf | | reflexivity ] + | solve [ auto ] + | progress intros + | match goal with + | [ |- interp_related_gen _ _ _ (UnderLet _ _) _ ] + => cbn [interp_related_gen]; do 2 eexists; repeat apply conj; + [ | | reflexivity ] + end ]. + Qed. + End with_var2_for_interp. End with_ident. Section reify. -- cgit v1.2.3