diff options
Diffstat (limited to 'src/Compilers/Z/Named/RewriteAddToAdcInterp.v')
-rw-r--r-- | src/Compilers/Z/Named/RewriteAddToAdcInterp.v | 449 |
1 files changed, 0 insertions, 449 deletions
diff --git a/src/Compilers/Z/Named/RewriteAddToAdcInterp.v b/src/Compilers/Z/Named/RewriteAddToAdcInterp.v deleted file mode 100644 index 8f4dc4644..000000000 --- a/src/Compilers/Z/Named/RewriteAddToAdcInterp.v +++ /dev/null @@ -1,449 +0,0 @@ -Require Import Coq.ZArith.ZArith. -Require Import Crypto.Compilers.Named.Context. -Require Import Crypto.Compilers.Named.ContextDefinitions. -Require Import Crypto.Compilers.Named.ContextProperties.Proper. -Require Import Crypto.Compilers.Syntax. -Require Import Crypto.Compilers.Z.Syntax. -Require Import Crypto.Compilers.Z.Syntax.Equality. -Require Import Crypto.Compilers.Z.Named.RewriteAddToAdc. -Require Import Crypto.Compilers.Named.GetNames. -Require Import Crypto.Compilers.Named.Syntax. -Require Import Crypto.Util.Notations. -Require Import Crypto.Util.Option. -Require Import Crypto.Util.Sum. -Require Import Crypto.Util.Tactics.DestructHead. -Require Import Crypto.Util.Tactics.BreakMatch. -Require Import Crypto.Util.Prod. -Require Import Crypto.Util.LetIn. -Require Import Crypto.Util.Bool. -Require Import Crypto.Util.ZUtil.AddGetCarry. -Require Import Crypto.Util.ListUtil.FoldBool. -Require Import Crypto.Util.Decidable. - -Local Open Scope Z_scope. - -Section named. - Context {Name : Type} - {InterpContext : Context Name interp_base_type} - {InterpContextOk : ContextOk InterpContext} - (Name_beq : Name -> Name -> bool) - (Name_bl : forall n1 n2, Name_beq n1 n2 = true -> n1 = n2) - (Name_lb : forall n1 n2, n1 = n2 -> Name_beq n1 n2 = true). - - Local Notation name_list_has_duplicate := (@name_list_has_duplicate Name Name_beq). - Local Notation exprf := (@exprf base_type op Name). - Local Notation expr := (@expr base_type op Name). - Local Notation do_rewrite := (@do_rewrite Name Name_beq). - Local Notation invert_for_do_rewrite := (@invert_for_do_rewrite Name Name_beq). - Local Notation rewrite_exprf := (@rewrite_exprf Name Name_beq). - Local Notation rewrite_exprf_prestep := (@rewrite_exprf_prestep Name). - Local Notation rewrite_expr := (@rewrite_expr Name Name_beq). - - Local Instance Name_dec : DecidableRel (@eq Name) - := dec_rel_of_bool_dec_rel Name_beq Name_bl Name_lb. - - Local Notation retT e re := - (forall (ctx : InterpContext) - v, - Named.interpf (interp_op:=interp_op) (ctx:=ctx) re = Some v - -> Named.interpf (interp_op:=interp_op) (ctx:=ctx) e = Some v) - (only parsing). - Local Notation tZ := (Tbase TZ). - Local Notation ADC bw c x y := (Op (@AddWithGetCarry bw TZ TZ TZ TZ TZ) - (Pair (Pair (t1:=tZ) c (t2:=tZ) x) (t2:=tZ) y)). - Local Notation ADD bw x y := (ADC bw (Op (OpConst 0) TT) x y). - Local Notation ADX x y := (Op (@Add TZ TZ TZ) (Pair (t1:=tZ) x (t2:=tZ) y)). - Local Infix "=Z?" := Z.eqb. - Local Infix "=n?" := Name_beq. - - Local Ltac simple_t_step := - first [ exact I - | progress intros - | progress subst - | progress inversion_option - | progress inversion_sum - | progress inversion_prod ]. - Local Ltac destruct_t_step := - first [ break_innermost_match_hyps_step - | break_innermost_match_step ]. - Local Ltac do_small_inversion e := - is_var e; - lazymatch type of e with - | exprf ?T - => revert dependent e; - let P := match goal with |- forall e, @?P e => P end in - intro e; - lazymatch T with - | Unit - => refine match e in Named.exprf _ _ _ t return match t return Named.exprf _ _ _ t -> _ with Unit => P | _ => fun _ => True end e with TT => _ | _ => _ end - | tZ - => refine match e in Named.exprf _ _ _ t return match t return Named.exprf _ _ _ t -> _ with tZ => P | _ => fun _ => True end e with TT => _ | _ => _ end - | (tZ * tZ)%ctype - => refine match e in Named.exprf _ _ _ t return match t return Named.exprf _ _ _ t -> _ with (tZ * tZ)%ctype => P | _ => fun _ => True end e with TT => _ | _ => _ end - | (tZ * tZ * tZ)%ctype - => refine match e in Named.exprf _ _ _ t return match t return Named.exprf _ _ _ t -> _ with (tZ * tZ * tZ)%ctype => P | _ => fun _ => True end e with TT => _ | _ => _ end - end; - try exact I - | op ?a ?T - => first [ is_var a; - move e at top; - revert dependent a; - let P := match goal with |- forall a e, @?P a e => P end in - intros a e; - lazymatch T with - | tZ - => refine match e in op a t return match t return op a t -> _ with tZ => P a | _ => fun _ => True end e with OpConst _ _ => _ | _ => _ end - | (tZ * tZ)%ctype - => refine match e in op a t return match t return op a t -> _ with (tZ * tZ)%ctype => P a | _ => fun _ => True end e with OpConst _ _ => _ | _ => _ end - end ]; - try exact I - end. - Local Ltac small_inversion_prestep _ := - match goal with - | [ H : match ?e with _ => _ end = Some _ |- _ ] => do_small_inversion e - | [ H : match ?e with _ => _ end = true |- _ ] => do_small_inversion e - | [ H : match ?e with _ => _ end _ = Some _ |- _ ] => do_small_inversion e - end. - Local Ltac small_inversion_step := - small_inversion_prestep (); break_innermost_match; intros; try exact I. - - Local Ltac t_rewrite_step_correct_step := - first [ reflexivity - | progress inversion_option - | simple_t_step - | break_innermost_match_hyps_step - | small_inversion_step - | progress unfold invert_for_do_rewrite_step1, invert_for_do_rewrite_step2, invert_for_do_rewrite_step3 in * ]. - Local Ltac t_rewrite_step_correct := repeat t_rewrite_step_correct_step. - - Local Ltac mk_lookupb_extendb_lemma_debug := constr:(false). - Local Ltac debug_print_fail tac := - let lvl := mk_lookupb_extendb_lemma_debug in - lazymatch lvl with - | true => let dummy := match goal with - | _ => tac () - end in - constr:(I : I) - | false => constr:(I : I) - | _ => let TRUE := uconstr:(true) in - let FALSE := uconstr:(false) in - let dummy := match goal with - | _ => idtac "Error: Invalid mk_lookupb_extendb_lemma_debug level" lvl "which is neither" TRUE "nor" FALSE - end in - constr:(I : I) - end. - - (** We build the lemma explicitly, because letting [rewrite] and - [assumption || congruence] pick out the hypotheses and build the - lemmas is actually a bottleneck (timesavings: about 25s) *) - Local Ltac mk_lookupb_extendb_lemma base_type_code Name var Context t t' ctx n n' v := - lazymatch n with - | n' => lazymatch t with - | t' => constr:(@lookupb_extendb_same base_type_code Name var Context _ ctx n t v) - | _ => let lem := constr:(@lookupb_extendb_wrong_type base_type_code Name var Context _ ctx n t t' v) in - lazymatch goal with - | [ H : t <> t' |- _ ] - => constr:(lem H) - | [ H : t' <> t |- _ ] - => constr:(lem (@not_eq_sym _ _ _ H)) - | _ => let HT := uconstr:(t <> t') in - debug_print_fail ltac:(fun _ => idtac "Error in mk_lookupb_exntedb_lemma: could not find hypothesis of type" HT) - end - end - | _ => let lem := constr:(@lookupb_extendb_different base_type_code Name var Context _ ctx n n' t t' v) in - lazymatch goal with - | [ H : n <> n' |- _ ] - => constr:(lem H) - | [ H : n' <> n |- _ ] - => constr:(lem (@not_eq_sym _ _ _ H)) - | _ => let HT := uconstr:(n <> n') in - debug_print_fail ltac:(fun _ => idtac "Error in mk_lookupb_exntedb_lemma: could not find hypothesis of type" HT) - end - end. - Local Ltac rewrite_lookupb_step := - first [ match goal with - | [ H : context[@lookupb ?base_type_code ?Name ?var ?Context ?t' (extendb (t:=?t) ?ctx ?n ?v) ?n'] |- _ ] - => let lem := mk_lookupb_extendb_lemma base_type_code Name var Context t t' ctx n n' v in - rewrite lem in H - | [ |- context[@lookupb ?base_type_code ?Name ?var ?Context ?t' (extendb (t:=?t) ?ctx ?n ?v) ?n'] ] - => let lem := mk_lookupb_extendb_lemma base_type_code Name var Context t t' ctx n n' v in - rewrite lem - end - | match goal with - | [ H : context[lookupb (extendb _ _ _) _] |- _ ] => revert H - | [ |- context[lookupb (extendb _ ?n _) ?n'] ] - => (tryif constr_eq n n' then fail else idtac); - lazymatch goal with - | [ H : n = n' |- _ ] => fail - | [ H : n' = n |- _ ] => fail - | [ H : n <> n' |- _ ] => fail - | [ H : n' <> n |- _ ] => fail - | _ => destruct (dec (n = n')); subst - end - | [ |- context[lookupb (t:=?t0) (extendb (t:=?t1) _ _ _) _] ] - => (tryif constr_eq t0 t1 then fail else idtac); - lazymatch goal with - | [ H : t0 = t1 |- _ ] => fail - | [ H : t1 = t0 |- _ ] => fail - | [ H : t0 <> t1 |- _ ] => fail - | [ H : t1 <> t0 |- _ ] => fail - | _ => destruct (dec (t0 = t1)); subst - end - end ]. - Local Ltac rewrite_lookupb := repeat rewrite_lookupb_step. - - Local Ltac do_rewrite_adc' P := - let lem := open_constr:(Z.add_get_carry_to_add_with_get_carry_cps _ _ _ _ P) in - let T := type of lem in - let T := (eval cbv [Let_In Definitions.Z.add_with_get_carry Definitions.Z.add_with_get_carry Definitions.Z.get_carry Definitions.Z.add_get_carry] in T) in - etransitivity; [ | eapply (lem : T) ]; - try reflexivity. - Local Ltac do_rewrite_adc := - first [ do_rewrite_adc' uconstr:(fun a b => Some b) - | do_rewrite_adc' uconstr:(fun a b => Some a) ]. - Local Ltac do_small_inversion_ctx := - repeat match goal with - | [ H : is_const_or_var ?e = true |- _ ] - => do_small_inversion e; break_innermost_match; intros; try exact I; - simpl in H; try solve [ clear -H; discriminate ] - | [ H : match ?e with _ => _ end = true |- _ ] - => do_small_inversion e; break_innermost_match; intros; try exact I; - simpl in H; try solve [ clear -H; discriminate ] - | [ H : match ?e with _ => _ end _ = true |- _ ] - => do_small_inversion e; break_innermost_match; intros; try exact I; - simpl in H; try solve [ clear -H; discriminate ] - end. - Local Ltac t_fin_step := - match goal with - | [ |- ?x = ?x ] => reflexivity - | [ H : ?x = Some _ |- context[?x] ] => rewrite H - | [ H : ?x = None |- context[?x] ] => rewrite H - | [ H : ?x = Some ?a, H' : ?x = Some ?b |- _ ] - => assert (a = b) by congruence; (subst a || subst b) - | [ H : interpf ?x = Some ?v, H' : interpf ?x = None |- interpf _ = None ] - => cut (Some v = None); - [ congruence | rewrite <- H, <- H'; clear H H' ] - | _ => progress rewrite_lookupb - | _ => progress simpl in * - | _ => progress intros - | _ => progress subst - | _ => progress inversion_option - | [ |- (dlet x := _ in _) = (dlet y := _ in _) ] - => apply Proper_Let_In_nd_changebody_eq; intros ?? - | _ => progress unfold Let_In - | [ |- interpf ?x = interpf ?x ] - => eapply @interpf_Proper; [ eauto with typeclass_instances.. | intros ?? | reflexivity ] - | _ => progress break_innermost_match; try reflexivity - | _ => progress break_innermost_match_hyps; try reflexivity - | _ => progress break_match; try reflexivity - end. - Local Ltac t_fin := - repeat t_fin_step; - try do_rewrite_adc. - - - Lemma invert_for_do_rewrite_step1_correct {t} {e : exprf t} {v} - (H : invert_for_do_rewrite_step1 e = Some v) - : e = let '((a2, c1, bw1, a, b), P) := v in - (nlet (a2, c1) : tZ * tZ := ADD bw1 a b in P)%nexpr. - Proof. t_rewrite_step_correct. Qed. - Lemma invert_for_do_rewrite_step2_correct {t} {e : exprf t} {v} - (H : invert_for_do_rewrite_step2 e = Some v) - : e = let '((s, c2, bw2, c0, a2'), P) := v in - (nlet (s , c2) : tZ * tZ := (ADD bw2 c0 (Var a2')) in P)%nexpr. - Proof. t_rewrite_step_correct. Qed. - Lemma invert_for_do_rewrite_step3_correct {t} {e : exprf t} {v} - (H : invert_for_do_rewrite_step3 e = Some v) - : e = let '((c, c1', c2'), P) := v in - (nlet c : tZ := (ADX (Var c1') (Var c2')) in P)%nexpr. - Proof. t_rewrite_step_correct. Qed. - - Lemma invert_for_do_rewrite_correct {t} {e : exprf t} {v} - (H : invert_for_do_rewrite e = Some v) - : match v with - | ((a2, c1, bw1, a, b), - (s, c2, bw2, c0, a2'), - inl ((c, c1', c2'), P)) - => (nlet (a2, c1) : tZ * tZ := ADD bw1 a b in - nlet (s , c2) : tZ * tZ := ADD bw2 c0 (Var a2') in - nlet c : tZ := ADX (Var c1') (Var c2') in - P) = e - /\ ((((bw1 =Z? bw2) && (a2 =n? a2') && (c1 =n? c1') && (c2 =n? c2')) - && (is_const_or_var c0 && is_const_or_var a && is_const_or_var b) - && negb (name_list_has_duplicate (a2::c1::s::c2::c::nil ++ get_namesf c0 ++ get_namesf a ++ get_namesf b)%list)) - = true) - | ((a2, c1, bw1, a, b), - (s, c2, bw2, c0, a2'), - inr P) - => (nlet (a2, c1) : tZ * tZ := ADD bw1 a b in - nlet (s , c2) : tZ * tZ := ADD bw2 c0 (Var a2') in - P) = e - /\ ((((bw1 =Z? bw2) && (a2 =n? a2')) - && (is_const_or_var c0 && is_const_or_var a && is_const_or_var b) - && negb (name_list_has_duplicate (a2::c1::s::c2::nil ++ get_namesf c0 ++ get_namesf a ++ get_namesf b)%list)) - = true) - end%core%nexpr%bool. - Proof. - unfold invert_for_do_rewrite in H; break_innermost_match_hyps; - repeat first [ progress subst - | progress inversion_option - | progress inversion_sum - | progress inversion_prod - | match goal with - | [ H : _ = Some _ |- _ ] - => first [ rewrite (invert_for_do_rewrite_step1_correct H) - | rewrite (invert_for_do_rewrite_step2_correct H) - | rewrite (invert_for_do_rewrite_step3_correct H) ] - | [ H : ?x = true |- _ ] => rewrite H; clear H - | [ |- _ /\ _ ] => split - | [ |- ?x = ?x ] => reflexivity - | [ H : Name_beq _ _ = true |- _ ] => apply Name_bl in H - | [ H : Z.eqb _ _ = true |- _ ] => apply Z.eqb_eq in H - | [ H : Name_beq ?x ?y = false |- _ ] - => assert (x <> y) by (clear -H Name_lb; intro; rewrite Name_lb in H by assumption; congruence); - clear H - end - | progress rewrite !Bool.negb_orb in * - | progress rewrite !Bool.negb_true_iff in * - | progress split_andb - | progress simpl @negb in * - | progress do_small_inversion_ctx ]. - Qed. - - Lemma interpf_do_rewrite - {t} {e : exprf t} - : retT e (do_rewrite e). - Proof. - unfold do_rewrite. - pose proof (@invert_for_do_rewrite_correct t e) as H'. - break_innermost_match; inversion_option; - [ specialize (H' _ eq_refl) - | specialize (H' _ eq_refl) - | intros; subst; assumption ]. - all: intros *; let H := fresh in intro H; rewrite <- H; clear H. - Time all:repeat first [ progress cbv beta iota in * - | progress destruct_head'_and - | progress subst - | progress rewrite !Bool.negb_orb in * - | progress split_andb - | progress simpl @name_list_has_duplicate in * - | match goal with - | [ H : Name_beq _ _ = true |- _ ] => apply Name_bl in H - | [ H : Z.eqb _ _ = true |- _ ] => apply Z.eqb_eq in H - | [ H : Name_beq ?x ?y = false |- _ ] - => assert (x <> y) by (clear -H Name_lb; intro; rewrite Name_lb in H by assumption; congruence); - clear H - | [ H : context[List.fold_left orb ?ls ?v] |- _ ] - => lazymatch v with - | false => fail - | _ => rewrite (fold_left_orb_pull ls v) in H - end - end - | progress simpl @List.fold_left in * - | progress do_small_inversion_ctx - | progress rewrite !Bool.negb_true_iff in * - | progress intros * - | match goal with - | [ H : invert_for_do_rewrite _ = Some _ |- _ ] => clear H - end ]. - Time all: repeat first [ progress simpl - | progress cbv [interp_op option_map lift_op Zinterp_op] in * ]. - Time all: repeat first [ progress subst - | progress inversion_option - | progress rewrite_lookupb - | progress intros - | match goal with - | [ H : ?x = Some ?a, H' : ?x = Some ?b |- _ ] - => assert (a = b) by congruence; (subst a || subst b) - | [ H : ?T, H' : ?T |- _ ] => clear H' - end ]. - Set Ltac Profiling. - Time all: repeat first [ reflexivity - | progress subst - | progress inversion_option - | progress rewrite_lookupb - | progress intros - | progress cbn [fst snd] - | match goal with - | [ H : ?x = Some ?a, H' : ?x = Some ?b |- _ ] - => assert (a = b) by congruence; (subst a || subst b) - | [ H : ?T, H' : ?T |- _ ] => clear H' - | [ |- context[match lookupb ?ctx ?n with _ => _ end] ] - => is_var ctx; destruct (lookupb ctx n) eqn:? - | [ |- (dlet x := ?e in _) = (dlet y := ?e in _) ] - => apply Proper_Let_In_nd_changebody_eq; intros ?? - end - | progress unfold Let_In at 1 ]. - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - { Time t_fin. } - Time Qed. - - Local Opaque RewriteAddToAdc.do_rewrite. - Lemma interpf_rewrite_exprf - {t} (e : exprf t) - : retT e (rewrite_exprf e). - Proof. - pose t as T. - pose (rewrite_exprf_prestep (@rewrite_exprf) e) as E. - induction e; simpl in *; - intros ctx v H; - pose proof (interpf_do_rewrite (t:=T) (e:=E) ctx v H); clear H; - subst T E; - repeat first [ assumption - | progress unfold option_map, Let_In in * - | progress simpl in * - | progress subst - | progress inversion_option - | apply (f_equal (@Some _)) - | break_innermost_match_step - | break_innermost_match_hyps_step - | congruence - | solve [ eauto ] - | match goal with - | [ IH : forall ctx v, interpf ?e = Some v -> _ = Some _, H' : interpf ?e = Some _ |- _ ] - => specialize (IH _ _ H') - | [ H : ?x = Some ?a, H' : ?x = Some ?b |- _ ] - => assert (a = b) by congruence; (subst a || subst b) - | [ |- ?rhs = Some _ ] - => lazymatch rhs with - | Some _ => fail - | None => fail - | _ => destruct rhs eqn:? - end - end ]. - Qed. - - Lemma interp_rewrite_expr - {t} (e : expr t) - : forall (ctx : InterpContext) - v x, - Named.interp (interp_op:=interp_op) (ctx:=ctx) (rewrite_expr e) x = Some v - -> Named.interp (interp_op:=interp_op) (ctx:=ctx) e x = Some v. - Proof. - unfold Named.interp, rewrite_expr; destruct e; simpl. - intros *; apply interpf_rewrite_exprf. - Qed. - - Lemma Interp_rewrite_expr - {t} (e : expr t) - : forall v x, - Named.Interp (Context:=InterpContext) (interp_op:=interp_op) (rewrite_expr e) x = Some v - -> Named.Interp (Context:=InterpContext) (interp_op:=interp_op) e x = Some v. - Proof. - intros *; apply interp_rewrite_expr. - Qed. -End named. |