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, Euclid convention

We use here the "usual" formulation of the Euclid Theorem a b, b<>0 r q, a = b×q+r 0 r < |b|
The outcome of the modulo function is hence always positive. This corresponds to convention "E" 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 ZDivFloor for others conventions.
We simply extend NZDiv with a bound for modulo that holds regardless of the sign of a and b. This new specification subsume mod_bound_pos, which nonetheless stays there for subtyping. Note also that ZAxiomSig now already contain a div and a modulo (that follow the Floor convention). We just ignore them here.
Module Type EuclidSpec (Import A : ZAxiomsSig')(Import B : DivMod A).
 Axiom mod_always_pos : forall a b, b ~= 0 -> 0 <= B.modulo a b < abs b.
End EuclidSpec.

Module Type ZEuclid (Z:ZAxiomsSig) := NZDiv.NZDiv Z <+ EuclidSpec Z.

Module ZEuclidProp
 (Import A : ZAxiomsSig')
 (Import B : ZMulOrderProp A)
 (Import C : ZSgnAbsProp A B)
 (Import D : ZEuclid A).
We put notations in a scope, to avoid warnings about redefinitions of notations
 Declare Scope euclid.
 Infix "/" := D.div : euclid.
 Infix "mod" := D.modulo : euclid.
 Local Open Scope euclid.

 Module Import Private_NZDiv := Nop <+ NZDivProp A D 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. 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].
Uniqueness theorems

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

forall b q1 q2 r1 r2 : t, 0 <= r1 < abs b -> 0 <= r2 < abs b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < abs b
Hr2:0 <= r2 < abs b
EQ:b * q1 + r1 == b * q2 + r2

q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < abs b
Hr2:0 <= r2 < abs b
EQ:b * q1 + r1 == b * q2 + r2
LE:0 <= b

q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < abs b
Hr2:0 <= r2 < abs b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b
q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2
LE:0 <= b

q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < abs b
Hr2:0 <= r2 < abs b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b
q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < abs b
Hr2:0 <= r2 < abs b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < - b
Hr2:0 <= r2 < - b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

q1 == q2 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < - b
Hr2:0 <= r2 < - b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

q2 == q1 /\ r1 == r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < - b
Hr2:0 <= r2 < - b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

- b * q2 + r1 == - b * q1 + r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < - b
Hr2:0 <= r2 < - b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

- (b * q2) + r1 == - (b * q1) + r2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < - b
Hr2:0 <= r2 < - b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

r1 == - (b * q1) + r2 + b * q2
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < - b
Hr2:0 <= r2 < - b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

r1 == - (b * q1) + (r2 + b * q2)
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < - b
Hr2:0 <= r2 < - b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

- (b * q1) + (r2 + b * q2) == r1
b, q1, q2, r1, r2:t
Hr1:0 <= r1 < - b
Hr2:0 <= r2 < - b
EQ:b * q1 + r1 == b * q2 + r2
LT:0 < - b

r2 + b * q2 == r1 + b * q1
now rewrite (add_comm r2), (add_comm r1). Qed.

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

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

q == a / b
a, b, q, r:t
Hr:0 <= r < abs b
EQ:a == b * q + r

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

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

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

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

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

0 <= a mod b < abs b
a, b, q, r:t
Hr:0 <= r < abs b
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 < abs b
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 < abs b -> a == b * q + r -> r == a mod b

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

r == a mod b
a, b, q, r:t
Hr:0 <= r < abs b
EQ:a == b * q + r

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

b ~= 0
a, b, q, r:t
Hr:0 <= r < abs b
EQ:a == b * q + r
LT:0 < - b
b ~= 0
a, b, q, r:t
Hr:0 <= r < abs b
EQ:a == b * q + r
Hb:b ~= 0
r == a mod b
a, b, q, r:t
Hr:0 <= r < abs b
EQ:a == b * q + r
LT:0 < - b

b ~= 0
a, b, q, r:t
Hr:0 <= r < abs b
EQ:a == b * q + r
Hb:b ~= 0
r == a mod b
a, b, q, r:t
Hr:0 <= r < abs b
EQ:a == b * q + r
LT:0 < - b

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

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

0 <= a mod b < abs b
a, b, q, r:t
Hr:0 <= r < abs b
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 < abs b
EQ:a == b * q + r
Hb:b ~= 0

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

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 < abs (- b)
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_opp; now apply div_mod. 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 < abs (- b)
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_opp; now apply div_mod. 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
Hb:b ~= 0
Hab:a mod b == 0

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

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

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

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

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

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

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

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

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

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

0 <= abs b - a mod b < abs b
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0
- a == b * (- (a / b) - sgn b) + (abs b - a mod b)
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0

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

a mod b + 0 <= abs b < a mod b + abs b
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0
- a == b * (- (a / b) - sgn b) + (abs b - a mod b)
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0

a mod b <= abs b < a mod b + abs b
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0
- a == b * (- (a / b) - sgn b) + (abs b - a mod b)
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0

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

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

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

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

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

- a == - (b * (a / b)) + - (a mod b)
rewrite <-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
Hab:a mod b == 0

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

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

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

- a == b * - (a / b) + 0
now rewrite <-opp_0, <-Hab, mul_opp_r, <-opp_add_distr, <-div_mod. Qed.

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

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

- a mod b == abs b - a mod b
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0

abs b - a mod b == - a mod b
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0

0 <= abs b - a mod b < abs b
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0
- a == b * (- (a / b) - sgn b) + (abs b - a mod b)
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0

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

a mod b + 0 <= abs b < a mod b + abs b
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0
- a == b * (- (a / b) - sgn b) + (abs b - a mod b)
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0

a mod b <= abs b < a mod b + abs b
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0
- a == b * (- (a / b) - sgn b) + (abs b - a mod b)
a, b:t
Hb:b ~= 0
Hab:a mod b ~= 0

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

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

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

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

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

- a == - (b * (a / b)) + - (a mod b)
rewrite <-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
now rewrite div_opp_r, div_opp_l_z, opp_involutive. Qed.

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

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

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

- (- (a / b) - sgn b) == a / b + sgn b
now rewrite opp_sub_distr, opp_involutive. 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
now rewrite mod_opp_r, mod_opp_l_z. Qed.

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

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

- a mod - b == abs b - a mod b
now rewrite mod_opp_r, mod_opp_l_nz. 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

1 == a / a
a:t
H:a ~= 0

0 <= 0 < abs a
a:t
H:a ~= 0
a == a * 1 + 0
a:t
H:a ~= 0

a == a * 1 + 0
now nzsimpl. 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
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 < abs 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
apply neq_sym, 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 < abs b
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 -> b ~= 0 -> a mod b <= a

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

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

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

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

a mod - b <= a
apply mod_le; order. 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 < abs b

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

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

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

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

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

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

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

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

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

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

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

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

0 <= a < abs b
trivial. Qed.

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

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

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

b mod c <= 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

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

0 <= a mod c
destruct (mod_always_pos a c); order. Qed.
In this convention, div performs Rounding-Toward-Bottom when divisor is positive, and Rounding-Toward-Top otherwise.
Since we cannot speak of rational values here, we express this fact by multiplying back by b, and this leads to a nice unique statement.

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

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

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

0 <= a mod b
now destruct (mod_always_pos a b). Qed.
Giving a reversed bound is slightly more complex

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
a, b:t
H:0 < b

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

a mod b < b
rewrite abs_eq in *; order. Qed.

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

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

a < b * P (a / b)
a, b:t
Hb:b < 0

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

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

a mod b < - b
a, b:t
Hb:b < 0

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

a mod b < - b
a, b:t
Hb:0 < - b
H:0 <= a mod b
H0:a mod b < abs b

a mod b < - b
rewrite abs_neq' in *; order. Qed.
NB: The three 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
apply mul_div_le; order. 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 < abs 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 == 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.
With the current convention, the following isn't always true when c<0: -3*-1 / -2*-1 = 3/2 = 1 while -3/-2 = 2

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

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

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

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

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

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

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

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

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

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

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

b * (a / b * c) == b * (c * (a / b))
now rewrite (mul_comm c). Qed.

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

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

c * a / (c * b) == a / b
rewrite !(mul_comm c); now apply div_mul_cancel_r. Qed.

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

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

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

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:0 < c

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

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

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

c * b ~= 0
rewrite <- neq_mul_0; intuition; order. Qed.

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

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

(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 < abs n
now apply mod_always_pos. 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)) 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
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 intermediate divisor. For instance 3/(-2)/(-2) = 1 0 = 3 / (-2*-2) and 3/(-2)/2 = -1 0 = 3 / (-2*2) .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

a / b == c * (a / b / c) + (a / b) mod c
apply div_mod; order. Qed.
Similarly, the following result doesn't always hold when b<0. For instance 3 mod (-2*-2)) = 3 while 3 mod (-2) + (-2)*((3/-2) mod -2) = -1.

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

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

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

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:0 < b
Hc:c ~= 0

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

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

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

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 < abs b
auto using mod_always_pos. 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.
mod is related to divisibility

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

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

a mod b == 0 <-> (b | a)
a, b:t
Hb:b ~= 0

a mod b == 0 -> (b | a)
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
Hab:a mod b == 0

(b | a)
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
Hab:a mod b == 0

a == a / b * b
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
Hab:a mod b == 0

a == b * (a / b)
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
Hab:a mod b == 0

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

(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
c:t
Hc:a == c * b

a mod b == 0
a, b:t
Hb:b ~= 0
c:t
Hc:a == c * b

(c * b) mod b == 0
now apply mod_mul. Qed. End ZEuclidProp.