Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More zutil #384

Merged
merged 1 commit into from
Jul 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions _CoqProject
Expand Up @@ -6597,6 +6597,7 @@ src/Util/ZUtil/EquivModulo.v
src/Util/ZUtil/Ge.v
src/Util/ZUtil/Hints.v
src/Util/ZUtil/Land.v
src/Util/ZUtil/Le.v
src/Util/ZUtil/ModInv.v
src/Util/ZUtil/Modulo.v
src/Util/ZUtil/Morphisms.v
Expand Down
2 changes: 1 addition & 1 deletion src/Experiments/NewPipeline/Arithmetic.v
Expand Up @@ -2247,7 +2247,7 @@ Module BaseConversion.
eval dw dn (convert_bases sn dn p) = eval sw sn p.
Proof using dwprops.
cbv [convert_bases]; intros.
rewrite eval_chained_carries_no_reduce; auto using ZUtil.Z.positive_is_nonzero.
rewrite eval_chained_carries_no_reduce; auto using Z.positive_is_nonzero.
rewrite eval_from_associational; auto.
Qed.

Expand Down
2 changes: 1 addition & 1 deletion src/Experiments/SimplyTypedArithmetic.v
Expand Up @@ -1759,7 +1759,7 @@ Module BaseConversion.
eval dw dn (convert_bases sn dn p) = eval sw sn p.
Proof.
cbv [convert_bases]; intros.
rewrite eval_chained_carries_no_reduce; auto using ZUtil.Z.positive_is_nonzero.
rewrite eval_chained_carries_no_reduce; auto using Z.positive_is_nonzero.
rewrite eval_from_associational; auto.
Qed.

Expand Down
51 changes: 2 additions & 49 deletions src/Util/ZUtil.v
Expand Up @@ -13,6 +13,7 @@ Require Import Coq.Lists.List.
Require Export Crypto.Util.FixCoqMistakes.
Require Export Crypto.Util.ZUtil.Definitions.
Require Export Crypto.Util.ZUtil.Div.
Require Export Crypto.Util.ZUtil.Le.
Require Export Crypto.Util.ZUtil.EquivModulo.
Require Export Crypto.Util.ZUtil.Hints.
Require Export Crypto.Util.ZUtil.Land.
Expand All @@ -30,26 +31,9 @@ Import Nat.
Local Open Scope Z.

Module Z.
Lemma div_lt_upper_bound' a b q : 0 < b -> a < q * b -> a / b < q.
Proof. intros; apply Z.div_lt_upper_bound; nia. Qed.
Hint Resolve div_lt_upper_bound' : zarith.

Lemma mul_comm3 x y z : x * (y * z) = y * (x * z).
Proof. lia. Qed.

Lemma positive_is_nonzero : forall x, x > 0 -> x <> 0.
Proof. intros; omega. Qed.
Hint Resolve positive_is_nonzero : zarith.

Lemma div_positive_gt_0 : forall a b, a > 0 -> b > 0 -> a mod b = 0 ->
a / b > 0.
Proof.
intros; rewrite Z.gt_lt_iff.
apply Z.div_str_pos.
split; intuition auto with omega.
apply Z.divide_pos_le; try (apply Zmod_divide); omega.
Qed.

Lemma pos_pow_nat_pos : forall x n,
Z.pos x ^ Z.of_nat n > 0.
Proof.
Expand All @@ -59,7 +43,7 @@ Module Z.
Qed.

(** TODO: Should we get rid of this duplicate? *)
Notation gt0_neq0 := positive_is_nonzero (only parsing).
Notation gt0_neq0 := Z.positive_is_nonzero (only parsing).

Lemma pow_Z2N_Zpow : forall a n, 0 <= a ->
((Z.to_nat a) ^ n = Z.to_nat (a ^ Z.of_nat n)%Z)%nat.
Expand Down Expand Up @@ -708,19 +692,6 @@ Module Z.
Lemma sub_pos_bound a b X : 0 <= a < X -> 0 <= b < X -> -X < a - b < X.
Proof. lia. Qed.

Lemma div_opp_l_complete a b (Hb : b <> 0) : -a/b = -(a/b) - (if Z_zerop (a mod b) then 0 else 1).
Proof.
destruct (Z_zerop (a mod b)); autorewrite with zsimplify push_Zopp; reflexivity.
Qed.

Lemma div_opp_l_complete' a b (Hb : b <> 0) : -(a/b) = -a/b + (if Z_zerop (a mod b) then 0 else 1).
Proof.
destruct (Z_zerop (a mod b)); autorewrite with zsimplify pull_Zopp; lia.
Qed.

Hint Rewrite Z.div_opp_l_complete using zutil_arith : pull_Zopp.
Hint Rewrite Z.div_opp_l_complete' using zutil_arith : push_Zopp.

Lemma shiftl_opp_l a n
: Z.shiftl (-a) n = - Z.shiftl a n - (if Z_zerop (a mod 2 ^ (- n)) then 0 else 1).
Proof.
Expand All @@ -747,18 +718,6 @@ Module Z.
Hint Rewrite shiftr_opp_l : push_Zshift.
Hint Rewrite <- shiftr_opp_l : pull_Zshift.

Lemma div_opp a : a <> 0 -> -a / a = -1.
Proof.
intros; autorewrite with pull_Zopp zsimplify; lia.
Qed.

