diff options
Diffstat (limited to 'src/ModularArithmetic/Pow2BaseProofs.v')
-rw-r--r-- | src/ModularArithmetic/Pow2BaseProofs.v | 78 |
1 files changed, 69 insertions, 9 deletions
diff --git a/src/ModularArithmetic/Pow2BaseProofs.v b/src/ModularArithmetic/Pow2BaseProofs.v index db910ba93..78c6bba0f 100644 --- a/src/ModularArithmetic/Pow2BaseProofs.v +++ b/src/ModularArithmetic/Pow2BaseProofs.v @@ -15,22 +15,25 @@ Section Pow2BaseProofs. Lemma base_from_limb_widths_length : length base = length limb_widths. Proof. - induction limb_widths; try reflexivity. - simpl; rewrite map_length. - simpl in limb_widths_nonneg. - rewrite IHl; auto. + clear limb_widths_nonneg. + induction limb_widths; [ reflexivity | simpl in * ]. + autorewrite with distr_length; auto. Qed. + Hint Rewrite base_from_limb_widths_length : distr_length. Lemma sum_firstn_limb_widths_nonneg : forall n, 0 <= sum_firstn limb_widths n. Proof. unfold sum_firstn; intros. apply fold_right_invariant; try omega. - intros y In_y_lw ? ?. - apply Z.add_nonneg_nonneg; try assumption. - apply limb_widths_nonneg. - eapply In_firstn; eauto. + eauto using Z.add_nonneg_nonneg, limb_widths_nonneg, In_firstn. Qed. Hint Resolve sum_firstn_limb_widths_nonneg. + Lemma two_sum_firstn_limb_widths_pos n : 0 < 2^sum_firstn limb_widths n. + Proof. auto with zarith. Qed. + + Lemma two_sum_firstn_limb_widths_nonzero n : 2^sum_firstn limb_widths n <> 0. + Proof. pose proof (two_sum_firstn_limb_widths_pos n); omega. Qed. + Lemma base_from_limb_widths_step : forall i b w, (S i < length base)%nat -> nth_error base i = Some b -> nth_error limb_widths i = Some w -> @@ -162,6 +165,63 @@ Section Pow2BaseProofs. do 2 f_equal; apply map_ext; intros; lia. } Qed. + Section make_base_vector. + Local Notation k := (sum_firstn limb_widths (length limb_widths)). + Context (limb_widths_match_modulus : forall i j, + (i < length limb_widths)%nat -> + (j < length limb_widths)%nat -> + (i + j >= length limb_widths)%nat -> + let w_sum := sum_firstn limb_widths in + k + w_sum (i + j - length limb_widths)%nat <= w_sum i + w_sum j) + (limb_widths_good : forall i j, (i + j < length limb_widths)%nat -> + sum_firstn limb_widths (i + j) <= + sum_firstn limb_widths i + sum_firstn limb_widths j). + + Lemma base_matches_modulus: forall i j, + (i < length limb_widths)%nat -> + (j < length limb_widths)%nat -> + (i+j >= length limb_widths)%nat-> + let b := nth_default 0 base in + let r := (b i * b j) / (2^k * b (i+j-length base)%nat) in + b i * b j = r * (2^k * b (i+j-length base)%nat). + Proof. + intros. + rewrite (Z.mul_comm r). + subst r. + assert (i + j - length limb_widths < length limb_widths)%nat by omega. + rewrite Z.mul_div_eq by (apply Z.gt_lt_iff; apply Z.mul_pos_pos; + subst b; rewrite ?nth_default_base; zero_bounds; rewrite ?base_from_limb_widths_length; + auto using sum_firstn_limb_widths_nonneg, limb_widths_nonneg). + rewrite (Zminus_0_l_reverse (b i * b j)) at 1. + f_equal. + subst b. + repeat rewrite nth_default_base by (rewrite ?base_from_limb_widths_length; auto). + do 2 rewrite <- Z.pow_add_r by auto using sum_firstn_limb_widths_nonneg. + symmetry. + apply Z.mod_same_pow. + split. + + apply Z.add_nonneg_nonneg; auto using sum_firstn_limb_widths_nonneg. + + rewrite base_from_limb_widths_length; auto using limb_widths_nonneg, limb_widths_match_modulus. + Qed. + + Lemma base_good : forall i j : nat, + (i + j < length base)%nat -> + let b := nth_default 0 base in + let r := b i * b j / b (i + j)%nat in + b i * b j = r * b (i + j)%nat. + Proof. + intros; subst b r. + repeat rewrite nth_default_base by (omega || auto). + rewrite (Z.mul_comm _ (2 ^ (sum_firstn limb_widths (i+j)))). + rewrite Z.mul_div_eq by (apply Z.gt_lt_iff; zero_bounds; + auto using sum_firstn_limb_widths_nonneg). + rewrite <- Z.pow_add_r by auto using sum_firstn_limb_widths_nonneg. + rewrite Z.mod_same_pow; try ring. + split; [ auto using sum_firstn_limb_widths_nonneg | ]. + apply limb_widths_good. + rewrite <-base_from_limb_widths_length; auto using limb_widths_nonneg. + Qed. + End make_base_vector. End Pow2BaseProofs. Section BitwiseDecodeEncode. @@ -788,7 +848,7 @@ Section carrying. Hint Rewrite @nth_default_carry_simple using (omega || distr_length; omega) : push_nth_default. End carrying. -Hint Rewrite @length_carry_gen : distr_length. +Hint Rewrite @length_carry_gen @base_from_limb_widths_length : distr_length. Hint Rewrite @length_carry_simple @length_carry_simple_sequence @length_make_chain @length_full_carry_chain @length_carry_simple_full : distr_length. Hint Rewrite @nth_default_carry_simple_full @nth_default_carry_gen_full : push_nth_default. Hint Rewrite @nth_default_carry_simple @nth_default_carry_gen using (omega || distr_length; omega) : push_nth_default. |