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.
(* -*- coding: utf-8 -*- *)
(************************************************************************)
(*         *   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

Initial Contribution by Claude Marché and Xavier Urbain
Require Export ZArith_base.
Require Import Zbool Omega ZArithRing Zcomplements Setoid Morphisms.
Local Open Scope Z_scope.
The definition of the division is now in BinIntDef, the initial specifications and properties are in BinInt.
Notation Zdiv_eucl_POS := Z.pos_div_eucl (only parsing).
Notation Zmod := Z.modulo (only parsing).

Notation Z_div_mod_eq_full := Z.div_mod (only parsing).
Notation Zmod_POS_bound := Z.pos_div_eucl_bound (only parsing).
Notation Zmod_pos_bound := Z.mod_pos_bound (only parsing).
Notation Zmod_neg_bound := Z.mod_neg_bound (only parsing).

Main division theorems

NB: many things are stated twice for compatibility reasons

forall b : Z, b > 0 -> forall a : positive, let (q, r) := Z.pos_div_eucl a b in Z.pos a = b * q + r /\ 0 <= r < b

forall b : Z, b > 0 -> forall a : positive, let (q, r) := Z.pos_div_eucl a b in Z.pos a = b * q + r /\ 0 <= r < b
b:Z
Hb:b > 0
a:positive

let (q, r) := Z.pos_div_eucl a b in Z.pos a = b * q + r /\ 0 <= r < b
b:Z
Hb:0 < b
a:positive

let (q, r) := Z.pos_div_eucl a b in Z.pos a = b * q + r /\ 0 <= r < b
b:Z
Hb:0 < b
a:positive

(let (q, r) := Z.pos_div_eucl a b in Z.pos a = q * b + r) -> 0 <= snd (Z.pos_div_eucl a b) < b -> let (q, r) := Z.pos_div_eucl a b in Z.pos a = b * q + r /\ 0 <= r < b
b:Z
Hb:0 < b
a:positive
z, z0:Z

Z.pos a = z * b + z0 -> 0 <= snd (z, z0) < b -> Z.pos a = b * z + z0 /\ 0 <= z0 < b
b:Z
Hb:0 < b
a:positive
z, z0:Z

Z.pos a = b * z + z0 -> 0 <= snd (z, z0) < b -> Z.pos a = b * z + z0 /\ 0 <= z0 < b
auto. Qed.
a, b:Z

b > 0 -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ 0 <= r < b
a, b:Z

b > 0 -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ 0 <= r < b
a, b:Z

0 < b -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ 0 <= r < b
a, b:Z
Hb:0 < b

let (q, r) := Z.div_eucl a b in a = b * q + r /\ 0 <= r < b
a, b:Z
Hb:0 < b
Hb':b <> 0

let (q, r) := Z.div_eucl a b in a = b * q + r /\ 0 <= r < b
a, b:Z
Hb:0 < b
Hb':b <> 0

(let (q, r) := Z.div_eucl a b in a = b * q + r) -> 0 <= a mod b < b -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ 0 <= r < b
a, b:Z
Hb:0 < b
Hb':b <> 0

(let (q, r) := Z.div_eucl a b in a = b * q + r) -> 0 <= (let (_, r) := Z.div_eucl a b in r) < b -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ 0 <= r < b
a, b:Z
Hb:0 < b
Hb':b <> 0
z, z0:Z

a = b * z + z0 -> 0 <= z0 < b -> a = b * z + z0 /\ 0 <= z0 < b
auto. Qed.
For stating the fully general result, let's give a short name to the condition on the remainder.
Definition Remainder r b :=  0 <= r < b \/ b < r <= 0.
Another equivalent formulation:
Definition Remainder_alt r b :=  Z.abs r < Z.abs b /\ Z.sgn r <> - Z.sgn b.

(* In the last formulation, [ Z.sgn r <> - Z.sgn b ] is less nice than saying
    [ Z.sgn r = Z.sgn b ], but at least it works even when [r] is null. *)


forall r b : Z, Remainder r b <-> Remainder_alt r b

forall r b : Z, Remainder r b <-> Remainder_alt r b
intros; unfold Remainder, Remainder_alt; omega with *. Qed. Hint Unfold Remainder : core.
Now comes the fully general result about Euclidean division.
a, b:Z

b <> 0 -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ Remainder r b
a, b:Z

b <> 0 -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ Remainder r b
a, b:Z
Hb:b <> 0

let (q, r) := Z.div_eucl a b in a = b * q + r /\ Remainder r b
a, b:Z
Hb:b <> 0

(let (q, r) := Z.div_eucl a b in a = b * q + r) -> (0 < b -> 0 <= a mod b < b) -> (b < 0 -> b < a mod b <= 0) -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ Remainder r b
a, b:Z
Hb:b <> 0

(let (q, r) := Z.div_eucl a b in a = b * q + r) -> (0 < b -> 0 <= (let (_, r) := Z.div_eucl a b in r) < b) -> (b < 0 -> b < (let (_, r) := Z.div_eucl a b in r) <= 0) -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ Remainder r b
a, b:Z
Hb:b <> 0
q, r:Z

a = b * q + r -> (0 < b -> 0 <= r < b) -> (b < 0 -> b < r <= 0) -> a = b * q + r /\ Remainder r b
a, b:Z
Hb:b <> 0
q, r:Z
EQ:a = b * q + r
POS:0 < b -> 0 <= r < b
NEG:b < 0 -> b < r <= 0

a = b * q + r /\ Remainder r b
a, b:Z
Hb:b <> 0
q, r:Z
EQ:a = b * q + r
POS:0 < b -> 0 <= r < b
NEG:b < 0 -> b < r <= 0

Remainder r b
a:Z
Hb:0 <> 0
q, r:Z
EQ:a = 0 * q + r
POS:0 < 0 -> 0 <= r < 0
NEG:0 < 0 -> 0 < r <= 0

0 <= r < 0 \/ 0 < r <= 0
a:Z
p:positive
Hb:Z.pos p <> 0
q, r:Z
EQ:a = Z.pos p * q + r
POS:0 < Z.pos p -> 0 <= r < Z.pos p
NEG:Z.pos p < 0 -> Z.pos p < r <= 0
0 <= r < Z.pos p \/ Z.pos p < r <= 0
a:Z
p:positive
Hb:Z.neg p <> 0
q, r:Z
EQ:a = Z.neg p * q + r
POS:0 < Z.neg p -> 0 <= r < Z.neg p
NEG:Z.neg p < 0 -> Z.neg p < r <= 0
0 <= r < Z.neg p \/ Z.neg p < r <= 0
a:Z
p:positive
Hb:Z.pos p <> 0
q, r:Z
EQ:a = Z.pos p * q + r
POS:0 < Z.pos p -> 0 <= r < Z.pos p
NEG:Z.pos p < 0 -> Z.pos p < r <= 0

0 <= r < Z.pos p \/ Z.pos p < r <= 0
a:Z
p:positive
Hb:Z.neg p <> 0
q, r:Z
EQ:a = Z.neg p * q + r
POS:0 < Z.neg p -> 0 <= r < Z.neg p
NEG:Z.neg p < 0 -> Z.neg p < r <= 0
0 <= r < Z.neg p \/ Z.neg p < r <= 0
a:Z
p:positive
Hb:Z.neg p <> 0
q, r:Z
EQ:a = Z.neg p * q + r
POS:0 < Z.neg p -> 0 <= r < Z.neg p
NEG:Z.neg p < 0 -> Z.neg p < r <= 0

0 <= r < Z.neg p \/ Z.neg p < r <= 0
right; now apply NEG. Qed.
The same results as before, stated separately in terms of Z.div and Z.modulo
a, b:Z

b <> 0 -> Remainder (a mod b) b
a, b:Z

b <> 0 -> Remainder (a mod b) b
a, b:Z
Hb:b <> 0

(let (q, r) := Z.div_eucl a b in a = b * q + r /\ Remainder r b) -> Remainder (let (_, r) := Z.div_eucl a b in r) b
destruct Z.div_eucl; tauto. Qed.
a, b:Z

b > 0 -> 0 <= a mod b < b
Proof (fun Hb => Z.mod_pos_bound a b (Z.gt_lt _ _ Hb)).
a, b:Z

b < 0 -> b < a mod b <= 0
Proof (Z.mod_neg_bound a b).
a, b:Z

b > 0 -> a = b * (a / b) + a mod b
a, b:Z

b > 0 -> a = b * (a / b) + a mod b
intros Hb; apply Z.div_mod; auto with zarith. Qed.
a, b:Z

b <> 0 -> a mod b = a - a / b * b
a, b:Z

b <> 0 -> a mod b = a - a / b * b
a, b:Z
H:b <> 0

a mod b = a - a / b * b
a, b:Z
H:b <> 0

a mod b = a - b * (a / b)
now apply Z.mod_eq. Qed.
a, b:Z

b > 0 -> a mod b = a - a / b * b
a, b:Z

b > 0 -> a mod b = a - a / b * b
a, b:Z
H:b > 0

a mod b = a - a / b * b
a, b:Z
H:b > 0

b <> 0
now destruct b. Qed.
Existence theorem

forall b : Z, b > 0 -> forall a : Z, {qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < b}

forall b : Z, b > 0 -> forall a : Z, {qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < b}
b:Z
Hb:b > 0
a:Z

{qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < b}
b:Z
Hb:b > 0
a:Z

let (q, r) := Z.div_eucl a b in a = b * q + r /\ 0 <= r < b
exact (Z_div_mod a b Hb). Qed. Arguments Zdiv_eucl_exist : default implicits.
Uniqueness theorems
b, q1, q2, r1, r2:Z

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

0 <= r1 < Z.abs b -> 0 <= r2 < Z.abs b -> b * q1 + r1 = b * q2 + r2 -> q1 = q2 /\ r1 = r2
b, q1, q2, r1, r2:Z
Hr1:0 <= r1 < Z.abs b
Hr2:0 <= r2 < Z.abs b
H:b * q1 + r1 = b * q2 + r2

q1 = q2 /\ r1 = r2
b, q1, q2, r1, r2:Z
Hr1:0 <= r1 < Z.abs b
Hr2:0 <= r2 < Z.abs b
H:Z.abs b * (Z.sgn b * q1) + r1 = Z.abs b * (Z.sgn b * q2) + r2

q1 = q2 /\ r1 = r2
b, q1, q2, r1, r2:Z
Hr1:0 <= r1 < Z.abs b
Hr2:0 <= r2 < Z.abs b
H:Z.abs b * (Z.sgn b * q1) + r1 = Z.abs b * (Z.sgn b * q2) + r2
H0:Z.sgn b * q1 = Z.sgn b * q2
H1:r1 = r2

q1 = q2 /\ r1 = r2
b, q1, q2, r1, r2:Z
Hr1:0 <= r1 < Z.abs b
Hr2:0 <= r2 < Z.abs b
H:Z.abs b * (Z.sgn b * q1) + r1 = Z.abs b * (Z.sgn b * q2) + r2
H0:Z.sgn b * q1 = Z.sgn b * q2
H1:r1 = r2

q1 = q2
b, q1, q2, r1, r2:Z
Hr1:0 <= r1 < Z.abs b
Hr2:0 <= r2 < Z.abs b
H:Z.abs b * (Z.sgn b * q1) + r1 = Z.abs b * (Z.sgn b * q2) + r2
H0:Z.sgn b * q1 = Z.sgn b * q2
H1:r1 = r2

Z.sgn b <> 0
b, q1, q2, r1, r2:Z
Hr1:0 <= r1 < Z.abs b
Hr2:0 <= r2 < Z.abs b
H:Z.abs b * (Z.sgn b * q1) + r1 = Z.abs b * (Z.sgn b * q2) + r2
H0:Z.sgn b * q1 = Z.sgn b * q2
H1:r1 = r2

Z.abs b <> 0
destruct Hr1; Z.order. Qed.

forall b q1 q2 r1 r2 : Z, Remainder r1 b -> Remainder r2 b -> b * q1 + r1 = b * q2 + r2 -> q1 = q2 /\ r1 = r2
Proof Z.div_mod_unique.

forall a b q r : Z, Remainder r b -> a = b * q + r -> q = a / b
Proof Z.div_unique.

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

forall a b q r : Z, 0 <= r < b -> a = b * q + r -> q = a / b
intros; eapply Zdiv_unique_full; eauto. Qed.

forall a b q r : Z, Remainder r b -> a = b * q + r -> r = a mod b
Proof Z.mod_unique.

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

forall a b q r : Z, 0 <= r < b -> a = b * q + r -> r = a mod b
intros; eapply Zmod_unique_full; eauto. Qed.

Basic values of divisions and modulo.


forall a : Z, 0 mod a = 0

forall a : Z, 0 mod a = 0
destruct a; simpl; auto. Qed.

forall a : Z, a mod 0 = 0

forall a : Z, a mod 0 = 0
destruct a; simpl; auto. Qed.

forall a : Z, 0 / a = 0

forall a : Z, 0 / a = 0
destruct a; simpl; auto. Qed.

forall a : Z, a / 0 = 0

forall a : Z, a / 0 = 0
destruct a; simpl; auto. Qed. Ltac zero_or_not a := destruct (Z.eq_dec a 0); [subst; rewrite ?Zmod_0_l, ?Zdiv_0_l, ?Zmod_0_r, ?Zdiv_0_r; auto with zarith|].

forall a : Z, a mod 1 = 0

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

a mod 1 = 0
a:Z
n:a <> 0

a mod 1 = 0
apply Z.mod_1_r. Qed.

forall a : Z, a / 1 = a

forall a : Z, a / 1 = a
a:Z

a / 1 = a
a:Z
n:a <> 0

a / 1 = a
apply Z.div_1_r. Qed. Hint Resolve Zmod_0_l Zmod_0_r Zdiv_0_l Zdiv_0_r Zdiv_1_r Zmod_1_r : zarith.

forall a : Z, 1 < a -> 1 / a = 0
Proof Z.div_1_l.

forall a : Z, 1 < a -> 1 mod a = 1
Proof Z.mod_1_l.

forall a : Z, a <> 0 -> a / a = 1
Proof Z.div_same.

forall a : Z, a mod a = 0

forall a : Z, a mod a = 0
a:Z

a mod a = 0
a:Z
n:a <> 0

a mod a = 0
apply Z.mod_same; auto. Qed.

forall a b : Z, (a * b) mod b = 0

forall a b : Z, (a * b) mod b = 0
a, b:Z

(a * b) mod b = 0
a, b:Z
n:b <> 0

(a * b) mod b = 0
a, b:Z
n:b <> 0

b <> 0
auto. Qed.

forall a b : Z, b <> 0 -> a * b / b = a
Proof Z.div_mul.

Order results about Z.modulo and Z.div

(* Division of positive numbers is positive. *)


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

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

0 <= a / b
apply Z.div_pos; auto with zarith. Qed.

forall a b : Z, b > 0 -> a >= 0 -> a / b >= 0

forall a b : Z, b > 0 -> a >= 0 -> a / b >= 0
intros; generalize (Z_div_pos a b H); auto with zarith. Qed.
As soon as the divisor is greater or equal than 2, the division is strictly decreasing.

forall a b : Z, b >= 2 -> a > 0 -> a / b < a

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

a / b < a
apply Z.div_lt; auto with zarith. Qed.
A division of a small number by a bigger one yields zero.

forall a b : Z, 0 <= a < b -> a / b = 0
Proof Z.div_small.
Same situation, in term of modulo:

forall a n : Z, 0 <= a < n -> a mod n = a
Proof Z.mod_small.
Z.ge is compatible with a positive division.

forall a b c : Z, c > 0 -> a >= b -> a / c >= b / c

forall a b c : Z, c > 0 -> a >= b -> a / c >= b / c
a, b, c:Z
H:c > 0
H0:a >= b

a / c >= b / c
a, b, c:Z
H:c > 0
H0:a >= b

b / c <= a / c
apply Z.div_le_mono; auto with zarith. Qed.
Same, with Z.le.

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

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

a / c <= b / c
apply Z.div_le_mono; auto with zarith. Qed.
With our choice of division, rounding of (a/b) is always done toward bottom:

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

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

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

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

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

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

a <= b * (a / b)
apply Z.mul_div_ge; auto with zarith. Qed.
The previous inequalities are exact iff the modulo is zero.

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

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

a = b * (a / b) -> a mod b = 0
a, b:Z
n:b <> 0

a = b * (a / b) -> a mod b = 0
rewrite Z.div_exact; auto. Qed.

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

forall a b : Z, b <> 0 -> a mod b = 0 -> a = b * (a / b)
intros; rewrite Z.div_exact; auto. Qed.
A modulo cannot grow beyond its starting point.

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

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

a mod b <= a
apply Z.mod_le; auto. Qed.
Some additional inequalities about Z.div.

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

forall a b q : Z, 0 < b -> a < q * b -> a / b < q
intros a b q; rewrite Z.mul_comm; apply Z.div_lt_upper_bound. Qed.

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

forall a b q : Z, 0 < b -> a <= q * b -> a / b <= q
intros a b q; rewrite Z.mul_comm; apply Z.div_le_upper_bound. Qed.

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

forall a b q : Z, 0 < b -> q * b <= a -> q <= a / b
intros a b q; rewrite Z.mul_comm; apply Z.div_le_lower_bound. Qed.
A division of respect opposite monotonicity for the divisor

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

forall p q r : Z, 0 <= p -> 0 < q < r -> p / r <= p / q
intros; apply Z.div_le_compat_l; auto with zarith. Qed.

forall a b : Z, 0 <= Z.sgn (a / b) * Z.sgn a * Z.sgn b

forall a b : Z, 0 <= Z.sgn (a / b) * Z.sgn a * Z.sgn b
destruct a as [ |a|a]; destruct b as [ |b|b]; simpl; auto with zarith; generalize (Z.div_pos (Zpos a) (Zpos b)); unfold Z.div, Z.div_eucl; destruct Z.pos_div_eucl as (q,r); destruct r; omega with *. Qed.

Relations between usual operations and Z.modulo and Z.div


forall a b c : Z, (a + b * c) mod c = a mod c

forall a b c : Z, (a + b * c) mod c = a mod c
a, b, c:Z

(a + b * c) mod c = a mod c
a, b, c:Z
n:c <> 0

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

forall a b c : Z, c <> 0 -> (a + b * c) / c = a / c + b
Proof Z.div_add.

forall a b c : Z, b <> 0 -> (a * b + c) / b = a + c / b
Proof Z.div_add_l.
Z.opp and Z.div, Z.modulo. Due to the choice of convention for our Euclidean division, some of the relations about Z.opp and divisions are rather complex.

forall a b : Z, - a / - b = a / b

forall a b : Z, - a / - b = a / b
a, b:Z

- a / - b = a / b
a, b:Z
n:b <> 0

- a / - b = a / b
apply Z.div_opp_opp; auto. Qed.

forall a b : Z, - a mod - b = - (a mod b)

forall a b : Z, - a mod - b = - (a mod b)
a, b:Z

- a mod - b = - (a mod b)
a, b:Z
n:b <> 0

- a mod - b = - (a mod b)
apply Z.mod_opp_opp; auto. Qed.

forall a b : Z, a mod b = 0 -> - a mod b = 0

forall a b : Z, a mod b = 0 -> - a mod b = 0
a, b:Z
H:a mod b = 0

- a mod b = 0
a, b:Z
H:a mod b = 0
n:b <> 0

- a mod b = 0
apply Z.mod_opp_l_z; auto. Qed.

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

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

- a mod b = b - a mod b
a, b:Z
H:a mod b <> 0
n:b <> 0

- a mod b = b - a mod b
apply Z.mod_opp_l_nz; auto. Qed.

forall a b : Z, a mod b = 0 -> a mod - b = 0

forall a b : Z, a mod b = 0 -> a mod - b = 0
a, b:Z
H:a mod b = 0

a mod - b = 0
a, b:Z
H:a mod b = 0
n:b <> 0

a mod - b = 0
apply Z.mod_opp_r_z; auto. Qed.

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

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

a mod - b = a mod b - b
a, b:Z
H:a mod b <> 0
n:b <> 0

a mod - b = a mod b - b
apply Z.mod_opp_r_nz; auto. Qed.

forall a b : Z, a mod b = 0 -> - a / b = - (a / b)

forall a b : Z, a mod b = 0 -> - a / b = - (a / b)
a, b:Z
H:a mod b = 0

- a / b = - (a / b)
a, b:Z
H:a mod b = 0
n:b <> 0

- a / b = - (a / b)
apply Z.div_opp_l_z; auto. Qed.

forall a b : Z, a mod b <> 0 -> - a / b = - (a / b) - 1

forall a b : Z, a mod b <> 0 -> - a / b = - (a / b) - 1
a, b:Z

a mod b <> 0 -> - a / b = - (a / b) - 1
a, b:Z
n:b <> 0

a mod b <> 0 -> - a / b = - (a / b) - 1
intros; rewrite Z.div_opp_l_nz; auto. Qed.

forall a b : Z, a mod b = 0 -> a / - b = - (a / b)

forall a b : Z, a mod b = 0 -> a / - b = - (a / b)
a, b:Z
H:a mod b = 0

a / - b = - (a / b)
a, b:Z
H:a mod b = 0
n:b <> 0

a / - b = - (a / b)
apply Z.div_opp_r_z; auto. Qed.

forall a b : Z, a mod b <> 0 -> a / - b = - (a / b) - 1

forall a b : Z, a mod b <> 0 -> a / - b = - (a / b) - 1
a, b:Z

a mod b <> 0 -> a / - b = - (a / b) - 1
a, b:Z
n:b <> 0

a mod b <> 0 -> a / - b = - (a / b) - 1
intros; rewrite Z.div_opp_r_nz; auto. Qed.
Cancellations.

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

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

a * c / (b * c) = a / b
a, b, c:Z
H:c <> 0
n:b <> 0

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

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

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

c * a / (c * b) = a / b
a, b, c:Z
H:c <> 0
n:b <> 0

c * a / (b * c) = a / b
a, b, c:Z
H:c <> 0
n:b <> 0

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

forall a b c : Z, (c * a) mod (c * b) = c * (a mod b)

forall a b c : Z, (c * a) mod (c * b) = c * (a mod b)
a, b, c:Z

(c * a) mod (c * b) = c * (a mod b)
a, b, c:Z
n:c <> 0

(c * a) mod (c * b) = c * (a mod b)
a, b, c:Z
n:c <> 0
n0:b <> 0

(c * a) mod (b * c) = c * (a mod b)
a, b, c:Z
n:c <> 0
n0:b <> 0

(c * a) mod (c * b) = c * (a mod b)
apply Z.mul_mod_distr_l; auto. Qed.

forall a b c : Z, (a * c) mod (b * c) = a mod b * c

forall a b c : Z, (a * c) mod (b * c) = a mod b * c
a, b, c:Z

(a * c) mod (b * c) = a mod b * c
a, b, c:Z
n:b <> 0

(a * c) mod (b * c) = a mod b * c
a, b, c:Z
n:b <> 0
n0:c <> 0

(a * c) mod (c * b) = a mod b * c
a, b, c:Z
n:b <> 0
n0:c <> 0

(a * c) mod (b * c) = a mod b * c
apply Z.mul_mod_distr_r; auto. Qed.
Operations modulo.

forall a n : Z, (a mod n) mod n = a mod n

forall a n : Z, (a mod n) mod n = a mod n
a, n:Z

(a mod n) mod n = a mod n
a, n:Z
n0:n <> 0

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

forall a b n : Z, (a * b) mod n = (a mod n * (b mod n)) mod n

forall a b n : Z, (a * b) mod n = (a mod n * (b mod n)) mod n
a, b, n:Z

(a * b) mod n = (a mod n * (b mod n)) mod n
a, b, n:Z
n0:n <> 0

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

forall a b n : Z, (a + b) mod n = (a mod n + b mod n) mod n

forall a b n : Z, (a + b) mod n = (a mod n + b mod n) mod n
a, b, n:Z

(a + b) mod n = (a mod n + b mod n) mod n
a, b, n:Z
n0:n <> 0

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

forall a b n : Z, (a - b) mod n = (a mod n - b mod n) mod n

forall a b n : Z, (a - b) mod n = (a mod n - b mod n) mod n
a, b, n:Z

(a - b) mod n = (a mod n - b mod n) mod n
a, b, n:Z

(a + -1 * b) mod n = (a mod n - b mod n) mod n
a, b, n:Z

(a + -1 * b) mod n = (a mod n + -1 * (b mod n)) mod n
a, b, n:Z

(a mod n + (-1 * b) mod n) mod n = (a mod n + -1 * (b mod n)) mod n
a, b, n:Z

(a mod n + (-1 mod n * (b mod n)) mod n) mod n = (a mod n + -1 * (b mod n)) mod n
a, b, n:Z

(a mod n + (-1 mod n * (b mod n)) mod n) mod n = ((a mod n) mod n + (-1 * (b mod n)) mod n) mod n
a, b, n:Z

(a mod n + ((-1 mod n) mod n * ((b mod n) mod n)) mod n) mod n = ((a mod n) mod n + (-1 * (b mod n)) mod n) mod n
a, b, n:Z

(a mod n + ((-1 mod n) mod n * ((b mod n) mod n)) mod n) mod n = ((a mod n) mod n + (-1 mod n * ((b mod n) mod n)) mod n) mod n
repeat rewrite Zmod_mod; auto. Qed.

forall a b n : Z, (a mod n + b) mod n = (a + b) mod n

forall a b n : Z, (a mod n + b) mod n = (a + b) mod n
intros; rewrite Zplus_mod, Zmod_mod, <- Zplus_mod; auto. Qed.

forall a b n : Z, (b + a mod n) mod n = (b + a) mod n

forall a b n : Z, (b + a mod n) mod n = (b + a) mod n
intros; rewrite Zplus_mod, Zmod_mod, <- Zplus_mod; auto. Qed.

forall a b n : Z, (a mod n - b) mod n = (a - b) mod n

forall a b n : Z, (a mod n - b) mod n = (a - b) mod n
intros; rewrite Zminus_mod, Zmod_mod, <- Zminus_mod; auto. Qed.

forall a b n : Z, (a - b mod n) mod n = (a - b) mod n

forall a b n : Z, (a - b mod n) mod n = (a - b) mod n
intros; rewrite Zminus_mod, Zmod_mod, <- Zminus_mod; auto. Qed.

forall a b n : Z, (a mod n * b) mod n = (a * b) mod n

forall a b n : Z, (a mod n * b) mod n = (a * b) mod n
intros; rewrite Zmult_mod, Zmod_mod, <- Zmult_mod; auto. Qed.

forall a b n : Z, (b * (a mod n)) mod n = (b * a) mod n

forall a b n : Z, (b * (a mod n)) mod n = (b * a) mod n
intros; rewrite Zmult_mod, Zmod_mod, <- Zmult_mod; auto. Qed.
For a specific number N, equality modulo N is hence a nice setoid equivalence, compatible with +, - and ×.
Section EqualityModulo.
Variable N:Z.

Definition eqm a b := (a mod N = b mod N).
Infix "==" := eqm (at level 70).

N:Z

forall a : Z, a == a
N:Z

forall a : Z, a == a
unfold eqm; auto. Qed.
N:Z

forall a b : Z, a == b -> b == a
N:Z

forall a b : Z, a == b -> b == a
unfold eqm; auto. Qed.
N:Z

forall a b c : Z, a == b -> b == c -> a == c
N:Z

forall a b c : Z, a == b -> b == c -> a == c
unfold eqm; eauto with *. Qed.
N:Z

Equivalence eqm
N:Z

Equivalence eqm
constructor; [exact eqm_refl | exact eqm_sym | exact eqm_trans]. Qed.
N:Z

Proper (eqm ==> eqm ==> eqm) Z.add
N:Z

Proper (eqm ==> eqm ==> eqm) Z.add
N, x, y:Z
H:x mod N = y mod N
x0, y0:Z
H0:x0 mod N = y0 mod N

(x + x0) mod N = (y + y0) mod N
rewrite Zplus_mod, H, H0, <- Zplus_mod; auto. Qed.
N:Z

Proper (eqm ==> eqm ==> eqm) Z.sub
N:Z

Proper (eqm ==> eqm ==> eqm) Z.sub
N, x, y:Z
H:x mod N = y mod N
x0, y0:Z
H0:x0 mod N = y0 mod N

(x - x0) mod N = (y - y0) mod N
rewrite Zminus_mod, H, H0, <- Zminus_mod; auto. Qed.
N:Z

Proper (eqm ==> eqm ==> eqm) Z.mul
N:Z

Proper (eqm ==> eqm ==> eqm) Z.mul
N, x, y:Z
H:x mod N = y mod N
x0, y0:Z
H0:x0 mod N = y0 mod N

(x * x0) mod N = (y * y0) mod N
rewrite Zmult_mod, H, H0, <- Zmult_mod; auto. Qed.
N:Z

Proper (eqm ==> eqm) Z.opp
N:Z

Proper (eqm ==> eqm) Z.opp
N, x, y:Z
H:x == y

- x == - y
N, x, y:Z
H:x == y

0 - x == 0 - y
now rewrite H. Qed.
N:Z

forall a : Z, a mod N == a
N:Z

forall a : Z, a mod N == a
intros; exact (Zmod_mod a N). Qed. (* NB: Z.modulo and Z.div are not morphisms with respect to eqm. For instance, let (==) be (eqm 2). Then we have (3 == 1) but: ~ (3 mod 3 == 1 mod 3) ~ (1 mod 3 == 1 mod 1) ~ (3/3 == 1/3) ~ (1/3 == 1/1) *) End EqualityModulo.

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

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

a / b / c = a / (b * c)
a, b, c:Z
H:0 <= b
H0:0 <= c
n:b <> 0

a / b / c = a / (b * c)
a, b, c:Z
H:0 <= b
H0:0 <= c
n:b <> 0

a / b / c = a / (c * b)
a, b, c:Z
H:0 <= b
H0:0 <= c
n:b <> 0
n0:c <> 0

a / b / c = a / (c * b)
a, b, c:Z
H:0 <= b
H0:0 <= c
n:b <> 0
n0:c <> 0

a / b / c = a / (b * c)
apply Z.div_div; auto with zarith. Qed.
Unfortunately, the previous result isn't always true on negative numbers. For instance: 3/(-2)/(-2) = 1 <> 0 = 3 / (-2*-2)

forall a b : Z, a mod b / b = 0

forall a b : Z, a mod b / b = 0
a, b:Z

a mod b / b = 0
a, b:Z
n:b <> 0

a mod b / b = 0
auto using Z.mod_div. Qed.
A last inequality:

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

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

c * (a / b) <= c * a / b
a, b, c:Z
H:0 <= a
H0:0 <= b
H1:0 <= c
n:b <> 0

c * (a / b) <= c * a / b
apply Z.div_mul_le; auto with zarith. Qed.
Z.modulo is related to divisibility (see more in Znumtheory)

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

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

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

(b | a) <-> (exists c : Z, a = b * c)
split; intros (c,Hc); exists c; subst; auto with zarith. Qed.
Particular case : dividing by 2 is related with parity

forall a : Z, Z.div2 a = a / 2
Proof Z.div2_div.

forall a : Z, a mod 2 = (if Z.odd a then 1 else 0)

forall a : Z, a mod 2 = (if Z.odd a then 1 else 0)
a:Z

a mod 2 = (if Z.odd a then 1 else 0)
now rewrite <- Z.bit0_odd, <- Z.bit0_mod. Qed.

forall a : Z, a mod 2 = (if Z.even a then 0 else 1)

forall a : Z, a mod 2 = (if Z.even a then 0 else 1)
a:Z

a mod 2 = (if Z.even a then 0 else 1)
a:Z

(if negb (Z.even a) then 1 else 0) = (if Z.even a then 0 else 1)
now destruct Z.even. Qed.

forall a : Z, Z.odd a = Zeq_bool (a mod 2) 1

forall a : Z, Z.odd a = Zeq_bool (a mod 2) 1
a:Z

Z.odd a = Zeq_bool (a mod 2) 1
a:Z

Z.odd a = Zeq_bool (if Z.odd a then 1 else 0) 1
now destruct Z.odd. Qed.

forall a : Z, Z.even a = Zeq_bool (a mod 2) 0

forall a : Z, Z.even a = Zeq_bool (a mod 2) 0
a:Z

Z.even a = Zeq_bool (a mod 2) 0
a:Z

Z.even a = Zeq_bool (if Z.even a then 0 else 1) 0
now destruct Z.even. Qed.

Compatibility

Weaker results kept only for compatibility

forall a : Z, a > 0 -> a mod a = 0

forall a : Z, a > 0 -> a mod a = 0
intros; apply Z_mod_same_full. Qed.

forall a : Z, a > 0 -> a / a = 1

forall a : Z, a > 0 -> a / a = 1
intros; apply Z_div_same_full; auto with zarith. Qed.

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

forall a b c : Z, c > 0 -> (a + b * c) / c = a / c + b
intros; apply Z_div_plus_full; auto with zarith. Qed.

forall a b : Z, b > 0 -> a * b / b = a

forall a b : Z, b > 0 -> a * b / b = a
intros; apply Z_div_mult_full; auto with zarith. Qed.

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

forall a b c : Z, c > 0 -> (a + b * c) mod c = a mod c
intros; apply Z_mod_plus_full; auto with zarith. Qed.

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

forall a b : Z, b > 0 -> a = b * (a / b) -> a mod b = 0
intros; apply Z_div_exact_full_1; auto with zarith. Qed.

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

forall a b : Z, b > 0 -> a mod b = 0 -> a = b * (a / b)
intros; apply Z_div_exact_full_2; auto with zarith. Qed.

forall a b : Z, b > 0 -> a mod b = 0 -> - a mod b = 0

forall a b : Z, b > 0 -> a mod b = 0 -> - a mod b = 0
intros; apply Z_mod_zero_opp_full; auto with zarith. Qed.

A direct way to compute Z.modulo

Fixpoint Zmod_POS (a : positive) (b : Z) : Z  :=
  match a with
   | xI a' =>
      let r := Zmod_POS a' b in
      let r' := (2 * r + 1) in
      if r' <? b then r' else (r' - b)
   | xO a' =>
      let r := Zmod_POS a' b in
      let r' := (2 * r) in
      if r' <? b then r' else (r' - b)
   | xH => if 2 <=? b then 1 else 0
  end.

Definition Zmod' a b :=
  match a with
   | Z0 => 0
   | Zpos a' =>
      match b with
       | Z0 => 0
       | Zpos _ => Zmod_POS a' b
       | Zneg b' =>
          let r := Zmod_POS a' (Zpos b') in
          match r  with Z0 =>  0 |  _  =>   b + r end
      end
   | Zneg a' =>
      match b with
       | Z0 => 0
       | Zpos _ =>
          let r := Zmod_POS a' b in
          match r with Z0 =>  0 | _  =>  b - r end
       | Zneg b' => - (Zmod_POS a' (Zpos b'))
      end
  end.


a:positive
b:Z

Zmod_POS a b = snd (Z.pos_div_eucl a b)
a:positive
b:Z

Zmod_POS a b = snd (Z.pos_div_eucl a b)
a:positive
b:Z
IH:Zmod_POS a b = snd (Z.pos_div_eucl a b)

(if match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1 <? b then match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1 else match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1 - b) = snd (let (q, r) := Z.pos_div_eucl a b in if match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1 <? b then (match q with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end, match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1) else (match q with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1, match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1 - b))
a:positive
b:Z
IH:Zmod_POS a b = snd (Z.pos_div_eucl a b)
(if match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end <? b then match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end else match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end - b) = snd (let (q, r) := Z.pos_div_eucl a b in if match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end <? b then (match q with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end, match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end) else (match q with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1, match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end - b))
b:Z
(if 2 <=? b then 1 else 0) = snd (if 2 <=? b then (0, 1) else (1, 0))
a:positive
b:Z
IH:Zmod_POS a b = snd (Z.pos_div_eucl a b)

(if match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end <? b then match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end else match snd (Z.pos_div_eucl a b) with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end - b) = snd (let (q, r) := Z.pos_div_eucl a b in if match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end <? b then (match q with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end, match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end) else (match q with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end + 1, match r with | 0 => 0 | Z.pos y' => Z.pos y'~0 | Z.neg y' => Z.neg y'~0 end - b))
b:Z
(if 2 <=? b then 1 else 0) = snd (if 2 <=? b then (0, 1) else (1, 0))
b:Z

(if 2 <=? b then 1 else 0) = snd (if 2 <=? b then (0, 1) else (1, 0))
case Z.leb_spec; trivial. Qed.

forall a b : Z, Zmod' a b = a mod b

forall a b : Z, Zmod' a b = a mod b
a, b:Z

forall p : positive, match b with | 0 => 0 | Z.pos _ => Zmod_POS p b | Z.neg b' => match Zmod_POS p (Z.pos b') with | 0 => 0 | _ => b + Zmod_POS p (Z.pos b') end end = (let (_, r) := match b with | 0 => (0, 0) | Z.pos _ => Z.pos_div_eucl p b | Z.neg b' => let (q, r) := Z.pos_div_eucl p (Z.pos b') in match r with | 0 => (- q, 0) | _ => (- (q + 1), b + r) end end in r)
a, b:Z
forall p : positive, match b with | 0 => 0 | Z.pos _ => match Zmod_POS p b with | 0 => 0 | _ => b - Zmod_POS p b end | Z.neg b' => - Zmod_POS p (Z.pos b') end = (let (_, r) := match b with | 0 => (0, 0) | Z.pos _ => let (q, r) := Z.pos_div_eucl p b in match r with | 0 => (- q, 0) | _ => (- (q + 1), b - r) end | Z.neg b' => let (q, r) := Z.pos_div_eucl p (Z.pos b') in (q, - r) end in r)
a, b:Z
p:positive

forall p0 : positive, Zmod_POS p (Z.pos p0) = (let (_, r) := Z.pos_div_eucl p (Z.pos p0) in r)
a, b:Z
p:positive
forall p0 : positive, match Zmod_POS p (Z.pos p0) with | 0 => 0 | _ => match Zmod_POS p (Z.pos p0) with | 0 => Z.neg p0 | Z.pos y' => Z.pos_sub y' p0 | Z.neg y' => Z.neg (p0 + y') end end = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p0) in match r with | 0 => (- q, 0) | _ => (- (q + 1), match r with | 0 => Z.neg p0 | Z.pos y' => Z.pos_sub y' p0 | Z.neg y' => Z.neg (p0 + y') end) end in r)
a, b:Z
forall p : positive, match b with | 0 => 0 | Z.pos _ => match Zmod_POS p b with | 0 => 0 | _ => b - Zmod_POS p b end | Z.neg b' => - Zmod_POS p (Z.pos b') end = (let (_, r) := match b with | 0 => (0, 0) | Z.pos _ => let (q, r) := Z.pos_div_eucl p b in match r with | 0 => (- q, 0) | _ => (- (q + 1), b - r) end | Z.neg b' => let (q, r) := Z.pos_div_eucl p (Z.pos b') in (q, - r) end in r)
a, b:Z
p:positive

