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)         *)
(************************************************************************)
Greatest Common Divisor
Require Import NZAxioms NZMulOrder.
Interface of a gcd function, then its specification on naturals
Module Type Gcd (Import A : Typ).
 Parameter Inline gcd : t -> t -> t.
End Gcd.

Module Type NZGcdSpec (A : NZOrdAxiomsSig')(B : Gcd A).
 Import A B.
 Definition divide n m := exists p, m == p*n.
 Local Notation "( n | m )" := (divide n m) (at level 0).
 Axiom gcd_divide_l : forall n m, (gcd n m | n).
 Axiom gcd_divide_r : forall n m, (gcd n m | m).
 Axiom gcd_greatest : forall n m p, (p | n) -> (p | m) -> (p | gcd n m).
 Axiom gcd_nonneg : forall n m, 0 <= gcd n m.
End NZGcdSpec.

Module Type DivideNotation (A:NZOrdAxiomsSig')(B:Gcd A)(C:NZGcdSpec A B).
 Import A B C.
 Notation "( n | m )" := (divide n m) (at level 0).
End DivideNotation.

Module Type NZGcd (A : NZOrdAxiomsSig) := Gcd A <+ NZGcdSpec A.
Module Type NZGcd' (A : NZOrdAxiomsSig) :=
 Gcd A <+ NZGcdSpec A <+ DivideNotation A.
Derived properties of gcd
Module NZGcdProp
 (Import A : NZOrdAxiomsSig')
 (Import B : NZGcd' A)
 (Import C : NZMulOrderProp A).
Results concerning divisibility

Proper (eq ==> eq ==> iff) divide

Proper (eq ==> eq ==> iff) divide

Proper (eq ==> eq ==> iff) (fun n m : t => exists p : t, m == p * n)
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

(exists p : t, y == p * x) <-> (exists p : t, y' == p * x')
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

(exists p : t, y == p * x') <-> (exists p : t, y' == p * x')
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

(exists p : t, y' == p * x') <-> (exists p : t, y' == p * x')
easy. Qed.

forall n : t, (1 | n)

forall n : t, (1 | n)
n:t

(1 | n)
n:t

n == n * 1
now nzsimpl. Qed.

forall n : t, (n | 0)

forall n : t, (n | 0)
n:t

(n | 0)
n:t

0 == 0 * n
now nzsimpl. Qed.

forall n : t, (0 | n) -> n == 0

forall n : t, (0 | n) -> n == 0
n, m:t
Hm:n == m * 0

n == 0
n, m:t

n == m * 0 -> n == 0
now nzsimpl. Qed.

forall n m : t, 0 <= n -> n * m == 1 -> n == 1 /\ m == 1

forall n m : t, 0 <= n -> n * m == 1 -> n == 1 /\ m == 1
n, m:t
Hn:0 <= n
H:n * m == 1

n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1

n == 1 /\ m == 1
n, m:t
Hn:0 == n
H:n * m == 1
n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1

n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1
Hm:m < 0

n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1
Hm:0 <= m
n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1
Hm:m < 0

n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1
Hm:m < 0

n * m < 0 -> n == 1 /\ m == 1
order'.
n, m:t
Hn:0 < n
H:n * m == 1
Hm:0 <= m

n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1
Hm:0 < m

n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1
Hm:0 == m
n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:n * m == 1
Hm:0 < m

n == 1 /\ m == 1
n, m:t
Hn:S 0 <= n
H:n * m == 1
Hm:0 < m

n == 1 /\ m == 1
n, m:t
Hn:1 <= n
H:n * m == 1
Hm:0 < m

n == 1 /\ m == 1
n, m:t
Hn:1 < n
H:n * m == 1
Hm:0 < m

n == 1 /\ m == 1
n, m:t
Hn:1 == n
H:n * m == 1
Hm:0 < m
n == 1 /\ m == 1
n, m:t
Hn:1 < n
H:n * m == 1
Hm:0 < m

n == 1 /\ m == 1
n, m:t
Hn:1 < n
H:n * m == 1
Hm:0 < m

1 < n * m -> n == 1 /\ m == 1
order.
n, m:t
Hn:1 == n
H:n * m == 1
Hm:0 < m

n == 1 /\ m == 1
n, m:t
Hn:1 == n
H:m == 1
Hm:0 < m

n == 1 /\ m == 1
now split.
n, m:t
Hn:0 < n
H:n * m == 1
Hm:0 == m

n == 1 /\ m == 1
n, m:t
Hn:0 < n
H:0 == 1
Hm:0 == m

n == 1 /\ m == 1
order'.
n, m:t
Hn:0 == n
H:n * m == 1

n == 1 /\ m == 1
n, m:t
Hn:0 == n
H:0 == 1

n == 1 /\ m == 1
order'. Qed.

forall n m : t, 0 <= m -> n * m == 1 -> n == 1 /\ m == 1

forall n m : t, 0 <= m -> n * m == 1 -> n == 1 /\ m == 1
n, m:t
Hm:0 <= m
H:n * m == 1

n == 1 /\ m == 1
n, m:t
Hm:0 <= m
H:m * n == 1

n == 1 /\ m == 1
now apply and_comm, eq_mul_1_nonneg. Qed.

forall n : t, 0 <= n -> (n | 1) -> n == 1

forall n : t, 0 <= n -> (n | 1) -> n == 1
n:t
Hn:0 <= n
m:t
Hm:1 == m * n

n == 1
n:t
Hn:0 <= n
m:t
Hm:m * n == 1

n == 1
now apply (eq_mul_1_nonneg' m n). Qed.

forall n : t, (n | n)

forall n : t, (n | n)
n:t

(n | n)
n:t

n == 1 * n
now nzsimpl. Qed.

forall n m p : t, (n | m) -> (m | p) -> (n | p)

forall n m p : t, (n | m) -> (m | p) -> (n | p)
n, m, p, q:t
Hq:m == q * n
r:t
Hr:p == r * m

(n | p)
n, m, p, q:t
Hq:m == q * n
r:t
Hr:p == r * m

p == r * q * n
now rewrite Hr, Hq, mul_assoc. Qed. Instance divide_reflexive : Reflexive divide | 5 := divide_refl. Instance divide_transitive : Transitive divide | 5 := divide_trans.
Due to sign, no general antisymmetry result

forall n m : t, 0 <= n -> 0 <= m -> (n | m) -> (m | n) -> n == m

forall n m : t, 0 <= n -> 0 <= m -> (n | m) -> (m | n) -> n == m
n, m:t
Hn:0 <= n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m

n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m

n == m
n, m:t
Hn:0 == n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m
n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m

n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m
Hq':q < 0

n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m
Hq':0 <= q
n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m
Hq':q < 0

n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m
Hq':q < 0

q * n < 0 -> n == m
order.
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m
Hq':0 <= q

n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * q * n
Hq':0 <= q

n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:r * q * n == n
Hq':0 <= q

n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:r * q == 1
Hq':0 <= q

n == m
n, m:t
Hn:0 < n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:r * q == 1
Hq':0 <= q
H:q == 1

n == m
now rewrite H, mul_1_l in Hq.
n, m:t
Hn:0 == n
Hm:0 <= m
q:t
Hq:m == q * n
r:t
Hr:n == r * m

n == m
n, m:t
Hn:0 == n
Hm:0 <= m
q:t
Hq:m == 0
r:t
Hr:n == r * m

n == m
now rewrite <- Hn. Qed.

forall n m p : t, (n | m) -> (p * n | p * m)

forall n m p : t, (n | m) -> (p * n | p * m)
n, m, p, q:t
Hq:m == q * n

(p * n | p * m)
n, m, p, q:t
Hq:m == q * n

p * m == q * (p * n)
now rewrite mul_shuffle3, Hq. Qed.

forall n m p : t, (n | m) -> (n * p | m * p)

forall n m p : t, (n | m) -> (n * p | m * p)
n, m, p, q:t
Hq:m == q * n

(n * p | m * p)
n, m, p, q:t
Hq:m == q * n

m * p == q * (n * p)
now rewrite mul_assoc, Hq. Qed.

forall n m p : t, p ~= 0 -> (p * n | p * m) <-> (n | m)

forall n m p : t, p ~= 0 -> (p * n | p * m) <-> (n | m)
n, m, p:t
Hp:p ~= 0

(p * n | p * m) <-> (n | m)
n, m, p:t
Hp:p ~= 0

(p * n | p * m) -> (n | m)
n, m, p:t
Hp:p ~= 0
(n | m) -> (p * n | p * m)
n, m, p:t
Hp:p ~= 0

(p * n | p * m) -> (n | m)
n, m, p:t
Hp:p ~= 0
q:t
Hq:p * m == q * (p * n)

(n | m)
n, m, p:t
Hp:p ~= 0
q:t
Hq:p * m == q * (p * n)

m == q * n
now rewrite mul_shuffle3, mul_cancel_l in Hq.
n, m, p:t
Hp:p ~= 0

(n | m) -> (p * n | p * m)
apply mul_divide_mono_l. Qed.

forall n m p : t, p ~= 0 -> (n * p | m * p) <-> (n | m)

forall n m p : t, p ~= 0 -> (n * p | m * p) <-> (n | m)
n, m, p:t
H:p ~= 0

(n * p | m * p) <-> (n | m)
n, m, p:t
H:p ~= 0

(p * n | p * m) <-> (n | m)
now apply mul_divide_cancel_l. Qed.

forall n m p : t, (n | m) -> (n | p) -> (n | m + p)

forall n m p : t, (n | m) -> (n | p) -> (n | m + p)
n, m, p, q:t
Hq:m == q * n
r:t
Hr:p == r * n

(n | m + p)
n, m, p, q:t
Hq:m == q * n
r:t
Hr:p == r * n

m + p == (q + r) * n
now rewrite mul_add_distr_r, Hq, Hr. Qed.

forall n m p : t, (n | m) -> (n | m * p)

forall n m p : t, (n | m) -> (n | m * p)
n, m, p, q:t
Hq:m == q * n

(n | m * p)
n, m, p, q:t
Hq:m == q * n

m * p == q * p * n
now rewrite mul_shuffle0, Hq. Qed.

forall n m p : t, (n | p) -> (n | m * p)

forall n m p : t, (n | p) -> (n | m * p)
n, m, p:t

(n | p) -> (n | m * p)
n, m, p:t

(n | p) -> (n | p * m)
apply divide_mul_l. Qed.

forall n m : t, (n | n * m)

forall n m : t, (n | n * m)
n, m:t

(n | n * m)
apply divide_mul_l, divide_refl. Qed.

forall n m : t, (n | m * n)

forall n m : t, (n | m * n)
n, m:t

(n | m * n)
apply divide_mul_r, divide_refl. Qed.

forall n m : t, 0 < m -> (n | m) -> n <= m

forall n m : t, 0 < m -> (n | m) -> n <= m
n, m:t
Hm:0 < m
q:t
Hq:m == q * n

n <= m
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:n <= 0

n <= m
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
n <= m
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:n <= 0

n <= m
order.
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n

n <= m
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n

n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':q < 0

n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':0 <= q
n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':q < 0

n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':q < 0

q * n < 0 -> n <= q * n
order.
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':0 <= q

n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':0 < q

n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':0 == q
n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':0 < q

n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':0 < q

1 * n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':0 < q

1 <= q
now rewrite one_succ, le_succ_l.
n, m:t
Hm:0 < m
q:t
Hq:m == q * n
Hn:0 < n
Hq':0 == q

n <= q * n
n, m:t
Hm:0 < m
q:t
Hq:m == 0
Hn:0 < n
Hq':0 == q

n <= q * n
order. Qed.
Basic properties of gcd

forall n m p : t, 0 <= p -> (p | n) -> (p | m) -> (forall q : t, (q | n) -> (q | m) -> (q | p)) -> gcd n m == p

forall n m p : t, 0 <= p -> (p | n) -> (p | m) -> (forall q : t, (q | n) -> (q | m) -> (q | p)) -> gcd n m == p
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)

gcd n m == p
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)

0 <= gcd n m
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)
(gcd n m | p)
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)
(p | gcd n m)
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)

0 <= gcd n m
apply gcd_nonneg.
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)

