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 NAxioms NSub NZDiv.
Properties of Euclidean Division
Module Type NDivProp (Import N : NAxiomsSig')(Import NP : NSubProp N).
We benefit from what already exists for NZ
Module Import Private_NZDiv := Nop <+ NZDivProp N N NP. Ltac auto' := try rewrite <- neq_0_lt_0; auto using le_0_l.
Let's now state again theorems, but without useless hypothesis.
forall a b : t, b ~= 0 -> a mod b < bforall a b : t, b ~= 0 -> a mod b < bapply mod_bound_pos; auto'. Qed.a, b:tH:b ~= 0a mod b < 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 ~= 0a - b * (a / b) == a mod ba, 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
Uniqueness theorems
forall b q1 q2 r1 r2 : t, r1 < b -> r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2forall b q1 q2 r1 r2 : t, r1 < b -> r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2apply div_mod_unique with b; auto'. Qed.b, q1, q2, r1, r2:tH:r1 < bH0:r2 < bH1:b * q1 + r1 == b * q2 + r2q1 == q2 /\ r1 == r2forall a b q r : t, r < b -> a == b * q + r -> q == a / bintros; apply div_unique with r; auto'. Qed.forall a b q r : t, r < b -> a == b * q + r -> q == a / bforall a b q r : t, r < b -> a == b * q + r -> r == a mod bforall a b q r : t, r < b -> a == b * q + r -> r == a mod bapply mod_unique with q; auto'. Qed.a, b, q, r:tH:r < bH0:a == b * q + rr == a mod bforall a b q : t, b ~= 0 -> a == b * q -> q == a / bforall a b q : t, b ~= 0 -> a == b * q -> q == a / bapply div_unique_exact; auto'. Qed.a, b, q:tH:b ~= 0H0:a == b * qq == a / b
A division by itself returns 1
forall a : t, a ~= 0 -> a / a == 1forall a : t, a ~= 0 -> a / a == 1apply div_same; auto'. Qed.a:tH:a ~= 0a / a == 1forall a : t, a ~= 0 -> a mod a == 0forall a : t, a ~= 0 -> a mod a == 0apply mod_same; auto'. Qed.a:tH:a ~= 0a mod a == 0
A division of a small number by a bigger one yields zero.
forall a b : t, a < b -> a / b == 0forall a b : t, a < b -> a / b == 0apply div_small; auto'. Qed.a, b:tH:a < ba / b == 0
Same situation, in term of modulo:
forall a b : t, a < b -> a mod b == aforall a b : t, a < b -> a mod b == aapply mod_small; auto'. Qed.a, b:tH:a < ba mod b == a
forall a : t, a ~= 0 -> 0 / a == 0forall a : t, a ~= 0 -> 0 / a == 0apply div_0_l; auto'. Qed.a:tH:a ~= 00 / a == 0forall a : t, a ~= 0 -> 0 mod a == 0forall a : t, a ~= 0 -> 0 mod a == 0apply mod_0_l; auto'. Qed.a:tH:a ~= 00 mod a == 0forall a : t, a / 1 == aforall a : t, a / 1 == aapply div_1_r; auto'. Qed.a:ta / 1 == aforall a : t, a mod 1 == 0forall a : t, a mod 1 == 0apply mod_1_r; auto'. Qed.a:ta mod 1 == 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 == aapply div_mul; auto'. Qed.a, b:tH:b ~= 0a * b / b == aforall a b : t, b ~= 0 -> (a * b) mod b == 0forall a b : t, b ~= 0 -> (a * b) mod b == 0apply mod_mul; auto'. Qed.a, b:tH:b ~= 0(a * b) mod b == 0
A modulo cannot grow beyond its starting point.
forall a b : t, b ~= 0 -> a mod b <= aforall a b : t, b ~= 0 -> a mod b <= aapply mod_le; auto'. Qed.a, b:tH:b ~= 0a mod b <= aforall 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 <-> a < bforall a b : t, b ~= 0 -> a / b == 0 <-> a < bapply div_small_iff; auto'. Qed.a, b:tH:b ~= 0a / b == 0 <-> a < bforall a b : t, b ~= 0 -> a mod b == a <-> a < bforall a b : t, b ~= 0 -> a mod b == a <-> a < bapply mod_small_iff; auto'. Qed.a, b:tH:b ~= 0a mod b == a <-> a < bforall a b : t, b ~= 0 -> 0 < a / b <-> b <= aforall a b : t, b ~= 0 -> 0 < a / b <-> b <= aapply div_str_pos_iff; auto'. Qed.a, b:tH:b ~= 00 < a / b <-> b <= a
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, c ~= 0 -> a <= b -> a / c <= b / cforall a b c : t, c ~= 0 -> a <= b -> a / c <= b / capply div_le_mono; auto'. Qed.a, b, c:tH:c ~= 0H0:a <= ba / c <= b / cforall a b : t, b ~= 0 -> b * (a / b) <= aforall a b : t, b ~= 0 -> b * (a / b) <= aapply mul_div_le; auto'. Qed.a, b:tH:b ~= 0b * (a / b) <= aforall a b : t, b ~= 0 -> a < b * S (a / b)intros; apply mul_succ_div_gt; auto'. Qed.forall a b : t, b ~= 0 -> a < b * S (a / b)
The previous inequality 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 == 0apply div_exact; auto'. Qed.a, b:tH:b ~= 0a == b * (a / b) <-> a mod b == 0
Some additional inequalities about div.
forall a b q : t, b ~= 0 -> a < b * q -> a / b < qforall a b q : t, b ~= 0 -> a < b * q -> a / b < qapply div_lt_upper_bound; auto'. Qed.a, b, q:tH:b ~= 0H0:a < b * qa / b < qforall a b q : t, b ~= 0 -> a <= b * q -> a / b <= qintros; apply div_le_upper_bound; auto'. Qed.forall a b q : t, b ~= 0 -> a <= b * q -> a / b <= qforall a b q : t, b ~= 0 -> b * q <= a -> q <= a / bintros; apply div_le_lower_bound; auto'. Qed.forall a b q : t, b ~= 0 -> b * q <= a -> q <= a / b
A division respects opposite monotonicity for the divisor
forall p q r : t, 0 < q <= r -> p / r <= p / qforall p q r : t, 0 < q <= r -> p / r <= p / qp, q, r:tH:0 < q <= rp / r <= p / qp, q, r:tH:0 < q <= r0 <= pp, q, r:tH:0 < q <= r0 < q <= rauto. Qed.p, q, r:tH:0 < q <= r0 < q <= r
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 capply mod_add; auto'. Qed.a, b, c:tH:c ~= 0(a + b * c) mod c == a mod cforall 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 + bapply div_add; auto'. Qed.a, b, c:tH:c ~= 0(a + b * c) / 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 / bapply div_add_l; auto'. Qed.a, b, c:tH:b ~= 0(a * b + c) / b == a + c / b
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 / bapply div_mul_cancel_r; auto'. Qed.a, b, c:tH:b ~= 0H0:c ~= 0a * c / (b * c) == a / bforall 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 / bapply div_mul_cancel_l; auto'. Qed.a, b, c:tH:b ~= 0H0:c ~= 0c * a / (c * b) == a / bforall 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 * capply mul_mod_distr_r; auto'. Qed.a, b, c:tH:b ~= 0H0:c ~= 0(a * c) mod (b * c) == a mod b * cforall 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)apply mul_mod_distr_l; auto'. Qed.a, b, c:tH:b ~= 0H0:c ~= 0(c * a) mod (c * b) == c * (a mod b)
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 napply mod_mod; auto'. Qed.a, n:tH:n ~= 0(a mod n) mod n == a 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 napply mul_mod_idemp_l; auto'. Qed.a, b, n:tH:n ~= 0(a mod n * b) mod n == (a * 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 napply mul_mod_idemp_r; auto'. Qed.a, b, n:tH:n ~= 0(a * (b mod n)) mod n == (a * b) 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 napply mul_mod; auto'. 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 napply add_mod_idemp_l; auto'. Qed.a, b, n:tH:n ~= 0(a mod n + b) mod n == (a + 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 napply add_mod_idemp_r; auto'. Qed.a, b, n:tH:n ~= 0(a + b mod n) mod n == (a + b) 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 napply add_mod; auto'. Qed.a, b, n:tH:n ~= 0(a + b) mod n == (a mod n + b mod n) mod nforall a b c : t, b ~= 0 -> c ~= 0 -> a / b / c == a / (b * c)forall a b c : t, b ~= 0 -> c ~= 0 -> a / b / c == a / (b * c)apply div_div; auto'. Qed.a, b, c:tH:b ~= 0H0:c ~= 0a / b / c == a / (b * c)forall a b c : t, b ~= 0 -> c ~= 0 -> a mod (b * c) == a mod b + b * ((a / b) mod c)forall a b c : t, b ~= 0 -> c ~= 0 -> a mod (b * c) == a mod b + b * ((a / b) mod c)apply mod_mul_r; auto'. Qed.a, b, c:tH:b ~= 0H0:c ~= 0a mod (b * c) == a mod b + b * ((a / b) mod c)
A last inequality:
forall a b c : t, b ~= 0 -> c * (a / b) <= c * a / bforall a b c : t, b ~= 0 -> c * (a / b) <= c * a / bapply div_mul_le; auto'. Qed.a, b, c:tH:b ~= 0c * (a / b) <= c * a / b
mod is related to divisibility
forall a b : t, b ~= 0 -> a mod b == 0 <-> (exists c : t, a == b * c)forall a b : t, b ~= 0 -> a mod b == 0 <-> (exists c : t, a == b * c)apply mod_divides; auto'. Qed. End NDivProp.a, b:tH:b ~= 0a mod b == 0 <-> (exists c : t, a == b * c)