forall p0 : positive, match Zmod_POS p (Z.pos p0) with | 0 => 0 | _ => match Zmod_POS p (Z.pos p0) with | 0 => Z.neg p0 | Z.pos y' => Z.pos_sub y' p0 | Z.neg y' => Z.neg (p0 + y') end end = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p0) in match r with | 0 => (- q, 0) | _ => (- (q + 1), match r with | 0 => Z.neg p0 | Z.pos y' => Z.pos_sub y' p0 | Z.neg y' => Z.neg (p0 + y') end) end in r)
a, b:Z
forall p : positive, match b with | 0 => 0 | Z.pos _ => match Zmod_POS p b with | 0 => 0 | _ => b - Zmod_POS p b end | Z.neg b' => - Zmod_POS p (Z.pos b') end = (let (_, r) := match b with | 0 => (0, 0) | Z.pos _ => let (q, r) := Z.pos_div_eucl p b in match r with | 0 => (- q, 0) | _ => (- (q + 1), b - r) end | Z.neg b' => let (q, r) := Z.pos_div_eucl p (Z.pos b') in (q, - r) end in r)
a, b:Z
p, p1:positive

match snd (Z.pos_div_eucl p (Z.pos p1)) with | 0 => 0 | _ => match snd (Z.pos_div_eucl p (Z.pos p1)) with | 0 => Z.neg p1 | Z.pos y' => Z.pos_sub y' p1 | Z.neg y' => Z.neg (p1 + y') end end = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p1) in match r with | 0 => (- q, 0) | _ => (- (q + 1), match r with | 0 => Z.neg p1 | Z.pos y' => Z.pos_sub y' p1 | Z.neg y' => Z.neg (p1 + y') end) end in r)
a, b:Z
forall p : positive, match b with | 0 => 0 | Z.pos _ => match Zmod_POS p b with | 0 => 0 | _ => b - Zmod_POS p b end | Z.neg b' => - Zmod_POS p (Z.pos b') end = (let (_, r) := match b with | 0 => (0, 0) | Z.pos _ => let (q, r) := Z.pos_div_eucl p b in match r with | 0 => (- q, 0) | _ => (- (q + 1), b - r) end | Z.neg b' => let (q, r) := Z.pos_div_eucl p (Z.pos b') in (q, - r) end in r)
a, b:Z