Hint Rewrite Z.div_opp using zutil_arith : zsimplify.

Lemma div_sub_1_0 x : x > 0 -> (x - 1) / x = 0.
Proof. auto with zarith lia. Qed.

Hint Rewrite div_sub_1_0 using zutil_arith : zsimplify.

Lemma sub_pos_bound_div a b X : 0 <= a < X -> 0 <= b < X -> -1 <= (a - b) / X <= 0.
Proof.
intros H0 H1; pose proof (Z.sub_pos_bound a b X H0 H1).
Expand Down Expand Up @@ -805,12 +764,6 @@ Module Z.
Qed.
Hint Resolve mod_eq_le_to_eq : zarith.

Lemma div_same' a b : b <> 0 -> a = b -> a / b = 1.
Proof.
intros; subst; auto with zarith.
Qed.
Hint Resolve div_same' : zarith.

Lemma mod_eq_le_div_1 a b : 0 < a <= b -> a mod b = 0 -> a / b = 1.
Proof. auto with zarith. Qed.
Hint Resolve mod_eq_le_div_1 : zarith.
Expand Down
71 changes: 71 additions & 0 deletions src/Util/ZUtil/Div.v
@@ -1,5 +1,8 @@
Require Import Coq.ZArith.ZArith Coq.micromega.Lia.
Require Import Coq.ZArith.Znumtheory.
Require Import Crypto.Util.ZUtil.Tactics.CompareToSgn.
Require Import Crypto.Util.ZUtil.Tactics.DivModToQuotRem.
Require Import Crypto.Util.ZUtil.Le.
Require Import Crypto.Util.ZUtil.Hints.Core.
Require Import Crypto.Util.ZUtil.Hints.ZArith.
Require Import Crypto.Util.ZUtil.Hints.PullPush.
Expand Down Expand Up @@ -187,4 +190,72 @@ Module Z.
intros; rewrite !Z.div_div by omega.
f_equal; ring.
Qed.

Lemma div_lt_upper_bound' a b q : 0 < b -> a < q * b -> a / b < q.
Proof. intros; apply Z.div_lt_upper_bound; nia. Qed.
Hint Resolve div_lt_upper_bound' : zarith.

Lemma div_cross_le_abs a b c' d : c' <> 0 -> d <> 0 -> a * Z.sgn c' * Z.abs d <= b * Z.sgn d * Z.abs c' -> a / c' <= b / d.
Proof.
clear.
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;
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
| [ H : context[-1 * _] |- _ ] => rewrite (Z.mul_add_distr_l (-1)), <- ?(Z.mul_comm (-1)), ?Z.mul_assoc in H
| [ H : context[-1 * Z.neg ?x] |- _ ] => rewrite (Z.mul_comm (-1) (Z.neg x)), <- Z.opp_eq_mul_m1 in H
| [ H : context[-1 * ?x] |- _ ] => rewrite (Z.mul_comm (-1) x), <- Z.opp_eq_mul_m1 in H
| [ H : context[-Z.neg _] |- _ ] => cbn [Z.opp] in H
end.
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);
revert H'
end.
all:Z.div_mod_to_quot_rem; nia.
Qed.

Lemma div_positive_gt_0 : forall a b, a > 0 -> b > 0 -> a mod b = 0 ->
a / b > 0.
Proof.
intros; rewrite Z.gt_lt_iff.
apply Z.div_str_pos.
split; intuition auto with omega.
apply Z.divide_pos_le; try (apply Zmod_divide); omega.
Qed.

Lemma div_opp_l_complete a b (Hb : b <> 0) : -a/b = -(a/b) - (if Z_zerop (a mod b) then 0 else 1).
Proof.
destruct (Z_zerop (a mod b)); autorewrite with zsimplify push_Zopp; reflexivity.
Qed.

Lemma div_opp_l_complete' a b (Hb : b <> 0) : -(a/b) = -a/b + (if Z_zerop (a mod b) then 0 else 1).
Proof.
destruct (Z_zerop (a mod b)); autorewrite with zsimplify pull_Zopp; lia.
Qed.

Hint Rewrite Z.div_opp_l_complete using zutil_arith : pull_Zopp.
Hint Rewrite Z.div_opp_l_complete' using zutil_arith : push_Zopp.

Lemma div_opp a : a <> 0 -> -a / a = -1.
Proof.
intros; autorewrite with pull_Zopp zsimplify; lia.
Qed.

Hint Rewrite Z.div_opp using zutil_arith : zsimplify.

Lemma div_sub_1_0 x : x > 0 -> (x - 1) / x = 0.
Proof. auto with zarith lia. Qed.

Hint Rewrite div_sub_1_0 using zutil_arith : zsimplify.

Lemma div_same' a b : b <> 0 -> a = b -> a / b = 1.
Proof.
intros; subst; auto with zarith.
Qed.
Hint Resolve div_same' : zarith.
End Z.
9 changes: 9 additions & 0 deletions src/Util/ZUtil/Le.v
@@ -0,0 +1,9 @@
Require Import Coq.ZArith.ZArith.
Require Import Coq.micromega.Lia.
Local Open Scope Z_scope.

Module Z.
Lemma positive_is_nonzero : forall x, x > 0 -> x <> 0.
Proof. intros; omega. Qed.
Hint Resolve positive_is_nonzero : zarith.
End Z.