aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--_CoqProject1
-rw-r--r--src/Experiments/NewPipeline/RewriterRulesInterpGood.v532
-rw-r--r--src/Experiments/NewPipeline/RewriterWf1.v215
-rw-r--r--src/Experiments/NewPipeline/RewriterWf2.v2
4 files changed, 728 insertions, 22 deletions
diff --git a/_CoqProject b/_CoqProject
index 70fca8fd2..0b4816189 100644
--- a/_CoqProject
+++ b/_CoqProject
@@ -264,6 +264,7 @@ src/Experiments/NewPipeline/MiscCompilerPassesProofs.v
src/Experiments/NewPipeline/Rewriter.v
src/Experiments/NewPipeline/RewriterProofs.v
src/Experiments/NewPipeline/RewriterRulesGood.v
+src/Experiments/NewPipeline/RewriterRulesInterpGood.v
src/Experiments/NewPipeline/RewriterWf1.v
src/Experiments/NewPipeline/RewriterWf2.v
src/Experiments/NewPipeline/SlowPrimeSynthesisExamples.v
diff --git a/src/Experiments/NewPipeline/RewriterRulesInterpGood.v b/src/Experiments/NewPipeline/RewriterRulesInterpGood.v
new file mode 100644
index 000000000..7647b1f06
--- /dev/null
+++ b/src/Experiments/NewPipeline/RewriterRulesInterpGood.v
@@ -0,0 +1,532 @@
+Require Import Coq.ZArith.ZArith.
+Require Import Coq.micromega.Lia.
+Require Import Coq.Lists.List.
+Require Import Coq.Classes.Morphisms.
+Require Import Coq.MSets.MSetPositive.
+Require Import Coq.FSets.FMapPositive.
+Require Import Crypto.Experiments.NewPipeline.Language.
+Require Import Crypto.Experiments.NewPipeline.LanguageInversion.
+Require Import Crypto.Experiments.NewPipeline.LanguageWf.
+Require Import Crypto.Experiments.NewPipeline.UnderLetsProofs.
+Require Import Crypto.Experiments.NewPipeline.GENERATEDIdentifiersWithoutTypesProofs.
+Require Import Crypto.Experiments.NewPipeline.Rewriter.
+Require Import Crypto.Experiments.NewPipeline.RewriterWf1.
+Require Import Crypto.Util.ZUtil.Tactics.LtbToLt.
+Require Import Crypto.Util.ZUtil.Tactics.DivModToQuotRem.
+Require Import Crypto.Util.ZUtil.Tactics.PullPush.Modulo.
+Require Import Crypto.Util.ZUtil.Hints.
+Require Import Crypto.Util.ZUtil.Hints.Core.
+Require Import Crypto.Util.ZUtil.ZSimplify.Core.
+Require Import Crypto.Util.ZUtil.ZSimplify.
+Require Import Crypto.Util.ZUtil.ZSimplify.Simple.
+Require Import Crypto.Util.ZUtil.Definitions.
+Require Import Crypto.Util.ZUtil.AddGetCarry.
+Require Import Crypto.Util.ZUtil.MulSplit.
+Require Import Crypto.Util.ZUtil.Zselect.
+Require Import Crypto.Util.Tactics.NormalizeCommutativeIdentifier.
+Require Import Crypto.Util.Tactics.BreakMatch.
+Require Import Crypto.Util.Tactics.SplitInContext.
+Require Import Crypto.Util.Tactics.SpecializeAllWays.
+Require Import Crypto.Util.Tactics.SpecializeBy.
+Require Import Crypto.Util.Tactics.RewriteHyp.
+Require Import Crypto.Util.Tactics.Head.
+Require Import Crypto.Util.Prod.
+Require Import Crypto.Util.Bool.
+Require Import Crypto.Util.ListUtil.
+Require Import Crypto.Util.ListUtil.ForallIn.
+Require Import Crypto.Util.NatUtil.
+Require Import Crypto.Util.Option.
+Require Import Crypto.Util.CPSNotations.
+Require Import Crypto.Util.HProp.
+Require Import Crypto.Util.Decidable.
+Import ListNotations. Local Open Scope list_scope.
+Local Open Scope Z_scope.
+
+Import EqNotations.
+Module Compilers.
+ Import Language.Compilers.
+ Import LanguageInversion.Compilers.
+ Import LanguageWf.Compilers.
+ Import UnderLetsProofs.Compilers.
+ Import GENERATEDIdentifiersWithoutTypesProofs.Compilers.
+ Import Rewriter.Compilers.
+ Import RewriterWf1.Compilers.
+ Import expr.Notations.
+ Import RewriterWf1.Compilers.RewriteRules.
+ Import defaults.
+
+ Module Import RewriteRules.
+ Import Rewriter.Compilers.RewriteRules.
+
+ Local Lemma rlist_rect_eq {var A P ivar} Pnil Pcons ls
+ : @rlist_rect var A P ivar Pnil Pcons ls
+ = match invert_expr.reflect_list ls with
+ | Some ls
+ => Some (list_rect
+ (fun _ => _)
+ Pnil
+ (fun x xs rec => rec' <-- rec; Pcons x xs rec')
+ ls)%under_lets
+ | None => None
+ end.
+ Proof. cbv [rlist_rect Compile.option_bind' Option.bind]; reflexivity. Qed.
+
+ Local Lemma UnderLets_interp_list_rect {A P} Pnil Pcons ls
+ : UnderLets.interp
+ (@ident.interp)
+ (list_rect
+ (fun _ : list A => UnderLets.UnderLets base.type ident _ P)
+ Pnil
+ (fun x xs rec => rec' <-- rec; Pcons x xs rec')
+ ls)%under_lets
+ = list_rect
+ (fun _ => P)
+ (UnderLets.interp (@ident.interp) Pnil)
+ (fun x xs rec => UnderLets.interp (@ident.interp) (Pcons x xs rec))
+ ls.
+ Proof.
+ induction ls as [|x xs IHxs]; cbn [list_rect]; [ reflexivity | ].
+ rewrite UnderLets.interp_splice, IHxs; reflexivity.
+ Qed.
+
+ Local Notation rewrite_rules_interp_goodT := (@Compile.rewrite_rules_interp_goodT ident pattern.ident (@pattern.ident.arg_types) (@pattern.ident.type_vars) (@pattern.ident.to_typed) (@ident.interp)).
+
+ Local Ltac do_cbv0 :=
+ cbv [id
+ Compile.rewrite_rules_interp_goodT
+ Compile.rewrite_rule_data_interp_goodT Compile.under_with_unification_resultT_relation_hetero Compile.under_with_unification_resultT'_relation_hetero Compile.wf_with_unification_resultT Compile.under_type_of_list_relation_cps pattern.pattern_of_anypattern pattern.type_of_anypattern Compile.rew_replacement Compile.rew_is_cps Compile.rew_should_do_again Compile.rew_with_opt Compile.rew_under_lets Compile.wf_with_unification_resultT' Compile.pattern_default_interp pattern.type.under_forall_vars_relation Compile.deep_rewrite_ruleTP_gen Compile.with_unification_resultT' pattern.ident.arg_types pattern.type.lam_forall_vars Compile.pattern_default_interp' pattern.collect_vars PositiveMap.empty Compile.ident_collect_vars pattern.ident.type_vars pattern.type.collect_vars PositiveSet.elements PositiveSet.union pattern.base.collect_vars PositiveSet.empty PositiveSet.xelements Compile.lam_type_of_list id pattern.ident.to_typed Compile.forall2_type_of_list_cps Compile.deep_rewrite_ruleTP_gen_good_relation Compile.normalize_deep_rewrite_rule_cps_id_hypsT Compile.normalize_deep_rewrite_rule pattern.type.subst_default PositiveSet.add PositiveSet.rev PositiveSet.rev_append PositiveMap.add Compile.option_bind' Compile.wf_value Compile.value pattern.base.subst_default PositiveMap.find Compile.rewrite_ruleTP ident.smart_Literal Compile.value_interp_related Compile.value'_interp_related].
+ Local Ltac do_cbv :=
+ do_cbv0;
+ cbv [List.map List.fold_right List.rev list_rect orb List.app].
+
+ Local Ltac start_interp_good :=
+ do_cbv;
+ lazymatch goal with
+ | [ |- forall x p, In (@existT ?A ?P x p) ?ls -> @?Q x p ]
+ => let Q' := fresh in
+ pose Q as Q';
+ change (forall x p, In (@existT A P x p) ls -> Q' x p);
+ apply (@forall_In_existT A P Q' ls); cbn [projT1 projT2]; cbv [id];
+ subst Q'; cbn [projT1 projT2]
+ end;
+ do_cbv0;
+ repeat first [ progress intros
+ | match goal with
+ | [ |- { pf : ?x = ?x | _ } ] => (exists eq_refl)
+ | [ |- True /\ _ ] => split; [ exact I | ]
+ end
+ | progress cbn [eq_rect] in * ];
+ cbn [fst snd base.interp base.base_interp type.interp projT1 projT2 UnderLets.interp expr.interp type.related ident.interp ident.gen_interp] in *.
+
+ Local Ltac interp_good_t_step :=
+ first [ reflexivity
+ | match goal with
+ | [ |- context[(fst ?x, snd ?x)] ] => progress eta_expand
+ | [ |- context[match ?x with pair a b => _ end] ] => progress eta_expand
+ end
+ | progress cbn [expr.interp ident.interp ident.gen_interp fst snd Compile.reify Compile.reflect Compile.wf_value' Compile.value' Option.bind UnderLets.interp list_case type.interp base.interp base.base_interp ident.to_fancy invert_Some ident.fancy.interp ident.fancy.interp_with_wordmax Compile.reify_expr] in *
+ | progress cbv [Compile.option_bind' respectful] in *
+ | progress fold (@type.interp _ base.interp)
+ | progress fold (@base.interp)
+ | match goal with
+ | [ |- context[List.map _ (Lists.List.repeat _ _)] ] => rewrite map_repeat
+ | [ |- context[List.map _ (List.map _ _)] ] => rewrite map_map
+ | [ |- context[List.map (fun x => x) _] ] => rewrite map_id
+ | [ |- context[List.map _ (List.rev _)] ] => rewrite map_rev
+ | [ |- context[List.map _ (firstn _ _)] ] => rewrite <- firstn_map
+ | [ |- context[List.map _ (skipn _ _)] ] => rewrite <- skipn_map
+ | [ |- context[List.length (List.map _ _)] ] => rewrite map_length
+ | [ |- context[List.combine (List.map _ _) _] ] => rewrite combine_map_l
+ | [ |- context[List.combine _ (List.map _ _)] ] => rewrite combine_map_r
+ | [ |- context[expr.interp _ (reify_list _)] ] => rewrite interp_reify_list
+ | [ |- context[expr.interp _ (UnderLets.to_expr ?e)] ] => rewrite UnderLets.interp_to_expr
+ | [ |- context[UnderLets.interp _ (UnderLets.splice_list _ _)] ] => rewrite UnderLets.interp_splice_list
+ | [ |- context[rlist_rect] ] => rewrite rlist_rect_eq
+ | [ |- context[UnderLets.interp _ (list_rect _ _ _ _)] ] => rewrite UnderLets_interp_list_rect
+ | [ |- context[UnderLets.interp _ (UnderLets.splice _ _)] ] => rewrite UnderLets.interp_splice
+ | [ |- context[list_rect _ _ _ (List.map _ _)] ] => rewrite list_rect_map
+ | [ |- list_rect _ _ _ _ = List.app ?ls1 ?ls2 ]
+ => rewrite (eq_app_list_rect ls1 ls2)
+ | [ |- list_rect _ _ _ _ = @flat_map ?A ?B ?f ?ls ]
+ => rewrite (@eq_flat_map_list_rect A B f ls)
+ | [ |- list_rect _ _ _ _ = @partition ?A ?f ?ls ]
+ => rewrite (@eq_partition_list_rect A f ls)
+ | [ |- list_rect _ _ _ _ = @List.map ?A ?B ?f ?ls ]
+ => rewrite (@eq_map_list_rect A B f ls)
+ | [ |- _ = @fold_right ?A ?B ?f ?v ?ls ]
+ => rewrite (@eq_fold_right_list_rect A B f v ls)
+ end
+ | progress intros
+ | progress subst
+ | progress inversion_option
+ | progress Z.ltb_to_lt
+ | progress split_andb
+ | match goal with
+ | [ |- Lists.List.repeat _ _ = Lists.List.repeat _ _ ] => apply f_equal2
+ | [ |- firstn _ _ = firstn _ _ ] => apply f_equal2
+ | [ |- skipn _ _ = skipn _ _ ] => apply f_equal2
+ | [ |- rev _ = rev _ ] => apply f_equal
+ | [ |- List.app ?l1 ?l2 = List.app ?l1' ?l2 ] => apply f_equal2
+ | [ |- List.app ?l1 ?l2 = List.app ?l1 ?l2' ] => apply f_equal2
+ | [ |- cons _ _ = cons _ _ ] => apply f_equal2
+ | [ |- list_rect _ ?Pnil ?Pcons ?ls = list_rect _ ?Pnil ?Pcons' ?ls ]
+ => apply list_rect_Proper; [ reflexivity | repeat intro | reflexivity ]
+ | [ |- bool_rect _ ?x ?y ?b = bool_rect _ ?x ?y ?b' ]
+ => apply f_equal3; [ reflexivity | reflexivity | solve [ repeat interp_good_t_step ] ]
+ | [ H : expr.wf _ ?v1 ?v2 |- expr.interp _ ?v1 = expr.interp _ ?v2 ]
+ => apply (expr.wf_interp_Proper _ _ _ H ltac:(assumption))
+ | [ |- ?R (?f (?g (if ?b then ?x else ?y))) (bool_rect ?A ?B ?C ?D) ]
+ => rewrite <- (@Bool.pull_bool_if _ _ g b), <- (@Bool.pull_bool_if _ _ f b);
+ change (R (bool_rect _ (f (g x)) (f (g y)) b) (bool_rect A B C D))
+ | [ |- context[invert_expr.reflect_list ?ls] ]
+ => destruct (invert_expr.reflect_list ls) eqn:?; expr.invert_subst
+ | [ |- ?f (nth_default _ _ _) = _ ]
+ => rewrite <- (@map_nth_default_always _ _ f)
+ | [ |- map ?f ?ls = map ?g ?ls ] => apply map_ext_in
+ | [ |- List.map _ (update_nth _ _ _) = update_nth _ _ _ ] => apply map_update_nth_ext
+ | [ H : ?x = ?x -> _ |- _ ] => specialize (H eq_refl)
+ | [ H : forall v : unit, _ |- _ ] => specialize (H tt)
+ | [ H : _ = expr.interp ?ii ?v |- _ ] => is_var v; generalize dependent (expr.interp ii v); clear v
+ | [ |- bool_rect _ _ _ ?b = bool_rect _ _ _ ?b ]
+ => is_var b; destruct b; cbv [bool_rect]
+ | [ H : (forall x y, _ -> expr.interp _ (UnderLets.interp _ (?f1 x)) = expr.interp _ (UnderLets.interp _ (?f2 y)))
+ |- expr.interp _ (UnderLets.interp _ (?f1 ?x1)) = expr.interp _ (UnderLets.interp _ (?f2 ?x2)) ]
+ => apply H
+ | [ H : (forall x y, _ -> forall x' y', _ -> expr.interp _ (UnderLets.interp _ (?f1 x x')) = expr.interp _ (UnderLets.interp _ (?f2 y y')))
+ |- expr.interp _ (UnderLets.interp _ (?f1 ?x1 ?y1)) = expr.interp _ (UnderLets.interp _ (?f2 ?x2 ?y2)) ]
+ => apply H
+ | [ |- context G[rwhen ?v ?b] ]
+ => let c := constr:(rwhen v b) in
+ let c := (eval cbv [rwhen] in c) in
+ let G' := context G[c] in
+ change G';
+ destruct b eqn:?
+ | [ |- context G[rwhenl ?v ?b] ]
+ => let c := constr:(rwhenl v b) in
+ let c := (eval cbv [rwhenl] in c) in
+ let G' := context G[c] in
+ change G';
+ destruct b eqn:?
+ | [ H : negb ?b = true |- _ ] => rewrite (@Bool.negb_true_iff b) in H
+ | [ |- context[expr.interp ?ii ?v] ]
+ => is_var v; generalize dependent (expr.interp ii v); clear v; intro v
+ | [ |- context[Z.mul_split ?a ?b ?c] ]
+ => rewrite (surjective_pairing (Z.mul_split a b c)), Z.mul_split_div, Z.mul_split_mod
+ | [ |- context[Z.zselect] ] => rewrite Z.zselect_correct
+ | [ |- context[Z.sub_get_borrow_full ?a ?b ?c] ]
+ => rewrite (surjective_pairing (Z.sub_get_borrow_full a b c)), Z.sub_get_borrow_full_div, Z.sub_get_borrow_full_mod
+ | [ |- context[Z.sub_with_get_borrow_full ?a ?b ?c ?d] ]
+ => rewrite (surjective_pairing (Z.sub_with_get_borrow_full a b c d)), Z.sub_with_get_borrow_full_div, Z.sub_with_get_borrow_full_mod
+ | [ |- context[Z.add_get_carry_full ?a ?b ?c] ]
+ => rewrite (surjective_pairing (Z.add_get_carry_full a b c)), Z.add_get_carry_full_div, Z.add_get_carry_full_mod
+ | [ |- context[Z.add_with_get_carry_full ?a ?b ?c ?d] ]
+ => rewrite (surjective_pairing (Z.add_with_get_carry_full a b c d)), Z.add_with_get_carry_full_div, Z.add_with_get_carry_full_mod
+ | [ |- pair _ _ = pair _ _ ] => apply f_equal2
+ | [ |- ?a mod ?b = ?a' mod ?b ] => apply f_equal2; lia
+ | [ |- ?a / ?b = ?a' / ?b ] => apply f_equal2; lia
+ | [ |- Z.opp _ = Z.opp _ ] => apply f_equal
+ end
+ | match goal with
+ | [ |- context[?f (list_rect _ _ _ _)] ]
+ => match f with
+ | expr.interp _ => idtac
+ | Compile.reify_expr => idtac
+ end;
+ erewrite (@push_f_list_rect _ _ f)
+ by (intros;
+ repeat first [ progress cbn [expr.interp ident.interp ident.gen_interp UnderLets.interp Compile.reify_expr]
+ | rewrite UnderLets.interp_splice ];
+ match goal with
+ | [ |- ?LHS = ?Pcons' ?x ?xs ?rec ]
+ => let LHS' := match (eval pattern x, xs, rec in LHS) with ?f _ _ _ => f end in
+ unify Pcons' LHS'; reflexivity
+ end)
+ | [ |- context[?f (nat_rect _ _ _ _)] ]
+ => match f with
+ | expr.interp _ => idtac
+ | UnderLets.interp _ => idtac
+ | Compile.reify_expr => idtac
+ end;
+ erewrite (@push_f_nat_rect _ _ f)
+ by (intros;
+ repeat first [ progress cbn [expr.interp ident.interp ident.gen_interp UnderLets.interp Compile.reify_expr]
+ | rewrite UnderLets.interp_splice ];
+ match goal with
+ | [ |- ?LHS = ?PS' ?x ?rec ]
+ => let LHS' := match (eval pattern x, rec in LHS) with ?f _ _ => f end in
+ unify PS' LHS'; reflexivity
+ end)
+ | [ |- ?f (list_rect _ _ _ _) = list_rect _ _ _ _ ]
+ => match f with
+ | expr.interp _ => idtac
+ | Compile.reify_expr => idtac
+ end;
+ erewrite (@push_f_list_rect _ _ f);
+ [ apply list_rect_Proper; repeat intro; try reflexivity | ]
+ | [ |- ?f (nat_rect _ _ _ _) = nat_rect _ _ _ _ ]
+ => match f with
+ | expr.interp _ => idtac
+ | UnderLets.interp _ => idtac
+ | Compile.reify_expr => idtac
+ end;
+ erewrite (@push_f_nat_rect _ _ f);
+ [ apply nat_rect_Proper_nondep; repeat intro; try reflexivity | ]
+ end
+ | break_innermost_match_step
+ | break_innermost_match_hyps_step
+ | match goal with
+ | [ H : context[expr.interp _ (UnderLets.interp _ (?f _ _ _))]
+ |- expr.interp _ (UnderLets.interp _ (?f _ _ _)) = _ ]
+ => apply H
+ | [ |- context[Z.shiftl] ] => rewrite Z.shiftl_mul_pow2 by auto with zarith
+ | [ |- context[Z.shiftr] ] => rewrite Z.shiftr_div_pow2 by auto with zarith
+ | [ |- context[Z.shiftl _ (-_)] ] => rewrite Z.shiftl_opp_r
+ | [ H : ?x = 2^Z.log2 ?x |- context[2^Z.log2 ?x] ] => rewrite <- H
+ | [ H : ?x = 2^?n |- context[Z.land _ (?x - 1)] ]
+ => rewrite !Z.sub_1_r, H, <- Z.ones_equiv, Z.land_ones by auto with zarith
+ | [ |- _ = _ :> BinInt.Z ] => progress normalize_commutative_identifier Z.land Z.land_comm
+ | [ H : ?x = ?y, H' : ?x <> ?y |- _ ] => exfalso; apply H', H
+ | [ H : ?x = 2^Z.log2_up ?x - 1 |- context[2^Z.log2_up ?x - 1] ] => rewrite <- H
+ | [ H : ?x = 2^Z.log2 ?x, H' : context[2^Z.log2 ?x] |- _ = _ :> BinInt.Z ]
+ => rewrite <- H in H'
+ | [ |- _ = _ :> BinInt.Z ] => progress autorewrite with zsimplify_const
+ | [ |- ?f (?g (nat_rect _ _ _ ?n ?v)) = nat_rect _ _ _ ?n _ ]
+ => revert v; is_var n; induction n; intro v; cbn [nat_rect]
+ | [ |- _ mod ?x = _ mod ?x ]
+ => progress (push_Zmod; pull_Zmod)
+ | [ |- _ mod ?x = _ mod ?x ]
+ => apply f_equal2; (lia + nia)
+ | [ |- _ = _ :> BinInt.Z ] => progress autorewrite with zsimplify_fast
+ end ].
+
+ Lemma nbe_rewrite_rules_interp_good
+ : rewrite_rules_interp_goodT nbe_rewrite_rules.
+ Proof using Type.
+ Time start_interp_good.
+ Time all: repeat interp_good_t_step.
+ Qed.
+
+ Axiom proof_admitted : False.
+ Local Notation admit := (match proof_admitted with end).
+
+ Lemma arith_rewrite_rules_interp_good max_const
+ : rewrite_rules_interp_goodT (arith_rewrite_rules max_const).
+ Proof using Type.
+ Time start_interp_good.
+ Time all: try solve [ repeat interp_good_t_step; (lia + nia) ].
+ (* This is mainly for display *)
+ all: repeat first [ progress cbn [Compile.value' Compile.reify] in *
+ | progress subst
+ | match goal with
+ | [ H : context[expr.interp ?ii ?v] |- _ ]
+ => is_var v; generalize dependent (expr.interp ii v); clear v; intro v; intros
+ | [ |- context[expr.interp ?ii ?v] ]
+ => is_var v; generalize dependent (expr.interp ii v); clear v; intro v; intros
+ end ].
+ (* 9 subgoals (ID 30397)
+
+ max_const, x, x0 : Z
+ v1 : expr (type.base base.type.Z)
+ ============================
+ match
+ (x1 <- rwhen (Some (v1, (##0)%expr)%expr_pat) (x0 =? 1);
+ Some (UnderLets.Base x1))%option
+ with
+ | Some v0 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v0) =
+ Z.mul_split x x0 (expr.interp (@ident.interp) v1)
+ | None => True
+ end
+
+subgoal 2 (ID 30445) is:
+ match
+ (x1 <- rwhen (Some (v1, (##0)%expr)%expr_pat) (x0 =? 1);
+ Some (UnderLets.Base x1))%option
+ with
+ | Some v0 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v0) =
+ Z.mul_split x (expr.interp (@ident.interp) v1) x0
+ | None => True
+ end
+subgoal 3 (ID 30493) is:
+ match
+ (x1 <- rwhen (Some ((- v1)%expr, (##0)%expr)%expr_pat) (x0 =? -1);
+ Some (UnderLets.Base x1))%option
+ with
+ | Some v0 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v0) =
+ Z.mul_split x x0 (expr.interp (@ident.interp) v1)
+ | None => True
+ end
+subgoal 4 (ID 30541) is:
+ match
+ (x1 <- rwhen (Some ((- v1)%expr, (##0)%expr)%expr_pat) (x0 =? -1);
+ Some (UnderLets.Base x1))%option
+ with
+ | Some v0 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v0) =
+ Z.mul_split x (expr.interp (@ident.interp) v1) x0
+ | None => True
+ end
+subgoal 5 (ID 30631) is:
+ match
+ (x0 <- rwhen (Some (v0, (##0)%expr)%expr_pat) (x =? 0);
+ Some (UnderLets.Base x0))%option
+ with
+ | Some v1 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v1) =
+ Z.add_get_carry_full v2 x (expr.interp (@ident.interp) v0)
+ | None => True
+ end
+subgoal 6 (ID 30721) is:
+ match
+ (x0 <- rwhen (Some (v0, (##0)%expr)%expr_pat) (x =? 0);
+ Some (UnderLets.Base x0))%option
+ with
+ | Some v1 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v1) =
+ Z.add_get_carry_full v2 (expr.interp (@ident.interp) v0) x
+ | None => True
+ end
+subgoal 7 (ID 30772) is:
+ match
+ (x2 <- rwhen (Some (v1, (##0)%expr)%expr_pat) ((x0 =? 0) && (x1 =? 0));
+ Some (UnderLets.Base x2))%option
+ with
+ | Some v0 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v0) =
+ Z.add_with_get_carry_full x x0 x1 (expr.interp (@ident.interp) v1)
+ | None => True
+ end
+subgoal 8 (ID 30824) is:
+ match
+ (x2 <- rwhen (Some (v1, (##0)%expr)%expr_pat) ((x0 =? 0) && (x1 =? 0));
+ Some (UnderLets.Base x2))%option
+ with
+ | Some v0 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v0) =
+ Z.add_with_get_carry_full x x0 (expr.interp (@ident.interp) v1) x1
+ | None => True
+ end
+subgoal 9 (ID 30915) is:
+ match
+ rwhenl
+ (Some
+ (UnderLets.UnderLet
+ (#(ident.Z_add_with_get_carry)%expr @ v1 @ v0 @ (##x)%expr @
+ (##x0)%expr)%expr_pat
+ (fun vc : Z * Z =>
+ UnderLets.Base (#(ident.fst)%expr @ ($vc)%expr, (##0)%expr)%expr_pat)))
+ ((x =? 0) && (x0 =? 0))
+ with
+ | Some v2 =>
+ expr.interp (@ident.interp) (UnderLets.interp (@ident.interp) v2) =
+ Z.add_with_get_carry_full (expr.interp (@ident.interp) v1)
+ (expr.interp (@ident.interp) v0) x x0
+ | None => True
+ end
+*)
+ 1-9: exact admit.
+ Qed.
+
+ Local Ltac fancy_local_t :=
+ repeat first [ match goal with
+ | [ H : forall s v v', ?invert_low s v = Some v' -> v = _,
+ H' : ?invert_low _ _ = Some _ |- _ ] => apply H in H'
+ end
+ | progress autorewrite with zsimplify in * ].
+
+ Lemma fancy_rewrite_rules_interp_good
+ (invert_low invert_high : Z -> Z -> option Z)
+ (Hlow : forall s v v', invert_low s v = Some v' -> v = Z.land v' (2^(s/2)-1))
+ (Hhigh : forall s v v', invert_high s v = Some v' -> v = Z.shiftr v' (s/2))
+ : rewrite_rules_interp_goodT (fancy_rewrite_rules invert_low invert_high).
+ Proof using Type.
+ Time start_interp_good.
+ Time all: try solve [
+ repeat interp_good_t_step;
+ cbv [Option.bind] in *;
+ repeat interp_good_t_step;
+ fancy_local_t;
+ repeat interp_good_t_step ].
+ Time all: repeat interp_good_t_step.
+ Time all: cbv [Option.bind] in *.
+ Time all: repeat interp_good_t_step.
+ Time all: fancy_local_t.
+ Time all: repeat interp_good_t_step.
+ all: repeat first [ progress cbn [Compile.value' Compile.reify] in *
+ | progress subst
+ | match goal with
+ | [ H : context[expr.interp ?ii ?v] |- _ ]
+ => is_var v; generalize dependent (expr.interp ii v); clear v; intro v; intros
+ | [ |- context[expr.interp ?ii ?v] ]
+ => is_var v; generalize dependent (expr.interp ii v); clear v; intro v; intros
+ end ].
+ all: repeat match goal with
+ | [ H : _ = _ :> BinInt.Z |- _ ] => revert H
+ | [ v : BinInt.Z |- _ ] => clear v || revert v
+ end.
+ (* 16 subgoals (ID 100240)
+
+ invert_low, invert_high : Z -> Z -> option Z
+ Hlow : forall s v v' : Z,
+ invert_low s v = Some v' -> v = Z.land v' (2 ^ (s / 2) - 1)
+ Hhigh : forall s v v' : Z, invert_high s v = Some v' -> v = Z.shiftr v' (s / 2)
+ ============================
+ forall x x0 v1 v0 : Z,
+ x = 2 ^ Z.log2 x -> (v1 + Z.shiftl v0 x0 mod x) / x = (v1 + Z.shiftl v0 x0) / x
+
+subgoal 2 (ID 100250) is:
+ forall x x0 v0 v1 : Z,
+ x = 2 ^ Z.log2 x -> (v0 + Z.shiftl v1 x0 mod x) / x = (Z.shiftl v1 x0 + v0) / x
+subgoal 3 (ID 100260) is:
+ forall x x0 v1 v0 : Z,
+ x = 2 ^ Z.log2 x -> (v1 + Z.shiftr v0 x0 mod x) / x = (v1 + Z.shiftr v0 x0) / x
+subgoal 4 (ID 100270) is:
+ forall x x0 v0 v1 : Z,
+ x = 2 ^ Z.log2 x -> (v0 + Z.shiftr v1 x0 mod x) / x = (Z.shiftr v1 x0 + v0) / x
+subgoal 5 (ID 100278) is:
+ forall x v1 v0 : Z, x = 2 ^ Z.log2 x -> (v1 + v0 mod x) / x = (v1 + v0) / x
+subgoal 6 (ID 100290) is:
+ forall x x0 v1 v0 v4 : Z,
+ x = 2 ^ Z.log2 x ->
+ (v1 + v0 + Z.shiftl v4 x0 mod x) / x = (v1 + v0 + Z.shiftl v4 x0) / x
+subgoal 7 (ID 100302) is:
+ forall x x0 v1 v4 v0 : Z,
+ x = 2 ^ Z.log2 x ->
+ (v1 + v4 + Z.shiftl v0 x0 mod x) / x = (v1 + Z.shiftl v0 x0 + v4) / x
+subgoal 8 (ID 100314) is:
+ forall x x0 v1 v0 v4 : Z,
+ x = 2 ^ Z.log2 x ->
+ (v1 + v0 + Z.shiftr v4 x0 mod x) / x = (v1 + v0 + Z.shiftr v4 x0) / x
+subgoal 9 (ID 100326) is:
+ forall x x0 v1 v4 v0 : Z,
+ x = 2 ^ Z.log2 x ->
+ (v1 + v4 + Z.shiftr v0 x0 mod x) / x = (v1 + Z.shiftr v0 x0 + v4) / x
+subgoal 10 (ID 100336) is:
+ forall x v1 v0 v4 : Z,
+ x = 2 ^ Z.log2 x -> (v1 + v0 + v4 mod x) / x = (v1 + v0 + v4) / x
+subgoal 11 (ID 100346) is:
+ forall x x0 v1 v0 : Z,
+ x = 2 ^ Z.log2 x -> (v1 - Z.shiftl v0 x0 mod x) / x = (v1 - Z.shiftl v0 x0) / x
+subgoal 12 (ID 100356) is:
+ forall x x0 v1 v0 : Z,
+ x = 2 ^ Z.log2 x -> (v1 - Z.shiftr v0 x0 mod x) / x = (v1 - Z.shiftr v0 x0) / x
+subgoal 13 (ID 100364) is:
+ forall x v1 v0 : Z, x = 2 ^ Z.log2 x -> (v1 - v0 mod x) / x = (v1 - v0) / x
+subgoal 14 (ID 100376) is:
+ forall x x0 v1 v0 v4 : Z,
+ x = 2 ^ Z.log2 x ->
+ (v0 - Z.shiftl v4 x0 mod x - v1) / x = (v0 - Z.shiftl v4 x0 - v1) / x
+subgoal 15 (ID 100388) is:
+ forall x x0 v1 v0 v4 : Z,
+ x = 2 ^ Z.log2 x ->
+ (v0 - Z.shiftr v4 x0 mod x - v1) / x = (v0 - Z.shiftr v4 x0 - v1) / x
+subgoal 16 (ID 100398) is:
+ forall x v1 v0 v4 : Z,
+ x = 2 ^ Z.log2 x -> (v0 - v4 mod x - v1) / x = (v0 - v4 - v1) / x
+*)
+ all: exact admit.
+ Qed.
+ End RewriteRules.
+End Compilers.
diff --git a/src/Experiments/NewPipeline/RewriterWf1.v b/src/Experiments/NewPipeline/RewriterWf1.v
index 37e192f07..4f2017cbf 100644
--- a/src/Experiments/NewPipeline/RewriterWf1.v
+++ b/src/Experiments/NewPipeline/RewriterWf1.v
@@ -204,6 +204,9 @@ Module Compilers.
(full_types : raw_pident -> Type)
(invert_bind_args invert_bind_args_unknown : forall t (idc : ident t) (pidc : raw_pident), option (full_types pidc))
+ (pident_to_typed
+ : forall t (idc : pident t) (evm : EvarMap),
+ type_of_list (pident_arg_types t idc) -> ident (pattern.type.subst_default t evm))
(type_of_raw_pident : forall (pidc : raw_pident), full_types pidc -> type.type base.type)
(raw_pident_to_typed : forall (pidc : raw_pident) (args : full_types pidc), ident (type_of_raw_pident pidc args))
(raw_pident_is_simple : raw_pident -> bool)
@@ -236,15 +239,24 @@ Module Compilers.
Local Notation to_raw_pattern := (@pattern.to_raw pident raw_pident (@strip_types)).
Local Notation reify := (@reify ident).
Local Notation reflect := (@reflect ident).
+ Local Notation reify_expr := (@reify_expr ident).
Local Notation rawexpr := (@rawexpr ident).
Local Notation eval_decision_tree var := (@eval_decision_tree ident var pident full_types invert_bind_args type_of_raw_pident raw_pident_to_typed).
Local Notation reveal_rawexpr e := (@reveal_rawexpr_cps ident _ e _ id).
Local Notation unify_pattern' var := (@unify_pattern' ident var pident pident_arg_types pident_unify pident_unify_unknown).
Local Notation unify_pattern var := (@unify_pattern ident var pident pident_arg_types pident_unify pident_unify_unknown type_vars_of_pident).
+ Definition lam_type_of_list {ls K} : (type_of_list ls -> K) -> type_of_list_cps K ls
+ := list_rect
+ (fun ls => (type_of_list ls -> K) -> type_of_list_cps K ls)
+ (fun f => f tt)
+ (fun T Ts rec k t => rec (fun ts => k (t, ts)))
+ ls.
+
Section with_var1.
Context {var : type -> Type}.
Local Notation expr := (@expr.expr base.type ident var).
+ Local Notation deep_rewrite_ruleTP_gen := (@deep_rewrite_ruleTP_gen ident var).
Local Notation "e1 === e2" := (existT expr _ e1 = existT expr _ e2) : type_scope.
@@ -572,27 +584,37 @@ Module Compilers.
| break_match_step ltac:(fun _ => idtac) ].
Qed.
- Lemma normalize_deep_rewrite_rule_cps_id
- {should_do_again with_opt under_lets is_cps t v T k}
- (Hk : k None = None)
- (Hv : (match is_cps, with_opt return @deep_rewrite_ruleTP_gen ident var should_do_again with_opt under_lets is_cps t -> Prop
- with
- | true, true => fun v => forall T k, v T k = k (v _ id)
- | true, false => fun v => forall T k, v T k = (v' <- v _ (@Some _); k v')%option
- | false, _ => fun _ => True
- end)
- v)
- : @normalize_deep_rewrite_rule ident var should_do_again with_opt under_lets is_cps t v T k = k (@normalize_deep_rewrite_rule ident var should_do_again with_opt under_lets is_cps t v _ id).
- Proof using Type.
- clear -Hv Hk; cbn in *.
- repeat first [ progress cbn in *
- | progress destruct_head'_bool
- | reflexivity
- | progress cbv [id Option.bind] in *
- | solve [ auto ]
- | break_innermost_match_step
- | rewrite Hv; (solve [ auto ] + break_innermost_match_step) ].
- Qed.
+ Section normalize_deep_rewrite_rule_cps_id.
+ Context {should_do_again with_opt under_lets is_cps : bool}
+ {t}
+ {v : @deep_rewrite_ruleTP_gen should_do_again with_opt under_lets is_cps t}
+ {T}
+ {k : option (UnderLets var (@expr.expr base.type ident (if should_do_again then @value var else var) t)) -> option T}.
+
+ Definition normalize_deep_rewrite_rule_cps_id_hypsT
+ := ((match is_cps, with_opt return @deep_rewrite_ruleTP_gen should_do_again with_opt under_lets is_cps t -> Prop
+ with
+ | true, true => fun v => forall T k, v T k = k (v _ id)
+ | true, false => fun v => forall T k, v T k = (v' <- v _ (@Some _); k v')%option
+ | false, _ => fun _ => True
+ end)
+ v).
+
+ Lemma normalize_deep_rewrite_rule_cps_id
+ (Hk : k None = None)
+ (Hv : normalize_deep_rewrite_rule_cps_id_hypsT)
+ : @normalize_deep_rewrite_rule ident var should_do_again with_opt under_lets is_cps t v T k = k (@normalize_deep_rewrite_rule ident var should_do_again with_opt under_lets is_cps t v _ id).
+ Proof using Type.
+ clear -Hk Hv; cbv [normalize_deep_rewrite_rule_cps_id_hypsT] in *; cbn in *.
+ repeat first [ progress cbn in *
+ | progress destruct_head'_bool
+ | reflexivity
+ | progress cbv [id Option.bind] in *
+ | solve [ auto ]
+ | break_innermost_match_step
+ | rewrite Hv; (solve [ auto ] + break_innermost_match_step) ].
+ Qed.
+ End normalize_deep_rewrite_rule_cps_id.
End with_var1.
Section with_var2.
@@ -671,6 +693,26 @@ Module Compilers.
eapply wf_reify; auto. }
Qed.
+ Lemma wf_reify_expr G G' {t}
+ (HG : forall t v1 v2, List.In (existT _ t (v1, v2)) G -> @wf_value G' t v1 v2)
+ e1 e2
+ (Hwf : expr.wf G e1 e2)
+ : expr.wf G' (@reify_expr var1 t e1) (@reify_expr var2 t e2).
+ Proof using Type.
+ cbv [wf_value] in *; revert dependent G'; induction Hwf; intros; cbn [reify_expr];
+ first [ constructor | apply wf_reify ]; eauto; intros.
+ all: match goal with H : _ |- _ => apply H end.
+ all: repeat first [ progress cbn [In eq_rect] in *
+ | progress intros
+ | progress destruct_head'_or
+ | progress subst
+ | progress inversion_sigma
+ | progress inversion_prod
+ | apply wf_reflect
+ | solve [ eapply wf_value'_Proper_list; [ | solve [ eauto ] ]; wf_safe_t ]
+ | constructor ].
+ Qed.
+
Inductive wf_rawexpr : list { t : type & var1 t * var2 t }%type -> forall {t}, @rawexpr var1 -> @expr var1 t -> @rawexpr var2 -> @expr var2 t -> Prop :=
| Wf_rIdent {t} G known (idc : ident t) : wf_rawexpr G (rIdent known idc (expr.Ident idc)) (expr.Ident idc) (rIdent known idc (expr.Ident idc)) (expr.Ident idc)
| Wf_rApp {s d} G
@@ -994,6 +1036,137 @@ Module Compilers.
(rew [fun tp => @rewrite_rule_data1 _ (pattern.pattern_of_anypattern tp)] pf in r1)
r2 }).
End with_var2.
+
+ Section with_interp.
+ Context (ident_interp : forall t, ident t -> type.interp base.interp t)
+ {ident_interp_Proper : forall t, Proper (eq ==> type.eqv) (ident_interp t)}.
+ Local Notation var := (type.interp base.interp) (only parsing).
+ Local Notation expr := (@expr.expr base.type ident var).
+ Local Notation rewrite_rulesT := (@rewrite_rulesT ident var pident pident_arg_types type_vars_of_pident).
+ Local Notation rewrite_rule_data := (@rewrite_rule_data ident var pident pident_arg_types type_vars_of_pident).
+ Local Notation with_unif_rewrite_ruleTP_gen := (@with_unif_rewrite_ruleTP_gen ident var pident pident_arg_types type_vars_of_pident).
+ Local Notation with_unification_resultT' := (@with_unification_resultT' ident var pident pident_arg_types).
+ Local Notation normalize_deep_rewrite_rule := (@normalize_deep_rewrite_rule ident var).
+ Local Notation under_with_unification_resultT_relation := (@under_with_unification_resultT_relation ident var pident pident_arg_types type_vars_of_pident).
+ Local Notation under_with_unification_resultT_relation_hetero := (@under_with_unification_resultT_relation_hetero ident var pident pident_arg_types type_vars_of_pident).
+ Local Notation deep_rewrite_ruleTP_gen := (@deep_rewrite_ruleTP_gen ident var).
+
+ Local Notation UnderLets_maybe_interp with_lets
+ := (if with_lets as with_lets' return (if with_lets' then UnderLets var _ else _) -> _
+ then UnderLets.interp ident_interp
+ else (fun x => x)).
+
+ Fixpoint value'_interp_related
+ {with_lets1 with_lets2 t}
+ : @value' var with_lets1 t
+ -> @value' var with_lets2 t
+ -> Prop
+ := match t return value' _ t -> value' _ t -> Prop with
+ | type.base t
+ => fun v1 v2
+ => expr.interp ident_interp (UnderLets_maybe_interp with_lets1 v1)
+ == expr.interp ident_interp (UnderLets_maybe_interp with_lets2 v2)
+ | type.arrow s d
+ => fun (f1 f2 : value' _ s -> value' _ d)
+ => forall x1 x2,
+ @value'_interp_related _ _ s x1 x2
+ -> @value'_interp_related _ _ d (f1 x1) (f2 x2)
+ end.
+
+ Definition value_interp_related {t} : relation (@value var t)
+ := value'_interp_related.
+
+ 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.
+ revert with_lets; induction t as [|s IHs d IHd]; intro;
+ cbn [type.related reflect reify];
+ fold (@reify var) (@reflect var); cbv [respectful]; break_innermost_match;
+ cbn [expr.interp UnderLets.to_expr]; auto; [].
+ intros Hf ? ? Hx.
+ apply IHd; cbn [expr.interp]; auto.
+ 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
+ (Hwf : expr.wf G e1 e2)
+ : expr.interp ident_interp (@reify_expr _ t e1) == expr.interp ident_interp e2.
+ Proof using ident_interp_Proper.
+ induction Hwf; cbn [expr.interp reify_expr]; cbv [LetIn.Let_In];
+ try solve [ auto
+ | apply ident_interp_Proper; reflexivity ].
+ all: cbn [type.related] in *; cbv [respectful]; intros.
+ all: match goal with H : _ |- _ => apply H; clear H end.
+ all: repeat first [ progress cbn [In eq_rect fst snd] in *
+ | progress intros
+ | progress destruct_head'_or
+ | progress subst
+ | progress inversion_sigma
+ | progress inversion_prod
+ | apply interp_reify_reflect
+ | solve [ auto ] ].
+ Qed.
+
+ Fixpoint pattern_default_interp' {K t} (p : pattern t) evm {struct p} : (expr (pattern.type.subst_default t evm) -> K) -> @with_unification_resultT' t p evm K
+ := match p in pattern.pattern t return (expr (pattern.type.subst_default t evm) -> K) -> @with_unification_resultT' t p evm K with
+ | pattern.Wildcard t => fun k v => k (reify v)
+ | pattern.Ident t idc
+ => fun k
+ => lam_type_of_list (fun args => k (expr.Ident (pident_to_typed _ idc _ args)))
+ | pattern.App s d f x
+ => fun k
+ => @pattern_default_interp'
+ _ _ f evm
+ (fun ef
+ => @pattern_default_interp'
+ _ _ x evm
+ (fun ex
+ => k (expr.App ef ex)))
+ end.
+
+ Definition pattern_default_interp {t} (p : pattern t) : @with_unif_rewrite_ruleTP_gen t p false false false false
+ := pattern.type.lam_forall_vars
+ (fun evm
+ => pattern_default_interp' p evm id).
+
+ Definition deep_rewrite_ruleTP_gen_good_relation
+ {should_do_again with_opt under_lets is_cps : bool} {t}
+ (v1 : @deep_rewrite_ruleTP_gen should_do_again with_opt under_lets is_cps t)
+ (v2 : expr t)
+ : Prop
+ := @normalize_deep_rewrite_rule_cps_id_hypsT var _ _ _ _ _ v1
+ /\ (let v1 := normalize_deep_rewrite_rule v1 _ id in
+ match v1 with
+ | None => True
+ | Some v1 => let v1 := UnderLets.interp ident_interp v1 in
+ (if should_do_again
+ return (@expr.expr base.type ident (if should_do_again then @value var else var) t) -> Prop
+ then
+ (fun v1
+ => expr.interp ident_interp (reify_expr v1) == expr.interp ident_interp v2)
+ else
+ (fun v1 => expr.interp ident_interp v1 == expr.interp ident_interp v2))
+ v1
+ end).
+
+ Definition rewrite_rule_data_interp_goodT
+ {t} {p : pattern t} (r : @rewrite_rule_data t p)
+ : Prop
+ := @under_with_unification_resultT_relation_hetero
+ _ _ _ _
+ (fun _ => value_interp_related)
+ (fun evm => deep_rewrite_ruleTP_gen_good_relation)
+ (rew_replacement _ _ r)
+ (pattern_default_interp p).
+
+ Definition rewrite_rules_interp_goodT
+ (rews : rewrite_rulesT)
+ : Prop
+ := forall p r,
+ List.In (existT _ p r) rews
+ -> rewrite_rule_data_interp_goodT r.
+ End with_interp.
End with_var.
End Compile.
End RewriteRules.
diff --git a/src/Experiments/NewPipeline/RewriterWf2.v b/src/Experiments/NewPipeline/RewriterWf2.v
index 6b2d92971..de17f2896 100644
--- a/src/Experiments/NewPipeline/RewriterWf2.v
+++ b/src/Experiments/NewPipeline/RewriterWf2.v
@@ -799,7 +799,7 @@ Module Compilers.
=> rewrite ap_transport_Base
| [ |- True ] => exact I
end
- | progress cbv [wf_rewrite_rule_data wf_with_unif_rewrite_ruleTP_gen option_bind'] in *
+ | progress cbv [wf_rewrite_rule_data wf_with_unif_rewrite_ruleTP_gen option_bind' normalize_deep_rewrite_rule_cps_id_hypsT] in *
| lazymatch goal with
| [ |- (@unify_pattern1 ?t ?re1 ?p ?K1 ?v1 ?T1 ?cont1 = None
<-> @unify_pattern2 ?t ?re2 ?p ?K2 ?v2 ?T2 ?cont2 = None)