(gcd n m | p)
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)

(gcd n m | n)
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)
(gcd n m | m)
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)

(gcd n m | n)
apply gcd_divide_l.
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)

(gcd n m | m)
apply gcd_divide_r.
n, m, p:t
Hp:0 <= p
Hn:(p | n)
Hm:(p | m)
H:forall q : t, (q | n) -> (q | m) -> (q | p)

(p | gcd n m)
now apply gcd_greatest. Qed.

Proper (eq ==> eq ==> eq) gcd

Proper (eq ==> eq ==> eq) gcd
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

gcd x y == gcd x' y'
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

0 <= gcd x' y'
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'
(gcd x' y' | x)
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'
(gcd x' y' | y)
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'
forall q : t, (q | x) -> (q | y) -> (q | gcd x' y')
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

0 <= gcd x' y'
apply gcd_nonneg.
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

(gcd x' y' | x)
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

(gcd x' y' | x')
apply gcd_divide_l.
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

(gcd x' y' | y)
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

(gcd x' y' | y')
apply gcd_divide_r.
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'

forall q : t, (q | x) -> (q | y) -> (q | gcd x' y')
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'
q:t

(q | x) -> (q | y) -> (q | gcd x' y')
x, x':t
Hx:x == x'
y, y':t
Hy:y == y'
q:t

(q | x') -> (q | y') -> (q | gcd x' y')
apply gcd_greatest. Qed.

forall n m p : t, (p | gcd n m) <-> (p | n) /\ (p | m)

forall n m p : t, (p | gcd n m) <-> (p | n) /\ (p | m)
n, m, p:t

(p | gcd n m) <-> (p | n) /\ (p | m)
n, m, p:t

(p | gcd n m) -> (p | n) /\ (p | m)
n, m, p:t
(p | n) /\ (p | m) -> (p | gcd n m)
n, m, p:t

(p | gcd n m) -> (p | n) /\ (p | m)
n, m, p:t
H:(p | gcd n m)

(p | n)
n, m, p:t
H:(p | gcd n m)
(p | m)
n, m, p:t
H:(p | gcd n m)

(p | n)
transitivity (gcd n m); trivial using gcd_divide_l.
n, m, p:t
H:(p | gcd n m)

(p | m)
transitivity (gcd n m); trivial using gcd_divide_r.
n, m, p:t

(p | n) /\ (p | m) -> (p | gcd n m)
n, m, p:t
H:(p | n)
H':(p | m)

(p | gcd n m)
now apply gcd_greatest. Qed.

forall n m p : t, 0 <= p -> (forall q : t, (q | p) <-> (q | n) /\ (q | m)) -> gcd n m == p

forall n m p : t, 0 <= p -> (forall q : t, (q | p) <-> (q | n) /\ (q | m)) -> gcd n m == p
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)

gcd n m == p
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)