forall p : positive, match b with | 0 => 0 | Z.pos _ => match Zmod_POS p b with | 0 => 0 | _ => b - Zmod_POS p b end | Z.neg b' => - Zmod_POS p (Z.pos b') end = (let (_, r) := match b with | 0 => (0, 0) | Z.pos _ => let (q, r) := Z.pos_div_eucl p b in match r with | 0 => (- q, 0) | _ => (- (q + 1), b - r) end | Z.neg b' => let (q, r) := Z.pos_div_eucl p (Z.pos b') in (q, - r) end in r)
a, b:Z
p:positive

forall p0 : positive, match Zmod_POS p (Z.pos p0) with | 0 => 0 | _ => match - Zmod_POS p (Z.pos p0) with | 0 => Z.pos p0 | Z.pos y' => Z.pos (p0 + y') | Z.neg y' => Z.pos_sub p0 y' end end = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p0) in match r with | 0 => (- q, 0) | _ => (- (q + 1), match - r with | 0 => Z.pos p0 | Z.pos y' => Z.pos (p0 + y') | Z.neg y' => Z.pos_sub p0 y' end) end in r)
a, b:Z
p:positive
forall p0 : positive, - Zmod_POS p (Z.pos p0) = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p0) in (q, - r) in r)
a, b:Z
p, p1:positive

