Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Import ZAxioms ZMulOrder ZSgnAbs NZDiv.
Euclidean Division for integers (Floor convention)
Module Type ZDivProp
(Import A : ZAxiomsSig')
(Import B : ZMulOrderProp A)
(Import C : ZSgnAbsProp A B).
We benefit from what already exists for NZ
Module Import Private_NZDiv := Nop <+ NZDivProp A A B.
Another formulation of the main equation
forall a b : t, b ~= 0 -> a mod b == a - b * (a / b)forall a b : t, b ~= 0 -> a mod b == a - b * (a / b)a, b:tH:b ~= 0a mod b == a - b * (a / b)a, b:tH:b ~= 0b * (a / b) + a mod b == anow apply div_mod. Qed.a, b:tH:b ~= 0a == b * (a / b) + a mod b
We have a general bound for absolute values
forall a b : t, b ~= 0 -> abs (a mod b) < abs bforall a b : t, b ~= 0 -> abs (a mod b) < abs ba, b:tH:b ~= 0abs (a mod b) < abs ba, b:tH:b ~= 0LE:0 <= bEQ:abs b == babs (a mod b) < ba, b:tH:b ~= 0LE:b < 0EQ:abs b == - babs (a mod b) < - ba, b:tH:b ~= 0LE:0 <= bEQ:abs b == b0 < ba, b:tH:b ~= 0LE:0 <= bEQ:abs b == bH0:0 <= a mod bH1:a mod b < babs (a mod b) < ba, b:tH:b ~= 0LE:b < 0EQ:abs b == - babs (a mod b) < - ba, b:tH:b ~= 0LE:0 <= bEQ:abs b == bH0:0 <= a mod bH1:a mod b < babs (a mod b) < ba, b:tH:b ~= 0LE:b < 0EQ:abs b == - babs (a mod b) < - ba, b:tH:b ~= 0LE:b < 0EQ:abs b == - babs (a mod b) < - ba, b:tH:b ~= 0LE:b < 0EQ:abs b == - bb < 0a, b:tH:b ~= 0LE:b < 0EQ:abs b == - bH0:b < a mod bH1:a mod b <= 0abs (a mod b) < - ba, b:tH:b ~= 0LE:b < 0EQ:abs b == - bH0:b < a mod bH1:a mod b <= 0abs (a mod b) < - bnow rewrite <- opp_lt_mono. Qed.a, b:tH:b ~= 0LE:b < 0EQ:abs b == - bH0:b < a mod bH1:a mod b <= 0- (a mod b) < - b
Uniqueness theorems
forall b q1 q2 r1 r2 : t, 0 <= r1 < b \/ b < r1 <= 0 -> 0 <= r2 < b \/ b < r2 <= 0 -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2forall b q1 q2 r1 r2 : t, 0 <= r1 < b \/ b < r1 <= 0 -> 0 <= r2 < b \/ b < r2 <= 0 -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2b, q1, q2, r1, r2:tHr1:0 <= r1 < b \/ b < r1 <= 0Hr2:0 <= r2 < b \/ b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r2q1 == q2 /\ r1 == r2b, q1, q2, r1, r2:tH:0 <= r1 < bH0:0 <= r2 < bEQ:b * q1 + r1 == b * q2 + r2q1 == q2 /\ r1 == r2b, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r2q1 == q2 /\ r1 == r2b, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r2q1 == q2 /\ r1 == r2b, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r2q1 == q2 /\ - r1 == - r2b, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r20 <= - r1 < - bb, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r20 <= - r2 < - bb, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r2- b * q1 + - r1 == - b * q2 + - r2b, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r20 <= - r2 < - bb, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r2- b * q1 + - r1 == - b * q2 + - r2now rewrite 2 mul_opp_l, <- 2 opp_add_distr, opp_inj_wd. Qed.b, q1, q2, r1, r2:tH:b < r1 <= 0H0:b < r2 <= 0EQ:b * q1 + r1 == b * q2 + r2- b * q1 + - r1 == - b * q2 + - r2forall a b q r : t, 0 <= r < b \/ b < r <= 0 -> a == b * q + r -> q == a / bforall a b q r : t, 0 <= r < b \/ b < r <= 0 -> a == b * q + r -> q == a / ba, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rq == a / ba, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rHb:b ~= 0q == a / ba, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rHb:b ~= 00 <= a mod b < b \/ b < a mod b <= 0a, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rHb:b ~= 0b * q + r == b * (a / b) + a mod bnow rewrite <- div_mod. Qed.a, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rHb:b ~= 0b * q + r == b * (a / b) + a mod bforall a b q r : t, 0 <= r < b -> a == b * q + r -> q == a / bintros; apply div_unique with r; auto. Qed.forall a b q r : t, 0 <= r < b -> a == b * q + r -> q == a / bforall a b q r : t, b < r <= 0 -> a == b * q + r -> q == a / bintros; apply div_unique with r; auto. Qed.forall a b q r : t, b < r <= 0 -> a == b * q + r -> q == a / bforall a b q r : t, 0 <= r < b \/ b < r <= 0 -> a == b * q + r -> r == a mod bforall a b q r : t, 0 <= r < b \/ b < r <= 0 -> a == b * q + r -> r == a mod ba, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rr == a mod ba, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rHb:b ~= 0r == a mod ba, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rHb:b ~= 00 <= a mod b < b \/ b < a mod b <= 0a, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rHb:b ~= 0b * q + r == b * (a / b) + a mod bnow rewrite <- div_mod. Qed.a, b, q, r:tHr:0 <= r < b \/ b < r <= 0EQ:a == b * q + rHb:b ~= 0b * q + r == b * (a / b) + a mod bforall a b q r : t, 0 <= r < b -> a == b * q + r -> r == a mod bintros; apply mod_unique with q; auto. Qed.forall a b q r : t, 0 <= r < b -> a == b * q + r -> r == a mod bforall a b q r : t, b < r <= 0 -> a == b * q + r -> r == a mod bintros; apply mod_unique with q; auto. Qed.forall a b q r : t, b < r <= 0 -> a == b * q + r -> r == a mod b
Sign rules
Ltac pos_or_neg a := let LT := fresh "LT" in let LE := fresh "LE" in destruct (le_gt_cases 0 a) as [LE|LT]; [|rewrite <- opp_pos_neg in LT].forall a b : t, b ~= 0 -> 0 <= a mod b < b \/ b < a mod b <= 0forall a b : t, b ~= 0 -> 0 <= a mod b < b \/ b < a mod b <= 0a, b:tH:b ~= 00 <= a mod b < b \/ b < a mod b <= 0a, b:tH:b ~= 0H0:0 < b0 <= a mod b < ba, b:tH:b ~= 0H0:b <= 0b < a mod b <= 0apply mod_neg_bound; order. Qed.a, b:tH:b ~= 0H0:b <= 0b < a mod b <= 0forall a b : t, b ~= 0 -> 0 <= - (a mod b) < - b \/ - b < - (a mod b) <= 0forall a b : t, b ~= 0 -> 0 <= - (a mod b) < - b \/ - b < - (a mod b) <= 0a, b:tH:b ~= 00 <= - (a mod b) < - b \/ - b < - (a mod b) <= 0a, b:tH:b ~= 0H0:0 < b- b < - (a mod b) <= 0a, b:tH:b ~= 0H0:b <= 00 <= - (a mod b) < - ba, b:tH:b ~= 0H0:0 < ba mod b < b /\ 0 <= a mod ba, b:tH:b ~= 0H0:b <= 00 <= - (a mod b) < - ba, b:tH:b ~= 0H0:b <= 00 <= - (a mod b) < - bdestruct (mod_neg_bound a b); intuition; order. Qed.a, b:tH:b ~= 0H0:b <= 0a mod b <= 0 /\ b < a mod bforall a b : t, b ~= 0 -> - a / - b == a / bforall a b : t, b ~= 0 -> - a / - b == a / ba, b:tH:b ~= 0- a / - b == a / ba, b:tH:b ~= 0a / b == - a / - ba, b:tH:b ~= 00 <= - (a mod b) < - b \/ - b < - (a mod b) <= 0a, b:tH:b ~= 0- a == - b * (a / b) + - (a mod b)rewrite mul_opp_l, <- opp_add_distr, <- div_mod; order. Qed.a, b:tH:b ~= 0- a == - b * (a / b) + - (a mod b)forall a b : t, b ~= 0 -> - a mod - b == - (a mod b)forall a b : t, b ~= 0 -> - a mod - b == - (a mod b)a, b:tH:b ~= 0- a mod - b == - (a mod b)a, b:tH:b ~= 0- (a mod b) == - a mod - ba, b:tH:b ~= 00 <= - (a mod b) < - b \/ - b < - (a mod b) <= 0a, b:tH:b ~= 0- a == - b * (a / b) + - (a mod b)rewrite mul_opp_l, <- opp_add_distr, <- div_mod; order. Qed.a, b:tH:b ~= 0- a == - b * (a / b) + - (a mod b)
With the current conventions, the other sign rules are rather complex.
forall a b : t, b ~= 0 -> a mod b == 0 -> - a / b == - (a / b)forall a b : t, b ~= 0 -> a mod b == 0 -> - a / b == - (a / b)a, b:tHb:b ~= 0H:a mod b == 0- a / b == - (a / b)a, b:tHb:b ~= 0H:a mod b == 0- (a / b) == - a / ba, b:tHb:b ~= 0H:a mod b == 00 <= 0 < b \/ b < 0 <= 0a, b:tHb:b ~= 0H:a mod b == 0- a == b * - (a / b) + 0a, b:tHb:b ~= 0H:a mod b == 0- a == b * - (a / b) + 0rewrite mul_opp_r, <- opp_add_distr, <- div_mod; order. Qed.a, b:tHb:b ~= 0H:a mod b == 0- a == b * - (a / b) + - (a mod b)forall a b : t, b ~= 0 -> a mod b ~= 0 -> - a / b == - (a / b) - 1forall a b : t, b ~= 0 -> a mod b ~= 0 -> - a / b == - (a / b) - 1a, b:tHb:b ~= 0H:a mod b ~= 0- a / b == - (a / b) - 1a, b:tHb:b ~= 0H:a mod b ~= 0- (a / b) - 1 == - a / ba, b:tHb:b ~= 0H:a mod b ~= 00 <= b - a mod b < b \/ b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:0 < b0 <= b - a mod b < ba, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:0 < ba mod b <= b /\ b - a mod b < ba, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:0 < ba mod b <= b /\ b - a mod b < b - 0a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:0 < ba mod b <= b /\ 0 < a mod ba, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b /\ b <= a mod ba, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b - 0 < b - a mod b /\ b <= a mod ba, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0a mod b < 0 /\ b <= a mod ba, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)rewrite mul_opp_r, <-opp_add_distr, <-div_mod; order. Qed.a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * - (a / b) + - (a mod b)forall a b : t, b ~= 0 -> a mod b == 0 -> - a mod b == 0forall a b : t, b ~= 0 -> a mod b == 0 -> - a mod b == 0a, b:tHb:b ~= 0H:a mod b == 0- a mod b == 0a, b:tHb:b ~= 0H:a mod b == 00 == - a mod ba, b:tHb:b ~= 0H:a mod b == 00 <= 0 < b \/ b < 0 <= 0a, b:tHb:b ~= 0H:a mod b == 0- a == b * - (a / b) + 0a, b:tHb:b ~= 0H:a mod b == 0- a == b * - (a / b) + 0rewrite mul_opp_r, <- opp_add_distr, <- div_mod; order. Qed.a, b:tHb:b ~= 0H:a mod b == 0- a == b * - (a / b) + - (a mod b)forall a b : t, b ~= 0 -> a mod b ~= 0 -> - a mod b == b - a mod bforall a b : t, b ~= 0 -> a mod b ~= 0 -> - a mod b == b - a mod ba, b:tHb:b ~= 0H:a mod b ~= 0- a mod b == b - a mod ba, b:tHb:b ~= 0H:a mod b ~= 0b - a mod b == - a mod ba, b:tHb:b ~= 0H:a mod b ~= 00 <= b - a mod b < b \/ b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:0 < b0 <= b - a mod b < ba, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:0 < ba mod b <= b /\ b - a mod b < ba, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:0 < ba mod b <= b /\ b - a mod b < b - 0a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:0 < ba mod b <= b /\ 0 < a mod ba, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b <= 0a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b < b - a mod b /\ b <= a mod ba, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0b - 0 < b - a mod b /\ b <= a mod ba, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0H0:b <= 0a mod b < 0 /\ b <= a mod ba, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * (- (a / b) - 1) + (b - a mod b)rewrite mul_opp_r, <-opp_add_distr, <-div_mod; order. Qed.a, b:tHb:b ~= 0H:a mod b ~= 0- a == b * - (a / b) + - (a mod b)forall a b : t, b ~= 0 -> a mod b == 0 -> a / - b == - (a / b)forall a b : t, b ~= 0 -> a mod b == 0 -> a / - b == - (a / b)a, b:tH:b ~= 0H0:a mod b == 0a / - b == - (a / b)rewrite div_opp_opp; auto using div_opp_l_z. Qed.a, b:tH:b ~= 0H0:a mod b == 0- - a / - b == - (a / b)forall a b : t, b ~= 0 -> a mod b ~= 0 -> a / - b == - (a / b) - 1forall a b : t, b ~= 0 -> a mod b ~= 0 -> a / - b == - (a / b) - 1a, b:tH:b ~= 0H0:a mod b ~= 0a / - b == - (a / b) - 1rewrite div_opp_opp; auto using div_opp_l_nz. Qed.a, b:tH:b ~= 0H0:a mod b ~= 0- - a / - b == - (a / b) - 1forall a b : t, b ~= 0 -> a mod b == 0 -> a mod - b == 0forall a b : t, b ~= 0 -> a mod b == 0 -> a mod - b == 0a, b:tH:b ~= 0H0:a mod b == 0a mod - b == 0now rewrite mod_opp_opp, mod_opp_l_z, opp_0. Qed.a, b:tH:b ~= 0H0:a mod b == 0- - a mod - b == 0forall a b : t, b ~= 0 -> a mod b ~= 0 -> a mod - b == a mod b - bforall a b : t, b ~= 0 -> a mod b ~= 0 -> a mod - b == a mod b - ba, b:tH:b ~= 0H0:a mod b ~= 0a mod - b == a mod b - ba, b:tH:b ~= 0H0:a mod b ~= 0- - a mod - b == a mod b - bnow rewrite opp_sub_distr, add_comm, add_opp_r. Qed.a, b:tH:b ~= 0H0:a mod b ~= 0- (b - a mod b) == a mod b - b
The sign of a mod b is the one of b (when it isn't null)
forall a b : t, b ~= 0 -> a mod b ~= 0 -> sgn (a mod b) == sgn bforall a b : t, b ~= 0 -> a mod b ~= 0 -> sgn (a mod b) == sgn ba, b:tHb:b ~= 0H:a mod b ~= 0sgn (a mod b) == sgn ba, b:tHb:b ~= 0H:a mod b ~= 0Hb':0 < bsgn (a mod b) == sgn ba, b:tHb:b ~= 0H:a mod b ~= 0Hb':b <= 0sgn (a mod b) == sgn ba, b:tHb:b ~= 0H:a mod b ~= 0Hb':0 < bH0:0 <= a mod bH1:a mod b < bsgn (a mod b) == sgn ba, b:tHb:b ~= 0H:a mod b ~= 0Hb':b <= 0sgn (a mod b) == sgn ba, b:tHb:b ~= 0H:a mod b ~= 0Hb':b <= 0sgn (a mod b) == sgn ba, b:tHb:b ~= 0H:a mod b ~= 0Hb':b <= 0b < 0a, b:tHb:b ~= 0H:a mod b ~= 0Hb':b <= 0H0:b < a mod bH1:a mod b <= 0sgn (a mod b) == sgn brewrite 2 sgn_neg; order. Qed.a, b:tHb:b ~= 0H:a mod b ~= 0Hb':b <= 0H0:b < a mod bH1:a mod b <= 0sgn (a mod b) == sgn bforall a b : t, b ~= 0 -> sgn (a mod b) ~= - sgn bforall a b : t, b ~= 0 -> sgn (a mod b) ~= - sgn ba, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bFalsea, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bEQ:a mod b == 0Falsea, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0Falsea, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bEQ:a mod b == 0- sgn b == - 0a, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0Falsea, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0Falsea, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0sgn b == 0a, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0sgn b * 2 == 0a, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0sgn b + sgn b == 0a, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0sgn b == - sgn ba, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0sgn b == sgn (a mod b)now apply mod_sign_nz. Qed.a, b:tHb:b ~= 0H:sgn (a mod b) == - sgn bNEQ:a mod b ~= 0sgn (a mod b) == sgn bforall a b : t, b ~= 0 -> 0 <= a mod b * bforall a b : t, b ~= 0 -> 0 <= a mod b * ba, b:tH:b ~= 00 <= a mod b * ba, b:tH:b ~= 0H0:0 < b0 <= a mod b * ba, b:tH:b ~= 0H0:b <= 00 <= a mod b * bapply mul_nonpos_nonpos; destruct (mod_neg_bound a b); order. Qed.a, b:tH:b ~= 0H0:b <= 00 <= a mod b * b
A division by itself returns 1
forall a : t, a ~= 0 -> a / a == 1forall a : t, a ~= 0 -> a / a == 1a:tH:a ~= 0a / a == 1a:tH:a ~= 0LE:0 <= aa / a == 1a:tH:a ~= 0LT:0 < - aa / a == 1a:tH:a ~= 0LT:0 < - aa / a == 1now apply div_same. Qed.a:tH:a ~= 0LT:0 < - a- a / - a == 1forall a : t, a ~= 0 -> a mod a == 0forall a : t, a ~= 0 -> a mod a == 0a:tH:a ~= 0a mod a == 0a:tH:a ~= 0a - a * 1 == 0apply sub_diag. Qed.a:tH:a ~= 0a - a == 0
A division of a small number by a bigger one yields zero.
forall a b : t, 0 <= a < b -> a / b == 0exact div_small. Qed.forall a b : t, 0 <= a < b -> a / b == 0
Same situation, in term of modulo:
forall a b : t, 0 <= a < b -> a mod b == aexact mod_small. Qed.forall a b : t, 0 <= a < b -> a mod b == a
forall a : t, a ~= 0 -> 0 / a == 0forall a : t, a ~= 0 -> 0 / a == 0a:tH:a ~= 00 / a == 0a:tH:a ~= 0LE:0 <= a0 / a == 0a:tH:a ~= 0LT:0 < - a0 / a == 0a:tH:a ~= 0LT:0 < - a0 / a == 0now apply div_0_l. Qed.a:tH:a ~= 0LT:0 < - a0 / - a == 0forall a : t, a ~= 0 -> 0 mod a == 0intros; rewrite mod_eq, div_0_l; now nzsimpl. Qed.forall a : t, a ~= 0 -> 0 mod a == 0forall a : t, a / 1 == aforall a : t, a / 1 == aa:ta / 1 == aa:ta == a / 1a:t0 <= 0 < 1 \/ 1 < 0 <= 0a:ta == 1 * a + 0a:t0 <= 0 < 1a:ta == 1 * a + 0now nzsimpl. Qed.a:ta == 1 * a + 0forall a : t, a mod 1 == 0forall a : t, a mod 1 == 0a:ta mod 1 == 0intro EQ; symmetry in EQ; revert EQ; apply lt_neq; apply lt_0_1. Qed.a:t1 ~= 0forall a : t, 1 < a -> 1 / a == 0exact div_1_l. Qed.forall a : t, 1 < a -> 1 / a == 0forall a : t, 1 < a -> 1 mod a == 1exact mod_1_l. Qed.forall a : t, 1 < a -> 1 mod a == 1forall a b : t, b ~= 0 -> a * b / b == aforall a b : t, b ~= 0 -> a * b / b == aa, b:tH:b ~= 0a * b / b == aa, b:tH:b ~= 0a == a * b / ba, b:tH:b ~= 00 <= 0 < b \/ b < 0 <= 0a, b:tH:b ~= 0a * b == b * a + 0nzsimpl; apply mul_comm. Qed.a, b:tH:b ~= 0a * b == b * a + 0forall a b : t, b ~= 0 -> (a * b) mod b == 0forall a b : t, b ~= 0 -> (a * b) mod b == 0a, b:tH:b ~= 0(a * b) mod b == 0rewrite mul_comm; apply sub_diag. Qed.a, b:tH:b ~= 0a * b - b * a == 0a, b, q:tb ~= 0 -> a == b * q -> q == a / ba, b, q:tb ~= 0 -> a == b * q -> q == a / ba, b, q:tHb:b ~= 0H:a == b * qq == a / ba, b, q:tHb:b ~= 0H:a == b * qq == q * b / bnow apply div_mul. Qed.a, b, q:tHb:b ~= 0H:a == b * qq * b / b == q
A modulo cannot grow beyond its starting point.
forall a b : t, 0 <= a -> 0 < b -> a mod b <= aexact mod_le. Qed.forall a b : t, 0 <= a -> 0 < b -> a mod b <= aforall a b : t, 0 <= a -> 0 < b -> 0 <= a / bexact div_pos. Qed.forall a b : t, 0 <= a -> 0 < b -> 0 <= a / bforall a b : t, 0 < b <= a -> 0 < a / bexact div_str_pos. Qed.forall a b : t, 0 < b <= a -> 0 < a / bforall a b : t, b ~= 0 -> a / b == 0 <-> 0 <= a < b \/ b < a <= 0forall a b : t, b ~= 0 -> a / b == 0 <-> 0 <= a < b \/ b < a <= 0a, b:tHb:b ~= 0a / b == 0 <-> 0 <= a < b \/ b < a <= 0a, b:tHb:b ~= 0a / b == 0 -> 0 <= a < b \/ b < a <= 0a, b:tHb:b ~= 00 <= a < b \/ b < a <= 0 -> a / b == 0a, b:tHb:b ~= 0EQ:a / b == 00 <= a < b \/ b < a <= 0a, b:tHb:b ~= 00 <= a < b \/ b < a <= 0 -> a / b == 0a, b:tHb:b ~= 0EQ:a / b == 00 <= a mod b < b \/ b < a mod b <= 0a, b:tHb:b ~= 00 <= a < b \/ b < a <= 0 -> a / b == 0a, b:tHb:b ~= 00 <= a < b \/ b < a <= 0 -> a / b == 0a, b:tHb:b ~= 0H:0 <= a < ba / b == 0a, b:tHb:b ~= 0H:b < a <= 0a / b == 0a, b:tHb:b ~= 0H:b < a <= 0a / b == 0a, b:tHb:b ~= 0H:b < a <= 0- a / - b == 0rewrite <- opp_lt_mono, opp_nonneg_nonpos; tauto. Qed.a, b:tHb:b ~= 0H:b < a <= 00 <= - a < - bforall a b : t, b ~= 0 -> a mod b == a <-> 0 <= a < b \/ b < a <= 0forall a b : t, b ~= 0 -> a mod b == a <-> 0 <= a < b \/ b < a <= 0a, b:tH:b ~= 0a mod b == a <-> 0 <= a < b \/ b < a <= 0a, b:tH:b ~= 0a - b * (a / b) == a <-> a / b == 0a, b:tH:b ~= 0a + 0 == a + b * (a / b) <-> a / b == 0a, b:tH:b ~= 00 == b * (a / b) <-> a / b == 0tauto. Qed.a, b:tH:b ~= 0b == 0 \/ a / b == 0 <-> a / b == 0
As soon as the divisor is strictly greater than 1,
the division is strictly decreasing.
forall a b : t, 0 < a -> 1 < b -> a / b < aexact div_lt. Qed.forall a b : t, 0 < a -> 1 < b -> a / b < a
le is compatible with a positive division.
forall a b c : t, 0 < c -> a <= b -> a / c <= b / cforall a b c : t, 0 < c -> a <= b -> a / c <= b / ca, b, c:tHc:0 < cHab:a <= ba / c <= b / ca, b, c:tHc:0 < cHab:a < b \/ a == ba / c <= b / ca, b, c:tHc:0 < cLT:a < ba / c <= b / ca, b, c:tHc:0 < cLT:a < ba / c < S (b / c)a, b, c:tHc:0 < cLT:a < bc * (a / c) < c * S (b / c)a, b, c:tHc:0 < cLT:a < bc * (a / c) < c * (b / c) + ca, b, c:tHc:0 < cLT:a < bc * (a / c) + a mod c < c * (b / c) + c + a mod ca, b, c:tHc:0 < cLT:a < ba < c * (b / c) + c + a mod ca, b, c:tHc:0 < cLT:a < bb <= c * (b / c) + c + a mod ca, b, c:tHc:0 < cLT:a < bc * (b / c) + b mod c <= c * (b / c) + c + a mod ca, b, c:tHc:0 < cLT:a < bb mod c <= c + a mod ca, b, c:tHc:0 < cLT:a < bb mod c <= c + 0a, b, c:tHc:0 < cLT:a < bc + 0 <= c + a mod ca, b, c:tHc:0 < cLT:a < bc + 0 <= c + a mod cdestruct (mod_pos_bound a c); order. Qed.a, b, c:tHc:0 < cLT:a < b0 <= a mod c
In this convention, div performs Rounding-Toward-Bottom.
Since we cannot speak of rational values here, we express this
fact by multiplying back by b, and this leads to separates
statements according to the sign of b.
First, a/b is below the exact fraction ...
forall a b : t, 0 < b -> b * (a / b) <= aforall a b : t, 0 < b -> b * (a / b) <= aa, b:tH:0 < bb * (a / b) <= aa, b:tH:0 < bb * (a / b) <= b * (a / b) + a mod ba, b:tH:0 < bb * (a / b) + 0 <= b * (a / b) + a mod bnow destruct (mod_pos_bound a b). Qed.a, b:tH:0 < b0 <= a mod bforall a b : t, b < 0 -> a <= b * (a / b)forall a b : t, b < 0 -> a <= b * (a / b)a, b:tH:b < 0a <= b * (a / b)a, b:tH:b < 0- b * (- a / - b) <= - anow rewrite opp_pos_neg. Qed.a, b:tH:b < 00 < - b
... and moreover it is the larger such integer, since S(a/b)
is strictly above the exact fraction.
forall a b : t, 0 < b -> a < b * S (a / b)forall a b : t, 0 < b -> a < b * S (a / b)a, b:tH:0 < ba < b * S (a / b)a, b:tH:0 < ba < b * (a / b) + ba, b:tH:0 < bb * (a / b) + a mod b < b * (a / b) + bdestruct (mod_pos_bound a b); order. Qed.a, b:tH:0 < ba mod b < bforall a b : t, b < 0 -> b * S (a / b) < aforall a b : t, b < 0 -> b * S (a / b) < aa, b:tH:b < 0b * S (a / b) < aa, b:tH:b < 0- a < - b * S (- a / - b)now rewrite opp_pos_neg. Qed.a, b:tH:b < 00 < - b
NB: The four previous properties could be used as
specifications for div.
Inequality mul_div_le is exact iff the modulo is zero.
forall a b : t, b ~= 0 -> a == b * (a / b) <-> a mod b == 0forall a b : t, b ~= 0 -> a == b * (a / b) <-> a mod b == 0a, b:tH:b ~= 0a == b * (a / b) <-> a mod b == 0a, b:tH:b ~= 0b * (a / b) + a mod b == b * (a / b) <-> a mod b == 0apply add_cancel_l. Qed.a, b:tH:b ~= 0b * (a / b) + a mod b == b * (a / b) + 0 <-> a mod b == 0
Some additional inequalities about div.
forall a b q : t, 0 < b -> a < b * q -> a / b < qforall a b q : t, 0 < b -> a < b * q -> a / b < qa, b, q:tH:0 < bH0:a < b * qa / b < qa, b, q:tH:0 < bH0:a < b * qb * (a / b) < b * qnow apply mul_div_le. Qed.a, b, q:tH:0 < bH0:a < b * qb * (a / b) <= aforall a b q : t, 0 < b -> a <= b * q -> a / b <= qforall a b q : t, 0 < b -> a <= b * q -> a / b <= qa, b, q:tH:0 < bH0:a <= b * qa / b <= qa, b, q:tH:0 < bH0:a <= b * qa / b <= q * b / bnow rewrite mul_comm. Qed.a, b, q:tH:0 < bH0:a <= b * qa <= q * bforall a b q : t, 0 < b -> b * q <= a -> q <= a / bforall a b q : t, 0 < b -> b * q <= a -> q <= a / ba, b, q:tH:0 < bH0:b * q <= aq <= a / ba, b, q:tH:0 < bH0:b * q <= aq * b / b <= a / bnow rewrite mul_comm. Qed.a, b, q:tH:0 < bH0:b * q <= aq * b <= a
A division respects opposite monotonicity for the divisor
forall p q r : t, 0 <= p -> 0 < q <= r -> p / r <= p / qexact div_le_compat_l. Qed.forall p q r : t, 0 <= p -> 0 < q <= r -> p / r <= p / q
forall a b c : t, c ~= 0 -> (a + b * c) mod c == a mod cforall a b c : t, c ~= 0 -> (a + b * c) mod c == a mod ca, b, c:tH:c ~= 0(a + b * c) mod c == a mod ca, b, c:tH:c ~= 0a mod c == (a + b * c) mod ca, b, c:tH:c ~= 00 <= a mod c < c \/ c < a mod c <= 0a, b, c:tH:c ~= 0a + b * c == c * (a / c + b) + a mod ca, b, c:tH:c ~= 0a + b * c == c * (a / c + b) + a mod cnow rewrite mul_comm. Qed.a, b, c:tH:c ~= 0a + b * c == a + c * bforall a b c : t, c ~= 0 -> (a + b * c) / c == a / c + bforall a b c : t, c ~= 0 -> (a + b * c) / c == a / c + ba, b, c:tH:c ~= 0(a + b * c) / c == a / c + ba, b, c:tH:c ~= 0c * ((a + b * c) / c) == c * (a / c + b)a, b, c:tH:c ~= 0c * ((a + b * c) / c) + (a + b * c) mod c == c * (a / c + b) + (a + b * c) mod ca, b, c:tH:c ~= 0a + b * c == c * (a / c + b) + a mod cnow rewrite mul_comm. Qed.a, b, c:tH:c ~= 0a + b * c == a + c * bforall a b c : t, b ~= 0 -> (a * b + c) / b == a + c / bforall a b c : t, b ~= 0 -> (a * b + c) / b == a + c / ba, b, c:tb ~= 0 -> (a * b + c) / b == a + c / bnow apply div_add. Qed.a, b, c:tb ~= 0 -> (c + a * b) / b == c / b + a
Cancellations.
forall a b c : t, b ~= 0 -> c ~= 0 -> a * c / (b * c) == a / bforall a b c : t, b ~= 0 -> c ~= 0 -> a * c / (b * c) == a / ba, b, c:tH:b ~= 0H0:c ~= 0a * c / (b * c) == a / ba, b, c:tH:b ~= 0H0:c ~= 0a / b == a * c / (b * c)(* ineqs *)a, b, c:tH:b ~= 0H0:c ~= 00 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0a, b, c:tH:b ~= 0H0:c ~= 0a * c == b * c * (a / b) + a mod b * ca, b, c:tH:b ~= 0H0:c ~= 0H1:0 < c0 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0a, b, c:tH:b ~= 0H0:c ~= 0H1:c <= 00 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0a, b, c:tH:b ~= 0H0:c ~= 0a * c == b * c * (a / b) + a mod b * ca, b, c:tH:b ~= 0H0:c ~= 0H1:0 < c0 <= a mod b < b \/ b < a mod b <= 0a, b, c:tH:b ~= 0H0:c ~= 0H1:c <= 00 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0a, b, c:tH:b ~= 0H0:c ~= 0a * c == b * c * (a / b) + a mod b * ca, b, c:tH:b ~= 0H0:c ~= 0H1:c <= 00 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0a, b, c:tH:b ~= 0H0:c ~= 0a * c == b * c * (a / b) + a mod b * ca, b, c:tH:b ~= 0H0:c ~= 0H1:c <= 0a mod b <= 0 /\ b < a mod b \/ a mod b < b /\ 0 <= a mod ba, b, c:tH:b ~= 0H0:c ~= 0a * c == b * c * (a / b) + a mod b * c(* equation *)a, b, c:tH:b ~= 0H0:c ~= 0a * c == b * c * (a / b) + a mod b * ca, b, c:tH:b ~= 0H0:c ~= 0(b * (a / b) + a mod b) * c == b * c * (a / b) + a mod b * ca, b, c:tH:b ~= 0H0:c ~= 0b * (a / b) * c + a mod b * c == b * c * (a / b) + a mod b * ca, b, c:tH:b ~= 0H0:c ~= 0b * (a / b) * c == b * c * (a / b)now rewrite (mul_comm c). Qed.a, b, c:tH:b ~= 0H0:c ~= 0b * (a / b * c) == b * (c * (a / b))forall a b c : t, b ~= 0 -> c ~= 0 -> c * a / (c * b) == a / bforall a b c : t, b ~= 0 -> c ~= 0 -> c * a / (c * b) == a / brewrite !(mul_comm c); now apply div_mul_cancel_r. Qed.a, b, c:tH:b ~= 0H0:c ~= 0c * a / (c * b) == a / bforall a b c : t, b ~= 0 -> c ~= 0 -> (c * a) mod (c * b) == c * (a mod b)forall a b c : t, b ~= 0 -> c ~= 0 -> (c * a) mod (c * b) == c * (a mod b)a, b, c:tH:b ~= 0H0:c ~= 0(c * a) mod (c * b) == c * (a mod b)a, b, c:tH:b ~= 0H0:c ~= 0c * b * (c * a / (c * b)) + (c * a) mod (c * b) == c * b * (c * a / (c * b)) + c * (a mod b)a, b, c:tH:b ~= 0H0:c ~= 0c * a == c * b * (c * a / (c * b)) + c * (a mod b)a, b, c:tH:b ~= 0H0:c ~= 0c * b ~= 0a, b, c:tH:b ~= 0H0:c ~= 0c * a == c * b * (a / b) + c * (a mod b)a, b, c:tH:b ~= 0H0:c ~= 0c * b ~= 0a, b, c:tH:b ~= 0H0:c ~= 0a == b * (a / b) + a mod ba, b, c:tH:b ~= 0H0:c ~= 0c * b ~= 0rewrite <- neq_mul_0; auto. Qed.a, b, c:tH:b ~= 0H0:c ~= 0c * b ~= 0forall a b c : t, b ~= 0 -> c ~= 0 -> (a * c) mod (b * c) == a mod b * cforall a b c : t, b ~= 0 -> c ~= 0 -> (a * c) mod (b * c) == a mod b * crewrite !(mul_comm _ c); now rewrite mul_mod_distr_l. Qed.a, b, c:tH:b ~= 0H0:c ~= 0(a * c) mod (b * c) == a mod b * c
Operations modulo.
forall a n : t, n ~= 0 -> (a mod n) mod n == a mod nforall a n : t, n ~= 0 -> (a mod n) mod n == a mod na, n:tH:n ~= 0(a mod n) mod n == a mod nnow apply mod_bound_or. Qed.a, n:tH:n ~= 00 <= a mod n < n \/ n < a mod n <= 0forall a b n : t, n ~= 0 -> (a mod n * b) mod n == (a * b) mod nforall a b n : t, n ~= 0 -> (a mod n * b) mod n == (a * b) mod na, b, n:tHn:n ~= 0(a mod n * b) mod n == (a * b) mod na, b, n:tHn:n ~= 0(a * b) mod n == (a mod n * b) mod na, b, n:tHn:n ~= 0((n * (a / n) + a mod n) * b) mod n == (a mod n * b) mod na, b, n:tHn:n ~= 0(b * (a mod n + a / n * n)) mod n == (a mod n * b) mod na, b, n:tHn:n ~= 0(b * (a mod n) + b * (a / n) * n) mod n == (a mod n * b) mod na, b, n:tHn:n ~= 0(b * (a mod n) + b * (a / n) * n) mod n == (a mod n * b) mod nnow rewrite mul_comm. Qed.a, b, n:tHn:n ~= 0(b * (a mod n)) mod n == (a mod n * b) mod nforall a b n : t, n ~= 0 -> (a * (b mod n)) mod n == (a * b) mod nforall a b n : t, n ~= 0 -> (a * (b mod n)) mod n == (a * b) mod na, b, n:tH:n ~= 0(a * (b mod n)) mod n == (a * b) mod nnow apply mul_mod_idemp_l. Qed.a, b, n:tH:n ~= 0(b mod n * a) mod n == (b * a) mod nforall a b n : t, n ~= 0 -> (a * b) mod n == (a mod n * (b mod n)) mod nforall a b n : t, n ~= 0 -> (a * b) mod n == (a mod n * (b mod n)) mod nnow rewrite mul_mod_idemp_l, mul_mod_idemp_r. Qed.a, b, n:tH:n ~= 0(a * b) mod n == (a mod n * (b mod n)) mod nforall a b n : t, n ~= 0 -> (a mod n + b) mod n == (a + b) mod nforall a b n : t, n ~= 0 -> (a mod n + b) mod n == (a + b) mod na, b, n:tHn:n ~= 0(a mod n + b) mod n == (a + b) mod na, b, n:tHn:n ~= 0(a + b) mod n == (a mod n + b) mod na, b, n:tHn:n ~= 0(n * (a / n) + a mod n + b) mod n == (a mod n + b) mod na, b, n:tHn:n ~= 0(a mod n + b + a / n * n) mod n == (a mod n + b) mod nnow rewrite mod_add. Qed.a, b, n:tHn:n ~= 0(a mod n + b + a / n * n) mod n == (a mod n + b) mod nforall a b n : t, n ~= 0 -> (a + b mod n) mod n == (a + b) mod nforall a b n : t, n ~= 0 -> (a + b mod n) mod n == (a + b) mod na, b, n:tH:n ~= 0(a + b mod n) mod n == (a + b) mod nnow apply add_mod_idemp_l. Qed.a, b, n:tH:n ~= 0(b mod n + a) mod n == (b + a) mod nforall a b n : t, n ~= 0 -> (a + b) mod n == (a mod n + b mod n) mod nforall a b n : t, n ~= 0 -> (a + b) mod n == (a mod n + b mod n) mod nnow rewrite add_mod_idemp_l, add_mod_idemp_r. Qed.a, b, n:tH:n ~= 0(a + b) mod n == (a mod n + b mod n) mod n
With the current convention, the following result isn't always
true with a negative last divisor. For instance
3/(-2)/(-2) = 1 ≠ 0 = 3 / (-2*-2) , or
5/2/(-2) = -1 ≠ -2 = 5 / (2*-2) .
forall a b c : t, b ~= 0 -> 0 < c -> a / b / c == a / (b * c)forall a b c : t, b ~= 0 -> 0 < c -> a / b / c == a / (b * c)a, b, c:tHb:b ~= 0Hc:0 < ca / b / c == a / (b * c)(* begin 0<= ... <b*c \/ ... *)a, b, c:tHb:b ~= 0Hc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0 \/ 0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0Hc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0Hc:0 < cb * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * c < b * ((a / b) mod c) + a mod ba, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * c <= b * ((a / b) mod c) + ba, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * ((a / b) mod c) + b < b * ((a / b) mod c) + a mod ba, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * ((a / b) mod c) + b < b * ((a / b) mod c) + a mod ba, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b < 0Hc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:b < a mod bH2:a mod b <= 0b * ((a / b) mod c) <= 0a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * ca, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < b0 <= b * ((a / b) mod c) + a mod b < b * ca, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < b0 <= b * ((a / b) mod c) + a mod ba, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + a mod b < b * ca, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < b0 <= b * ((a / b) mod c)a, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + a mod b < b * ca, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + a mod b < b * ca, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + a mod b < b * ((a / b) mod c) + ba, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + b <= b * ca, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + b <= b * ca, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)(* end 0<= ... < b*c \/ ... *)a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b ~= 0Hc:0 < cb * (a / b) + a mod b == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHb:b ~= 0Hc:0 < cb * (a / b) == b * c * (a / b / c) + b * ((a / b) mod c)apply div_mod; order. Qed.a, b, c:tHb:b ~= 0Hc:0 < ca / b == c * (a / b / c) + (a / b) mod c
Similarly, the following result doesn't always hold when c<0.
For instance 3 mod (-2*-2)) = 3 while
3 mod (-2) + (-2)*((3/-2) mod -2) = -1.
forall a b c : t, b ~= 0 -> 0 < c -> a mod (b * c) == a mod b + b * ((a / b) mod c)forall a b c : t, b ~= 0 -> 0 < c -> a mod (b * c) == a mod b + b * ((a / b) mod c)a, b, c:tHb:b ~= 0Hc:0 < ca mod (b * c) == a mod b + b * ((a / b) mod c)a, b, c:tHb:b ~= 0Hc:0 < cb * c * (a / (b * c)) + a mod (b * c) == b * c * (a / (b * c)) + (a mod b + b * ((a / b) mod c))a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / (b * c)) + (a mod b + b * ((a / b) mod c))a, b, c:tHb:b ~= 0Hc:0 < ca == b * c * (a / b / c) + (a mod b + b * ((a / b) mod c))a, b, c:tHb:b ~= 0Hc:0 < ca == b * (c * (a / b / c) + (a / b) mod c) + a mod bapply div_mod; order. Qed.a, b, c:tHb:b ~= 0Hc:0 < ca == b * (a / b) + a mod bforall a b : t, b ~= 0 -> a mod b / b == 0forall a b : t, b ~= 0 -> a mod b / b == 0a, b:tHb:b ~= 0a mod b / b == 0auto using mod_bound_or. Qed.a, b:tHb:b ~= 00 <= a mod b < b \/ b < a mod b <= 0
A last inequality:
forall a b c : t, 0 <= a -> 0 < b -> 0 <= c -> c * (a / b) <= c * a / bexact div_mul_le. Qed. End ZDivProp.forall a b c : t, 0 <= a -> 0 < b -> 0 <= c -> c * (a / b) <= c * a / b