(p | n)
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)
(p | m)
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)
forall q : t, (q | n) -> (q | m) -> (q | p)
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)

(p | n)
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)

(p | p)
apply divide_refl.
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)

(p | m)
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)

(p | p)
apply divide_refl.
n, m, p:t
Hp:0 <= p
H:forall q : t, (q | p) <-> (q | n) /\ (q | m)

forall q : t, (q | n) -> (q | m) -> (q | p)
n, m, p:t
Hp:0 <= p
H:forall q0 : t, (q0 | p) <-> (q0 | n) /\ (q0 | m)
q:t
H0:(q | n)
H1:(q | m)

(q | p)
n, m, p:t
Hp:0 <= p
H:forall q0 : t, (q0 | p) <-> (q0 | n) /\ (q0 | m)
q:t
H0:(q | n)
H1:(q | m)

(q | n) /\ (q | m)
now split. Qed.

forall n m : t, gcd n m == gcd m n

forall n m : t, gcd n m == gcd m n
n, m:t

gcd n m == gcd m n
n, m:t

forall q : t, (q | gcd m n) <-> (q | n) /\ (q | m)
n, m, q:t

(q | gcd m n) <-> (q | n) /\ (q | m)
n, m, q:t

(q | gcd m n) <-> (q | m) /\ (q | n)
apply gcd_divide_iff. Qed.

