aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jason Gross <jgross@mit.edu>2018-11-22 00:38:54 -0500
committerGravatar Jason Gross <jasongross9@gmail.com>2018-11-27 18:37:02 -0500
commit3d3c983d5e2ff759a7e11be3b96ba6f87babf9e1 (patch)
treec0a5e6edbd143862021658886ccc226e96ca4a35 /src
parent4386d4e6ad9cf8f76ac04746497db27e15b5c7d7 (diff)
Refactor interpretation of values
We now use interp-relatedness of values primarily to define an "ok" relation on them, and thereafter mostly talk about expr-interping the reified value. This will hopefully be easier to prove things about. Idea came from Andres, after much discussion between me and Andres and Adam.
Diffstat (limited to 'src')
-rw-r--r--src/Experiments/NewPipeline/RewriterWf1.v212
1 files changed, 191 insertions, 21 deletions
diff --git a/src/Experiments/NewPipeline/RewriterWf1.v b/src/Experiments/NewPipeline/RewriterWf1.v
index 659fb018c..aec270ef2 100644
--- a/src/Experiments/NewPipeline/RewriterWf1.v
+++ b/src/Experiments/NewPipeline/RewriterWf1.v
@@ -1660,22 +1660,9 @@ Module Compilers.
then UnderLets.interp ident_interp
else (fun x => x)).
- Fixpoint value_interp_related1
- {with_lets1 t}
- : @value' var with_lets1 t
- -> var t
- -> Prop
- := match t return value' _ t -> var t -> Prop with
- | type.base t
- => fun v1 v2
- => expr.interp ident_interp (UnderLets_maybe_interp with_lets1 v1)
- == v2
- | type.arrow s d
- => fun (f1 : value' _ s -> value' _ d) (f2 : var s -> var d)
- => forall x1 x2,
- @value_interp_related1 _ s x1 x2
- -> @value_interp_related1 _ d (f1 x1) (f2 x2)
- end.
+ Definition value'_interp {with_lets t} (v : @value' var with_lets t)
+ : var t
+ := expr.interp ident_interp (reify v).
Fixpoint value'_interp_related
{with_lets1 with_lets2 t}
@@ -1694,6 +1681,14 @@ Module Compilers.
-> @value'_interp_related _ _ d (f1 x1) (f2 x2)
end.
+ Local Infix "===" := value'_interp_related : type_scope.
+
+ Definition value_interp_related {t} : relation (@value var t)
+ := value'_interp_related.
+
+ Definition value_interp_ok {with_lets t} : @value' var with_lets t -> Prop
+ := fun v => value'_interp_related v v.
+
Lemma value'_interp_related_sym_iff {with_lets1 with_lets2 t v1 v2}
: @value'_interp_related with_lets1 with_lets2 t v1 v2
<-> @value'_interp_related with_lets2 with_lets1 t v2 v1.
@@ -1722,9 +1717,6 @@ Module Compilers.
: Transitive (@value'_interp_related with_lets with_lets t) | 10
:= fun v1 v2 v3 => value'_interp_related_trans.
- Definition value_interp_related {t} : relation (@value var t)
- := value'_interp_related.
-
Lemma value_interp_related_sym_iff {t v1 v2}
: @value_interp_related t v1 v2
<-> @value_interp_related t v2 v1.
@@ -1743,6 +1735,40 @@ Module Compilers.
: Transitive (@value_interp_related t) | 10
:= fun v1 v2 v3 => value_interp_related_trans.
+ Lemma interp_Base_value {with_lets2 t} v1 (v2 : value' with_lets2 t)
+ : v1 === v2 -> @Base_value var t v1 === v2.
+ Proof using Type.
+ cbv [Base_value]; break_innermost_match; destruct with_lets2; cbn [value'_interp_related UnderLets.interp];
+ exact id.
+ Qed.
+
+ Fixpoint value_interp_related_reify {with_lets1 with_lets2 t e1 e2} {struct t}
+ : e1 === e2
+ -> expr.interp ident_interp (@reify var with_lets1 t e1) == expr.interp ident_interp (@reify var with_lets2 t e2)
+ with value_interp_related_reflect {with_lets1 with_lets2 t e1 e2} {struct t}
+ : expr.interp ident_interp e1 == expr.interp ident_interp e2
+ -> @reflect var with_lets1 t e1 === @reflect var with_lets2 t e2.
+ Proof using Type.
+ all: destruct t as [t|s d];
+ [ clear value_interp_related_reflect value_interp_related_reify
+ | pose proof (fun with_lets1 with_lets2 => value_interp_related_reify with_lets1 with_lets2 s) as value_interp_related_reify_s;
+ pose proof (fun with_lets1 with_lets2 => value_interp_related_reify with_lets1 with_lets2 d) as value_interp_related_reify_d;
+ pose proof (fun with_lets1 with_lets2 => value_interp_related_reflect with_lets1 with_lets2 s) as value_interp_related_reflect_s;
+ pose proof (fun with_lets1 with_lets2 => value_interp_related_reflect with_lets1 with_lets2 d) as value_interp_related_reflect_d;
+ clear value_interp_related_reify value_interp_related_reflect ].
+
+ all: repeat first [ progress cbn [reflect reify type.related value'_interp_related expr.interp] in *
+ | progress cbv [respectful]
+ | progress fold (@reify) (@reflect) in *
+ | break_innermost_match_step
+ | rewrite UnderLets.interp_to_expr
+ | exact id
+ | progress intros
+ | match goal with
+ | [ H : _ |- _ ] => apply H; clear H
+ end ].
+ Qed.
+
Lemma interp_reify_reflect {with_lets t} e v
: expr.interp ident_interp e == v -> expr.interp ident_interp (@reify _ with_lets t (reflect e)) == v.
Proof using Type.
@@ -1754,6 +1780,150 @@ Module Compilers.
apply IHd; cbn [expr.interp]; auto.
Qed.
+ Lemma interp_reflect_reify {with_lets with_lets1 with_lets2 t} x y
+ : @value'_interp_related with_lets with_lets2 t x y -> @value'_interp_related with_lets1 with_lets2 t (reflect (@reify _ with_lets t x)) y.
+ Proof using Type.
+ revert with_lets with_lets1 with_lets2 x y; induction t as [|s IHs d IHd]; intros ? ? ? ? ?;
+ cbn [type.related value'_interp_related reflect reify] in *;
+ fold (@reify var) (@reflect var); cbv [respectful]; break_innermost_match;
+ cbn [expr.interp UnderLets.to_expr UnderLets.interp]; rewrite ?UnderLets.interp_to_expr; auto; [].
+ intros Hf ? ? Hx.
+ etransitivity.
+ { eapply value_interp_related_reflect; cbn [expr.interp].
+ eapply value_interp_related_reify.
+ eapply Hf.
+ eapply value_interp_related_reflect; cbn [expr.interp].
+ eapply value_interp_related_reify; eassumption. }
+ { etransitivity; [ eapply IHd; symmetry | ]; eapply Hf; [ symmetry | eassumption ].
+ eapply IHs; symmetry; eassumption. }
+ Qed.
+
+ Lemma value_interp_related_of_ok {with_lets1 with_lets2 t v1 v2}
+ : @value'_interp_related with_lets1 with_lets2 t v1 v2
+ -> value'_interp v1 == value'_interp v2.
+ Proof using Type.
+ revert with_lets1 with_lets2 v1 v2; induction t as [|s IHs d IHd].
+ { cbn; intros; break_innermost_match; rewrite ?UnderLets.interp_to_expr; assumption. }
+ { cbn [type.related value'_interp value'_interp_related value']; cbv [respectful].
+ intros.
+ apply IHd; fold (@reify var) (@reflect var).
+ match goal with H : _ |- _ => apply H end.
+ apply value_interp_related_reflect; cbn [expr.interp]; assumption. }
+ Qed.
+
+ Local Ltac t_value_interp_related :=
+ repeat match goal with
+ | _ => progress cbn [expr.interp]
+ | [ |- expr.interp ?ii ?e == ?v ]
+ => is_var v; is_evar e; refine (_ : expr.interp ii (expr.Var v) == v)
+ | [ H : ?R ?x ?y |- ?R ?x ?x ]
+ => etransitivity; (idtac + symmetry); eassumption
+ | [ H : ?R ?y ?x |- ?R ?x ?x ]
+ => etransitivity; (idtac + symmetry); eassumption
+ | [ |- expr.interp _ (reify _) == expr.interp _ (reify _) ]
+ => eapply value_interp_related_reify
+ | [ |- reflect _ === reflect _ ]
+ => eapply value_interp_related_reflect
+ | [ |- reflect (expr.Var _) === _ ]
+ => etransitivity; [ eapply value_interp_related_reflect | ]
+ | [ |- _ === reflect (expr.Var _) ]
+ => etransitivity; [ | eapply value_interp_related_reflect ]
+ | [ |- _ === reflect ?v ]
+ => is_evar v; symmetry; eapply interp_reflect_reify
+ | [ |- reflect ?v === _ ]
+ => is_evar v; eapply interp_reflect_reify
+ | [ |- _ == expr.interp _ (reify ?v) ]
+ => is_evar v; symmetry; eapply interp_reify_reflect
+ | [ |- expr.interp _ (reify ?v) == _ ]
+ => is_evar v; eapply interp_reify_reflect
+ | [ |- expr.interp _ (reify ?x) == ?v ]
+ => is_var x; is_evar v; eapply value_interp_related_reify
+ | [ |- ?v == expr.interp _ (reify ?x) ]
+ => is_var x; is_evar v; eapply value_interp_related_reify
+ | [ |- expr.interp _ (reify ?x) == expr.interp _ ?v ]
+ => is_var x; is_evar v; eapply value_interp_related_reify
+ | [ |- expr.interp _ ?v == expr.interp _ (reify ?x) ]
+ => is_var x; is_evar v; eapply value_interp_related_reify
+ | [ H : forall x1 x2, x1 === x2 -> ?f1 x1 === ?f2 x2 |- ?f1 _ === _ ] => eapply H; clear H
+ | [ H : (forall x1 x2, x1 === x2 -> ?f1 x1 === reflect (?f2 @ reify x2)%expr)
+ |- ?f1 _ === reflect (?f2 @ reify _)%expr ]
+ => eapply H; clear H
+ | [ H : forall x y, x == y -> _ == expr.interp _ ?f2 y |- _ == expr.interp _ ?f2 _ ]
+ => etransitivity; [ | eapply H ]; clear H
+ | _ => (idtac + symmetry); eassumption
+ end.
+
+ Lemma value_interp_related_reify_reflect_iff
+ {with_lets1 with_lets2 t v1 e2}
+ (v2 := reflect e2)
+ : @value_interp_ok with_lets1 t v1
+ -> expr.interp ident_interp e2 == expr.interp ident_interp e2
+ -> (@value'_interp_related with_lets1 with_lets2 t v1 v2
+ <-> expr.interp ident_interp (reify v1) == expr.interp ident_interp e2).
+ Proof using Type.
+ subst v2; cbv [value_interp_ok] in *.
+ revert with_lets1 with_lets2 v1 e2.
+ induction t as [|s IHs d IHd]; cbn [value'_interp_related] in *.
+ { cbn; intros; break_innermost_match; rewrite ?UnderLets.interp_to_expr; reflexivity. }
+ { intros ? ? v1 e2 H1 H2.
+ cbn [type.related] in *; cbv [respectful] in *.
+ specialize (IHd true true); specialize (IHs false false).
+ cbn [reify reflect expr.interp] in *.
+ fold (@reify var) (@reflect var) in *.
+ cbn [value' expr.interp] in *.
+ specialize (fun x1 (x2 : value' false s) pf1 => IHd (v1 x1) (e2 @ reify x2)%expr (H1 _ _ pf1)); cbn [expr.interp] in *.
+ specialize (fun x1 x2 pf1 pf2 => IHd x1 x2 pf1 (H2 _ _ (value_interp_related_reify pf2))).
+ split; intros H ? ? H'; [ etransitivity; [ eapply IHd | eapply H2 ]; clear IHd | apply IHd; clear IHd ]; cbn [expr.interp] in *.
+ all: unshelve (t_value_interp_related; t_value_interp_related); trivial. }
+ Qed.
+
+ Lemma value_interp_related_iff_of_ok {t with_lets1 with_lets2 v1 v2}
+ : @value_interp_ok with_lets1 t v1
+ -> @value_interp_ok with_lets2 t v2
+ -> (@value'_interp_related with_lets1 with_lets2 t v1 v2
+ <-> value'_interp v1 == value'_interp v2).
+ Proof using Type.
+ cbv [value_interp_ok value'_interp] in *.
+ intros H1 H2; split; intro H.
+ { eapply value_interp_related_reify_reflect_iff;
+ [ eassumption | eapply value_interp_related_reify | symmetry; eapply interp_reflect_reify ].
+ { etransitivity; (idtac + symmetry); eassumption. }
+ { eapply value'_interp_related_sym_iff; eassumption. } }
+ { eapply value_interp_related_reify_reflect_iff in H; [ | eassumption | ].
+ { eapply value'_interp_related_trans; [ eexact H | eapply interp_reflect_reify ].
+ etransitivity; (idtac + symmetry); eassumption. }
+ { eapply value_interp_related_reify.
+ etransitivity; (idtac + symmetry); eassumption. } }
+ Unshelve.
+ all: trivial.
+ Qed.
+
+ Lemma value'_interp_app {with_lets s d f x}
+ : @value_interp_ok with_lets (type.arrow s d) f
+ -> @value_interp_ok _ s x
+ -> value'_interp (f x) == value'_interp f (value'_interp x).
+ Proof using Type.
+ cbv [value_interp_ok]; cbn [value'_interp_related value'] in *.
+ intros Hf Hx.
+ transitivity (value'_interp (with_lets:=false) (t:=type.arrow s d) (fun x => f (reflect (reify x))) (value'_interp x)).
+ all: fold (@value' var).
+ { cbv [value'_interp]; cbn [reify reflect expr.interp].
+ fold (@reify var) (@reflect var).
+ eapply value_interp_related_iff_of_ok; apply Hf;
+ repeat first [ eassumption
+ | progress cbn [expr.interp]
+ | (idtac + symmetry); apply interp_reflect_reify
+ | eapply value_interp_related_reflect
+ | eapply value_interp_related_reify
+ | etransitivity; [ eapply value_interp_related_reflect; progress cbn [expr.interp] | ] ]. }
+ { eapply (@value_interp_related_iff_of_ok (type.arrow s d));
+ fold (@type.related); cbv [value_interp_ok]; cbn [value'_interp_related];
+ [ .. | eapply value_interp_related_iff_of_ok ]; try assumption.
+ all: intros; apply Hf.
+ all: repeat first [ (idtac + symmetry); apply interp_reflect_reify
+ | (idtac + symmetry); assumption ]. }
+ Qed.
+
Lemma interp_of_wf_reify_expr G {t}
(HG : forall t v1 v2, List.In (existT _ t (v1, v2)) G -> expr.interp ident_interp (reify v1) == v2)
e1 e2
@@ -1820,7 +1990,7 @@ Module Compilers.
{t} {p : pattern t} (r : @rewrite_rule_data t p)
: Prop
:= forall x y,
- related_unification_resultT (fun t => value_interp_related) x y
+ related_unification_resultT (fun t v1 v2 => value_interp_ok v1 /\ value_interp_ok v2 /\ value'_interp v1 == value'_interp v2) x y
-> option_eq
(fun fx gy
=> related_sigT_by_eq
@@ -1861,7 +2031,7 @@ Module Compilers.
intro H.
repeat (let x := fresh "x" in intro x; specialize (H x)).
intros X Y HXY.
- pose proof (related_app_with_unification_resultT _ _ _ _ _ _ ltac:(eassumption) ltac:(eassumption)) as H'.
+ pose proof (related_app_with_unification_resultT _ _ _ _ _ _ ltac:(eassumption) ltac:(eapply map_related_unification_resultT; [ | eassumption ]; intros; cbv beta in *; destruct_head'_and; eapply value_interp_related_iff_of_ok; eassumption)) as H'.
cps_id'_with_option app_with_unification_resultT_cps_id.
cbv [deep_rewrite_ruleTP_gen] in *.
let H1 := fresh in