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 < b

forall a b : t, b ~= 0 -> a mod b < b
a, b:t
H:b ~= 0

a mod b < b
apply mod_bound_pos; auto'. Qed.
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:t
H:b ~= 0

a mod b == a - b * (a / b)
a, b:t
H:b ~= 0

a - b * (a / b) == a mod b
a, b:t
H:b ~= 0

b * (a / b) + a mod b == a
a, b:t
H:b ~= 0

a == b * (a / b) + a mod b
now apply div_mod. Qed.
Uniqueness theorems

forall b q1 q2 r1 r2 : t, r1 < b -> r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2

forall b q1 q2 r1 r2 : t, r1 < b -> r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
H:r1 < b
H0:r2 < b
H1:b * q1 + r1 == b * q2 + r2

q1 == q2 /\ r1 == r2
apply div_mod_unique with b; auto'. Qed.

forall a b q r : t, r < b -> a == b * q + r -> q == a / b

forall a b q r : t, r < b -> a == b * q + r -> q == a / b
intros; apply div_unique with r; auto'. Qed.

forall a b q r : t, r < b -> a == b * q + r -> r == a mod b

forall a b q r : t, r < b -> a == b * q + r -> r == a mod b
a, b, q, r:t
H:r < b
H0:a == b * q + r

r == a mod b
apply mod_unique with q; auto'. Qed.

forall a b q : t, b ~= 0 -> a == b * q -> q == a / b

forall a b q : t, b ~= 0 -> a == b * q -> q == a / b
a, b, q:t
H:b ~= 0
H0:a == b * q

q == a / b
apply div_unique_exact; auto'. Qed.
A division by itself returns 1

forall a : t, a ~= 0 -> a / a == 1

forall a : t, a ~= 0 -> a / a == 1
a:t
H:a ~= 0

a / a == 1
apply div_same; auto'. Qed.

forall a : t, a ~= 0 -> a mod a == 0

forall a : t, a ~= 0 -> a mod a == 0
a:t
H:a ~= 0

a mod a == 0
apply mod_same; auto'. Qed.
A division of a small number by a bigger one yields zero.

forall a b : t, a < b -> a / b == 0

forall a b : t, a < b -> a / b == 0
a, b:t
H:a < b

a / b == 0
apply div_small; auto'. Qed.
Same situation, in term of modulo:

forall a b : t, a < b -> a mod b == a

forall a b : t, a < b -> a mod b == a
a, b:t
H:a < b

a mod b == a
apply mod_small; auto'. Qed.

Basic values of divisions and modulo.


forall a : t, a ~= 0 -> 0 / a == 0

forall a : t, a ~= 0 -> 0 / a == 0
a:t
H:a ~= 0

0 / a == 0
apply div_0_l; auto'. Qed.

forall a : t, a ~= 0 -> 0 mod a == 0

forall a : t, a ~= 0 -> 0 mod a == 0
a:t
H:a ~= 0

0 mod a == 0
apply mod_0_l; auto'. Qed.

forall a : t, a / 1 == a

forall a : t, a / 1 == a
a:t

a / 1 == a
apply div_1_r; auto'. Qed.

forall a : t, a mod 1 == 0

forall a : t, a mod 1 == 0
a:t

a mod 1 == 0
apply mod_1_r; auto'. Qed.

forall a : t, 1 < a -> 1 / a == 0

forall a : t, 1 < a -> 1 / a == 0
exact div_1_l. Qed.

forall a : t, 1 < a -> 1 mod a == 1

forall a : t, 1 < a -> 1 mod a == 1
exact mod_1_l. Qed.

forall a b : t, b ~= 0 -> a * b / b == a

forall a b : t, b ~= 0 -> a * b / b == a
a, b:t
H:b ~= 0

a * b / b == a
apply div_mul; auto'. Qed.

forall a b : t, b ~= 0 -> (a * b) mod b == 0

forall a b : t, b ~= 0 -> (a * b) mod b == 0
a, b:t
H:b ~= 0

(a * b) mod b == 0
apply mod_mul; auto'. Qed.

Order results about mod and div

A modulo cannot grow beyond its starting point.

forall a b : t, b ~= 0 -> a mod b <= a

forall a b : t, b ~= 0 -> a mod b <= a
a, b:t
H:b ~= 0

a mod b <= a
apply mod_le; auto'. Qed.

forall a b : t, 0 < b <= a -> 0 < a / b

