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)

We use here the convention known as Floor, or Round-Toward-Bottom, where a/b is the closest integer below the exact fraction. It can be summarized by:
a = bq+r 0 |r| < |b| Sign(r) = Sign(b)
This is the convention followed historically by Z.div in Coq, and corresponds to convention "F" in the following paper:
R. Boute, "The Euclidean definition of the functions div and mod", ACM Transactions on Programming Languages and Systems, Vol. 14, No.2, pp. 127-144, April 1992.
See files ZDivTrunc and ZDivEucl for others conventions.
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:t
H:b ~= 0

a mod b == a - b * (a / 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.
We have a general bound for absolute values

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

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

abs (a mod b) < abs b
a, b:t
H:b ~= 0
LE:0 <= b
EQ:abs b == b

abs (a mod b) < b
a, b:t
H:b ~= 0
LE:b < 0
EQ:abs b == - b
abs (a mod b) < - b
a, b:t
H:b ~= 0
LE:0 <= b
EQ:abs b == b

0 < b
a, b:t
H:b ~= 0
LE:0 <= b
EQ:abs b == b
H0:0 <= a mod b
H1:a mod b < b
abs (a mod b) < b
a, b:t
H:b ~= 0
LE:b < 0
EQ:abs b == - b
abs (a mod b) < - b
a, b:t
H:b ~= 0
LE:0 <= b
EQ:abs b == b
H0:0 <= a mod b
H1:a mod b < b

abs (a mod b) < b
a, b:t
H:b ~= 0
LE:b < 0
EQ:abs b == - b
abs (a mod b) < - b
a, b:t
H:b ~= 0
LE:b < 0
EQ:abs b == - b

abs (a mod b) < - b
a, b:t
H:b ~= 0
LE:b < 0
EQ:abs b == - b

b < 0
a, b:t
H:b ~= 0
LE:b < 0
EQ:abs b == - b
H0:b < a mod b
H1:a mod b <= 0
abs (a mod b) < - b
a, b:t
H:b ~= 0
LE:b < 0
EQ:abs b == - b
H0:b < a mod b
H1:a mod b <= 0

abs (a mod b) < - b
a, b:t
H:b ~= 0
LE:b < 0
EQ:abs b == - b
H0:b < a mod b
H1:a mod b <= 0

- (a mod b) < - b
now rewrite <- opp_lt_mono. Qed.
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 == r2

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 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < b \/ b < r1 <= 0
Hr2:0 <= r2 < b \/ b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2

q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
H:0 <= r1 < b
H0:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2

q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2
q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2

q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2

q1 == q2 /\ - r1 == - r2
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2

0 <= - r1 < - b
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2
0 <= - r2 < - b
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2
- b * q1 + - r1 == - b * q2 + - r2
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2

0 <= - r2 < - b
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2
- b * q1 + - r1 == - b * q2 + - r2
b, q1, q2, r1, r2:t
H:b < r1 <= 0
H0:b < r2 <= 0
EQ:b * q1 + r1 == b * q2 + r2

- b * q1 + - r1 == - b * q2 + - r2
now rewrite 2 mul_opp_l, <- 2 opp_add_distr, opp_inj_wd. Qed.

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

forall a b q r : t, 0 <= r < b \/ b < r <= 0 -> a == b * q + r -> q == a / b
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r

q == a / b
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r
Hb:b ~= 0

q == a / b
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r
Hb:b ~= 0

0 <= a mod b < b \/ b < a mod b <= 0
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r
Hb:b ~= 0
b * q + r == b * (a / b) + a mod b
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r
Hb:b ~= 0

b * q + r == b * (a / b) + a mod b
now rewrite <- div_mod. Qed.

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

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

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

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

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

forall a b q r : t, 0 <= r < b \/ b < r <= 0 -> a == b * q + r -> r == a mod b
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r

r == a mod b
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r
Hb:b ~= 0

r == a mod b
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r
Hb:b ~= 0

0 <= a mod b < b \/ b < a mod b <= 0
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r
Hb:b ~= 0
b * q + r == b * (a / b) + a mod b
a, b, q, r:t
Hr:0 <= r < b \/ b < r <= 0
EQ:a == b * q + r
Hb:b ~= 0

b * q + r == b * (a / b) + a mod b
now rewrite <- div_mod. Qed.

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

forall a b q r : t, 0 <= r < b -> a == b * q + r -> r == a mod b
intros; apply mod_unique with q; auto. Qed.

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

forall a b q r : t, b < r <= 0 -> a == b * q + r -> r == a mod b
intros; apply mod_unique with q; auto. Qed.
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 <= 0

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

0 <= a mod b < b \/ b < a mod b <= 0
a, b:t
H:b ~= 0
H0:0 < b

0 <= a mod b < b
a, b:t
H:b ~= 0
H0:b <= 0
b < a mod b <= 0
a, b:t
H:b ~= 0
H0:b <= 0

b < a mod b <= 0
apply mod_neg_bound; order. Qed.

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

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

0 <= - (a mod b) < - b \/ - b < - (a mod b) <= 0
a, b:t
H:b ~= 0
H0:0 < b

- b < - (a mod b) <= 0
a, b:t
H:b ~= 0
H0:b <= 0
0 <= - (a mod b) < - b
a, b:t
H:b ~= 0
H0:0 < b

a mod b < b /\ 0 <= a mod b
a, b:t
H:b ~= 0
H0:b <= 0
0 <= - (a mod b) < - b
a, b:t
H:b ~= 0
H0:b <= 0

0 <= - (a mod b) < - b
a, b:t
H:b ~= 0
H0:b <= 0

a mod b <= 0 /\ b < a mod b
destruct (mod_neg_bound a b); intuition; order. Qed.

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

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

- a / - b == a / b
a, b:t
H:b ~= 0

a / b == - a / - b
a, b:t
H:b ~= 0

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

- a == - b * (a / b) + - (a mod b)
rewrite mul_opp_l, <- opp_add_distr, <- div_mod; order. Qed.

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

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

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

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

- a == - b * (a / b) + - (a mod b)
rewrite mul_opp_l, <- opp_add_distr, <- div_mod; order. Qed.
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:t
Hb:b ~= 0
H:a mod b == 0

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

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

0 <= 0 < b \/ b < 0 <= 0
a, b:t
Hb:b ~= 0
H:a mod b == 0
- a == b * - (a / b) + 0
a, b:t
Hb:b ~= 0
H:a mod b == 0

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

- a == b * - (a / b) + - (a mod b)
rewrite mul_opp_r, <- opp_add_distr, <- div_mod; order. Qed.

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

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

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

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

0 <= b - a mod b < b \/ b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:0 < b

0 <= b - a mod b < b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0
b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:0 < b

a mod b <= b /\ b - a mod b < b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0
b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:0 < b

a mod b <= b /\ b - a mod b < b - 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0
b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:0 < b

a mod b <= b /\ 0 < a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0
b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0

b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0

b < b - a mod b /\ b <= a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0

b - 0 < b - a mod b /\ b <= a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0

a mod b < 0 /\ b <= a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0

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

- a == b * - (a / b) + - (a mod b)
rewrite mul_opp_r, <-opp_add_distr, <-div_mod; order. Qed.

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

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

- a mod b == 0
a, b:t
Hb:b ~= 0
H:a mod b == 0

0 == - a mod b
a, b:t
Hb:b ~= 0
H:a mod b == 0

0 <= 0 < b \/ b < 0 <= 0
a, b:t
Hb:b ~= 0
H:a mod b == 0
- a == b * - (a / b) + 0
a, b:t
Hb:b ~= 0
H:a mod b == 0

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

- a == b * - (a / b) + - (a mod b)
rewrite mul_opp_r, <- opp_add_distr, <- div_mod; order. Qed.

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

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

- a mod b == b - a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0

b - a mod b == - a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0

0 <= b - a mod b < b \/ b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:0 < b

0 <= b - a mod b < b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0
b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:0 < b

a mod b <= b /\ b - a mod b < b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0
b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:0 < b

a mod b <= b /\ b - a mod b < b - 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0
b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:0 < b

a mod b <= b /\ 0 < a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0
b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0

b < b - a mod b <= 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0

b < b - a mod b /\ b <= a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0

b - 0 < b - a mod b /\ b <= a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
H0:b <= 0

a mod b < 0 /\ b <= a mod b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
- a == b * (- (a / b) - 1) + (b - a mod b)
a, b:t
Hb:b ~= 0
H:a mod b ~= 0

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

- a == b * - (a / b) + - (a mod b)
rewrite mul_opp_r, <-opp_add_distr, <-div_mod; order. Qed.

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

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

- - a / - b == - (a / b)
rewrite div_opp_opp; auto using div_opp_l_z. Qed.

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

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

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

- - a / - b == - (a / b) - 1
rewrite div_opp_opp; auto using div_opp_l_nz. Qed.

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

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

a mod - b == 0
a, b:t
H:b ~= 0
H0:a mod b == 0

- - a mod - b == 0
now rewrite mod_opp_opp, mod_opp_l_z, opp_0. Qed.

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

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

a mod - b == a mod b - b
a, b:t
H:b ~= 0
H0:a mod b ~= 0

- - a mod - b == a mod b - b
a, b:t
H:b ~= 0
H0:a mod b ~= 0

- (b - a mod b) == a mod b - b
now rewrite opp_sub_distr, add_comm, add_opp_r. Qed.
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 b

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

sgn (a mod b) == sgn b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
Hb':0 < b

sgn (a mod b) == sgn b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
Hb':b <= 0
sgn (a mod b) == sgn b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
Hb':0 < b
H0:0 <= a mod b
H1:a mod b < b

sgn (a mod b) == sgn b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
Hb':b <= 0
sgn (a mod b) == sgn b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
Hb':b <= 0

sgn (a mod b) == sgn b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
Hb':b <= 0

b < 0
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
Hb':b <= 0
H0:b < a mod b
H1:a mod b <= 0
sgn (a mod b) == sgn b
a, b:t
Hb:b ~= 0
H:a mod b ~= 0
Hb':b <= 0
H0:b < a mod b
H1:a mod b <= 0

sgn (a mod b) == sgn b
rewrite 2 sgn_neg; order. Qed.

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

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

False
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
EQ:a mod b == 0

False
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0
False
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
EQ:a mod b == 0

- sgn b == - 0
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0
False
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0

False
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0

sgn b == 0
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0

sgn b * 2 == 0
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0

sgn b + sgn b == 0
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0

sgn b == - sgn b
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0

sgn b == sgn (a mod b)
a, b:t
Hb:b ~= 0
H:sgn (a mod b) == - sgn b
NEQ:a mod b ~= 0

sgn (a mod b) == sgn b
now apply mod_sign_nz. Qed.

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

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

0 <= a mod b * b
a, b:t
H:b ~= 0
H0:0 < b

0 <= a mod b * b
a, b:t
H:b ~= 0
H0:b <= 0
0 <= a mod b * b
a, b:t
H:b ~= 0
H0:b <= 0

0 <= a mod b * b
apply mul_nonpos_nonpos; destruct (mod_neg_bound a b); order. 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
a:t
H:a ~= 0
LE:0 <= a

a / a == 1
a:t
H:a ~= 0
LT:0 < - a
a / a == 1
a:t
H:a ~= 0
LT:0 < - a

a / a == 1
a:t
H:a ~= 0
LT:0 < - a

- a / - a == 1
now apply div_same. 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
a:t
H:a ~= 0

a - a * 1 == 0
a:t
H:a ~= 0

a - a == 0
apply sub_diag. Qed.
A division of a small number by a bigger one yields zero.

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

forall a b : t, 0 <= a < b -> a / b == 0
exact div_small. Qed.
Same situation, in term of modulo:

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

forall a b : t, 0 <= a < b -> a mod b == a
exact mod_small. 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
a:t
H:a ~= 0
LE:0 <= a

0 / a == 0
a:t
H:a ~= 0
LT:0 < - a
0 / a == 0
a:t
H:a ~= 0
LT:0 < - a

0 / a == 0
a:t
H:a ~= 0
LT:0 < - a

0 / - a == 0
now apply div_0_l. Qed.

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

forall a : t, a ~= 0 -> 0 mod a == 0
intros; rewrite mod_eq, div_0_l; now nzsimpl. Qed.

forall a : t, a / 1 == a

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

a / 1 == a
a:t

a == a / 1
a:t

0 <= 0 < 1 \/ 1 < 0 <= 0
a:t
a == 1 * a + 0
a:t

0 <= 0 < 1
a:t
a == 1 * a + 0
a:t

a == 1 * a + 0
now nzsimpl. Qed.

forall a : t, a mod 1 == 0

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

a mod 1 == 0
a:t

1 ~= 0
intro EQ; symmetry in EQ; revert EQ; apply lt_neq; apply lt_0_1. 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
a, b:t
H:b ~= 0

a == a * b / b
a, b:t
H:b ~= 0

0 <= 0 < b \/ b < 0 <= 0
a, b:t
H:b ~= 0
a * b == b * a + 0
a, b:t
H:b ~= 0

a * b == b * a + 0
nzsimpl; apply mul_comm. 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
a, b:t
H:b ~= 0

a * b - b * a == 0
rewrite mul_comm; apply sub_diag. Qed.
a, b, q:t

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

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

q == a / b
a, b, q:t
Hb:b ~= 0
H:a == b * q

q == q * b / b
a, b, q:t
Hb:b ~= 0
H:a == b * q

q * b / b == q
now apply div_mul. Qed.

Order results about mod and div

A modulo cannot grow beyond its starting point.

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

forall a b : t, 0 <= a -> 0 < b -> a mod b <= a
exact mod_le. Qed.

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

forall a b : t, 0 <= a -> 0 < b -> 0 <= a / b
exact div_pos. 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 <-> 0 <= a < b \/ b < a <= 0

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

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

a / b == 0 -> 0 <= a < b \/ b < a <= 0
a, b:t
Hb:b ~= 0
0 <= a < b \/ b < a <= 0 -> a / b == 0
a, b:t
Hb:b ~= 0
EQ:a / b == 0

0 <= a < b \/ b < a <= 0
a, b:t
Hb:b ~= 0
0 <= a < b \/ b < a <= 0 -> a / b == 0
a, b:t
Hb:b ~= 0
EQ:a / b == 0

0 <= a mod b < b \/ b < a mod b <= 0
a, b:t
Hb:b ~= 0
0 <= a < b \/ b < a <= 0 -> a / b == 0
a, b:t
Hb:b ~= 0

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

a / b == 0
a, b:t
Hb:b ~= 0
H:b < a <= 0
a / b == 0
a, b:t
Hb:b ~= 0
H:b < a <= 0

a / b == 0
a, b:t
Hb:b ~= 0
H:b < a <= 0

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

0 <= - a < - b
rewrite <- opp_lt_mono, opp_nonneg_nonpos; tauto. Qed.

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

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

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

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

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

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

b == 0 \/ a / b == 0 <-> a / b == 0
tauto. 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, 0 < c -> a <= b -> a / c <= b / c

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

a / c <= b / c
a, b, c:t
Hc:0 < c
Hab:a < b \/ a == b

a / c <= b / c
a, b, c:t
Hc:0 < c
LT:a < b

a / c <= b / c
a, b, c:t
Hc:0 < c
LT:a < b

a / c < S (b / c)
a, b, c:t
Hc:0 < c
LT:a < b

c * (a / c) < c * S (b / c)
a, b, c:t
Hc:0 < c
LT:a < b

c * (a / c) < c * (b / c) + c
a, b, c:t
Hc:0 < c
LT:a < b

c * (a / c) + a mod c < c * (b / c) + c + a mod c
a, b, c:t
Hc:0 < c
LT:a < b

a < c * (b / c) + c + a mod c
a, b, c:t
Hc:0 < c
LT:a < b

b <= c * (b / c) + c + a mod c
a, b, c:t
Hc:0 < c
LT:a < b

c * (b / c) + b mod c <= c * (b / c) + c + a mod c
a, b, c:t
Hc:0 < c
LT:a < b

b mod c <= c + a mod c
a, b, c:t
Hc:0 < c
LT:a < b

b mod c <= c + 0
a, b, c:t
Hc:0 < c
LT:a < b
c + 0 <= c + a mod c
a, b, c:t
Hc:0 < c
LT:a < b

c + 0 <= c + a mod c
a, b, c:t
Hc:0 < c
LT:a < b

0 <= a mod c
destruct (mod_pos_bound a c); order. Qed.
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) <= a

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