match snd (Z.pos_div_eucl p (Z.pos p1)) with | 0 => 0 | _ => match - snd (Z.pos_div_eucl p (Z.pos p1)) with | 0 => Z.pos p1 | Z.pos y' => Z.pos (p1 + y') | Z.neg y' => Z.pos_sub p1 y' end end = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p1) in match r with | 0 => (- q, 0) | _ => (- (q + 1), match - r with | 0 => Z.pos p1 | Z.pos y' => Z.pos (p1 + y') | Z.neg y' => Z.pos_sub p1 y' end) end in r)
a, b:Z
p:positive
forall p0 : positive, - Zmod_POS p (Z.pos p0) = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p0) in (q, - r) in r)
a, b:Z
p:positive

forall p0 : positive, - Zmod_POS p (Z.pos p0) = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p0) in (q, - r) in r)
a, b:Z
p, p1:positive

- snd (Z.pos_div_eucl p (Z.pos p1)) = (let (_, r) := let (q, r) := Z.pos_div_eucl p (Z.pos p1) in (q, - r) in r)
case (Z.pos_div_eucl p (Zpos p1)); auto. Qed.
Another convention is possible for division by negative numbers:

quotient is always the biggest integer smaller than or equal to a/b

remainder is hence always positive or null.


forall b : Z, b <> 0 -> forall a : Z, {qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}