forall n m p : t, gcd n (gcd m p) == gcd (gcd n m) p

forall n m p : t, gcd n (gcd m p) == gcd (gcd n m) p
n, m, p:t

gcd n (gcd m p) == gcd (gcd n m) p
n, m, p:t

forall q : t, (q | gcd (gcd n m) p) <-> (q | n) /\ (q | gcd m p)
n, m, p, q:t

(q | gcd (gcd n m) p) <-> (q | n) /\ (q | gcd m p)
now rewrite !gcd_divide_iff, and_assoc. Qed.

forall n : t, 0 <= n -> gcd 0 n == n

forall n : t, 0 <= n -> gcd 0 n == n
n:t
H:0 <= n

gcd 0 n == n
n:t
H:0 <= n

(n | 0)
n:t
H:0 <= n
(n | n)
n:t
H:0 <= n

(n | 0)
apply divide_0_r.
n:t
H:0 <= n

(n | n)
apply divide_refl. Qed.

forall n : t, 0 <= n -> gcd n 0 == n

forall n : t, 0 <= n -> gcd n 0 == n
n:t
H:0 <= n

gcd n 0 == n
now rewrite gcd_comm, gcd_0_l_nonneg. Qed.

forall n : t, gcd 1 n == 1

forall n : t, gcd 1 n == 1
n:t