b * (a / b) <= a
a, b:t
H:0 < b

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

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

0 <= a mod b
now destruct (mod_pos_bound a b). Qed.

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

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

a <= b * (a / b)
a, b:t
H:b < 0

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

0 < - b
now rewrite opp_pos_neg. Qed.
... 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:t
H:0 < b

a < b * S (a / b)
a, b:t
H:0 < b

a < b * (a / b) + b
a, b:t
H:0 < b

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

a mod b < b
destruct (mod_pos_bound a b); order. Qed.

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

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

b * S (a / b) < a
a, b:t
H:b < 0

- a < - b * S (- a / - b)
a, b:t
H:b < 0

0 < - b
now rewrite opp_pos_neg. Qed.
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 == 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
a, b:t
H:b ~= 0

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

b * (a / b) + a mod b == b * (a / b) + 0 <-> a mod b == 0
apply add_cancel_l. Qed.
Some additional inequalities about div.

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

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

a / b < q
a, b, q:t
H:0 < b
H0:a < b * q

b * (a / b) < b * q
a, b, q:t
H:0 < b
H0:a < b * q

b * (a / b) <= a
now apply mul_div_le. Qed.

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

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

a / b <= q
a, b, q:t
H:0 < b
H0:a <= b * q

a / b <= q * b / b
a, b, q:t
H:0 < b
H0:a <= b * q

