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) divideProper (eq ==> eq ==> iff) divideProper (eq ==> eq ==> iff) (fun n m : t => exists p : t, m == p * n)x, x':tHx:x == x'y, y':tHy:y == y'(exists p : t, y == p * x) <-> (exists p : t, y' == p * x')x, x':tHx:x == x'y, y':tHy:y == y'(exists p : t, y == p * x') <-> (exists p : t, y' == p * x')easy. Qed.x, x':tHx:x == x'y, y':tHy:y == y'(exists p : t, y' == p * x') <-> (exists p : t, y' == p * x')forall n : t, (1 | n)forall n : t, (1 | n)n:t(1 | n)now nzsimpl. Qed.n:tn == n * 1forall n : t, (n | 0)forall n : t, (n | 0)n:t(n | 0)now nzsimpl. Qed.n:t0 == 0 * nforall n : t, (0 | n) -> n == 0forall n : t, (0 | n) -> n == 0n, m:tHm:n == m * 0n == 0now nzsimpl. Qed.n, m:tn == m * 0 -> n == 0forall n m : t, 0 <= n -> n * m == 1 -> n == 1 /\ m == 1forall n m : t, 0 <= n -> n * m == 1 -> n == 1 /\ m == 1n, m:tHn:0 <= nH:n * m == 1n == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1n == 1 /\ m == 1n, m:tHn:0 == nH:n * m == 1n == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1n == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1Hm:m < 0n == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1Hm:0 <= mn == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1Hm:m < 0n == 1 /\ m == 1order'.n, m:tHn:0 < nH:n * m == 1Hm:m < 0n * m < 0 -> n == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1Hm:0 <= mn == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1Hm:0 < mn == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1Hm:0 == mn == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1Hm:0 < mn == 1 /\ m == 1n, m:tHn:S 0 <= nH:n * m == 1Hm:0 < mn == 1 /\ m == 1n, m:tHn:1 <= nH:n * m == 1Hm:0 < mn == 1 /\ m == 1n, m:tHn:1 < nH:n * m == 1Hm:0 < mn == 1 /\ m == 1n, m:tHn:1 == nH:n * m == 1Hm:0 < mn == 1 /\ m == 1n, m:tHn:1 < nH:n * m == 1Hm:0 < mn == 1 /\ m == 1order.n, m:tHn:1 < nH:n * m == 1Hm:0 < m1 < n * m -> n == 1 /\ m == 1n, m:tHn:1 == nH:n * m == 1Hm:0 < mn == 1 /\ m == 1now split.n, m:tHn:1 == nH:m == 1Hm:0 < mn == 1 /\ m == 1n, m:tHn:0 < nH:n * m == 1Hm:0 == mn == 1 /\ m == 1order'.n, m:tHn:0 < nH:0 == 1Hm:0 == mn == 1 /\ m == 1n, m:tHn:0 == nH:n * m == 1n == 1 /\ m == 1order'. Qed.n, m:tHn:0 == nH:0 == 1n == 1 /\ m == 1forall n m : t, 0 <= m -> n * m == 1 -> n == 1 /\ m == 1forall n m : t, 0 <= m -> n * m == 1 -> n == 1 /\ m == 1n, m:tHm:0 <= mH:n * m == 1n == 1 /\ m == 1now apply and_comm, eq_mul_1_nonneg. Qed.n, m:tHm:0 <= mH:m * n == 1n == 1 /\ m == 1forall n : t, 0 <= n -> (n | 1) -> n == 1forall n : t, 0 <= n -> (n | 1) -> n == 1n:tHn:0 <= nm:tHm:1 == m * nn == 1now apply (eq_mul_1_nonneg' m n). Qed.n:tHn:0 <= nm:tHm:m * n == 1n == 1forall n : t, (n | n)forall n : t, (n | n)n:t(n | n)now nzsimpl. Qed.n:tn == 1 * nforall 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:tHq:m == q * nr:tHr:p == r * m(n | p)now rewrite Hr, Hq, mul_assoc. Qed. Instance divide_reflexive : Reflexive divide | 5 := divide_refl. Instance divide_transitive : Transitive divide | 5 := divide_trans.n, m, p, q:tHq:m == q * nr:tHr:p == r * mp == r * q * n
Due to sign, no general antisymmetry result
forall n m : t, 0 <= n -> 0 <= m -> (n | m) -> (m | n) -> n == mforall n m : t, 0 <= n -> 0 <= m -> (n | m) -> (m | n) -> n == mn, m:tHn:0 <= nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mn == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mn == mn, m:tHn:0 == nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mn == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mn == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mHq':q < 0n == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mHq':0 <= qn == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mHq':q < 0n == morder.n, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mHq':q < 0q * n < 0 -> n == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mHq':0 <= qn == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * q * nHq':0 <= qn == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:r * q * n == nHq':0 <= qn == mn, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:r * q == 1Hq':0 <= qn == mnow rewrite H, mul_1_l in Hq.n, m:tHn:0 < nHm:0 <= mq:tHq:m == q * nr:tHr:r * q == 1Hq':0 <= qH:q == 1n == mn, m:tHn:0 == nHm:0 <= mq:tHq:m == q * nr:tHr:n == r * mn == mnow rewrite <- Hn. Qed.n, m:tHn:0 == nHm:0 <= mq:tHq:m == 0r:tHr:n == r * mn == mforall 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:tHq:m == q * n(p * n | p * m)now rewrite mul_shuffle3, Hq. Qed.n, m, p, q:tHq:m == q * np * m == q * (p * n)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:tHq:m == q * n(n * p | m * p)now rewrite mul_assoc, Hq. Qed.n, m, p, q:tHq:m == q * nm * p == q * (n * p)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:tHp:p ~= 0(p * n | p * m) <-> (n | m)n, m, p:tHp:p ~= 0(p * n | p * m) -> (n | m)n, m, p:tHp:p ~= 0(n | m) -> (p * n | p * m)n, m, p:tHp:p ~= 0(p * n | p * m) -> (n | m)n, m, p:tHp:p ~= 0q:tHq:p * m == q * (p * n)(n | m)now rewrite mul_shuffle3, mul_cancel_l in Hq.n, m, p:tHp:p ~= 0q:tHq:p * m == q * (p * n)m == q * napply mul_divide_mono_l. Qed.n, m, p:tHp:p ~= 0(n | m) -> (p * n | p * m)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:tH:p ~= 0(n * p | m * p) <-> (n | m)now apply mul_divide_cancel_l. Qed.n, m, p:tH:p ~= 0(p * n | p * m) <-> (n | m)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:tHq:m == q * nr:tHr:p == r * n(n | m + p)now rewrite mul_add_distr_r, Hq, Hr. Qed.n, m, p, q:tHq:m == q * nr:tHr:p == r * nm + p == (q + r) * nforall n m p : t, (n | m) -> (n | m * p)forall n m p : t, (n | m) -> (n | m * p)n, m, p, q:tHq:m == q * n(n | m * p)now rewrite mul_shuffle0, Hq. Qed.n, m, p, q:tHq:m == q * nm * p == q * p * nforall 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)apply divide_mul_l. Qed.n, m, p:t(n | p) -> (n | p * m)forall n m : t, (n | n * m)forall n m : t, (n | n * m)apply divide_mul_l, divide_refl. Qed.n, m:t(n | n * m)forall n m : t, (n | m * n)forall n m : t, (n | m * n)apply divide_mul_r, divide_refl. Qed.n, m:t(n | m * n)forall n m : t, 0 < m -> (n | m) -> n <= mforall n m : t, 0 < m -> (n | m) -> n <= mn, m:tHm:0 < mq:tHq:m == q * nn <= mn, m:tHm:0 < mq:tHq:m == q * nHn:n <= 0n <= mn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nn <= morder.n, m:tHm:0 < mq:tHq:m == q * nHn:n <= 0n <= mn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nn <= mn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nn <= q * nn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':q < 0n <= q * nn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':0 <= qn <= q * nn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':q < 0n <= q * norder.n, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':q < 0q * n < 0 -> n <= q * nn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':0 <= qn <= q * nn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':0 < qn <= q * nn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':0 == qn <= q * nn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':0 < qn <= q * nn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':0 < q1 * n <= q * nnow rewrite one_succ, le_succ_l.n, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':0 < q1 <= qn, m:tHm:0 < mq:tHq:m == q * nHn:0 < nHq':0 == qn <= q * norder. Qed.n, m:tHm:0 < mq:tHq:m == 0Hn:0 < nHq':0 == qn <= q * n
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 == pforall n m p : t, 0 <= p -> (p | n) -> (p | m) -> (forall q : t, (q | n) -> (q | m) -> (q | p)) -> gcd n m == pn, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)gcd n m == pn, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)0 <= gcd n mn, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)(gcd n m | p)n, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)(p | gcd n m)apply gcd_nonneg.n, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)0 <= gcd n mn, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)(gcd n m | p)n, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)(gcd n m | n)n, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)(gcd n m | m)apply gcd_divide_l.n, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)(gcd n m | n)apply gcd_divide_r.n, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)(gcd n m | m)now apply gcd_greatest. Qed.n, m, p:tHp:0 <= pHn:(p | n)Hm:(p | m)H:forall q : t, (q | n) -> (q | m) -> (q | p)(p | gcd n m)Proper (eq ==> eq ==> eq) gcdProper (eq ==> eq ==> eq) gcdx, x':tHx:x == x'y, y':tHy:y == y'gcd x y == gcd x' y'x, x':tHx:x == x'y, y':tHy:y == y'0 <= gcd x' y'x, x':tHx:x == x'y, y':tHy:y == y'(gcd x' y' | x)x, x':tHx:x == x'y, y':tHy:y == y'(gcd x' y' | y)x, x':tHx:x == x'y, y':tHy:y == y'forall q : t, (q | x) -> (q | y) -> (q | gcd x' y')apply gcd_nonneg.x, x':tHx:x == x'y, y':tHy:y == y'0 <= gcd x' y'x, x':tHx:x == x'y, y':tHy:y == y'(gcd x' y' | x)apply gcd_divide_l.x, x':tHx:x == x'y, y':tHy:y == y'(gcd x' y' | x')x, x':tHx:x == x'y, y':tHy:y == y'(gcd x' y' | y)apply gcd_divide_r.x, x':tHx:x == x'y, y':tHy:y == y'(gcd x' y' | y')x, x':tHx:x == x'y, y':tHy:y == y'forall q : t, (q | x) -> (q | y) -> (q | gcd x' y')x, x':tHx:x == x'y, y':tHy:y == y'q:t(q | x) -> (q | y) -> (q | gcd x' y')apply gcd_greatest. Qed.x, x':tHx:x == x'y, y':tHy:y == y'q:t(q | x') -> (q | y') -> (q | gcd x' y')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:tH:(p | gcd n m)(p | n)n, m, p:tH:(p | gcd n m)(p | m)transitivity (gcd n m); trivial using gcd_divide_l.n, m, p:tH:(p | gcd n m)(p | n)transitivity (gcd n m); trivial using gcd_divide_r.n, m, p:tH:(p | gcd n m)(p | m)n, m, p:t(p | n) /\ (p | m) -> (p | gcd n m)now apply gcd_greatest. Qed.n, m, p:tH:(p | n)H':(p | m)(p | gcd n m)forall n m p : t, 0 <= p -> (forall q : t, (q | p) <-> (q | n) /\ (q | m)) -> gcd n m == pforall n m p : t, 0 <= p -> (forall q : t, (q | p) <-> (q | n) /\ (q | m)) -> gcd n m == pn, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)gcd n m == pn, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)(p | n)n, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)(p | m)n, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)forall q : t, (q | n) -> (q | m) -> (q | p)n, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)(p | n)apply divide_refl.n, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)(p | p)n, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)(p | m)apply divide_refl.n, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)(p | p)n, m, p:tHp:0 <= pH:forall q : t, (q | p) <-> (q | n) /\ (q | m)forall q : t, (q | n) -> (q | m) -> (q | p)n, m, p:tHp:0 <= pH:forall q0 : t, (q0 | p) <-> (q0 | n) /\ (q0 | m)q:tH0:(q | n)H1:(q | m)(q | p)now split. Qed.n, m, p:tHp:0 <= pH:forall q0 : t, (q0 | p) <-> (q0 | n) /\ (q0 | m)q:tH0:(q | n)H1:(q | m)(q | n) /\ (q | m)forall n m : t, gcd n m == gcd m nforall n m : t, gcd n m == gcd m nn, m:tgcd n m == gcd m nn, m:tforall q : t, (q | gcd m n) <-> (q | n) /\ (q | m)n, m, q:t(q | gcd m n) <-> (q | n) /\ (q | m)apply gcd_divide_iff. Qed.n, m, q:t(q | gcd m n) <-> (q | m) /\ (q | n)forall n m p : t, gcd n (gcd m p) == gcd (gcd n m) pforall n m p : t, gcd n (gcd m p) == gcd (gcd n m) pn, m, p:tgcd n (gcd m p) == gcd (gcd n m) pn, m, p:tforall q : t, (q | gcd (gcd n m) p) <-> (q | n) /\ (q | gcd m p)now rewrite !gcd_divide_iff, and_assoc. Qed.n, m, p, q:t(q | gcd (gcd n m) p) <-> (q | n) /\ (q | gcd m p)forall n : t, 0 <= n -> gcd 0 n == nforall n : t, 0 <= n -> gcd 0 n == nn:tH:0 <= ngcd 0 n == nn:tH:0 <= n(n | 0)n:tH:0 <= n(n | n)apply divide_0_r.n:tH:0 <= n(n | 0)apply divide_refl. Qed.n:tH:0 <= n(n | n)forall n : t, 0 <= n -> gcd n 0 == nforall n : t, 0 <= n -> gcd n 0 == nnow rewrite gcd_comm, gcd_0_l_nonneg. Qed.n:tH:0 <= ngcd n 0 == nforall n : t, gcd 1 n == 1forall n : t, gcd 1 n == 1apply gcd_unique; trivial using divide_1_l, le_0_1. Qed.n:tgcd 1 n == 1forall n : t, gcd n 1 == 1forall n : t, gcd n 1 == 1now rewrite gcd_comm, gcd_1_l. Qed.n:tgcd n 1 == 1forall n : t, 0 <= n -> gcd n n == nforall n : t, 0 <= n -> gcd n n == napply gcd_unique; trivial using divide_refl. Qed.n:tH:0 <= ngcd n n == nforall n m : t, gcd n m == 0 -> n == 0forall n m : t, gcd n m == 0 -> n == 0n, m:tH:gcd n m == 0n == 0n, m:tH:gcd n m == 0(gcd n m | n) -> n == 0apply divide_0_l. Qed.n, m:tH:gcd n m == 0(0 | n) -> n == 0forall n m : t, gcd n m == 0 -> m == 0forall n m : t, gcd n m == 0 -> m == 0n, m:tH:gcd n m == 0m == 0now rewrite gcd_comm. Qed.n, m:tH:gcd n m == 0gcd m n == 0forall n m : t, gcd n m == 0 <-> n == 0 /\ m == 0forall n m : t, gcd n m == 0 <-> n == 0 /\ m == 0n, m:tgcd n m == 0 <-> n == 0 /\ m == 0n, m:tgcd n m == 0 -> n == 0 /\ m == 0n, m:tn == 0 /\ m == 0 -> gcd n m == 0n, m:tgcd n m == 0 -> n == 0 /\ m == 0n, m:tH:gcd n m == 0n == 0n, m:tH:gcd n m == 0m == 0now apply gcd_eq_0_l with m.n, m:tH:gcd n m == 0n == 0now apply gcd_eq_0_r with n.n, m:tH:gcd n m == 0m == 0n, m:tn == 0 /\ m == 0 -> gcd n m == 0n, m:tEQ:n == 0EQ':m == 0gcd n m == 0now apply gcd_0_r_nonneg. Qed.n, m:tEQ:n == 0EQ':m == 0gcd 0 0 == 0forall n m : t, 0 <= n -> gcd n (n * m) == nforall n m : t, 0 <= n -> gcd n (n * m) == nn, m:tHn:0 <= ngcd n (n * m) == nn, m:tHn:0 <= nforall q : t, (q | n) <-> (q | n) /\ (q | n * m)n, m:tHn:0 <= nq:t(q | n) <-> (q | n) /\ (q | n * m)n, m:tHn:0 <= nq:t(q | n) -> (q | n) /\ (q | n * m)n, m:tHn:0 <= nq:t(q | n) /\ (q | n * m) -> (q | n)n, m:tHn:0 <= nq:t(q | n) -> (q | n) /\ (q | n * m)now apply divide_mul_l.n, m:tHn:0 <= nq:tH:(q | n)(q | n * m)now destruct 1. Qed.n, m:tHn:0 <= nq:t(q | n) /\ (q | n * m) -> (q | n)forall n m : t, 0 <= n -> (n | m) <-> gcd n m == nforall n m : t, 0 <= n -> (n | m) <-> gcd n m == nn, m:tHn:0 <= n(n | m) <-> gcd n m == nn, m:tHn:0 <= n(n | m) -> gcd n m == nn, m:tHn:0 <= ngcd n m == n -> (n | m)n, m:tHn:0 <= n(n | m) -> gcd n m == nn, m:tHn:0 <= nq:tHq:m == q * ngcd n m == nn, m:tHn:0 <= nq:tHq:m == q * ngcd n (q * n) == nnow apply gcd_mul_diag_l.n, m:tHn:0 <= nq:tHq:m == q * ngcd n (n * q) == nn, m:tHn:0 <= ngcd n m == n -> (n | m)n, m:tHn:0 <= nEQ:gcd n m == n(n | m)apply gcd_divide_r. Qed. End NZGcdProp.n, m:tHn:0 <= nEQ:gcd n m == n(gcd n m | m)