diff options
-rw-r--r-- | _CoqProject | 2 | ||||
-rw-r--r-- | src/Arithmetic/BarrettReduction/Generalized.v | 12 | ||||
-rw-r--r-- | src/Arithmetic/BarrettReduction/RidiculousFish.v | 12 | ||||
-rw-r--r-- | src/Arithmetic/Saturated/MontgomeryAPI.v | 2 | ||||
-rw-r--r-- | src/Experiments/NewPipeline/Arithmetic.v | 14 | ||||
-rw-r--r-- | src/Experiments/NewPipeline/Toplevel1.v | 8 | ||||
-rw-r--r-- | src/Experiments/SimplyTypedArithmetic.v | 12 | ||||
-rw-r--r-- | src/LegacyArithmetic/Double/Proofs/Multiply.v | 2 | ||||
-rw-r--r-- | src/LegacyArithmetic/Double/Proofs/RippleCarryAddSub.v | 8 | ||||
-rw-r--r-- | src/Util/QUtil.v | 8 | ||||
-rw-r--r-- | src/Util/ZUtil.v | 10 | ||||
-rw-r--r-- | src/Util/ZUtil/AddGetCarry.v | 2 | ||||
-rw-r--r-- | src/Util/ZUtil/CC.v | 2 | ||||
-rw-r--r-- | src/Util/ZUtil/Div.v | 6 | ||||
-rw-r--r-- | src/Util/ZUtil/Div/Bootstrap.v | 12 | ||||
-rw-r--r-- | src/Util/ZUtil/Modulo.v | 6 | ||||
-rw-r--r-- | src/Util/ZUtil/Modulo/Bootstrap.v | 22 | ||||
-rw-r--r-- | src/Util/ZUtil/Tactics/DivModToQuotRem.v | 39 | ||||
-rw-r--r-- | src/Util/ZUtil/Tactics/RewriteModSmall.v | 2 | ||||
-rw-r--r-- | src/Util/ZUtil/ZSimplify/Autogenerated.v | 2 |
20 files changed, 116 insertions, 67 deletions
diff --git a/_CoqProject b/_CoqProject index bbfffaabc..9e426282f 100644 --- a/_CoqProject +++ b/_CoqProject @@ -6615,10 +6615,12 @@ src/Util/ZUtil/Testbit.v src/Util/ZUtil/Z2Nat.v src/Util/ZUtil/ZSimplify.v src/Util/ZUtil/Zselect.v +src/Util/ZUtil/Div/Bootstrap.v src/Util/ZUtil/Hints/Core.v src/Util/ZUtil/Hints/PullPush.v src/Util/ZUtil/Hints/ZArith.v src/Util/ZUtil/Hints/Ztestbit.v +src/Util/ZUtil/Modulo/Bootstrap.v src/Util/ZUtil/Modulo/PullPush.v src/Util/ZUtil/Tactics/CompareToSgn.v src/Util/ZUtil/Tactics/DivModToQuotRem.v diff --git a/src/Arithmetic/BarrettReduction/Generalized.v b/src/Arithmetic/BarrettReduction/Generalized.v index 54b8c7c6c..9fa37721a 100644 --- a/src/Arithmetic/BarrettReduction/Generalized.v +++ b/src/Arithmetic/BarrettReduction/Generalized.v @@ -145,8 +145,8 @@ Section barrett. pose proof (Z.mod_pos_bound (b ^ (2*k)) n). assert (0 < b ^ (k - offset)) by auto with zarith. assert (a/n < b ^ k) by auto using Z.div_lt_upper_bound with zarith. - assert (b ^ (2 * k) - m * n = b ^ (2 * k) mod n) by (subst m; Z.div_mod_to_quot_rem; nia). - autorewrite with push_Zpow in *; Z.div_mod_to_quot_rem; nia. + assert (b ^ (2 * k) - m * n = b ^ (2 * k) mod n) by (subst m; Z.div_mod_to_quot_rem_in_goal; nia). + autorewrite with push_Zpow in *; Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma helper_2 : n * (a / n) - b ^ (k - offset) < b ^ (k - offset) * (a / b ^ (k - offset)). @@ -154,7 +154,7 @@ Section barrett. pose proof (Z.mod_pos_bound a n). pose proof (Z.mod_pos_bound a (b ^ (k - offset))). assert (0 < b ^ (k - offset)) by auto with zarith. - Z.div_mod_to_quot_rem; lia. + Z.div_mod_to_quot_rem_in_goal; lia. Qed. Let epsilon := (a / n) * b ^ (k+offset) - (a / b ^ (k - offset)) * m. @@ -162,7 +162,7 @@ Section barrett. Lemma q_epsilon : q = (a / n) + (- epsilon) / b ^ (k + offset). Proof. subst q epsilon. - autorewrite with push_Zpow in *; do 2 Z.div_mod_to_quot_rem; nia. + autorewrite with push_Zpow in *; do 2 Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma epsilon_lower : - b ^ (k + offset) < epsilon. @@ -170,7 +170,7 @@ Section barrett. pose proof q_epsilon as Hq_epsilon. rewrite (proj2_sig q_nice) in Hq_epsilon. cut (- epsilon / b ^ (k + offset) <= 0); - [ Z.div_mod_to_quot_rem | break_match_hyps ]; nia. + [ Z.div_mod_to_quot_rem_in_goal | break_match_hyps ]; nia. Qed. Lemma m_pos : 0 < m. @@ -192,7 +192,7 @@ Section barrett. exists (0 <? epsilon). rewrite q_epsilon. pose proof epsilon_bound. pose proof epsilon_lower. - break_match; Z.ltb_to_lt; Z.div_mod_to_quot_rem; nia. + break_match; Z.ltb_to_lt; Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma q_bound : a / n - 1 <= q. diff --git a/src/Arithmetic/BarrettReduction/RidiculousFish.v b/src/Arithmetic/BarrettReduction/RidiculousFish.v index 908e098b8..b9697839d 100644 --- a/src/Arithmetic/BarrettReduction/RidiculousFish.v +++ b/src/Arithmetic/BarrettReduction/RidiculousFish.v @@ -138,7 +138,7 @@ Lemma wrap_bound (a b : Z) (H : 0 < a) : 0 <= wrap a b < 2^a. Proof. unfold wrap. - Z.div_mod_to_quot_rem. + Z.div_mod_to_quot_rem_in_goal. lia. Qed. @@ -147,7 +147,7 @@ Lemma remove_outer_wrap (a a' b : Z) (H : 0 < a' <= a) : Proof. unfold wrap. apply Z.mod_small. - Z.div_mod_to_quot_rem. + Z.div_mod_to_quot_rem_in_goal. assert (2^a' <= 2^a) by (apply Z.pow_le_mono_r; lia). lia. Qed. @@ -185,7 +185,7 @@ Qed. Lemma a_minus_b_div_2_plus_b (a b : Z) (H : a >= b) : (a - b) / 2 + b = (a + b) / 2. -Proof. Z.div_mod_to_quot_rem; lia. Qed. +Proof. Z.div_mod_to_quot_rem_in_goal; lia. Qed. Lemma p_bound (d bits : Z) (Hbits : 0 < bits) (H : 1 < d < 2^bits) : 0 < Z.log2_up d <= bits. @@ -218,11 +218,11 @@ Qed. Lemma division_shrinks (a b c : Z) (Hb : 0 < b) (H : 0 <= a < c) : a / b < c. -Proof. Z.div_mod_to_quot_rem; nia. Qed. +Proof. Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma mul_div_ceil_ge (a b : Z) (Hb : 0 < b) : a <= b * ((a + b - 1) / b). -Proof. Z.div_mod_to_quot_rem; nia. Qed. +Proof. Z.div_mod_to_quot_rem_in_goal; nia. Qed. (** This is the main theorem this algorithm relies on. *) Lemma division_algorithm (bits n d k : Z) @@ -380,6 +380,6 @@ Proof. (* And finish with the main theorem. *) rewrite (division_algorithm 32) by lia; - Z.div_mod_to_quot_rem; + Z.div_mod_to_quot_rem_in_goal; nia. Qed. diff --git a/src/Arithmetic/Saturated/MontgomeryAPI.v b/src/Arithmetic/Saturated/MontgomeryAPI.v index 5b5ec1748..6dee1d22b 100644 --- a/src/Arithmetic/Saturated/MontgomeryAPI.v +++ b/src/Arithmetic/Saturated/MontgomeryAPI.v @@ -395,7 +395,7 @@ Section API. eapply small_left_append; eauto. rewrite @B.Positional.sat_add_div by omega. repeat match goal with H:_|-_=> unique pose proof (eval_small _ _ H) end. - cbv [eval] in *; Z.div_mod_to_quot_rem; nia. + cbv [eval] in *; Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma small_join0 {n} b : small b -> small (@join0 n b). diff --git a/src/Experiments/NewPipeline/Arithmetic.v b/src/Experiments/NewPipeline/Arithmetic.v index af5c2a766..0433bcda0 100644 --- a/src/Experiments/NewPipeline/Arithmetic.v +++ b/src/Experiments/NewPipeline/Arithmetic.v @@ -175,7 +175,7 @@ Module Associational. | _ => progress nsatz end. Qed. Lemma eval_splitQ s p (s_nz:Qnum s<>0) : eval (fst (splitQ s p)) + (Qnum s * eval (snd (splitQ s p))) / Zpos (Qden s) = eval p. - Proof. rewrite eval_snd_splitQ, eval_fst_partition by assumption; cbv [splitQ Let_In]; cbn [fst snd]; Z.div_mod_to_quot_rem; nia. Qed. + Proof. rewrite eval_snd_splitQ, eval_fst_partition by assumption; cbv [splitQ Let_In]; cbn [fst snd]; Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma eval_splitQ_mul s p (s_nz:Qnum s<>0) : eval (fst (splitQ s p)) * Zpos (Qden s) + (Qnum s * eval (snd (splitQ s p))) = eval p * Zpos (Qden s). Proof. rewrite eval_snd_splitQ, eval_fst_partition by assumption; cbv [splitQ Let_In]; cbn [fst snd]; nia. Qed. @@ -270,7 +270,7 @@ Module Associational. Lemma eval_map_mul_div' s a b c (s_nz:s <> 0) (a_mod : (a*a) mod s = 0) : eval (map (fun x => (((a * a) * fst x) / s, (b * b) * snd x)) c) = ((a * a) / s) * (b * b) * eval c. - Proof. rewrite <- eval_map_mul_div by assumption; f_equal; apply map_ext; intro; Z.div_mod_to_quot_rem; f_equal; nia. Qed. + Proof. rewrite <- eval_map_mul_div by assumption; f_equal; apply map_ext; intro; Z.div_mod_to_quot_rem_in_goal; f_equal; nia. Qed. Hint Rewrite eval_map_mul_div' using solve [ auto ] : push_eval. Lemma eval_flat_map_if A (f : A -> bool) g h p @@ -932,7 +932,7 @@ Section mod_ops. cut (1 < weight 1); [ lia | ]. cbv [weight Z.of_nat]; autorewrite with zsimplify_fast. apply Z.pow_gt_1; [ omega | ]. - Z.div_mod_to_quot_rem; nia. + Z.div_mod_to_quot_rem_in_goal; nia. Qed. Derive carry_mulmod @@ -1183,7 +1183,7 @@ Module Saturated. Lemma div_step a b c d : 0 < a -> 0 < b -> (c / a + d) / b = (a * d + c) / (a * b). - Proof. intros; Z.div_mod_to_quot_rem; nia. Qed. + Proof. intros; Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma add_mod_div_multiple a b n m: n > 0 -> @@ -2662,10 +2662,10 @@ Section freeze_mod_ops. transitivity (weight n); [ omega | ]. cbv [weight bytes_n]. Z.peel_le. - rewrite Z.log2_up_pow2 by (Z.div_mod_to_quot_rem; nia). + rewrite Z.log2_up_pow2 by (Z.div_mod_to_quot_rem_in_goal; nia). autorewrite with push_Zof_nat. - rewrite Z2Nat.id by (Z.div_mod_to_quot_rem; nia). - Z.div_mod_to_quot_rem; nia. } + rewrite Z2Nat.id by (Z.div_mod_to_quot_rem_in_goal; nia). + Z.div_mod_to_quot_rem_in_goal; nia. } { cbv [to_bytesmod]. rewrite Rows.flatten_partitions' by eauto using wprops, Rows.length_from_associational. rewrite Rows.eval_from_associational by (cbv [bytes_n]; eauto with omega). diff --git a/src/Experiments/NewPipeline/Toplevel1.v b/src/Experiments/NewPipeline/Toplevel1.v index 57c717e7c..e802c2dd7 100644 --- a/src/Experiments/NewPipeline/Toplevel1.v +++ b/src/Experiments/NewPipeline/Toplevel1.v @@ -2441,10 +2441,10 @@ Module BarrettReduction. Proof. cbv [mul_high Let_In]; rewrite Z.pow_add_r, Z.pow_1_r by omega; intros. assert (4 <= 2 ^ k) by (transitivity (Z.pow 2 2); auto with zarith). - assert (0 <= x * y / 2^k < 2^k*2^k) by (Z.div_mod_to_quot_rem; nia). + assert (0 <= x * y / 2^k < 2^k*2^k) by (Z.div_mod_to_quot_rem_in_goal; nia). rewrite mul_high_idea with (a:=x) (b:=y) (a0 := low a) (a1 := high a) (b0 := low b) (b1 := high b) in * - by (push_rep; Z.div_mod_to_quot_rem; lia). + by (push_rep; Z.div_mod_to_quot_rem_in_goal; lia). push_rep. subst a0b1. assert (y / 2 ^ k < 2) by (apply Z.div_lt_upper_bound; omega). @@ -2453,7 +2453,7 @@ Module BarrettReduction. eapply represents_trans. { repeat (apply wideadd_represents; - [ | apply represents_small; Z.div_mod_to_quot_rem; nia| ]). + [ | apply represents_small; Z.div_mod_to_quot_rem_in_goal; nia| ]). erewrite represents_high; [ | apply widemul_represents; solve [ auto with zarith ] ]. { apply represents_add; try reflexivity; solve [auto with zarith]. } { match goal with H : 0 <= ?x + ?y < ?z |- 0 <= ?x < ?z => @@ -2518,7 +2518,7 @@ Module BarrettReduction. (* assertions to help arith tactics *) pose proof x_bounds. assert (2^k * M < 2 ^ (2*k)) by (rewrite <-Z.add_diag, Z.pow_add_r; nia). - assert (0 <= x / (2 ^ k * (2 ^ k / 2)) < 2) by (Z.div_mod_to_quot_rem; auto with nia). + assert (0 <= x / (2 ^ k * (2 ^ k / 2)) < 2) by (Z.div_mod_to_quot_rem_in_goal; auto with nia). assert (0 < 2 ^ k / 2) by Z.zero_bounds. assert (2 ^ (k - 1) <> 0) by auto with zarith. assert (2 < 2 ^ k) by (eapply Z.le_lt_trans with (m:=2 ^ 1); auto with zarith). diff --git a/src/Experiments/SimplyTypedArithmetic.v b/src/Experiments/SimplyTypedArithmetic.v index 4c8830795..3745e59ff 100644 --- a/src/Experiments/SimplyTypedArithmetic.v +++ b/src/Experiments/SimplyTypedArithmetic.v @@ -526,7 +526,7 @@ Section mod_ops. cut (1 < weight 1); [ lia | ]. cbv [weight Z.of_nat]; autorewrite with zsimplify_fast. apply Z.pow_gt_1; [ omega | ]. - Z.div_mod_to_quot_rem; nia. + Z.div_mod_to_quot_rem_in_goal; nia. Qed. Derive carry_mulmod @@ -748,7 +748,7 @@ Module Saturated. Lemma div_step a b c d : 0 < a -> 0 < b -> (c / a + d) / b = (a * d + c) / (a * b). - Proof. intros; Z.div_mod_to_quot_rem; nia. Qed. + Proof. intros; Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma add_mod_div_multiple a b n m: n > 0 -> @@ -11096,10 +11096,10 @@ Module BarrettReduction. Proof. cbv [mul_high Let_In]; rewrite Z.pow_add_r, Z.pow_1_r by omega; intros. assert (4 <= 2 ^ k) by (transitivity (Z.pow 2 2); auto with zarith). - assert (0 <= x * y / 2^k < 2^k*2^k) by (Z.div_mod_to_quot_rem; nia). + assert (0 <= x * y / 2^k < 2^k*2^k) by (Z.div_mod_to_quot_rem_in_goal; nia). rewrite mul_high_idea with (a:=x) (b:=y) (a0 := low a) (a1 := high a) (b0 := low b) (b1 := high b) in * - by (push_rep; Z.div_mod_to_quot_rem; lia). + by (push_rep; Z.div_mod_to_quot_rem_in_goal; lia). push_rep. subst a0b1. assert (y / 2 ^ k < 2) by (apply Z.div_lt_upper_bound; omega). @@ -11108,7 +11108,7 @@ Module BarrettReduction. eapply represents_trans. { repeat (apply wideadd_represents; - [ | apply represents_small; Z.div_mod_to_quot_rem; nia| ]). + [ | apply represents_small; Z.div_mod_to_quot_rem_in_goal; nia| ]). erewrite represents_high; [ | apply widemul_represents; solve [ auto with zarith ] ]. { apply represents_add; try reflexivity; solve [auto with zarith]. } { match goal with H : 0 <= ?x + ?y < ?z |- 0 <= ?x < ?z => @@ -11173,7 +11173,7 @@ Module BarrettReduction. (* assertions to help arith tactics *) pose proof x_bounds. assert (2^k * M < 2 ^ (2*k)) by (rewrite <-Z.add_diag, Z.pow_add_r; nia). - assert (0 <= x / (2 ^ k * (2 ^ k / 2)) < 2) by (Z.div_mod_to_quot_rem; auto with nia). + assert (0 <= x / (2 ^ k * (2 ^ k / 2)) < 2) by (Z.div_mod_to_quot_rem_in_goal; auto with nia). assert (0 < 2 ^ k / 2) by Z.zero_bounds. assert (2 ^ (k - 1) <> 0) by auto with zarith. assert (2 < 2 ^ k) by (eapply Z.le_lt_trans with (m:=2 ^ 1); auto with zarith). diff --git a/src/LegacyArithmetic/Double/Proofs/Multiply.v b/src/LegacyArithmetic/Double/Proofs/Multiply.v index 8fed917d9..98692ed7f 100644 --- a/src/LegacyArithmetic/Double/Proofs/Multiply.v +++ b/src/LegacyArithmetic/Double/Proofs/Multiply.v @@ -89,7 +89,7 @@ Section tuple2. Z.rewrite_mod_small. push_Zmod; pull_Zmod. apply f_equal2; [ | reflexivity ]. - Z.div_mod_to_quot_rem; nia. + Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma decode_mul_double_function x y diff --git a/src/LegacyArithmetic/Double/Proofs/RippleCarryAddSub.v b/src/LegacyArithmetic/Double/Proofs/RippleCarryAddSub.v index d0514db57..4f6a79e8d 100644 --- a/src/LegacyArithmetic/Double/Proofs/RippleCarryAddSub.v +++ b/src/LegacyArithmetic/Double/Proofs/RippleCarryAddSub.v @@ -56,11 +56,11 @@ Proof. assert (0 < 2 ^ k) by auto with zarith. assert (0 < 2^n * 2^k) by nia. autorewrite with Zshift_to_pow push_Zpow. - rewrite <- (Zmod_small ((z0 mod _) + _) (2^k * 2^n)) by (Z.div_mod_to_quot_rem; nia). + rewrite <- (Zmod_small ((z0 mod _) + _) (2^k * 2^n)) by (Z.div_mod_to_quot_rem_in_goal; nia). rewrite <- !Z.mul_mod_distr_r by lia. rewrite !(Z.mul_comm (2^k)); pull_Zmod. split; [ | apply f_equal2 ]; - Z.div_mod_to_quot_rem; nia. + Z.div_mod_to_quot_rem_in_goal; nia. Qed. Section carry_sub_is_good. Context (n k z0 z1 : Z) @@ -93,10 +93,10 @@ Section carry_sub_is_good. assert (0 < 2 ^ k) by auto with zarith. assert (0 < 2^n * 2^k) by nia. autorewrite with Zshift_to_pow push_Zpow. - rewrite <- (Zmod_small ((z0 mod _) + _) (2^k * 2^n)) by (Z.div_mod_to_quot_rem; nia). + rewrite <- (Zmod_small ((z0 mod _) + _) (2^k * 2^n)) by (Z.div_mod_to_quot_rem_in_goal; nia). rewrite <- !Z.mul_mod_distr_r by lia. rewrite !(Z.mul_comm (2^k)); pull_Zmod. - apply f_equal2; Z.div_mod_to_quot_rem; break_match; Z.ltb_to_lt; try reflexivity; + apply f_equal2; Z.div_mod_to_quot_rem_in_goal; break_match; Z.ltb_to_lt; try reflexivity; match goal with | [ q : Z |- _ = _ :> Z ] => first [ cut (q = -1); [ intro; subst; ring | nia ] diff --git a/src/Util/QUtil.v b/src/Util/QUtil.v index 86dabd13e..dbdf4fba0 100644 --- a/src/Util/QUtil.v +++ b/src/Util/QUtil.v @@ -6,23 +6,23 @@ Local Open Scope Z_scope. Lemma Qfloor_le_add a b : Qfloor a + Qfloor b <= Qfloor (a + b). destruct a as [x y], b as [a b]; cbv [Qceiling Qfloor Qplus Qopp QArith_base.Qden QArith_base.Qnum]. - Z.div_mod_to_quot_rem; nia. + Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma Qceiling_le_add a b : Qceiling (a + b) <= Qceiling a + Qceiling b. destruct a as [x y], b as [a b]; cbv [Qceiling Qfloor Qplus Qopp QArith_base.Qden QArith_base.Qnum]. - Z.div_mod_to_quot_rem. nia. + Z.div_mod_to_quot_rem_in_goal. nia. Qed. Lemma add_floor_l_le_ceiling a b : Qfloor a + Qceiling b <= Qceiling (a + b). destruct a as [x y], b as [a b]; cbv [Qceiling Qfloor Qplus Qopp QArith_base.Qden QArith_base.Qnum]. - Z.div_mod_to_quot_rem; nia. + Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma Zle_floor_ceiling a : Z.le (Qfloor a) (Qceiling a). pose proof Qle_floor_ceiling. destruct a as [x y]; cbv [Qceiling Qfloor Qplus Qopp QArith_base.Qden QArith_base.Qnum]. - Z.div_mod_to_quot_rem; nia. + Z.div_mod_to_quot_rem_in_goal; nia. Qed. Section pow_ceil_mul_nat. diff --git a/src/Util/ZUtil.v b/src/Util/ZUtil.v index 2abfa7398..270bd0c90 100644 --- a/src/Util/ZUtil.v +++ b/src/Util/ZUtil.v @@ -891,7 +891,7 @@ Module Z. Hint Rewrite sub_mod_mod_0 : zsimplify. Lemma div_between n a b : 0 <= n -> b <> 0 -> n * b <= a < (1 + n) * b -> a / b = n. - Proof. intros; Z.div_mod_to_quot_rem; nia. Qed. + Proof. intros; Z.div_mod_to_quot_rem_in_goal; nia. Qed. Hint Rewrite div_between using zutil_arith : zsimplify. Lemma mod_small_n n a b : 0 <= n -> b <> 0 -> n * b <= a < (1 + n) * b -> a mod b = a - n * b. @@ -1371,7 +1371,7 @@ Module Z. => solve [ transitivity (-0); auto with zarith ] end. { repeat match goal with H : context[_ mod _] |- _ => revert H end; - Z.div_mod_to_quot_rem; nia. } + Z.div_mod_to_quot_rem_in_goal; nia. } Qed. Lemma shiftl_le_Proper1 x @@ -1424,7 +1424,7 @@ Module Z. assert (Hn : x <> y) by congruence; assert (x < y) by omega; clear H Hn | _ => solve [ repeat match goal with H : context[_ mod _] |- _ => revert H end; - Z.div_mod_to_quot_rem; subst; + Z.div_mod_to_quot_rem_in_goal; subst; lazymatch goal with | [ |- _ <= (?a * ?q + ?r) * ?q' ] => transitivity (q * (a * q') + r * q'); @@ -1438,10 +1438,10 @@ Module Z. assert (1 < 2^(y'-y)) by auto with zarith. assert (0 < x / 2^y) by (repeat match goal with H : context[_ mod _] |- _ => revert H end; - Z.div_mod_to_quot_rem; nia). + Z.div_mod_to_quot_rem_in_goal; nia). assert (2^y <= x) by (repeat match goal with H : context[_ / _] |- _ => revert H end; - Z.div_mod_to_quot_rem; nia). + Z.div_mod_to_quot_rem_in_goal; nia). match goal with | [ |- ?x + 1 <= ?y ] => cut (x < y); [ omega | ] end. diff --git a/src/Util/ZUtil/AddGetCarry.v b/src/Util/ZUtil/AddGetCarry.v index 5b8cbf13e..49b3e6332 100644 --- a/src/Util/ZUtil/AddGetCarry.v +++ b/src/Util/ZUtil/AddGetCarry.v @@ -38,7 +38,7 @@ Module Z. reflexivity. } { f_equal. { push_Zmod; pull_Zmod; apply f_equal2; omega. } - { Z.div_mod_to_quot_rem; nia. } } + { Z.div_mod_to_quot_rem_in_goal; nia. } } { subst; autorewrite with zsimplify; f_equal; omega. } Qed. diff --git a/src/Util/ZUtil/CC.v b/src/Util/ZUtil/CC.v index fb2fb1b93..4a130a9f2 100644 --- a/src/Util/ZUtil/CC.v +++ b/src/Util/ZUtil/CC.v @@ -27,6 +27,6 @@ Module Z. | _ => apply Z.div_lt_upper_bound | _ => solve [Z.zero_bounds] end. - Z.div_mod_to_quot_rem; lia. + Z.div_mod_to_quot_rem_in_goal; lia. Qed. End Z.
\ No newline at end of file diff --git a/src/Util/ZUtil/Div.v b/src/Util/ZUtil/Div.v index 4616a6090..a9fc4aae0 100644 --- a/src/Util/ZUtil/Div.v +++ b/src/Util/ZUtil/Div.v @@ -201,7 +201,7 @@ Module Z. destruct c', d; cbn [Z.abs Z.sgn]; rewrite ?Zdiv_0_r, ?Z.mul_0_r, ?Z.mul_0_l, ?Z.mul_1_l, ?Z.mul_1_r; try lia; intros ?? H; - Z.div_mod_to_quot_rem; + Z.div_mod_to_quot_rem_in_goal; subst. all: repeat match goal with | [ H : context[_ * -1] |- _ ] => rewrite (Z.mul_add_distr_r _ _ (-1)), <- ?(Z.mul_comm (-1)), ?Z.mul_assoc in H @@ -213,10 +213,10 @@ Module Z. all:lazymatch goal with | [ H : (Z.pos ?p * ?q + ?r) * Z.pos ?p' <= (Z.pos ?p' * ?q' + ?r') * Z.pos ?p |- _ ] => let H' := fresh in - assert (H' : q <= q' + (r' * Z.pos p - r * Z.pos p') / (Z.pos p * Z.pos p')) by (Z.div_mod_to_quot_rem; nia); + assert (H' : q <= q' + (r' * Z.pos p - r * Z.pos p') / (Z.pos p * Z.pos p')) by (Z.div_mod_to_quot_rem_in_goal; nia); revert H' end. - all:Z.div_mod_to_quot_rem; nia. + all:Z.div_mod_to_quot_rem_in_goal; nia. Qed. Lemma div_positive_gt_0 : forall a b, a > 0 -> b > 0 -> a mod b = 0 -> diff --git a/src/Util/ZUtil/Div/Bootstrap.v b/src/Util/ZUtil/Div/Bootstrap.v new file mode 100644 index 000000000..3b9338073 --- /dev/null +++ b/src/Util/ZUtil/Div/Bootstrap.v @@ -0,0 +1,12 @@ +(** Basic lemmas about [Z.div] for bootstrapping various tactics *) +Require Import Coq.ZArith.ZArith. +Require Import Coq.micromega.Lia. +Require Import Crypto.Util.ZUtil.Hints.Core. +Local Open Scope Z_scope. + +Module Z. + Lemma div_0_r_eq a b : b = 0 -> a / b = 0. + Proof. intro; subst; auto with zarith. Qed. + Hint Resolve div_0_r_eq : zarith. + Hint Rewrite div_0_r_eq using assumption : zsimplify. +End Z. diff --git a/src/Util/ZUtil/Modulo.v b/src/Util/ZUtil/Modulo.v index 953b3b2f3..be513eb3c 100644 --- a/src/Util/ZUtil/Modulo.v +++ b/src/Util/ZUtil/Modulo.v @@ -159,7 +159,7 @@ Module Z. + if c <? 0 then - X ((a / b) mod c) (a mod (c * b)) ((a mod (c * b)) / b) a b c (a / b) else 0. Proof. intros; break_match; Z.ltb_to_lt; rewrite ?Z.sub_0_r, ?Z.add_0_r; - assert (0 <> c * b) by nia; Z.div_mod_to_quot_rem; subst; + assert (0 <> c * b) by nia; Z.div_mod_to_quot_rem_in_goal; subst; destruct_head'_or; destruct_head'_and; try assert (b < 0) by omega; try assert (c < 0) by omega; @@ -259,7 +259,7 @@ Module Z. Proof. destruct (Z_dec d 0) as [ [?|?] | ? ]; try solve [ subst; autorewrite with zsimplify; simpl; split; reflexivity - | repeat first [ progress Z.div_mod_to_quot_rem + | repeat first [ progress Z.div_mod_to_quot_rem_in_goal | progress subst | progress break_innermost_match | progress Z.ltb_to_lt @@ -282,7 +282,7 @@ Module Z. Lemma mod_mod_0_0_eq x y : x mod y = 0 -> y mod x = 0 -> x = y \/ x = - y \/ x = 0 \/ y = 0. Proof. destruct (Z_zerop x), (Z_zerop y); eauto. - Z.div_mod_to_quot_rem; subst. + Z.div_mod_to_quot_rem_in_goal; subst. rewrite ?Z.add_0_r in *. match goal with | [ H : ?x = ?x * ?q * ?q' |- _ ] diff --git a/src/Util/ZUtil/Modulo/Bootstrap.v b/src/Util/ZUtil/Modulo/Bootstrap.v new file mode 100644 index 000000000..668aaa331 --- /dev/null +++ b/src/Util/ZUtil/Modulo/Bootstrap.v @@ -0,0 +1,22 @@ +(** Basic lemmas about [Z.modulo] for bootstrapping various tactics *) +Require Import Coq.ZArith.ZArith. +Require Import Coq.micromega.Lia. +Require Import Crypto.Util.ZUtil.Hints.Core. +Local Open Scope Z_scope. + +Module Z. + Lemma mod_0_r_eq a b : b = 0 -> a mod b = 0. + Proof. intro; subst; auto with zarith. Qed. + Hint Resolve mod_0_r_eq : zarith. + Hint Rewrite mod_0_r_eq using assumption : zsimplify. + + Lemma div_mod_cases x y : ((x = y * (x / y) + x mod y /\ (y < x mod y <= 0 \/ 0 <= x mod y < y)) + \/ (y = 0 /\ x / y = 0 /\ x mod y = 0)). + Proof. + destruct (Z_zerop y); [ right; subst; auto with zarith | left ]; subst. + split; [ apply Z.div_mod; assumption | ]. + destruct (Z_dec' y 0) as [ [H|H] | H]; [ left | right | congruence ]. + { apply Z.mod_neg_bound; assumption. } + { apply Z.mod_pos_bound; assumption. } + Qed. +End Z. diff --git a/src/Util/ZUtil/Tactics/DivModToQuotRem.v b/src/Util/ZUtil/Tactics/DivModToQuotRem.v index 178844d3b..a52798d20 100644 --- a/src/Util/ZUtil/Tactics/DivModToQuotRem.v +++ b/src/Util/ZUtil/Tactics/DivModToQuotRem.v @@ -1,4 +1,6 @@ Require Import Coq.ZArith.ZArith. +Require Import Crypto.Util.ZUtil.Div.Bootstrap. +Require Import Crypto.Util.ZUtil.Modulo.Bootstrap. Require Import Crypto.Util.ZUtil.Hints.Core. Local Open Scope Z_scope. @@ -12,18 +14,22 @@ Module Z. Ltac generalize_div_eucl x y := let H := fresh in let H' := fresh in - assert (H' : y <> 0) by div_mod_to_quot_rem_inequality_solver; - generalize (Z.div_mod x y H'); clear H'; - first [ assert (H' : 0 < y) by div_mod_to_quot_rem_inequality_solver; - generalize (Z.mod_pos_bound x y H'); clear H' - | assert (H' : y < 0) by div_mod_to_quot_rem_inequality_solver; - generalize (Z.mod_neg_bound x y H'); clear H' - | assert (H' : y < 0 \/ 0 < y) by (apply Z.neg_pos_cases; div_mod_to_quot_rem_inequality_solver); - let H'' := fresh in - assert (H'' : y < x mod y <= 0 \/ 0 <= x mod y < y) - by (destruct H'; [ left; apply Z.mod_neg_bound; assumption - | right; apply Z.mod_pos_bound; assumption ]); - clear H'; revert H'' ]; + first + [ assert (H' : y <> 0) by div_mod_to_quot_rem_inequality_solver; + generalize (Z.div_mod x y H'); clear H'; + first [ assert (H' : 0 < y) by div_mod_to_quot_rem_inequality_solver; + generalize (Z.mod_pos_bound x y H'); clear H' + | assert (H' : y < 0) by div_mod_to_quot_rem_inequality_solver; + generalize (Z.mod_neg_bound x y H'); clear H' + | assert (H' : y = 0) by div_mod_to_quot_rem_inequality_solver; + generalize (Z.div_0_r_eq x y H') (Z.mod_0_r_eq x y H'); clear H' + | assert (H' : y < 0 \/ 0 < y) by (apply Z.neg_pos_cases; div_mod_to_quot_rem_inequality_solver); + let H'' := fresh in + assert (H'' : y < x mod y <= 0 \/ 0 <= x mod y < y) + by (destruct H'; [ left; apply Z.mod_neg_bound; assumption + | right; apply Z.mod_pos_bound; assumption ]); + clear H'; revert H'' ] + | generalize (Z.div_mod_cases x y) ]; let q := fresh "q" in let r := fresh "r" in set (q := x / y) in *; @@ -36,5 +42,12 @@ Module Z. | [ |- context[?x mod ?y] ] => generalize_div_eucl x y end. - Ltac div_mod_to_quot_rem := repeat div_mod_to_quot_rem_step; intros. + Ltac div_mod_to_quot_rem_hyps_step := + match goal with + | [ H : context[?x / ?y] |- _ ] => generalize_div_eucl x y + | [ H : context[?x mod ?y] |- _ ] => generalize_div_eucl x y + end. + + Ltac div_mod_to_quot_rem := repeat first [ div_mod_to_quot_rem_step | div_mod_to_quot_rem_hyps_step ]; intros. + Ltac div_mod_to_quot_rem_in_goal := repeat div_mod_to_quot_rem_step; intros. End Z. diff --git a/src/Util/ZUtil/Tactics/RewriteModSmall.v b/src/Util/ZUtil/Tactics/RewriteModSmall.v index 45598b0c5..6b3b05a41 100644 --- a/src/Util/ZUtil/Tactics/RewriteModSmall.v +++ b/src/Util/ZUtil/Tactics/RewriteModSmall.v @@ -20,7 +20,7 @@ Module Z. | [ H : context[(_ mod _)%Z] |- _ ] => revert H end. - Z.div_mod_to_quot_rem. + Z.div_mod_to_quot_rem_in_goal. lazymatch goal with | [ H : a = (?x * ?n * ?q) + _, H' : a = (?n * ?q') + _ |- _ ] => assert (q' = x * q) by nia; subst q'; nia diff --git a/src/Util/ZUtil/ZSimplify/Autogenerated.v b/src/Util/ZUtil/ZSimplify/Autogenerated.v index b3b6d36b6..df2abfe33 100644 --- a/src/Util/ZUtil/ZSimplify/Autogenerated.v +++ b/src/Util/ZUtil/ZSimplify/Autogenerated.v @@ -5,7 +5,7 @@ Local Open Scope Z_scope. Module Z. Local Ltac simplify_div_tac := - intros; Z.div_mod_to_quot_rem; nia. + intros; Z.div_mod_to_quot_rem_in_goal; nia. (* Naming Convention: [X] for thing being divided by, [p] for plus, [m] for minus, [d] for div, and [_] to separate parentheses and multiplication. *) |