a <= q * b
now rewrite mul_comm. Qed.

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

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

q <= a / b
a, b, q:t
H:0 < b
H0:b * q <= a

q * b / b <= a / b
a, b, q:t
H:0 < b
H0:b * q <= a

q * b <= a
now rewrite mul_comm. Qed.
A division respects opposite monotonicity for the divisor

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

forall p q r : t, 0 <= p -> 0 < q <= r -> p / r <= p / q
exact div_le_compat_l. 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
a, b, c:t
H:c ~= 0

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

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

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

a + b * c == a + c * b
now rewrite mul_comm. 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
a, b, c:t
H:c ~= 0

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

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

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

a + b * c == a + c * b
now rewrite mul_comm. 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

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

b ~= 0 -> (c + a * b) / b == c / b + a
now apply div_add. 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
a, b, c:t
H:b ~= 0
H0:c ~= 0

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

0 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0
a, b, c:t
H:b ~= 0
H0:c ~= 0
a * c == b * c * (a / b) + a mod b * c
(* ineqs *)
a, b, c:t
H:b ~= 0
H0:c ~= 0
H1:0 < c

0 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0
a, b, c:t
H:b ~= 0
H0:c ~= 0
H1:c <= 0
0 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0
a, b, c:t
H:b ~= 0
H0:c ~= 0
a * c == b * c * (a / b) + a mod b * c
a, b, c:t
H:b ~= 0
H0:c ~= 0
H1:0 < c