forall b : Z, b <> 0 -> forall a : Z, {qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}
b:Z
Hb:b <> 0
a:Z

{qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}
b:Z
Hb:b <> 0
a:Z
Hb':0 <= b

{qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}
b:Z
Hb:b <> 0
a:Z
Hb':0 > b
{qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}
b:Z
Hb:b <> 0
a:Z
Hb':0 <= b

{qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}
b:Z
Hb:b <> 0
a:Z
Hb':0 <= b
Hb'':b > 0

{qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}
rewrite Z.abs_eq; [ apply Zdiv_eucl_exist; assumption | assumption ].
b:Z
Hb:b <> 0
a:Z
Hb':0 > b

{qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}
b:Z
Hb:b <> 0
a:Z
Hb':0 > b
Hb'':- b > 0

{qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < Z.abs b}
b:Z
Hb:b <> 0
a:Z
Hb':0 > b
Hb'':- b > 0
q, r:Z
H:a = - b * q + r
H0:0 <= r < - b

{qr : Z * Z | let (q0, r0) := qr in a = b * q0 + r0 /\ 0 <= r0 < Z.abs b}
b:Z
Hb:b <> 0
a:Z
Hb':0 > b
Hb'':- b > 0
q, r:Z
H:a = - b * q + r
H0:0 <= r < - b