gcd 1 n == 1
apply gcd_unique; trivial using divide_1_l, le_0_1. Qed.

forall n : t, gcd n 1 == 1

forall n : t, gcd n 1 == 1
n:t

gcd n 1 == 1
now rewrite gcd_comm, gcd_1_l. Qed.

forall n : t, 0 <= n -> gcd n n == n

forall n : t, 0 <= n -> gcd n n == n
n:t
H:0 <= n

gcd n n == n
apply gcd_unique; trivial using divide_refl. Qed.

forall n m : t, gcd n m == 0 -> n == 0

forall n m : t, gcd n m == 0 -> n == 0
n, m:t
H:gcd n m == 0

n == 0
n, m:t
H:gcd n m == 0

(gcd n m | n) -> n == 0
n, m:t
H:gcd n m == 0

(0 | n) -> n == 0
apply divide_0_l. Qed.

forall n m : t, gcd n m == 0 -> m == 0

forall n m : t, gcd n m == 0 -> m == 0
n, m:t
H:gcd n m == 0

m == 0
n, m:t
H:gcd n m == 0

gcd m n == 0
now rewrite gcd_comm. Qed.

forall n m : t, gcd n m == 0 <-> n == 0 /\ m == 0

forall n m : t, gcd n m == 0 <-> n == 0 /\ m == 0
n, m:t

gcd n m == 0 <-> n == 0 /\ m == 0
n, m:t

gcd n m == 0 -> n == 0 /\ m == 0
n, m:t
n == 0 /\ m == 0 -> gcd n m == 0
n, m:t

gcd n m == 0 -> n == 0 /\ m == 0
n, m:t
H:gcd n m == 0

n == 0
n, m:t
H:gcd n m == 0
m == 0
n, m:t
H:gcd n m == 0

n == 0
now apply gcd_eq_0_l with m.
n, m:t
H:gcd n m == 0

m == 0
now apply gcd_eq_0_r with n.
n, m:t

n == 0 /\ m == 0 -> gcd n m == 0
n, m:t
EQ:n == 0
EQ':m == 0

gcd n m == 0
n, m:t
EQ:n == 0
EQ':m == 0

gcd 0 0 == 0
now apply gcd_0_r_nonneg. Qed.

forall n m : t, 0 <= n -> gcd n (n * m) == n

forall n m : t, 0 <= n -> gcd n (n * m) == n
n, m:t
Hn:0 <= n

gcd n (n * m) == n
n, m:t
Hn:0 <= n

forall q : t, (q | n) <-> (q | n) /\ (q | n * m)
n, m:t
Hn:0 <= n
q:t

(q | n) <-> (q | n) /\ (q | n * m)
n, m:t
Hn:0 <= n
q:t

(q | n) -> (q | n) /\ (q | n * m)
n, m:t
Hn:0 <= n
q:t
(q | n) /\ (q | n * m) -> (q | n)
n, m:t
Hn:0 <= n
q:t

(q | n) -> (q | n) /\ (q | n * m)
n, m:t
Hn:0 <= n
q:t
H:(q | n)

(q | n * m)
now apply divide_mul_l.
n, m:t
Hn:0 <= n
q:t

(q | n) /\ (q | n * m) -> (q | n)
now destruct 1. Qed.

forall n m : t, 0 <= n -> (n | m) <-> gcd n m == n

forall n m : t, 0 <= n -> (n | m) <-> gcd n m == n
n, m:t
Hn:0 <= n

(n | m) <-> gcd n m == n
n, m:t
Hn:0 <= n

(n | m) -> gcd n m == n
n, m:t
Hn:0 <= n
gcd n m == n -> (n | m)
n, m:t
Hn:0 <= n

(n | m) -> gcd n m == n
n, m:t
Hn:0 <= n
q:t
Hq:m == q * n

gcd n m == n
n, m:t
Hn:0 <= n
q:t
Hq:m == q * n

gcd n (q * n) == n
n, m:t
Hn:0 <= n
q:t
Hq:m == q * n

gcd n (n * q) == n
now apply gcd_mul_diag_l.
n, m:t
Hn:0 <= n

gcd n m == n -> (n | m)
n, m:t
Hn:0 <= n
EQ:gcd n m == n

(n | m)
n, m:t
Hn:0 <= n
EQ:gcd n m == n

(gcd n m | m)
apply gcd_divide_r. Qed. End NZGcdProp.