0 <= a mod b < b \/ b < a mod b <= 0
a, b, c:t
H:b ~= 0
H0:c ~= 0
H1:c <= 0
0 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0
a, b, c:t
H:b ~= 0
H0:c ~= 0
a * c == b * c * (a / b) + a mod b * c
a, b, c:t
H:b ~= 0
H0:c ~= 0
H1:c <= 0

0 <= a mod b * c < b * c \/ b * c < a mod b * c <= 0
a, b, c:t
H:b ~= 0
H0:c ~= 0
a * c == b * c * (a / b) + a mod b * c
a, b, c:t
H:b ~= 0
H0:c ~= 0
H1:c <= 0

a mod b <= 0 /\ b < a mod b \/ a mod b < b /\ 0 <= a mod b
a, b, c:t
H:b ~= 0
H0:c ~= 0
a * c == b * c * (a / b) + a mod b * c
a, b, c:t
H:b ~= 0
H0:c ~= 0

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

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

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

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

b * (a / b * c) == b * (c * (a / b))
now rewrite (mul_comm c). 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
rewrite !(mul_comm c); now apply div_mul_cancel_r. 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)
a, b, c:t
H:b ~= 0
H0:c ~= 0

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

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

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

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

c * b ~= 0
rewrite <- neq_mul_0; 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
rewrite !(mul_comm _ c); now rewrite mul_mod_distr_l. 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
a, n:t
H:n ~= 0

