Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Import ZArith_base. Require Import ZArithRing. Require Import Zcomplements. Require Import Zdiv. Require Import Wf_nat.
For compatibility reasons, this Open Scope isn't local as it should
Open Scope Z_scope.
This file contains some notions of number theory upon Z numbers:
- a divisibility predicate Z.divide
- a gcd predicate gcd
- Euclid algorithm euclid
- a relatively prime predicate rel_prime
- a prime predicate prime
- properties of the efficient Z.gcd function
The former specialized inductive predicate Z.divide is now
a generic existential predicate.
Its former constructor is now a pseudo-constructor.
Definition Zdivide_intro a b q (H:b=q*a) : Z.divide a b := ex_intro _ q H.
Results concerning divisibility
Notation Zone_divide := Z.divide_1_l (only parsing). Notation Zdivide_0 := Z.divide_0_r (only parsing). Notation Zmult_divide_compat_l := Z.mul_divide_mono_l (only parsing). Notation Zmult_divide_compat_r := Z.mul_divide_mono_r (only parsing). Notation Zdivide_plus_r := Z.divide_add_r (only parsing). Notation Zdivide_minus_l := Z.divide_sub_r (only parsing). Notation Zdivide_mult_l := Z.divide_mul_l (only parsing). Notation Zdivide_mult_r := Z.divide_mul_r (only parsing). Notation Zdivide_factor_r := Z.divide_factor_l (only parsing). Notation Zdivide_factor_l := Z.divide_factor_r (only parsing).a, b:Z(a | b) -> (a | - b)apply Z.divide_opp_r. Qed.a, b:Z(a | b) -> (a | - b)a, b:Z(a | - b) -> (a | b)apply Z.divide_opp_r. Qed.a, b:Z(a | - b) -> (a | b)a, b:Z(a | b) -> (- a | b)apply Z.divide_opp_l. Qed.a, b:Z(a | b) -> (- a | b)a, b:Z(- a | b) -> (a | b)apply Z.divide_opp_l. Qed.a, b:Z(- a | b) -> (a | b)a, b:Z(Z.abs a | b) -> (a | b)apply Z.divide_abs_l. Qed.a, b:Z(Z.abs a | b) -> (a | b)a, b:Z(a | b) -> (Z.abs a | b)apply Z.divide_abs_l. Qed. Hint Resolve Z.divide_refl Z.divide_1_l Z.divide_0_r: zarith. Hint Resolve Z.mul_divide_mono_l Z.mul_divide_mono_r: zarith. Hint Resolve Z.divide_add_r Zdivide_opp_r Zdivide_opp_r_rev Zdivide_opp_l Zdivide_opp_l_rev Z.divide_sub_r Z.divide_mul_l Z.divide_mul_r Z.divide_factor_l Z.divide_factor_r: zarith.a, b:Z(a | b) -> (Z.abs a | b)
Auxiliary result.
x, y:Zx >= 0 -> x * y = 1 -> x = 1x, y:Zx >= 0 -> x * y = 1 -> x = 1apply Z.eq_mul_1_nonneg. Qed.x, y:Z0 <= x -> x * y = 1 -> x = 1
Only 1 and -1 divide 1.
Notation Zdivide_1 := Z.divide_1_r (only parsing).
If a divides b and b<>0 then |a| ≤ |b|.
a, b:Z(a | b) -> b <> 0 -> Z.abs a <= Z.abs ba, b:Z(a | b) -> b <> 0 -> Z.abs a <= Z.abs ba, b:ZH:(a | b)Hb:b <> 0Z.abs a <= Z.abs ba, b:ZH:(Z.abs a | Z.abs b)Hb:b <> 0Z.abs a <= Z.abs bnow apply Z.divide_pos_le. Qed.a, b:ZH:(Z.abs a | Z.abs b)Hb:0 < Z.abs bZ.abs a <= Z.abs b
Z.divide can be expressed using Z.modulo.
forall a b : Z, b <> 0 -> a mod b = 0 -> (b | a)apply Z.mod_divide. Qed.forall a b : Z, b <> 0 -> a mod b = 0 -> (b | a)forall a b : Z, (b | a) -> a mod b = 0intros a b (c,->); apply Z_mod_mult. Qed.forall a b : Z, (b | a) -> a mod b = 0
Z.divide is hence decidable
a, b:Z{(a | b)} + {~ (a | b)}a, b:Z{(a | b)} + {~ (a | b)}a, b:ZHa:a = 0{(a | b)} + {~ (a | b)}a, b:ZHa:a <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a = 0Hb:b = 0{(a | b)} + {~ (a | b)}a, b:ZHa:a = 0Hb:b <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a = 0Hb:b <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a = 0Hb:b <> 0~ (a | b)a, b:ZHa:a <> 0{(a | b)} + {~ (a | b)}b:ZHb:b <> 0~ (0 | b)a, b:ZHa:a <> 0{(a | b)} + {~ (a | b)}b:ZHb:(0 | b)b = 0a, b:ZHa:a <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a <> 0e:b mod a = 0{(a | b)} + {~ (a | b)}a, b:ZHa:a <> 0n:b mod a <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a <> 0e:b mod a = 0(a | b)a, b:ZHa:a <> 0n:b mod a <> 0{(a | b)} + {~ (a | b)}a, b:ZHa:a <> 0n:b mod a <> 0{(a | b)} + {~ (a | b)}now rewrite <- Z.mod_divide. Defined.a, b:ZHa:a <> 0n:b mod a <> 0~ (a | b)a, b:Z0 < a -> (a | b) -> b = a * (b / a)a, b:Z0 < a -> (a | b) -> b = a * (b / a)a, b:ZHa:0 < aH:(a | b)b = a * (b / a)rewrite Zdivide_mod; auto with zarith. Qed.a, b:ZHa:0 < aH:(a | b)a * (b / a) + b mod a = a * (b / a)a, b, c:Z0 < a -> (a | b) -> c * b / a = c * (b / a)a, b, c:Z0 < a -> (a | b) -> c * b / a = c * (b / a)apply Z.divide_div_mul_exact; auto with zarith. Qed.a, b, c:ZH:0 < aH0:(a | b)c * b / a = c * (b / a)forall a b : Z, 0 <= a -> 0 < b -> (a | b) -> a <= bforall a b : Z, 0 <= a -> 0 < b -> (a | b) -> a <= bnow apply Z.divide_pos_le. Qed.a, b:ZH:0 <= aH0:0 < bH1:(a | b)a <= ba, b:Z1 < a -> 0 < b -> (a | b) -> 0 < b / a < ba, b:Z1 < a -> 0 < b -> (a | b) -> 0 < b / a < ba, b:ZH1:1 < aH2:0 < bH3:(a | b)0 < b / aa, b:ZH1:1 < aH2:0 < bH3:(a | b)b / a < ba, b:ZH1:1 < aH2:0 < bH3:(a | b)0 < a * (b / a)a, b:ZH1:1 < aH2:0 < bH3:(a | b)b / a < bnow apply Z.div_lt. Qed.a, b:ZH1:1 < aH2:0 < bH3:(a | b)b / a < bn, m, a:Z0 < n -> 0 < m -> (n | m) -> a mod n = (a mod m) mod nn, m, a:Z0 < n -> 0 < m -> (n | m) -> a mod n = (a mod m) mod nn, m, a:ZH1:0 < nH2:0 < mp:ZHp:m = p * na mod n = (a mod m) mod nn, m, a:ZH1:0 < nH2:0 < mp:ZHp:m = p * n(m * (a / m) + a mod m) mod n = (a mod m) mod nrewrite Z.mul_shuffle0, Z.add_comm, Z.mod_add; auto with zarith. Qed.n, m, a:ZH1:0 < nH2:0 < mp:ZHp:m = p * n(p * n * (a / m) + a mod m) mod n = (a mod m) mod na, b, c:Z0 < b -> a mod b = c -> (b | a - c)a, b, c:Z0 < b -> a mod b = c -> (b | a - c)a, b, c:ZH:0 < bH1:a mod b = c(b | a - c)a, b, c:ZH:0 < bH1:a mod b = c(a - c) mod b = 0a, b, c:ZH:0 < bH1:a mod b = c(a mod b - c mod b) mod b = 0a, b, c:ZH:0 < bH1:a mod b = c(c - c mod b) mod b = 0a, b, c:ZH:0 < bH1:a mod b = c(c mod b - c mod b) mod b = 0a, b, c:ZH:0 < bH1:a mod b = c0 <= c < ba, b, c:ZH:0 < bH1:a mod b = c0 <= c < bnow apply Z.mod_pos_bound. Qed.a, b:ZH:0 < b0 <= a mod b < ba, b, c:Z0 <= c < b -> (b | a - c) -> a mod b = ca, b, c:Z0 <= c < b -> (b | a - c) -> a mod b = ca, b, c:ZH1:0 <= cH2:c < bH3:(b | a - c)a mod b = ca, b, c:ZH1:0 <= cH2:c < bH3:(b | a - c)H:0 < ba mod b = ca, b, c:ZH1:0 <= cH2:c < bH3:(b | a - c)H:0 < b(a - c + c) mod b = ca, b, c:ZH1:0 <= cH2:c < bH3:(b | a - c)H:0 < b((a - c) mod b + c mod b) mod b = crewrite Z.mod_mod; try apply Zmod_small; auto with zarith. Qed.a, b, c:ZH1:0 <= cH2:c < bH3:(b | a - c)H:0 < b(c mod b) mod b = c
There is no unicity of the gcd; hence we define the predicate
Zis_gcd a b g expressing that g is a gcd of a and b.
(We show later that the gcd is actually unique if we discard its sign.)
Inductive Zis_gcd (a b g:Z) : Prop :=
Zis_gcd_intro :
(g | a) ->
(g | b) ->
(forall x, (x | a) -> (x | b) -> (x | g)) ->
Zis_gcd a b g.
Trivial properties of gcd
forall a b d : Z, Zis_gcd a b d -> Zis_gcd b a dinduction 1; constructor; intuition. Qed.forall a b d : Z, Zis_gcd a b d -> Zis_gcd b a dforall a : Z, Zis_gcd a 0 aconstructor; auto with zarith. Qed.forall a : Z, Zis_gcd a 0 aforall a : Z, Zis_gcd a 1 1constructor; auto with zarith. Qed.forall a : Z, Zis_gcd a 1 1forall a : Z, Zis_gcd a a aconstructor; auto with zarith. Qed.forall a : Z, Zis_gcd a a aforall a b d : Z, Zis_gcd a (- b) d -> Zis_gcd b a dinduction 1; constructor; intuition. Qed.forall a b d : Z, Zis_gcd a (- b) d -> Zis_gcd b a dforall a b d : Z, Zis_gcd a b d -> Zis_gcd b a (- d)induction 1; constructor; intuition. Qed.forall a b d : Z, Zis_gcd a b d -> Zis_gcd b a (- d)a:ZZis_gcd 0 a (Z.abs a)a:ZZis_gcd 0 a (Z.abs a)a:Za >= 0 -> Zis_gcd 0 a aa:Za <= 0 -> Zis_gcd 0 a (- a)intros; apply Zis_gcd_opp; apply Zis_gcd_0; auto. Qed. Hint Resolve Zis_gcd_sym Zis_gcd_0 Zis_gcd_minus Zis_gcd_opp: zarith.a:Za <= 0 -> Zis_gcd 0 a (- a)forall a b c d : Z, Zis_gcd a b c -> Zis_gcd a b d -> c = d \/ c = - dforall a b c d : Z, Zis_gcd a b c -> Zis_gcd a b d -> c = d \/ c = - da, b, c, d:ZHc1:(c | a)Hc2:(c | b)Hc3:forall x : Z, (x | a) -> (x | b) -> (x | c)Hd1:(d | a)Hd2:(d | b)Hd3:forall x : Z, (x | a) -> (x | b) -> (x | d)c = d \/ c = - da, b, c, d:ZHc1:(c | a)Hc2:(c | b)Hc3:forall x : Z, (x | a) -> (x | b) -> (x | c)Hd1:(d | a)Hd2:(d | b)Hd3:forall x : Z, (x | a) -> (x | b) -> (x | d)H:(c | d)c = d \/ c = - dapply Z.divide_antisym; auto. Qed.a, b, c, d:ZHc1:(c | a)Hc2:(c | b)Hc3:forall x : Z, (x | a) -> (x | b) -> (x | c)Hd1:(d | a)Hd2:(d | b)Hd3:forall x : Z, (x | a) -> (x | b) -> (x | d)H:(c | d)H0:(d | c)c = d \/ c = - d
Euclid's algorithm to compute the gcd mainly relies on
the following property.
forall a b d q : Z, Zis_gcd b (a - q * b) d -> Zis_gcd a b dforall a b d q : Z, Zis_gcd b (a - q * b) d -> Zis_gcd a b da, b, d, q:ZH:Zis_gcd b (a - q * b) dH0:(d | b)H1:(d | a - q * b)H2:forall x : Z, (x | b) -> (x | a - q * b) -> (x | d)(d | a)a, b, d, q:ZH:Zis_gcd b (a - q * b) dH0:(d | b)H1:(d | a - q * b)H2:forall x : Z, (x | b) -> (x | a - q * b) -> (x | d)(d | a - q * b + q * b)a, b, d, q:ZH:Zis_gcd b (a - q * b) dH0:(d | b)H1:(d | a - q * b)H2:forall x : Z, (x | b) -> (x | a - q * b) -> (x | d)a - q * b + q * b = aring. Qed.a, b, d, q:ZH:Zis_gcd b (a - q * b) dH0:(d | b)H1:(d | a - q * b)H2:forall x : Z, (x | b) -> (x | a - q * b) -> (x | d)a - q * b + q * b = aforall b d q r : Z, Zis_gcd r b d -> Zis_gcd b (b * q + r) dforall b d q r : Z, Zis_gcd r b d -> Zis_gcd b (b * q + r) db, d, q, r:ZH:Zis_gcd r b dH0:(d | r)H1:(d | b)H2:forall x0 : Z, (x0 | r) -> (x0 | b) -> (x0 | d)x:ZH3:(x | b)H4:(x | b * q + r)(x | d)b, d, q, r:ZH:Zis_gcd r b dH0:(d | r)H1:(d | b)H2:forall x0 : Z, (x0 | r) -> (x0 | b) -> (x0 | d)x:ZH3:(x | b)H4:(x | b * q + r)(x | r)b, d, q, r:ZH:Zis_gcd r b dH0:(d | r)H1:(d | b)H2:forall x0 : Z, (x0 | r) -> (x0 | b) -> (x0 | d)x:ZH3:(x | b)H4:(x | b * q + r)(x | b * q + r - b * q)b, d, q, r:ZH:Zis_gcd r b dH0:(d | r)H1:(d | b)H2:forall x0 : Z, (x0 | r) -> (x0 | b) -> (x0 | d)x:ZH3:(x | b)H4:(x | b * q + r)b * q + r - b * q = rring. Qed.b, d, q, r:ZH:Zis_gcd r b dH0:(d | r)H1:(d | b)H2:forall x0 : Z, (x0 | r) -> (x0 | b) -> (x0 | d)x:ZH3:(x | b)H4:(x | b * q + r)b * q + r - b * q = r
We implement the extended version of Euclid's algorithm,
i.e. the one computing Bezout's coefficients as it computes
the gcd. We follow the algorithm given in Knuth's
"Art of Computer Programming", vol 2, page 325.
Section extended_euclid_algorithm. Variables a b : Z.
The specification of Euclid's algorithm is the existence of
u, v and d such that ua+vb=d and (gcd a b d).
Inductive Euclid : Set := Euclid_intro : forall u v d:Z, u * a + v * b = d -> Zis_gcd a b d -> Euclid.
The recursive part of Euclid's algorithm uses well-founded
recursion of non-negative integers. It maintains 6 integers
u1,u2,u3,v1,v2,v3 such that the following invariant holds:
u1×a+u2×b=u3 and v1×a+v2×b=v3 and gcd(u3,v3)=gcd(a,b).
a, b:Zforall v3 : Z, 0 <= v3 -> forall u1 u2 u3 v1 v2 : Z, u1 * a + u2 * b = u3 -> v1 * a + v2 * b = v3 -> (forall d : Z, Zis_gcd u3 v3 d -> Zis_gcd a b d) -> Euclida, b:Zforall v3 : Z, 0 <= v3 -> forall u1 u2 u3 v1 v2 : Z, u1 * a + u2 * b = u3 -> v1 * a + v2 * b = v3 -> (forall d : Z, Zis_gcd u3 v3 d -> Zis_gcd a b d) -> Euclida, b, v3:ZHv3:0 <= v3(fun z : Z => 0 <= z -> forall u1 u2 u3 v1 v2 : Z, u1 * a + u2 * b = u3 -> v1 * a + v2 * b = z -> (forall d : Z, Zis_gcd u3 z d -> Zis_gcd a b d) -> Euclid) v3a, b, v3:ZHv3:0 <= v3forall x : Z, (forall y : Z, 0 <= y < x -> 0 <= y -> forall u1 u2 u3 v1 v2 : Z, u1 * a + u2 * b = u3 -> v1 * a + v2 * b = y -> (forall d : Z, Zis_gcd u3 y d -> Zis_gcd a b d) -> Euclid) -> 0 <= x -> 0 <= x -> forall u1 u2 u3 v1 v2 : Z, u1 * a + u2 * b = u3 -> v1 * a + v2 * b = x -> (forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b d) -> Euclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHeq:x = 0Euclida, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0Euclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHeq:x = 0u1 * a + u2 * b = u3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHeq:x = 0Zis_gcd a b u3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0Euclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHeq:x = 0Zis_gcd a b u3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0Euclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHeq:x = 0Zis_gcd u3 x u3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0Euclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0Euclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Z0 <= u3 - q * x < xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Z0 <= u3 mod x < xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Zu3 mod x = u3 - q * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Zu3 mod x = u3 - q * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Zx > 0a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Zxpos:x > 0u3 mod x = u3 - q * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Zxpos:x > 0u3 mod x = u3 - q * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Zxpos:x > 0u3 = x * (u3 / x) + u3 mod x -> u3 mod x = u3 - q * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:Zxpos:x > 0u3 = x * (u3 / x) + u3 mod x -> u3 mod x = u3 - u3 / x * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xEuclida, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xv1 * a + v2 * b = xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < x(u1 - q * v1) * a + (u2 - q * v2) * b = u3 - q * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xforall d : Z, Zis_gcd x (u3 - q * x) d -> Zis_gcd a b da, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < x(u1 - q * v1) * a + (u2 - q * v2) * b = u3 - q * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xforall d : Z, Zis_gcd x (u3 - q * x) d -> Zis_gcd a b da, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xu1 * a + u2 * b - q * (v1 * a + v2 * b) = u3 - q * xa, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xu1 * a + u2 * b - q * (v1 * a + v2 * b) = (u1 - q * v1) * a + (u2 - q * v2) * ba, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xforall d : Z, Zis_gcd x (u3 - q * x) d -> Zis_gcd a b da, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xu1 * a + u2 * b - q * (v1 * a + v2 * b) = (u1 - q * v1) * a + (u2 - q * v2) * ba, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xforall d : Z, Zis_gcd x (u3 - q * x) d -> Zis_gcd a b da, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d : Z, Zis_gcd u5 y d -> Zis_gcd a b d) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d : Z, Zis_gcd u3 x d -> Zis_gcd a b dHneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xforall d : Z, Zis_gcd x (u3 - q * x) d -> Zis_gcd a b da, b, v3:ZHv3:0 <= v30 <= v3a, b, x:ZH:forall y : Z, 0 <= y < x -> 0 <= y -> forall u0 u4 u5 v0 v3 : Z, u0 * a + u4 * b = u5 -> v0 * a + v3 * b = y -> (forall d0 : Z, Zis_gcd u5 y d0 -> Zis_gcd a b d0) -> EuclidH0, Hv3:0 <= xu1, u2, u3, v1, v2:ZH1:u1 * a + u2 * b = u3H2:v1 * a + v2 * b = xH3:forall d0 : Z, Zis_gcd u3 x d0 -> Zis_gcd a b d0Hneq:x <> 0q:=u3 / x:ZHq:0 <= u3 - q * x < xd:ZH4:Zis_gcd x (u3 - q * x) dZis_gcd u3 x da, b, v3:ZHv3:0 <= v30 <= v3assumption. Qed.a, b, v3:ZHv3:0 <= v30 <= v3
We get Euclid's algorithm by applying euclid_rec on
1,0,a,0,1,b when b>=0 and 1,0,a,0,-1,-b when b<0.
a, b:ZEuclida, b:ZEuclida, b:Zl:0 <= bEuclida, b:Zg:0 > bEuclidintros; apply euclid_rec with (u1 := 1) (u2 := 0) (u3 := a) (v1 := 0) (v2 := -1) (v3 := - b); auto with zarith; try ring. Qed. End extended_euclid_algorithm.a, b:Zg:0 > bEuclidforall a b d d' : Z, Zis_gcd a b d -> Zis_gcd a b d' -> d = d' \/ d = - d'forall a b d d' : Z, Zis_gcd a b d -> Zis_gcd a b d' -> d = d' \/ d = - d'a, b, d, d':ZH:Zis_gcd a b d(d | a) -> (d | b) -> (forall x : Z, (x | a) -> (x | b) -> (x | d)) -> Zis_gcd a b d' -> d = d' \/ d = - d'a, b, d, d':ZH:Zis_gcd a b dH1:(d | a)H2:(d | b)H3:forall x : Z, (x | a) -> (x | b) -> (x | d)H0:Zis_gcd a b d'H4:(d' | a)H5:(d' | b)H6:forall x : Z, (x | a) -> (x | b) -> (x | d')d = d' \/ d = - d'a, b, d, d':ZH:Zis_gcd a b dH1:(d | a)H2:(d | b)H3:forall x : Z, (x | a) -> (x | b) -> (x | d)H0:Zis_gcd a b d'H4:(d' | a)H5:(d' | b)H6:forall x : Z, (x | a) -> (x | b) -> (x | d')Hd'd:(d' | d)d = d' \/ d = - d'exact (Z.divide_antisym d d' Hdd' Hd'd). Qed.a, b, d, d':ZH:Zis_gcd a b dH1:(d | a)H2:(d | b)H3:forall x : Z, (x | a) -> (x | b) -> (x | d)H0:Zis_gcd a b d'H4:(d' | a)H5:(d' | b)H6:forall x : Z, (x | a) -> (x | b) -> (x | d')Hd'd:(d' | d)Hdd':(d | d')d = d' \/ d = - d'
Inductive Bezout (a b d:Z) : Prop :=
Bezout_intro : forall u v:Z, u * a + v * b = d -> Bezout a b d.
Existence of Bezout's coefficients for the gcd of a and b
forall a b d : Z, Zis_gcd a b d -> Bezout a b dforall a b d : Z, Zis_gcd a b d -> Bezout a b da, b, d:ZHgcd:Zis_gcd a b dBezout a b da, b, d:ZHgcd:Zis_gcd a b du, v, d0:Ze:u * a + v * b = d0g:Zis_gcd a b d0Bezout a b da, b, d:ZHgcd:Zis_gcd a b du, v, d0:Ze:u * a + v * b = d0g:Zis_gcd a b d0d = d0 \/ d = - d0 -> Bezout a b da, b, d:ZHgcd:Zis_gcd a b du, v, d0:Ze:u * a + v * b = d0g:Zis_gcd a b d0H:d = d0Bezout a b da, b, d:ZHgcd:Zis_gcd a b du, v, d0:Ze:u * a + v * b = d0g:Zis_gcd a b d0H:d = - d0Bezout a b da, b, d:ZHgcd:Zis_gcd a b du, v, d0:Ze:u * a + v * b = d0g:Zis_gcd a b d0H:d = d0u * a + v * b = da, b, d:ZHgcd:Zis_gcd a b du, v, d0:Ze:u * a + v * b = d0g:Zis_gcd a b d0H:d = - d0Bezout a b da, b, d:ZHgcd:Zis_gcd a b du, v, d0:Ze:u * a + v * b = d0g:Zis_gcd a b d0H:d = - d0Bezout a b drewrite H; rewrite <- e; ring. Qed.a, b, d:ZHgcd:Zis_gcd a b du, v, d0:Ze:u * a + v * b = d0g:Zis_gcd a b d0H:d = - d0- u * a + - v * b = d
gcd of ca and cb is c gcd(a,b).
forall a b c d : Z, Zis_gcd a b d -> Zis_gcd (c * a) (c * b) (c * d)forall a b c d : Z, Zis_gcd a b d -> Zis_gcd (c * a) (c * b) (c * d)a, b, c, d:ZH:Zis_gcd a b d(d | a) -> (d | b) -> (forall x : Z, (x | a) -> (x | b) -> (x | d)) -> Zis_gcd (c * a) (c * b) (c * d)a, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x : Z, (x | a) -> (x | b) -> (x | d)forall x : Z, (x | c * a) -> (x | c * b) -> (x | c * d)a, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)(x | c * d)a, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)forall u v : Z, u * a + v * b = d -> (x | c * d)a, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)u, v:ZHuv:u * a + v * b = d(x | c * d)a, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)u, v:ZHuv:u * a + v * b = da':ZHa':c * a = a' * x(x | c * d)a, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)u, v:ZHuv:u * a + v * b = da':ZHa':c * a = a' * xb':ZHb':c * b = b' * x(x | c * d)a, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)u, v:ZHuv:u * a + v * b = da':ZHa':c * a = a' * xb':ZHb':c * b = b' * xc * d = (u * a' + v * b') * xa, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)u, v:ZHuv:u * a + v * b = da':ZHa':c * a = a' * xb':ZHb':c * b = b' * xc * (u * a + v * b) = (u * a' + v * b') * xa, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)u, v:ZHuv:u * a + v * b = da':ZHa':c * a = a' * xb':ZHb':c * b = b' * xu * (c * a) + v * (c * b) = (u * a' + v * b') * xa, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)u, v:ZHuv:u * a + v * b = da':ZHa':c * a = a' * xb':ZHb':c * b = b' * xu * (c * a) + v * (c * b) = c * (u * a + v * b)ring. Qed.a, b, c, d:ZH:Zis_gcd a b dH0:(d | a)H1:(d | b)H2:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | d)x:ZHa:(x | c * a)Hb:(x | c * b)u, v:ZHuv:u * a + v * b = da':ZHa':c * a = a' * xb':ZHb':c * b = b' * xu * (c * a) + v * (c * b) = c * (u * a + v * b)
Definition rel_prime (a b:Z) : Prop := Zis_gcd a b 1.
Bezout's theorem: a and b are relatively prime if and
only if there exist u and v such that ua+vb = 1.
forall a b : Z, rel_prime a b -> Bezout a b 1intros a b; exact (Zis_gcd_bezout a b 1). Qed.forall a b : Z, rel_prime a b -> Bezout a b 1forall a b : Z, Bezout a b 1 -> rel_prime a bforall a b : Z, Bezout a b 1 -> rel_prime a ba, b:ZH:Bezout a b 1u, v:ZH0:u * a + v * b = 1forall x : Z, (x | a) -> (x | b) -> (x | 1)rewrite <- H0; auto with zarith. Qed.a, b:ZH:Bezout a b 1u, v:ZH0:u * a + v * b = 1x:ZH1:(x | a)H2:(x | b)(x | 1)
Gauss's theorem: if a divides bc and if a and b are
relatively prime, then a divides c.
forall a b c : Z, (a | b * c) -> rel_prime a b -> (a | c)forall a b c : Z, (a | b * c) -> rel_prime a b -> (a | c)a, b, c:ZH:(a | b * c)H0:rel_prime a b(a | c)a, b, c:ZH:(a | b * c)H0:rel_prime a bu, v:ZH1:u * a + v * b = 1(a | c)a, b, c:ZH:(a | b * c)H0:rel_prime a bu, v:ZH1:u * a + v * b = 1(a | c * 1)replace (c * (u * a + v * b)) with (c * u * a + v * (b * c)); [ eauto with zarith | ring ]. Qed.a, b, c:ZH:(a | b * c)H0:rel_prime a bu, v:ZH1:u * a + v * b = 1(a | c * (u * a + v * b))
If a is relatively prime to b and c, then it is to bc
forall a b c : Z, rel_prime a b -> rel_prime a c -> rel_prime a (b * c)forall a b c : Z, rel_prime a b -> rel_prime a c -> rel_prime a (b * c)a, b, c:ZHb:rel_prime a bHc:rel_prime a crel_prime a (b * c)a, b, c:ZHb:rel_prime a bHc:rel_prime a cu, v:ZH:u * a + v * b = 1rel_prime a (b * c)a, b, c:ZHb:rel_prime a bHc:rel_prime a cu, v:ZH:u * a + v * b = 1u0, v0:ZH0:u0 * a + v0 * c = 1rel_prime a (b * c)a, b, c:ZHb:rel_prime a bHc:rel_prime a cu, v:ZH:u * a + v * b = 1u0, v0:ZH0:u0 * a + v0 * c = 1Bezout a (b * c) 1a, b, c:ZHb:rel_prime a bHc:rel_prime a cu, v:ZH:u * a + v * b = 1u0, v0:ZH0:u0 * a + v0 * c = 1(u * u0 * a + v0 * c * u + u0 * v * b) * a + v * v0 * (b * c) = 1a, b, c:ZHb:rel_prime a bHc:rel_prime a cu, v:ZH:u * a + v * b = 1u0, v0:ZH0:u0 * a + v0 * c = 1(u * u0 * a + v0 * c * u + u0 * v * b) * a + v * v0 * (b * c) = u * a + v * ba, b, c:ZHb:rel_prime a bHc:rel_prime a cu, v:ZH:u * a + v * b = 1u0, v0:ZH0:u0 * a + v0 * c = 1(u * u0 * a + v0 * c * u + u0 * v * b) * a + v * v0 * (b * c) = (u * a + v * b) * 1ring. Qed.a, b, c:ZHb:rel_prime a bHc:rel_prime a cu, v:ZH:u * a + v * b = 1u0, v0:ZH0:u0 * a + v0 * c = 1(u * u0 * a + v0 * c * u + u0 * v * b) * a + v * v0 * (b * c) = (u * a + v * b) * (u0 * a + v0 * c)forall a b c d : Z, rel_prime a b -> rel_prime c d -> b > 0 -> d > 0 -> a * d = b * c -> a = c /\ b = dforall a b c d : Z, rel_prime a b -> rel_prime c d -> b > 0 -> d > 0 -> a * d = b * c -> a = c /\ b = da, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * ca = c /\ b = da, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * cb = d -> a = c /\ b = da, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * cb = - d -> a = c /\ b = da, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(b | d)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * cH4:b = da = ca, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * cb = - d -> a = c /\ b = da, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(b | d)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = d * cH4:b = da = ca, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * cb = - d -> a = c /\ b = da, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(b | d)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:d * a = d * cH4:b = da = ca, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * cb = - d -> a = c /\ b = da, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(b | d)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * cb = - d -> a = c /\ b = da, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(b | d)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(b | d)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(b | a * d)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * crel_prime b aa, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(b | b * c)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * crel_prime b aa, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * crel_prime b aa, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | c * b)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * crel_prime d ca, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | b * c)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * crel_prime d ca, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * c(d | a * d)a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * crel_prime d cred; auto with zarith. Qed.a, b, c, d:ZH:rel_prime a bH0:rel_prime c dH1:b > 0H2:d > 0H3:a * d = b * crel_prime d c
After factorization by a gcd, the original numbers are relatively prime.
forall a b g : Z, b > 0 -> g >= 0 -> Zis_gcd a b g -> rel_prime (a / g) (b / g)forall a b g : Z, b > 0 -> g >= 0 -> Zis_gcd a b g -> rel_prime (a / g) (b / g)a, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b grel_prime (a / g) (b / g)a, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gg <> 0a, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g <> 0rel_prime (a / g) (b / g)a, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g = 0Falsea, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g <> 0rel_prime (a / g) (b / g)a, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g = 0H3:(g | a)H4:(g | b)H5:forall x : Z, (x | a) -> (x | b) -> (x | g)Falsea, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g <> 0rel_prime (a / g) (b / g)a, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g = 0H3:(g | a)H4:(g | b)H5:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)x:ZH6:b = x * gFalsea, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g <> 0rel_prime (a / g) (b / g)a, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g <> 0rel_prime (a / g) (b / g)a, b, g:ZH:b > 0H0:g >= 0H1:Zis_gcd a b gH2:g <> 0Zis_gcd (a / g) (b / g) 1a, b, g:ZH:b > 0H0:g >= 0H1:(g | a)H3:(g | b)H4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0Zis_gcd (a / g) (b / g) 1a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gH3:(g | b)H4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0Zis_gcd (a / g) (b / g) 1a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0Zis_gcd (a / g) (b / g) 1a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0Zis_gcd a' (b / g) 1a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0Zis_gcd a' b' 1a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0(1 | a')a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0(1 | b')a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0forall x : Z, (x | a') -> (x | b') -> (x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0(1 | b')a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0forall x : Z, (x | a') -> (x | b') -> (x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x : Z, (x | a) -> (x | b) -> (x | g)H2:g <> 0forall x : Z, (x | a') -> (x | b') -> (x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * x(x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * x(x * g | a)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * x(x * g | b)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * xx':ZHx':g = x' * (x * g)(x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * x(x * g | b)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * xx':ZHx':g = x' * (x * g)(x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * xx':ZHx':g = x' * (x * g)(x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * xx':ZHx':1 * g = x' * (x * (1 * g))(x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * xx':ZHx':1 * g = x' * x * 1 * g(x | 1)a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * xx':ZHx':1 = x' * x * 1(x | 1)exists x'; auto with zarith. Qed.a, b, g:ZH:b > 0H0:g >= 0a':ZH1:a = a' * gb':ZH3:b = b' * gH4:forall x0 : Z, (x0 | a) -> (x0 | b) -> (x0 | g)H2:g <> 0x, xa:ZH5:a' = xa * xxb:ZH6:b' = xb * xx':ZHx':1 = x' * x(x | 1)forall a b : Z, rel_prime a b -> rel_prime b aforall a b : Z, rel_prime a b -> rel_prime b ared; apply Zis_gcd_sym; auto with zarith. Qed.a, b:ZH:rel_prime a brel_prime b aforall p q r : Z, rel_prime p q -> (r | p) -> rel_prime r qforall p q r : Z, rel_prime p q -> (r | p) -> rel_prime r qq, r, u:ZH:rel_prime (u * r) qrel_prime r qq, r, u:ZH1:(1 | u * r)H2:(1 | q)H3:forall x : Z, (x | u * r) -> (x | q) -> (x | 1)rel_prime r qq, r, u:ZH1:(1 | u * r)H2:(1 | q)H3:forall x : Z, (x | u * r) -> (x | q) -> (x | 1)forall x : Z, (x | r) -> (x | q) -> (x | 1)apply Z.divide_mul_r; auto. Qed.q, r, u:ZH1:(1 | u * r)H2:(1 | q)H3:forall x0 : Z, (x0 | u * r) -> (x0 | q) -> (x0 | 1)x:ZH4:(x | r)H5:(x | q)(x | u * r)forall n : Z, rel_prime 1 nforall n : Z, rel_prime 1 nn:Z(1 | 1)n:Z(1 | n)exists n; auto with zarith. Qed.n:Z(1 | n)forall n : Z, 1 < n -> ~ rel_prime 0 nforall n : Z, 1 < n -> ~ rel_prime 0 nn:ZH:1 < nH1:rel_prime 0 n~ (n = 1 \/ n = -1)n:ZH:1 < nH1:rel_prime 0 nn = 1 \/ n = -1n:ZH:1 < nH1:rel_prime 0 nn = 1 \/ n = -1n:ZH:1 < nH1:rel_prime 0 nZis_gcd 0 n nn:ZH:1 < nH1:rel_prime 0 n(n | 0)n:ZH:1 < nH1:rel_prime 0 n(n | n)exists 1; auto with zarith. Qed.n:ZH:1 < nH1:rel_prime 0 n(n | n)forall p q : Z, 0 < q -> rel_prime p q -> rel_prime (p mod q) qforall p q : Z, 0 < q -> rel_prime p q -> rel_prime (p mod q) qp, q:ZH:0 < qH0:rel_prime p qrel_prime (p mod q) qp, q:ZH:0 < qH0:rel_prime p qBezout p q 1p, q:ZH:0 < qH0:rel_prime p qH1:Bezout p q 1rel_prime (p mod q) qp, q:ZH:0 < qH0:rel_prime p qH1:Bezout p q 1rel_prime (p mod q) qp, q:ZH:0 < qH0:rel_prime p qq1, r1:ZH2:q1 * p + r1 * q = 1rel_prime (p mod q) qp, q:ZH:0 < qH0:rel_prime p qq1, r1:ZH2:q1 * p + r1 * q = 1Bezout (p mod q) q 1p, q:ZH:0 < qH0:rel_prime p qq1, r1:ZH2:q1 * p + r1 * q = 1q1 * (p mod q) + (r1 + q1 * (p / q)) * q = 1pattern p at 3; rewrite (Z_div_mod_eq p q); try ring; auto with zarith. Qed.p, q:ZH:0 < qH0:rel_prime p qq1, r1:ZH2:q1 * p + r1 * q = 1q1 * (p mod q) + (r1 + q1 * (p / q)) * q = q1 * p + r1 * qforall p q : Z, 0 < q -> rel_prime (p mod q) q -> rel_prime p qforall p q : Z, 0 < q -> rel_prime (p mod q) q -> rel_prime p qp, q:ZH:0 < qH0:rel_prime (p mod q) qrel_prime p qapply Zis_gcd_sym; apply Zis_gcd_for_euclid2; auto with zarith. Qed.p, q:ZH:0 < qH0:rel_prime (p mod q) qZis_gcd (q * (p / q) + p mod q) q 1forall a b : Z, 1 < b -> rel_prime a b -> a mod b <> 0forall a b : Z, 1 < b -> rel_prime a b -> a mod b <> 0a, b:ZH:1 < bH1:rel_prime a bH2:a mod b = 0Falsea, b:ZH:1 < bH1:rel_prime a bH2:a mod b = 0rel_prime 0 bapply rel_prime_mod; auto with zarith. Qed.a, b:ZH:1 < bH1:rel_prime a bH2:a mod b = 0rel_prime (a mod b) b
Inductive prime (p:Z) : Prop :=
prime_intro :
1 < p -> (forall n:Z, 1 <= n < p -> rel_prime n p) -> prime p.
The sole divisors of a prime number p are -1, 1, p and -p.
forall p : Z, prime p -> forall a : Z, (a | p) -> a = -1 \/ a = 1 \/ a = p \/ a = - pforall p : Z, prime p -> forall a : Z, (a | p) -> a = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)a = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)a = - p \/ - p < a < -1 \/ a = -1 \/ a = 0 \/ a = 1 \/ 1 < a < p \/ a = pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H2:a = - p \/ - p < a < -1 \/ a = -1 \/ a = 0 \/ a = 1 \/ 1 < a < p \/ a = pa = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)a = - p \/ - p < a < -1 \/ a = -1 \/ a = 0 \/ a = 1 \/ 1 < a < p \/ a = pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)Z.abs a <= Z.abs pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H2:Z.abs a <= Z.abs pa = - p \/ - p < a < -1 \/ a = -1 \/ a = 0 \/ a = 1 \/ 1 < a < p \/ a = pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H2:Z.abs a <= Z.abs pa = - p \/ - p < a < -1 \/ a = -1 \/ a = 0 \/ a = 1 \/ 1 < a < p \/ a = ppattern (Z.abs a); apply Zabs_ind; pattern (Z.abs p); apply Zabs_ind; intros; omega.p:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)Z.abs a <= Z.abs p -> a = - p \/ - p < a < -1 \/ a = -1 \/ a = 0 \/ a = 1 \/ 1 < a < p \/ a = pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H2:a = - p \/ - p < a < -1 \/ a = -1 \/ a = 0 \/ a = 1 \/ 1 < a < p \/ a = pa = -1 \/ a = 1 \/ a = p \/ a = - p(* -p < a < -1 *)p:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:- p < aH4:a < -1a = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H2:a = 0a = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:1 < aH4:a < pa = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:- p < aH4:a < -1a = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:- p < aH4:a < -1H2:rel_prime (- a) pFalsep:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:- p < aH4:a < -1H2:rel_prime (- a) pH5:(1 | - a)H6:(1 | p)H7:forall x : Z, (x | - a) -> (x | p) -> (x | 1)Falsep:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:- p < aH4:a < -1H2:rel_prime (- a) pH5:(1 | - a)H6:(1 | p)H7:forall x : Z, (x | - a) -> (x | p) -> (x | 1)H8:(- a | - a)Falseapply H7, Z.divide_1_r in H8; intuition. (* a = 0 *)p:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:- p < aH4:a < -1H2:rel_prime (- a) pH5:(1 | - a)H6:(1 | p)H7:forall x : Z, (x | - a) -> (x | p) -> (x | 1)H8:(- a | - a)H9:(- a | p)Falsep:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H2:a = 0a = -1 \/ a = 1 \/ a = p \/ a = - psubst a; omega. (* 1 < a < p *)p:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H2:a = 0x:ZH3:p = x * aa = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:1 < aH4:a < pa = -1 \/ a = 1 \/ a = p \/ a = - pp:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:1 < aH4:a < pH2:rel_prime a pFalsep:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:1 < aH4:a < pH2:rel_prime a pH5:(1 | a)H6:(1 | p)H7:forall x : Z, (x | a) -> (x | p) -> (x | 1)Falsep:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:1 < aH4:a < pH2:rel_prime a pH5:(1 | a)H6:(1 | p)H7:forall x : Z, (x | a) -> (x | p) -> (x | 1)H8:(a | a)Falseapply H7, Z.divide_1_r in H8; intuition. Qed.p:ZH:1 < pH0:forall n : Z, 1 <= n < p -> rel_prime n pa:ZH1:(a | p)H3:1 < aH4:a < pH2:rel_prime a pH5:(1 | a)H6:(1 | p)H7:forall x : Z, (x | a) -> (x | p) -> (x | 1)H8:(a | a)H9:(a | p)False
A prime number is relatively prime with any number it does not divide
forall p : Z, prime p -> forall a : Z, ~ (p | a) -> rel_prime p aforall p : Z, prime p -> forall a : Z, ~ (p | a) -> rel_prime p ap:ZH:prime pa:ZH0:~ (p | a)x:ZH1:(x | p)H2:(x | a)(x | 1)p:ZH:prime pa:ZH0:(p | a) -> FalseH2:(p | a)(p | 1)p:ZH:prime pa:ZH0:(p | a) -> FalseH2:(- p | a)(- p | 1)absurd (p | a); auto with zarith.p:ZH:prime pa:ZH0:(p | a) -> FalseH2:(p | a)(p | 1)absurd (p | a); intuition. Qed. Hint Resolve prime_rel_prime: zarith.p:ZH:prime pa:ZH0:(p | a) -> FalseH2:(- p | a)(- p | 1)
As a consequence, a prime number is relatively prime with smaller numbers
forall a p : Z, prime p -> 1 <= a < p -> rel_prime a pforall a p : Z, prime p -> 1 <= a < p -> rel_prime a pa, p:ZHp:prime pH1:1 <= aH2:a < prel_prime a pa, p:ZHp:prime pH1:1 <= aH2:a < p~ (p | a)p:ZHp:prime pq:ZH2:q * p < pH1:1 <= q * pFalsep:ZHp:prime pq:ZH2:q * p < pH1:1 <= q * pHl:q <= 0Falsep:ZHp:prime pq:ZH2:q * p < pH1:1 <= q * pHl:0 < qFalseabsurd (1 * p <= q * p); auto with zarith. Qed.p:ZHp:prime pq:ZH2:q * p < pH1:1 <= q * pHl:0 < qFalse
If a prime p divides ab then it divides either a or b
forall p : Z, prime p -> forall a b : Z, (p | a * b) -> (p | a) \/ (p | b)forall p : Z, prime p -> forall a b : Z, (p | a * b) -> (p | a) \/ (p | b)p:ZH:prime pH0:1 < pH1:forall n : Z, 1 <= n < p -> rel_prime n pa, b:ZH2:(p | a * b)(p | a) \/ (p | b)right; apply Gauss with a; auto with zarith. Qed.p:ZH:prime pH0:1 < pH1:forall n0 : Z, 1 <= n0 < p -> rel_prime n0 pa, b:ZH2:(p | a * b)n:(p | a) -> False(p | a) \/ (p | b)~ prime 0intros H1; case (prime_divisors _ H1 2); auto with zarith. Qed.~ prime 0~ prime 1~ prime 1inversion H1; auto. Qed.H1:prime 11 < 1prime 2prime 2forall n : Z, 1 <= n < 2 -> rel_prime n 2n:ZH:1 < nH':n < 2rel_prime n 2n:ZH:1 = nH':n < 2rel_prime n 2contradict H'; auto with zarith.n:ZH:1 < nH':n < 2rel_prime n 2n:ZH:1 = nH':n < 2rel_prime n 2constructor; auto with zarith. Qed.H':1 < 2rel_prime 1 2prime 3prime 3forall n : Z, 1 <= n < 3 -> rel_prime n 3n:ZH:1 < nH':n < 3rel_prime n 3n:ZH:1 = nH':n < 3rel_prime n 3n:ZH:1 < nH':n < 3rel_prime n 3n:ZH:1 < nH':n < 3rel_prime 2 3n:ZH:1 < nH':n < 3forall x : Z, (x | 2) -> (x | 3) -> (x | 1)n:ZH:1 < nH':n < 3x, q:ZHq:2 = q * xq':ZHq':3 = q' * x(x | 1)n:ZH:1 < nH':n < 3x, q:ZHq:2 = q * xq':ZHq':3 = q' * x1 = (q' - q) * xnow rewrite <- Hq, <- Hq'.n:ZH:1 < nH':n < 3x, q:ZHq:2 = q * xq':ZHq':3 = q' * x1 = q' * x - q * xn:ZH:1 = nH':n < 3rel_prime n 3constructor; auto with zarith. Qed.n:ZH:1 = nH':n < 3rel_prime 1 3p:Zprime p -> 2 <= pintros (Hp,_); auto with zarith. Qed. Definition prime' p := 1<p /\ (forall n, 1<n<p -> ~ (n|p)).p:Zprime p -> 2 <= px:Z0 <= x -> x = 0 \/ x = 1 \/ 1 < xx:Z0 <= x -> x = 0 \/ x = 1 \/ 1 < xx:ZH:0 <= xx = 0 \/ x = 1 \/ 1 < xx:ZH:0 < xx = 0 \/ x = 1 \/ 1 < xx:ZH:Z.succ 0 <= xx = 0 \/ x = 1 \/ 1 < xZ.le_elim H; auto. Qed.x:ZH:1 <= xx = 0 \/ x = 1 \/ 1 < xp:Zprime' p <-> prime pp:Zprime' p <-> prime pp:ZHp:1 < pH:forall n : Z, 1 < n < p -> ~ (n | p)prime pp:ZHp:1 < pH:forall n : Z, 1 <= n < p -> rel_prime n pprime' pp:ZHp:1 < pH:forall n : Z, 1 < n < p -> ~ (n | p)prime pp:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < prel_prime n pp:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(x | n)Hxp:(x | p)(x | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(Z.abs x | n)Hxp:(Z.abs x | p)(Z.abs x | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(Z.abs x | n)Hxp:(Z.abs x | p)Hx:0 <= Z.abs x(Z.abs x | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(x | n)Hxp:(x | p)Hx:0 <= x(x | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < pHx:0 <= 0Hxp:(0 | p)Hxn:(0 | n)(0 | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < pHx:0 <= 1Hxp:(1 | p)Hxn:(1 | n)(1 | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(x | n)Hxp:(x | p)Hx:0 <= xHx':1 < x(x | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < pHx:0 <= 0Hxp:(0 | p)Hxn:(0 | n)(0 | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < pHx:0 <= 0Hxp:(0 | p)Hxn:(0 | n)Falseomega.p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < pHx:0 <= 0Hxp:(0 | p)Hxn:n = 0Falsenow exists 1.p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < pHx:0 <= 1Hxp:(1 | p)Hxn:(1 | n)(1 | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(x | n)Hxp:(x | p)Hx:0 <= xHx':1 < x(x | 1)p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(x | n)Hxp:(x | p)Hx:0 <= xHx':1 < x1 < x < pp:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(x | n)Hxp:(x | p)Hx:0 <= xHx':1 < xx < papply Z.divide_pos_le; auto with zarith.p:ZHp:1 < pH:forall n0 : Z, 1 < n0 < p -> ~ (n0 | p)n:ZHn:1 <= n < px:ZHxn:(x | n)Hxp:(x | p)Hx:0 <= xHx':1 < xx <= np:ZHp:1 < pH:forall n : Z, 1 <= n < p -> rel_prime n pprime' pp:ZHp:1 < pH:forall n : Z, 1 <= n < p -> rel_prime n pforall n : Z, 1 < n < p -> ~ (n | p)p:ZHp:1 < pH:forall n0 : Z, 1 <= n0 < p -> rel_prime n0 pn:ZHn:1 < n < pHnp:(n | p)Falsep:ZHp:1 < pH:forall n0 : Z, 1 <= n0 < p -> rel_prime n0 pn:ZHn:1 < n < pHnp:(n | p)Zis_gcd n p np:ZHp:1 < pH:forall n0 : Z, 1 <= n0 < p -> rel_prime n0 pn:ZHn:1 < n < pHnp:(n | p)Zis_gcd n p 1apply H; auto with zarith. Qed.p:ZHp:1 < pH:forall n0 : Z, 1 <= n0 < p -> rel_prime n0 pn:ZHn:1 < n < pHnp:(n | p)Zis_gcd n p 1forall a : Z, ~ prime (a * a)forall a : Z, ~ prime (a * a)a:ZHa:prime (a * a)Falsea:ZHa:prime (Z.abs a * Z.abs a)Falsea:ZHa:prime (Z.abs a * Z.abs a)H:0 <= Z.abs aFalsea:ZHa:prime (a * a)H:0 <= aFalsea:ZHa:1 < a * aHa':forall n : Z, 1 < n < a * a -> ~ (n | a * a)H:0 <= aFalsea:ZHa:1 < a * aHa':forall n : Z, 1 < n < a * a -> ~ (n | a * a)H:0 <= aH':1 < aFalsea:ZHa:1 < a * aHa':forall n : Z, 1 < n < a * a -> ~ (n | a * a)H:0 <= aH':1 < a1 < a < a * aa:ZHa:1 < a * aHa':forall n : Z, 1 < n < a * a -> ~ (n | a * a)H:0 <= aH':1 < a(a | a * a)a:ZHa:1 < a * aHa':forall n : Z, 1 < n < a * a -> ~ (n | a * a)H:0 <= aH':1 < a1 < a < a * aa:ZHa:1 < a * aHa':forall n : Z, 1 < n < a * a -> ~ (n | a * a)H:0 <= aH':1 < aa < a * aapply Z.mul_lt_mono_pos_r; omega.a:ZHa:1 < a * aHa':forall n : Z, 1 < n < a * a -> ~ (n | a * a)H:0 <= aH':1 < a1 * a < a * aexists a; auto. Qed.a:ZHa:1 < a * aHa':forall n : Z, 1 < n < a * a -> ~ (n | a * a)H:0 <= aH':1 < a(a | a * a)forall p q : Z, prime p -> prime q -> (p | q) -> p = qforall p q : Z, prime p -> prime q -> (p | q) -> p = qp, q:ZH:prime pH1:prime qH2:(p | q)Hp:0 < pp = qp, q:ZH:prime pH1:prime qH2:(p | q)Hp:0 < pHq:0 < qp = qp, q:ZH:prime pH1:prime qH2:(p | q)Hp:0 < pHq:0 < qp = -1 -> p = qp, q:ZH:prime pH1:prime qH2:(p | q)Hp:0 < pHq:0 < qp = 1 \/ p = q \/ p = - q -> p = qp, q:ZH:prime pH1:prime qH2:(p | q)Hp:0 < pHq:0 < qp = 1 \/ p = q \/ p = - q -> p = qq:ZH:prime 1H1:prime qHp:0 < 1H2:(1 | q)Hq:0 < q1 = qq:ZH:prime (- q)H1:prime qHp:0 < - qH2:(- q | q)Hq:0 < q- q = qcontradict Hp; auto with zarith. Qed.q:ZH:prime (- q)H1:prime qHp:0 < - qH2:(- q | q)Hq:0 < q- q = q
we now prove that Z.gcd is indeed a gcd in
the sense of Zis_gcd.
Notation Zgcd_is_pos := Z.gcd_nonneg (only parsing).forall a b : Z, Zis_gcd a b (Z.gcd a b)forall a b : Z, Zis_gcd a b (Z.gcd a b)a, b:Z(Z.gcd a b | a)a, b:Z(Z.gcd a b | b)a, b:Zforall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)a, b:Z(Z.gcd a b | b)a, b:Zforall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)apply Z.gcd_greatest. Qed.a, b:Zforall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)forall x y : Z, {z : Z | Zis_gcd x y z /\ 0 <= z}forall x y : Z, {z : Z | Zis_gcd x y z /\ 0 <= z}split; [apply Zgcd_is_gcd | apply Z.gcd_nonneg]. Qed.x, y:ZZis_gcd x y (Z.gcd x y) /\ 0 <= Z.gcd x yforall p q r : Z, (p | q) -> (p | r) -> (p | Z.gcd q r)forall p q r : Z, (p | q) -> (p | r) -> (p | Z.gcd q r)now apply Z.gcd_greatest. Qed.p, q, r:ZH:(p | q)H0:(p | r)(p | Z.gcd q r)forall a b c : Z, 0 <= c -> Zis_gcd a b c -> Z.gcd a b = cforall a b c : Z, 0 <= c -> Zis_gcd a b c -> Z.gcd a b = ca, b, c:ZH1:0 <= cH2:Zis_gcd a b cZ.gcd a b = ca, b, c:ZH1:0 <= cH2:Zis_gcd a b cZis_gcd a b (Z.gcd a b)a, b, c:ZH1:0 <= cH2:Zis_gcd a b cc = - Z.gcd a b -> Z.gcd a b = ca, b, c:ZH1:0 <= cH2:Zis_gcd a b cc = - Z.gcd a b -> Z.gcd a b = ca, b, c:ZH1:0 < cH2:Zis_gcd a b cc = - Z.gcd a b -> Z.gcd a b = ca, b, c:ZH1:0 = cH2:Zis_gcd a b cc = - Z.gcd a b -> Z.gcd a b = cgeneralize (Z.gcd_nonneg a b); auto with zarith.a, b, c:ZH1:0 < cH2:Zis_gcd a b cc = - Z.gcd a b -> Z.gcd a b = ca, b, c:ZH1:0 = cH2:Zis_gcd a b cc = - Z.gcd a b -> Z.gcd a b = cnow case (Z.gcd a b). Qed. Notation Zgcd_inv_0_l := Z.gcd_eq_0_l (only parsing). Notation Zgcd_inv_0_r := Z.gcd_eq_0_r (only parsing).a, b:ZH2:Zis_gcd a b 00 = - Z.gcd a b -> Z.gcd a b = 0forall a b : Z, 0 < Z.gcd a b -> 0 < b -> a / Z.gcd a b * b = a * (b / Z.gcd a b)forall a b : Z, 0 < Z.gcd a b -> 0 < b -> a / Z.gcd a b * b = a * (b / Z.gcd a b)a, b:ZHg:0 < Z.gcd a bHb:0 < ba / Z.gcd a b * b = a * (b / Z.gcd a b)a, b:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)a / Z.gcd a b * b = a * (b / Z.gcd a b)a, b:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)a / Z.gcd a b * (Z.gcd a b * (b / Z.gcd a b)) = a * (b / Z.gcd a b)a, b:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)a / Z.gcd a b * Z.gcd a b = arewrite <- Zdivide_Zdiv_eq; auto. Qed.a, b:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)Z.gcd a b * (a / Z.gcd a b) = aforall a b c : Z, 0 < Z.gcd a b -> 0 < b -> c * a / Z.gcd a b * b = c * a * (b / Z.gcd a b)forall a b c : Z, 0 < Z.gcd a b -> 0 < b -> c * a / Z.gcd a b * b = c * a * (b / Z.gcd a b)a, b, c:ZHg:0 < Z.gcd a bHb:0 < bc * a / Z.gcd a b * b = c * a * (b / Z.gcd a b)a, b, c:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)c * a / Z.gcd a b * b = c * a * (b / Z.gcd a b)a, b, c:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)c * a / Z.gcd a b * (Z.gcd a b * (b / Z.gcd a b)) = c * a * (b / Z.gcd a b)a, b, c:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)c * a / Z.gcd a b * Z.gcd a b = c * aa, b, c:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)c * (a / Z.gcd a b) * Z.gcd a b = c * aa, b, c:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)a / Z.gcd a b * Z.gcd a b = arewrite <- Zdivide_Zdiv_eq; auto. Qed.a, b, c:ZHg:0 < Z.gcd a bHb:0 < bF:Zis_gcd a b (Z.gcd a b)F1:(Z.gcd a b | a)F2:(Z.gcd a b | b)F3:forall x : Z, (x | a) -> (x | b) -> (x | Z.gcd a b)Z.gcd a b * (a / Z.gcd a b) = aa, b, c:ZZ.gcd (Z.gcd a b) c = Z.gcd a (Z.gcd b c)a, b, c:ZZ.gcd (Z.gcd a b) c = Z.gcd a (Z.gcd b c)apply Z.gcd_assoc. Qed. Notation Zgcd_Zabs := Z.gcd_abs_l (only parsing). Notation Zgcd_0 := Z.gcd_0_r (only parsing). Notation Zgcd_1 := Z.gcd_1_r (only parsing). Hint Resolve Z.gcd_0_r Z.gcd_1_r : zarith.a, b, c:ZZ.gcd a (Z.gcd b c) = Z.gcd (Z.gcd a b) cforall a b : Z, Z.gcd a b = 1 <-> rel_prime a bforall a b : Z, Z.gcd a b = 1 <-> rel_prime a ba, b:ZH:Z.gcd a b = 1Zis_gcd a b 1a, b:ZH:Zis_gcd a b 1Z.gcd a b = 1a, b:ZH:Zis_gcd a b 1Z.gcd a b = 1a, b:ZH:Zis_gcd a b 1Zis_gcd a b (Z.gcd a b)a, b:ZH:Zis_gcd a b 1Z.gcd a b = - (1) -> Z.gcd a b = 1a, b:ZH:Zis_gcd a b 1Z.gcd a b = - (1) -> Z.gcd a b = 1generalize (Z.gcd_nonneg a b); auto with zarith. Qed.a, b:ZH:Zis_gcd a b 1H2:Z.gcd a b = - (1)0 <= Z.gcd a bforall a b : Z, {rel_prime a b} + {~ rel_prime a b}forall a b : Z, {rel_prime a b} + {~ rel_prime a b}a, b:ZH1:Z.gcd a b = 1{rel_prime a b} + {~ rel_prime a b}a, b:ZH1:Z.gcd a b <> 1{rel_prime a b} + {~ rel_prime a b}right; contradict H1; apply <- Zgcd_1_rel_prime; auto. Defined.a, b:ZH1:Z.gcd a b <> 1{rel_prime a b} + {~ rel_prime a b}forall p m : Z, {forall n : Z, 1 < n < m -> rel_prime n p} + {exists n : Z, 1 < n < m /\ ~ rel_prime n p}forall p m : Z, {forall n : Z, 1 < n < m -> rel_prime n p} + {exists n : Z, 1 < n < m /\ ~ rel_prime n p}p, m:Z{forall n : Z, 1 < n < m -> rel_prime n p} + {exists n : Z, 1 < n < m /\ ~ rel_prime n p}p, m:ZH1:1 < m{forall n : Z, 1 < n < m -> rel_prime n p} + {exists n : Z, 1 < n < m /\ ~ rel_prime n p}p, m:ZH1:1 < m{forall n : Z, 1 < n < 0 -> rel_prime n p} + {exists n : Z, 1 < n < 0 /\ ~ rel_prime n p}p, m:ZH1:1 < mforall x : Z, 0 <= x -> {forall n : Z, 1 < n < x -> rel_prime n p} + {exists n : Z, 1 < n < x /\ ~ rel_prime n p} -> {forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mforall x : Z, 0 <= x -> {forall n : Z, 1 < n < x -> rel_prime n p} + {exists n : Z, 1 < n < x /\ ~ rel_prime n p} -> {forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xE:exists n : Z, 1 < n < x /\ ~ rel_prime n p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pY:rel_prime x p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xE:exists n : Z, 1 < n < x /\ ~ rel_prime n p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n0 : Z, 1 < n0 < x -> rel_prime n0 pY:rel_prime x pn:ZHH1:1 < nHH2:n < Z.succ xrel_prime n pp, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xE:exists n : Z, 1 < n < x /\ ~ rel_prime n p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n0 : Z, 1 < n0 < x -> rel_prime n0 pY:rel_prime x pn:ZHH1:1 < nHH2:n <= xrel_prime n pp, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xE:exists n : Z, 1 < n < x /\ ~ rel_prime n p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xE:exists n : Z, 1 < n < x /\ ~ rel_prime n p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x pHH1:1 < x{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x pHH1:~ 1 < x{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}right; exists x; split; auto with zarith.p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x pHH1:1 < x{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}left; intros n [HHH1 HHH2]; contradict HHH1; auto with zarith.p, m:ZH1:1 < mx:ZHx:0 <= xF:forall n : Z, 1 < n < x -> rel_prime n pN:~ rel_prime x pHH1:~ 1 < x{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}right; destruct E as (n,((H0,H2),H3)); exists n; auto with zarith. Defined.p, m:ZH1:1 < mx:ZHx:0 <= xE:exists n : Z, 1 < n < x /\ ~ rel_prime n p{forall n : Z, 1 < n < Z.succ x -> rel_prime n p} + {exists n : Z, 1 < n < Z.succ x /\ ~ rel_prime n p}forall p : Z, {prime p} + {~ prime p}forall p : Z, {prime p} + {~ prime p}p:ZH1:1 < p{prime p} + {~ prime p}p:ZH1:~ 1 < p{prime p} + {~ prime p}p:ZH1:1 < p{prime p} + {~ prime p}p:ZH1:1 < pH2:forall n : Z, 1 < n < p -> rel_prime n p{prime p} + {~ prime p}p:ZH1:1 < pH2:exists n : Z, 1 < n < p /\ ~ rel_prime n p{prime p} + {~ prime p}p:ZH1:1 < pH2:forall n : Z, 1 < n < p -> rel_prime n p{prime p} + {~ prime p}p:ZH1:1 < pH2:forall n : Z, 1 < n < p -> rel_prime n pforall n : Z, 1 <= n < p -> rel_prime n pp:ZH1:1 < pH2:forall n0 : Z, 1 < n0 < p -> rel_prime n0 pn:ZHn1:1 <= nHn2:n < prel_prime n pconstructor; auto with zarith.p:ZH1:1 < pH2:forall n : Z, 1 < n < p -> rel_prime n pHn2:1 < prel_prime 1 pp:ZH1:1 < pH2:exists n : Z, 1 < n < p /\ ~ rel_prime n p{prime p} + {~ prime p}case H2; intros n [Hn1 Hn2]; case Hn2; auto with zarith.p:ZH1:1 < pH2:exists n : Z, 1 < n < p /\ ~ rel_prime n pHp1:1 < pHp2:forall n : Z, 1 <= n < p -> rel_prime n pFalseright; intros H3; inversion_clear H3 as [Hp1 Hp2]; case H1; auto. Defined.p:ZH1:~ 1 < p{prime p} + {~ prime p}forall p : Z, 1 < p -> ~ prime p -> exists n : Z, 1 < n < p /\ (n | p)forall p : Z, 1 < p -> ~ prime p -> exists n : Z, 1 < n < p /\ (n | p)p:ZHp:1 < pHp1:~ prime pexists n : Z, 1 < n < p /\ (n | p)p:ZHp:1 < pHp1:~ prime pH1:forall n : Z, 1 < n < p -> rel_prime n pexists n : Z, 1 < n < p /\ (n | p)p:ZHp:1 < pHp1:~ prime pH1:exists n : Z, 1 < n < p /\ ~ rel_prime n pexists n : Z, 1 < n < p /\ (n | p)p:ZHp:1 < pHp1:~ prime pH1:forall n : Z, 1 < n < p -> rel_prime n pexists n : Z, 1 < n < p /\ (n | p)p:ZHp:1 < pHp1:~ prime pH1:forall n : Z, 1 < n < p -> rel_prime n pforall n : Z, 1 <= n < p -> rel_prime n pp:ZHp:1 < pHp1:~ prime pH1:forall n0 : Z, 1 < n0 < p -> rel_prime n0 pn:ZHn1:1 <= nHn2:n < prel_prime n psubst n; constructor; auto with zarith.p:ZHp:1 < pHp1:~ prime pH1:forall n0 : Z, 1 < n0 < p -> rel_prime n0 pn:ZHn1:1 = nHn2:n < prel_prime n pp:ZHp:1 < pHp1:~ prime pH1:exists n : Z, 1 < n < p /\ ~ rel_prime n pexists n : Z, 1 < n < p /\ (n | p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pexists n0 : Z, 1 < n0 < p /\ (n0 | p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:Z.gcd n p = 0exists n0 : Z, 1 < n0 < p /\ (n0 | p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:Z.gcd n p = 1exists n0 : Z, 1 < n0 < p /\ (n0 | p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:1 < Z.gcd n pexists n0 : Z, 1 < n0 < p /\ (n0 | p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:Z.gcd n p = 0exists n0 : Z, 1 < n0 < p /\ (n0 | p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:Z.gcd n p = 0Falseomega.p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:n = 0Falsep:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:Z.gcd n p = 1exists n0 : Z, 1 < n0 < p /\ (n0 | p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:Z.gcd n p = 1rel_prime n pp:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:Z.gcd n p = 1Zis_gcd n p 1apply Zgcd_is_gcd.p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:Z.gcd n p = 1Zis_gcd n p (Z.gcd n p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:1 < Z.gcd n pexists n0 : Z, 1 < n0 < p /\ (n0 | p)p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:1 < Z.gcd n pZ.gcd n p < pp:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:1 < Z.gcd n pZ.gcd n p <= napply Z.gcd_divide_l. Qed.p:ZHp:1 < pHp1:~ prime pH1:exists n0 : Z, 1 < n0 < p /\ ~ rel_prime n0 pn:ZHn1:1 < n < pHn2:~ rel_prime n pH:1 < Z.gcd n p(Z.gcd n p | n)