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)         *)
(************************************************************************)
Euclidean Division
Require Import NZAxioms NZMulOrder.
The first signatures will be common to all divisions over NZ, N and Z
Module Type DivMod (Import A : Typ).
 Parameters Inline div modulo : t -> t -> t.
End DivMod.

Module Type DivModNotation (A : Typ)(Import B : DivMod A).
 Infix "/" := div.
 Infix "mod" := modulo (at level 40, no associativity).
End DivModNotation.

Module Type DivMod' (A : Typ) := DivMod A <+ DivModNotation A.

Module Type NZDivSpec (Import A : NZOrdAxiomsSig')(Import B : DivMod' A).
 Declare Instance div_wd : Proper (eq==>eq==>eq) div.
 Declare Instance mod_wd : Proper (eq==>eq==>eq) modulo.
 Axiom div_mod : forall a b, b ~= 0 -> a == b*(a/b) + (a mod b).
 Axiom mod_bound_pos : forall a b, 0<=a -> 0<b -> 0 <= a mod b < b.
End NZDivSpec.
The different divisions will only differ in the conditions they impose on modulo. For NZ, we have only described the behavior on positive numbers.
Module Type NZDiv (A : NZOrdAxiomsSig) := DivMod A <+ NZDivSpec A.
Module Type NZDiv' (A : NZOrdAxiomsSig) := NZDiv A <+ DivModNotation A.