a = b * - q + r /\ 0 <= r < Z.abs b
b:Z
Hb:b <> 0
a:Z
Hb':0 > b
Hb'':- b > 0
q, r:Z
H:a = - b * q + r
H0:0 <= r < - b

a = b * - q + r
b:Z
Hb:b <> 0
a:Z
Hb':0 > b
Hb'':- b > 0
q, r:Z
H:a = - b * q + r
H0:0 <= r < - b
0 <= r < Z.abs b
b:Z
Hb:b <> 0
a:Z
Hb':0 > b
Hb'':- b > 0
q, r:Z
H:a = - b * q + r
H0:0 <= r < - b

a = b * - q + r
rewrite <- Z.mul_opp_comm; assumption.
b:Z
Hb:b <> 0
a:Z
Hb':0 > b
Hb'':- b > 0
q, r:Z
H:a = - b * q + r
H0:0 <= r < - b

0 <= r < Z.abs b
rewrite Z.abs_neq; [ assumption | omega ]. Qed. Arguments Zdiv_eucl_extended : default implicits.

Division and modulo in Z agree with same in nat:

Require Import PeanoNat.

n, m:nat

m <> 0%nat -> Z.of_nat (n / m) = Z.of_nat n / Z.of_nat m
n, m:nat

m <> 0%nat -> Z.of_nat (n / m) = Z.of_nat n / Z.of_nat m
n, m:nat
H:m <> 0%nat