0 <= a mod n < n \/ n < a mod n <= 0
now apply mod_bound_or. 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
Hn:n ~= 0

(a mod n * b) mod n == (a * b) mod n
a, b, n:t
Hn:n ~= 0

(a * b) mod n == (a mod n * b) mod n
a, b, n:t
Hn:n ~= 0

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

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

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

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

(b * (a mod n)) mod n == (a mod n * b) mod n
now rewrite mul_comm. 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
a, b, n:t
H:n ~= 0

(b mod n * a) mod n == (b * a) mod n
now apply mul_mod_idemp_l. 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
now rewrite mul_mod_idemp_l, mul_mod_idemp_r. 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
Hn:n ~= 0

(a mod n + b) mod n == (a + b) mod n
a, b, n:t
Hn:n ~= 0

(a + b) mod n == (a mod n + b) mod n
a, b, n:t
Hn:n ~= 0

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

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

(a mod n + b + a / n * n) mod n == (a mod n + b) mod n
now rewrite mod_add. 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
a, b, n:t
H:n ~= 0

(b mod n + a) mod n == (b + a) mod n
now apply add_mod_idemp_l. 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
now rewrite add_mod_idemp_l, add_mod_idemp_r. Qed.
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:t
Hb:b ~= 0
Hc:0 < c