forall a b : t, 0 < b <= a -> 0 < a / b
exact div_str_pos. Qed.

forall a b : t, b ~= 0 -> a / b == 0 <-> a < b

forall a b : t, b ~= 0 -> a / b == 0 <-> a < b
a, b:t
H:b ~= 0

a / b == 0 <-> a < b
apply div_small_iff; auto'. Qed.

forall a b : t, b ~= 0 -> a mod b == a <-> a < b

forall a b : t, b ~= 0 -> a mod b == a <-> a < b
a, b:t
H:b ~= 0

a mod b == a <-> a < b
apply mod_small_iff; auto'. Qed.

forall a b : t, b ~= 0 -> 0 < a / b <-> b <= a

forall a b : t, b ~= 0 -> 0 < a / b <-> b <= a
a, b:t
H:b ~= 0

0 < a / b <-> b <= a
apply div_str_pos_iff; auto'. Qed.
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 < a

forall a b : t, 0 < a -> 1 < b -> a / b < a
exact div_lt. Qed.
le is compatible with a positive division.

forall a b c : t, c ~= 0 -> a <= b -> a / c <= b / c

forall a b c : t, c ~= 0 -> a <= b -> a / c <= b / c
a, b, c:t
H:c ~= 0
H0:a <= b

a / c <= b / c
apply div_le_mono; auto'. Qed.

forall a b : t, b ~= 0 -> b * (a / b) <= a

forall a b : t, b ~= 0 -> b * (a / b) <= a
a, b:t
H:b ~= 0

b * (a / b) <= a
apply mul_div_le; auto'. Qed.

forall a b : t, b ~= 0 -> a < b * S (a / b)

forall a b : t, b ~= 0 -> a < b * S (a / b)
intros; apply mul_succ_div_gt; auto'. Qed.
The previous inequality is exact iff the modulo is zero.

forall a b : t, b ~= 0 -> a == b * (a / b) <-> a mod b == 0

forall a b : t, b ~= 0 -> a == b * (a / b) <-> a mod b == 0
a, b:t
H:b ~= 0

a == b * (a / b) <-> a mod b == 0
apply div_exact; auto'. Qed.
Some additional inequalities about div.

forall a b q : t, b ~= 0 -> a < b * q -> a / b < q

forall a b q : t, b ~= 0 -> a < b * q -> a / b < q
a, b, q:t
H:b ~= 0
H0:a < b * q

a / b < q
apply div_lt_upper_bound; auto'. Qed.

forall a b q : t, b ~= 0 -> a <= b * q -> a / b <= q

forall a b q : t, b ~= 0 -> a <= b * q -> a / b <= q
intros; apply div_le_upper_bound; auto'. Qed.

forall a b q : t, b ~= 0 -> b * q <= a -> q <= a / b

forall a b q : t, b ~= 0 -> b * q <= a -> q <= a / b
intros; apply div_le_lower_bound; auto'. Qed.
A division respects opposite monotonicity for the divisor

forall p q r : t, 0 < q <= r -> p / r <= p / q

forall p q r : t, 0 < q <= r -> p / r <= p / q
p, q, r:t
H:0 < q <= r

p / r <= p / q
p, q, r:t
H:0 < q <= r

0 <= p
p, q, r:t
H:0 < q <= r
0 < q <= r
p, q, r:t
H:0 < q <= r

0 < q <= r
auto. Qed.

Relations between usual operations and mod and div


forall a b c : t, c ~= 0 -> (a + b * c) mod c == a mod c

forall a b c : t, c ~= 0 -> (a + b * c) mod c == a mod c
a, b, c:t
H:c ~= 0

(a + b * c) mod c == a mod c
apply mod_add; auto'. Qed.

forall a b c : t, c ~= 0 -> (a + b * c) / c == a / c + b

forall a b c : t, c ~= 0 -> (a + b * c) / c == a / c + b
a, b, c:t
H:c ~= 0

(a + b * c) / c == a / c + b
apply div_add; auto'. Qed.

forall a b c : t, b ~= 0 -> (a * b + c) / b == a + c / b

forall a b c : t, b ~= 0 -> (a * b + c) / b == a + c / b
a, b, c:t
H:b ~= 0

(a * b + c) / b == a + c / b
apply div_add_l; auto'. Qed.
Cancellations.

forall a b c : t, b ~= 0 -> c ~= 0 -> a * c / (b * c) == a / b