Z.of_nat (n / m) = Z.of_nat n / Z.of_nat m
n, m:nat
H:m <> 0%nat

0 <= Z.of_nat (n mod m) < Z.of_nat m
n, m:nat
H:m <> 0%nat
Z.of_nat n = Z.of_nat m * Z.of_nat (n / m) + Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat

0 <= Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat
Z.of_nat (n mod m) < Z.of_nat m
n, m:nat
H:m <> 0%nat
Z.of_nat n = Z.of_nat m * Z.of_nat (n / m) + Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat

Z.of_nat (n mod m) < Z.of_nat m
n, m:nat
H:m <> 0%nat
Z.of_nat n = Z.of_nat m * Z.of_nat (n / m) + Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat

Z.of_nat n = Z.of_nat m * Z.of_nat (n / m) + Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat

Z.of_nat n = Z.of_nat (m * (n / m) + n mod m)
now apply inj_eq, Nat.div_mod. Qed.
n, m:nat

m <> 0%nat -> Z.of_nat (n mod m) = Z.of_nat n mod Z.of_nat m
n, m:nat

m <> 0%nat -> Z.of_nat (n mod m) = Z.of_nat n mod Z.of_nat m
n, m:nat
H:m <> 0%nat

Z.of_nat (n mod m) = Z.of_nat n mod Z.of_nat m
n, m:nat
H:m <> 0%nat

0 <= Z.of_nat (n mod m) < Z.of_nat m
n, m:nat
H:m <> 0%nat
Z.of_nat n = Z.of_nat m * (Z.of_nat n / Z.of_nat m) + Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat

0 <= Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat
Z.of_nat (n mod m) < Z.of_nat m
n, m:nat
H:m <> 0%nat
Z.of_nat n = Z.of_nat m * (Z.of_nat n / Z.of_nat m) + Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat

Z.of_nat (n mod m) < Z.of_nat m
n, m:nat
H:m <> 0%nat
Z.of_nat n = Z.of_nat m * (Z.of_nat n / Z.of_nat m) + Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat

Z.of_nat n = Z.of_nat m * (Z.of_nat n / Z.of_nat m) + Z.of_nat (n mod m)
n, m:nat
H:m <> 0%nat

Z.of_nat n = Z.of_nat (m * (n / m) + n mod m)
now apply inj_eq, Nat.div_mod. Qed.