a / b / c == a / (b * c)
a, b, c:t
Hb:b ~= 0
Hc:0 < c

0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
(* begin 0<= ... <b*c \/ ... *)
a, b, c:t
Hb:b < 0 \/ 0 < b
Hc:0 < c

0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b < 0
Hc:0 < c

0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:0 < b
Hc:0 < c
0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b < 0
Hc:0 < c

b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:0 < b
Hc:0 < c
0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0

b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:0 < b
Hc:0 < c
0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0

b * c < b * ((a / b) mod c) + a mod b
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0
b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:0 < b
Hc:0 < c
0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0

b * c <= b * ((a / b) mod c) + b
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0
b * ((a / b) mod c) + b < b * ((a / b) mod c) + a mod b
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0
b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:0 < b
Hc:0 < c
0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0

b * ((a / b) mod c) + b < b * ((a / b) mod c) + a mod b
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0
b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:0 < b
Hc:0 < c
0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0

b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:0 < b
Hc:0 < c
0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b < 0
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:b < a mod b
H2:a mod b <= 0

b * ((a / b) mod c) <= 0
a, b, c:t
Hb:0 < b
Hc:0 < c
0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:0 < b
Hc:0 < c

0 <= b * ((a / b) mod c) + a mod b < b * c \/ b * c < b * ((a / b) mod c) + a mod b <= 0
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:0 < b
Hc:0 < c

0 <= b * ((a / b) mod c) + a mod b < b * c
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b

0 <= b * ((a / b) mod c) + a mod b < b * c
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b

0 <= b * ((a / b) mod c) + a mod b
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b
b * ((a / b) mod c) + a mod b < b * c
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b

0 <= b * ((a / b) mod c)
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b
b * ((a / b) mod c) + a mod b < b * c
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b

b * ((a / b) mod c) + a mod b < b * c
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b

b * ((a / b) mod c) + a mod b < b * ((a / b) mod c) + b
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b
b * ((a / b) mod c) + b <= b * c
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:0 < b
Hc:0 < c
H:0 <= (a / b) mod c
H0:(a / b) mod c < c
H1:0 <= a mod b
H2:a mod b < b

b * ((a / b) mod c) + b <= b * c
a, b, c:t
Hb:b ~= 0
Hc:0 < c
a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b ~= 0
Hc:0 < c

a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
(* end 0<= ... < b*c \/ ... *)
a, b, c:t
Hb:b ~= 0
Hc:0 < c

b * (a / b) + a mod b == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Hb:b ~= 0
Hc:0 < c

b * (a / b) == b * c * (a / b / c) + b * ((a / b) mod c)
a, b, c:t
Hb:b ~= 0
Hc:0 < c

a / b == c * (a / b / c) + (a / b) mod c
apply div_mod; order. Qed.
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:t
Hb:b ~= 0
Hc:0 < c

a mod (b * c) == a mod b + b * ((a / b) mod c)
a, b, c:t
Hb:b ~= 0
Hc:0 < c

b * c * (a / (b * c)) + a mod (b * c) == b * c * (a / (b * c)) + (a mod b + b * ((a / b) mod c))
a, b, c:t
Hb:b ~= 0
Hc:0 < c

a == b * c * (a / (b * c)) + (a mod b + b * ((a / b) mod c))
a, b, c:t
Hb:b ~= 0
Hc:0 < c

a == b * c * (a / b / c) + (a mod b + b * ((a / b) mod c))
a, b, c:t
Hb:b ~= 0
Hc:0 < c

a == b * (c * (a / b / c) + (a / b) mod c) + a mod b
a, b, c:t
Hb:b ~= 0
Hc:0 < c

a == b * (a / b) + a mod b
apply div_mod; order. Qed.

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

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

a mod b / b == 0
a, b:t
Hb:b ~= 0

0 <= a mod b < b \/ b < a mod b <= 0
auto using mod_bound_or. Qed.
A last inequality:

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

forall a b c : t, 0 <= a -> 0 < b -> 0 <= c -> c * (a / b) <= c * a / b
exact div_mul_le. Qed. End ZDivProp.