forall a b c : t, b ~= 0 -> c ~= 0 -> a * c / (b * c) == a / b
a, b, c:t
H:b ~= 0
H0:c ~= 0

a * c / (b * c) == a / b
apply div_mul_cancel_r; auto'. Qed.

forall a b c : t, b ~= 0 -> c ~= 0 -> c * a / (c * b) == a / b

forall a b c : t, b ~= 0 -> c ~= 0 -> c * a / (c * b) == a / b
a, b, c:t
H:b ~= 0
H0:c ~= 0

c * a / (c * b) == a / b
apply div_mul_cancel_l; auto'. Qed.

forall a b c : t, b ~= 0 -> c ~= 0 -> (a * c) mod (b * c) == a mod b * c

forall a b c : t, b ~= 0 -> c ~= 0 -> (a * c) mod (b * c) == a mod b * c
a, b, c:t
H:b ~= 0
H0:c ~= 0

(a * c) mod (b * c) == a mod b * c
apply mul_mod_distr_r; auto'. Qed.

forall 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:t
H:b ~= 0
H0:c ~= 0

(c * a) mod (c * b) == c * (a mod b)
apply mul_mod_distr_l; auto'. Qed.
Operations modulo.

forall a n : t, n ~= 0 -> (a mod n) mod n == a mod n

forall a n : t, n ~= 0 -> (a mod n) mod n == a mod n
a, n:t
H:n ~= 0

(a mod n) mod n == a mod n
apply mod_mod; auto'. Qed.

forall a b n : t, n ~= 0 -> (a mod n * b) mod n == (a * b) mod n

forall a b n : t, n ~= 0 -> (a mod n * b) mod n == (a * b) mod n
a, b, n:t
H:n ~= 0

(a mod n * b) mod n == (a * b) mod n
apply mul_mod_idemp_l; auto'. Qed.

forall a b n : t, n ~= 0 -> (a * (b mod n)) mod n == (a * b) mod n

forall a b n : t, n ~= 0 -> (a * (b mod n)) mod n == (a * b) mod n
a, b, n:t
H:n ~= 0

(a * (b mod n)) mod n == (a * b) mod n
apply mul_mod_idemp_r; auto'. Qed.

forall a b n : t, n ~= 0 -> (a * b) mod n == (a mod n * (b mod n)) mod n

forall a b n : t, n ~= 0 -> (a * b) mod n == (a mod n * (b mod n)) mod n
a, b, n:t
H:n ~= 0

(a * b) mod n == (a mod n * (b mod n)) mod n
apply mul_mod; auto'. Qed.

forall a b n : t, n ~= 0 -> (a mod n + b) mod n == (a + b) mod n

forall a b n : t, n ~= 0 -> (a mod n + b) mod n == (a + b) mod n
a, b, n:t
H:n ~= 0

(a mod n + b) mod n == (a + b) mod n
apply add_mod_idemp_l; auto'. Qed.

forall a b n : t, n ~= 0 -> (a + b mod n) mod n == (a + b) mod n

forall a b n : t, n ~= 0 -> (a + b mod n) mod n == (a + b) mod n
a, b, n:t
H:n ~= 0

(a + b mod n) mod n == (a + b) mod n
apply add_mod_idemp_r; auto'. Qed.

forall a b n : t, n ~= 0 -> (a + b) mod n == (a mod n + b mod n) mod n

forall a b n : t, n ~= 0 -> (a + b) mod n == (a mod n + b mod n) mod n
a, b, n:t
H:n ~= 0

(a + b) mod n == (a mod n + b mod n) mod n
apply add_mod; auto'. Qed.

forall 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)
a, b, c:t
H:b ~= 0
H0:c ~= 0

a / b / c == a / (b * c)
apply div_div; auto'. Qed.

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)
a, b, c:t
H:b ~= 0
H0:c ~= 0

a mod (b * c) == a mod b + b * ((a / b) mod c)
apply mod_mul_r; auto'. Qed.
A last inequality:

forall a b c : t, b ~= 0 -> c * (a / b) <= c * a / b

forall a b c : t, b ~= 0 -> c * (a / b) <= c * a / b
a, b, c:t
H:b ~= 0

c * (a / b) <= c * a / b
apply div_mul_le; auto'. Qed.
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)
a, b:t
H:b ~= 0

a mod b == 0 <-> (exists c : t, a == b * c)
apply mod_divides; auto'. Qed. End NDivProp.