Module Type NZDivProp
 (Import A : NZOrdAxiomsSig')
 (Import B : NZDiv' A)
 (Import C : NZMulOrderProp A).
Uniqueness theorems

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

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

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

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

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

False
b, q1, q2, r1, r2:t
LT:0 <= r1 < b
Hr1:0 <= r2
Hr2:q1 < q2

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

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

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

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

r1 < b
tauto.
b, q1, q2, r1, r2:t
LT:0 <= r1 < b
Hr1:0 <= r2
Hr2:q1 < q2

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

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

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

b * S q1 <= b * q2
b, q1, q2, r1, r2:t
Hr1:0 <= r2
Hr2:q1 < q2
H:0 <= r1
H0:r1 < b

S q1 <= q2
rewrite le_succ_l; auto.
b, q1, q2, r1, r2:t
LT:0 <= r1 < b
Hr1:0 <= r2
Hr2:q1 < q2

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

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

0 <= r2
tauto.
b:t
U:forall q1 q2 r1 r2 : t, b * q1 + r1 == b * q2 + r2 -> 0 <= r1 < b -> 0 <= r2 -> q1 < q2 -> False

forall q1 q2 r1 r2 : t, 0 <= r1 < b -> 0 <= r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2
b:t
U:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> False
q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2
LT:q1 < q2

q1 == q2 /\ r1 == r2
b:t
U:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> False
q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2
EQ':q1 == q2
q1 == q2 /\ r1 == r2
b:t
U:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> False
q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2
GT:q2 < q1
q1 == q2 /\ r1 == r2
b:t
U:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> False
q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2
LT:q1 < q2

q1 == q2 /\ r1 == r2
elim (U q1 q2 r1 r2); intuition.
b:t
U:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> False
q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2
EQ':q1 == q2

q1 == q2 /\ r1 == r2
b:t
U:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> False
q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2
EQ':q1 == q2

r1 == r2
b:t
U:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> False
q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q2 + r1 == b * q2 + r2
EQ':q1 == q2

r1 == r2
rewrite add_cancel_l in EQ; auto.
b:t
U:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> False
q1, q2, r1, r2:t
Hr1:0 <= r1 < b
Hr2:0 <= r2 < b
EQ:b * q1 + r1 == b * q2 + r2
GT:q2 < q1

q1 == q2 /\ r1 == r2
elim (U q2 q1 r2 r1); intuition. Qed.

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

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

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

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

0 <= a mod b < b
apply mod_bound_pos; order.
a, b, q, r:t
Ha:0 <= a
Hb:0 <= r
Hr:r < b
EQ:a == b * q + r

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

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

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

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

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

0 <= a mod b < b
apply mod_bound_pos; order.
a, b, q, r:t
Ha:0 <= a
Hb:0 <= r
Hr:r < b
EQ:a == b * q + r

b * q + r == b * (a / b) + a mod b
rewrite <- div_mod; order. Qed.
a, b, q:t

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

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

q == a / b
apply div_unique with 0; nzsimpl; now try split. Qed.
A division by itself returns 1

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

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

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

1 == a / a
apply div_unique_exact; nzsimpl; order. Qed.

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

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

a mod a == 0
a:t
H:0 < a

0 == a mod a
a:t
H:0 < a

a == a * 1 + 0
now nzsimpl. 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
a, b:t
H:0 <= a < b

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

0 == a / b
a, b:t
H0:0 <= a
H1:a < b

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

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

a == a mod b
a, b:t
H0:0 <= a
H1:a < b

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

Basic values of divisions and modulo.


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

forall a : t, 0 < a -> 0 / a == 0
intros; apply div_small; split; order. Qed.

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

forall a : t, 0 < a -> 0 mod a == 0
intros; apply mod_small; split; order. Qed.

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

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

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

a == a / 1
apply div_unique_exact; nzsimpl; order'. Qed.

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

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

a mod 1 == 0
a:t
H:0 <= a

0 == a mod 1
a:t
H:0 <= a

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

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

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

0 <= 1
apply le_0_1. Qed.

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

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

0 <= 1
apply le_0_1. Qed.

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

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

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

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

0 <= a * b
apply mul_nonneg_nonneg; order.
a, b:t
H:0 <= a
H0:0 < b

a * b == b * a
apply mul_comm. Qed.

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

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

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

0 <= a * b
a, b:t
H:0 <= a
H0:0 < b
a * b == b * a + 0
a, b:t
H:0 <= a
H0:0 < b

0 <= a * b
apply mul_nonneg_nonneg; order.
a, b:t
H:0 <= a
H0:0 < b

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

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

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

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

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

a mod b < b
destruct (mod_bound_pos a b); auto.
a, b:t
H:0 <= a
H0:0 < b
H1:a < b

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

a mod b == a
apply mod_small; auto. Qed. (* Division of positive numbers is positive. *)

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

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

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

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

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

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

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
a, b:t
Hb:0 < b
Hab:b <= a

0 < a / b
a, b:t
Hb:0 < b
Hab:b <= a
LE:0 <= a / b

0 < a / b
a, b:t
Hb:0 < b
Hab:b <= a
LE:0 <= a / b
MOD:a mod b < b

0 < a / b
a, b:t
Hb:0 < b
Hab:b <= a
EQ:0 == a / b
MOD:a mod b < b

0 < a / b
a, b:t
Hb:0 < b
EQ:0 == a / b
MOD:a mod b < b

b <= a -> False
rewrite (div_mod a b), <-EQ; nzsimpl; order. Qed.

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

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

a < b
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:a < b
a / b == 0
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:a / b == 0

a < b
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:a / b == 0
H:b <= a

a < b
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:0 == a / b
H:b <= a

a < b
a, b:t
Ha:0 <= a
Hb:0 < b
H:b <= a

0 ~= a / b
apply lt_neq, div_str_pos; auto.
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:a < b

a / b == 0
apply div_small; auto. Qed.

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

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

a mod b == a <-> a < b
a, b:t
Ha:0 <= a
Hb:0 < b
H:a mod b == a

a < b
a, b:t
Ha:0 <= a
Hb:0 < b
H:a mod b == a

a / b == 0
a, b:t
Ha:0 <= a
Hb:0 < b
H:a mod b == a

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

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

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

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

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

b <= a
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:b <= a
0 < a / b
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:0 < a / b

b <= a
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:0 < a / b
LT:a < b

b <= a
rewrite <- div_small_iff in LT; order.
a, b:t
Ha:0 <= a
Hb:0 < b
Hab:b <= a

0 < a / b
apply div_str_pos; 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
a, b:t
H:0 < a
H0:1 < b

a / b < a
a, b:t
H:0 < a
H0:1 < b
H1:0 < b

a / b < a
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:a < b

a / b < a
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a
a / b < a
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:a < b

a / b < a
rewrite div_small; try split; order.
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

a / b < a
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

a / b < b * (a / b) + a mod b
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

a / b < b * (a / b)
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a
b * (a / b) <= b * (a / b) + a mod b
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

a / b < b * (a / b)
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

1 * (a / b) < b * (a / b)
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

0 < a / b
apply div_str_pos; auto.
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

b * (a / b) <= b * (a / b) + a mod b
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

b * (a / b) + 0 <= b * (a / b) + a mod b
a, b:t
H:0 < a
H0:1 < b
H1:0 < b
H2:b <= a

0 <= a mod b
destruct (mod_bound_pos a b); order. Qed.
le is compatible with a positive division.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

b mod c <= c + 0
nzsimpl; destruct (mod_bound_pos b c); order.
a, b, c:t
Hc:0 < c
Ha:0 <= a
LT:a < b

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

0 <= a mod c
destruct (mod_bound_pos a c); order. Qed.
The following two properties could be used as specification of div

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

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

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

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

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

0 <= a mod b
destruct (mod_bound_pos a b); order. Qed.

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

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

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

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

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

a mod b < b
destruct (mod_bound_pos a b); auto. Qed.
The previous inequality is exact iff the modulo is zero.

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

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

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

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

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 <= a -> 0 < b -> a < b * q -> a / b < q

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

0 <= b * q
apply lt_le_incl, mul_pos_pos; auto.
a, b, q:t
Ha:0 <= a
Hb:0 < b
H:b * q <= a
H0:q <= 0

q <= a / b
apply le_trans with 0; auto; apply div_pos; auto. 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
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

p / r <= p / q
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

q * (p / r) <= p
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

q * (p / r) <= r * (p / r) + p mod r
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

q * (p / r) <= r * (p / r)
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r
r * (p / r) <= r * (p / r) + p mod r
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

q * (p / r) <= r * (p / r)
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

0 <= p / r
apply div_pos; order.
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

r * (p / r) <= r * (p / r) + p mod r
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

r * (p / r) + 0 <= r * (p / r) + p mod r
p, q, r:t
Hp:0 <= p
Hq:0 < q
Hqr:q <= r

0 <= p mod r
destruct (mod_bound_pos p r); order. Qed.

Relations between usual operations and mod and div


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

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

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

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

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

0 <= a mod c < c
apply mod_bound_pos; auto.
a, b, c:t
H:0 <= a
H0:0 <= a + b * c
H1:0 < c

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

a + b * c == a + c * b
now rewrite mul_comm. Qed.

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

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

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

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

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

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

a + b * c == a + c * b
now rewrite mul_comm. Qed.

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

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

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

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

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

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

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

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

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

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

0 <= a * c
apply mul_nonneg_nonneg; order.
a, b, c:t
H:0 <= a
H0:0 < b
H1:0 < c

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

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

0 <= a mod b * c
apply mul_nonneg_nonneg; destruct (mod_bound_pos a b); order.
a, b, c:t
H:0 <= a
H0:0 < b
H1:0 < c

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

a mod b < b
destruct (mod_bound_pos a b); auto.
a, b, c:t
H:0 <= a
H0:0 < b
H1:0 < c

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

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

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

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

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

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

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

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

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

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

(c * a) mod (c * b) == c * (a mod b)
a, b, c:t
H:0 <= a
H0:0 < b
H1: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:0 <= a
H0:0 < b
H1:0 < c

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

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

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

a == b * (a / b) + a mod b
apply div_mod; order.
a, b, c:t
H:0 <= a
H0:0 < b
H1:0 < c

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

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

forall a b c : t, 0 <= a -> 0 < b -> 0 < c -> (a * c) mod (b * c) == a mod b * c
a, b, c:t
H:0 <= a
H0:0 < b
H1: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, 0 <= a -> 0 < n -> (a mod n) mod n == a mod n

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

(a mod n) mod n == a mod n
a, n:t
H:0 <= a
H0:0 < n
H1:0 <= a mod n
H2:a mod n < n

(a mod n) mod n == a mod n
now rewrite mod_small_iff. Qed.

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

forall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a mod n * b) mod n == (a * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

(a mod n * b) mod n == (a * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

(a * b) mod n == (a mod n * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

0 <= a * b -> (a * b) mod n == (a mod n * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

0 <= (n * (a / n) + a mod n) * b -> ((n * (a / n) + a mod n) * b) mod n == (a mod n * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

0 <= b * (a mod n + a / n * n) -> (b * (a mod n + a / n * n)) mod n == (a mod n * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

0 <= b * (a mod n) + b * (a / n) * n -> (b * (a mod n) + b * (a / n) * n) mod n == (a mod n * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= b * (a mod n) + b * (a / n) * n

(b * (a mod n) + b * (a / n) * n) mod n == (a mod n * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= b * (a mod n) + b * (a / n) * n

(b * (a mod n)) mod n == (a mod n * b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= b * (a mod n) + b * (a / n) * n
0 <= b * (a mod n)
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= b * (a mod n) + b * (a / n) * n

(b * (a mod n)) mod n == (a mod n * b) mod n
now rewrite mul_comm.
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= b * (a mod n) + b * (a / n) * n

0 <= b * (a mod n)
apply mul_nonneg_nonneg; destruct (mod_bound_pos a n); auto. Qed.

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

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

(a * (b mod n)) mod n == (a * b) mod n
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n

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

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

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

(a * b) mod n == (a mod n * (b mod n)) mod n
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n

(a * b) mod n == (a * b) mod n
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n
0 <= b mod n
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n

(a * b) mod n == (a * b) mod n
reflexivity.
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n

0 <= b mod n
now destruct (mod_bound_pos b n). Qed.

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

forall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a mod n + b) mod n == (a + b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

(a mod n + b) mod n == (a + b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

(a + b) mod n == (a mod n + b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

0 <= a + b -> (a + b) mod n == (a mod n + b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

0 <= n * (a / n) + a mod n + b -> (n * (a / n) + a mod n + b) mod n == (a mod n + b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n

0 <= a mod n + b + a / n * n -> (a mod n + b + a / n * n) mod n == (a mod n + b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= a mod n + b + a / n * n

(a mod n + b + a / n * n) mod n == (a mod n + b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= a mod n + b + a / n * n

(a mod n + b) mod n == (a mod n + b) mod n
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= a mod n + b + a / n * n
0 <= a mod n + b
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= a mod n + b + a / n * n

(a mod n + b) mod n == (a mod n + b) mod n
reflexivity.
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= a mod n + b + a / n * n

0 <= a mod n + b
a, b, n:t
Ha:0 <= a
Hb:0 <= b
Hn:0 < n
H:0 <= a mod n + b + a / n * n

0 <= a mod n
destruct (mod_bound_pos a n); auto. Qed.

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

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

(a + b mod n) mod n == (a + b) mod n
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n

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

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

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

(a + b) mod n == (a mod n + b mod n) mod n
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n

(a + b) mod n == (a + b) mod n
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n
0 <= b mod n
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n

(a + b) mod n == (a + b) mod n
reflexivity.
a, b, n:t
H:0 <= a
H0:0 <= b
H1:0 < n

0 <= b mod n
now destruct (mod_bound_pos b n). Qed.

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

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

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

0 <= b * ((a / b) mod c) + a mod b < b * c
a, b, c:t
Ha:0 <= a
Hb:0 < b
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
Ha:0 <= a
Hb:0 < b
Hc:0 < c

0 <= b * ((a / b) mod c) + a mod b < b * c
a, b, c:t
Ha:0 <= a
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
Ha:0 <= a
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
Ha:0 <= a
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
Ha:0 <= a
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
Ha:0 <= a
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)
apply mul_nonneg_nonneg; order.
a, b, c:t
Ha:0 <= a
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
Ha:0 <= a
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
Ha:0 <= a
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
Ha:0 <= a
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
rewrite <- add_lt_mono_l; auto.
a, b, c:t
Ha:0 <= a
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
rewrite <- mul_succ_r, <- mul_le_mono_pos_l, le_succ_l; auto. (* end 0<= ... < b*c *)
a, b, c:t
Ha:0 <= a
Hb:0 < b
Hc:0 < c

a == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)
a, b, c:t
Ha:0 <= a
Hb:0 < b
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
Ha:0 <= a
Hb:0 < b
Hc:0 < c

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

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

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

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

a mod (b * c) == a mod b + b * ((a / b) mod c)
a, b, c:t
Ha:0 <= a
Hb:0 < b
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
Ha:0 <= a
Hb:0 < b
Hc:0 < c

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

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

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

a == b * (a / b) + a mod b
apply div_mod; order. 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
a, b, c:t
H:0 <= a
H0:0 < b
H1:0 <= c

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

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

0 <= c * a
apply mul_nonneg_nonneg; auto.
a, b, c:t
H:0 <= a
H0:0 < b
H1:0 <= c

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

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

b * (a / b) <= a
apply mul_div_le; auto. Qed.
mod is related to divisibility

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

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

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

a mod b == 0 -> exists c : t, a == b * c
a, b:t
H:0 <= a
H0:0 < b
H1:a mod b == 0

exists c : t, a == b * c
a, b:t
H:0 <= a
H0:0 < b
H1:a mod b == 0

a == b * (a / b)
rewrite div_exact; auto.
a, b:t
H:0 <= a
H0:0 < b

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

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

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

0 <= c
a, b:t
H:0 <= a
H0:0 < b
c:t
Hc:a == b * c

b * 0 <= b * c
a, b:t
H:0 <= a
H0:0 < b
c:t
Hc:a == b * c

0 <= b * c
order. Qed. End NZDivProp.