Library Stdlib.ZArith.Znumtheory
For compatibility reasons, this Open Scope isn't local as it should
Open Scope Z_scope.
Local Ltac Tauto.intuition_solver ::= auto with zarith.
This file contains some notions of number theory upon Z numbers:
- a divisibility predicate Z.divide
- a gcd predicate gcd
- Euclid algorithm extgcd
- 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.
Results concerning divisibility
#[
deprecated(
use=
Z.divide_1_l,
since="9.1")]
Notation Zone_divide :=
Z.divide_1_l (
only parsing).
#[
deprecated(
use=
Z.divide_0_r,
since="9.1")]
Notation Zdivide_0 :=
Z.divide_0_r (
only parsing).
#[
deprecated(
use=
Z.mul_divide_mono_l,
since="9.1")]
Notation Zmult_divide_compat_l :=
Z.mul_divide_mono_l (
only parsing).
#[
deprecated(
use=
Z.mul_divide_mono_r,
since="9.1")]
Notation Zmult_divide_compat_r :=
Z.mul_divide_mono_r (
only parsing).
#[
deprecated(
use=
Z.divide_add_r,
since="9.1")]
Notation Zdivide_plus_r :=
Z.divide_add_r (
only parsing).
#[
deprecated(
use=
Z.divide_sub_r,
since="9.1")]
Notation Zdivide_minus_l :=
Z.divide_sub_r (
only parsing).
#[
deprecated(
use=
Z.divide_mul_l,
since="9.1")]
Notation Zdivide_mult_l :=
Z.divide_mul_l (
only parsing).
#[
deprecated(
use=
Z.divide_mul_r,
since="9.1")]
Notation Zdivide_mult_r :=
Z.divide_mul_r (
only parsing).
#[
deprecated(
use=
Z.divide_factor_l,
since="9.1")]
Notation Zdivide_factor_r :=
Z.divide_factor_l (
only parsing).
#[
deprecated(
use=
Z.divide_factor_r,
since="9.1")]
Notation Zdivide_factor_l :=
Z.divide_factor_r (
only parsing).
#[
deprecated(
use=
Z.divide_opp_r,
since="9.1")]
Lemma Zdivide_opp_r a b :
(a | b) -> (a | - b).
#[
deprecated(
use=
Z.divide_opp_r,
since="9.1")]
Lemma Zdivide_opp_r_rev a b :
(a | - b) -> (a | b).
#[
deprecated(
use=
Z.divide_opp_l,
since="9.1")]
Lemma Zdivide_opp_l a b :
(a | b) -> (- a | b).
#[
deprecated(
use=
Z.divide_opp_l,
since="9.1")]
Lemma Zdivide_opp_l_rev a b :
(- a | b) -> (a | b).
#[
deprecated(
use=
Z.divide_abs_l,
since="9.1")]
Theorem Zdivide_Zabs_l a b :
(Z.abs a | b) -> (a | b).
#[
deprecated(
use=
Z.divide_abs_l,
since="9.1")]
Theorem Zdivide_Zabs_inv_l a b :
(a | b) -> (Z.abs a | b).
#[
global]
Hint Resolve Z.divide_refl Z.divide_1_l Z.divide_0_r:
zarith.
#[
global]
Hint Resolve Z.mul_divide_mono_l Z.mul_divide_mono_r:
zarith.
#[
global]
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.
Auxiliary result.
Only 1 and -1 divide 1.
If a divides b and b<>0 then |a| <= |b|.
Z.divide can be expressed using Z.modulo.
Z.divide is hence decidable
Greatest common divisor (gcd).
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.)
Trivial properties of gcd
Lemma Zis_gcd_sym :
forall a b d,
Zis_gcd a b d -> Zis_gcd b a d.
Lemma Zis_gcd_0 :
forall a,
Zis_gcd a 0
a.
#[
deprecated(
use=
Z.gcd_1_r,
since="9.1")]
Lemma Zis_gcd_1 :
forall a,
Zis_gcd a 1 1.
#[
deprecated(
use=
Z.gcd_diag,
since="9.1")]
Lemma Zis_gcd_refl :
forall a,
Zis_gcd a a a.
Lemma Zis_gcd_minus :
forall a b d,
Zis_gcd a (
- b)
d -> Zis_gcd b a d.
#[
deprecated(
note="Z.cd is always non-negative",
since="9.1")]
Lemma Zis_gcd_opp :
forall a b d,
Zis_gcd a b d -> Zis_gcd b a (
- d).
Lemma Zis_gcd_0_abs a :
Zis_gcd 0
a (
Z.abs a).
#[
global]
Hint Resolve Zis_gcd_sym Zis_gcd_0 Zis_gcd_minus Zis_gcd_opp:
zarith.
#[
deprecated(
use=
f_equal,
note="Use Z.gcd",
since="9.1")]
Theorem Zis_gcd_unique:
forall a b c d :
Z,
Zis_gcd a b c -> Zis_gcd a b d -> c = d \/ c = (- d).
Extended Euclid algorithm.
Lemma deprecated_Zis_gcd_for_euclid :
forall a b d q:
Z,
Zis_gcd b (
a - q * b)
d -> Zis_gcd a b d.
#[
deprecated(
since="8.17")]
Notation Zis_gcd_for_euclid :=
deprecated_Zis_gcd_for_euclid (
only parsing).
#[
deprecated(
since="9.1")]
Lemma Zis_gcd_for_euclid2 :
forall b d q r:
Z,
Zis_gcd r b d -> Zis_gcd b (
b * q + r)
d.
#[
deprecated(
use=
Z.extgcd,
since="9.1")]
Notation extgcd :=
Z.extgcd (
only parsing).
#[
deprecated(
use=
Z.extgcd_correct,
since="9.1")]
Notation extgcd_correct :=
Z.extgcd_correct (
only parsing).
Section extended_euclid_algorithm.
Variables a b :
Z.
Inductive deprecated_Euclid :
Set :=
deprecated_Euclid_intro :
forall u v d:
Z,
u * a + v * b = d -> Zis_gcd a b d -> deprecated_Euclid.
Lemma deprecated_euclid :
deprecated_Euclid.
Lemma deprecated_euclid_rec :
forall 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) -> deprecated_Euclid.
End extended_euclid_algorithm.
#[
deprecated(
since="8.17",
note="Use Coq.ZArith.Znumtheory.extgcd")]
Notation Euclid :=
deprecated_Euclid (
only parsing).
#[
deprecated(
since="8.17",
note="Use Coq.ZArith.Znumtheory.extgcd")]
Notation Euclid_intro :=
deprecated_Euclid_intro (
only parsing).
#[
deprecated(
since="8.17",
note="Use Coq.ZArith.Znumtheory.extgcd")]
Notation euclid :=
deprecated_euclid (
only parsing).
#[
deprecated(
since="8.17",
note="Use Coq.ZArith.Znumtheory.extgcd")]
Notation euclid_rec :=
deprecated_euclid_rec (
only parsing).
#[
deprecated(
use=
Z.gcd_unique,
since="9.1")]
Theorem Zis_gcd_uniqueness_apart_sign :
forall a b d d':
Z,
Zis_gcd a b d -> Zis_gcd a b d' -> d = d' \/ d = - d'.
Existence of Bezout's coefficients for the gcd of a and b
gcd of ca and cb is c gcd(a,b).
Bezout's theorem: a and b are relatively prime if and
only if there exist u and v such that ua+vb = 1.
Gauss's theorem: if a divides bc and if a and b are
relatively prime, then a divides c.
If a is relatively prime to b and c, then it is to bc
After factorization by a gcd, the original numbers are relatively prime.
#[
deprecated(
use=
Z.gcd_div_gcd,
since="9.1")]
Lemma Zis_gcd_rel_prime :
forall a b g:
Z,
b > 0
-> g >= 0
-> Zis_gcd a b g -> rel_prime (
a / g) (
b / g).
#[
deprecated(
use=
Z.Symmetric_coprime,
since="9.1")]
Theorem rel_prime_sym:
forall a b,
rel_prime a b -> rel_prime b a.
Theorem rel_prime_div:
forall p q r,
rel_prime p q -> (r | p) -> rel_prime r q.
#[
deprecated(
use=
Z.coprime_1_l,
since="9.1")]
Theorem rel_prime_1:
forall n,
rel_prime 1
n.
#[
deprecated(
use=
Z.coprime_0_l_iff,
since="9.1")]
Theorem not_rel_prime_0:
forall n, 1
< n -> ~ rel_prime 0
n.
#[
deprecated(
use=
Z.coprime_mod_l_iff,
since="9.1")]
Theorem rel_prime_mod:
forall p q, 0
< q ->
rel_prime p q -> rel_prime (
p mod q)
q.
#[
deprecated(
use=
Z.coprime_mod_l_iff,
since="9.1")]
Theorem rel_prime_mod_rev:
forall p q, 0
< q ->
rel_prime (
p mod q)
q -> rel_prime p q.
#[
deprecated(
note="unfold Z.coprime",
since="9.1")]
Theorem Zrel_prime_neq_mod_0:
forall a b, 1
< b -> rel_prime a b -> a mod b <> 0.
Primality
Note: prefer Z.prime
The sole divisors of a prime number p are -1, 1, p and -p.
A prime number is relatively prime with any number it does not divide
As a consequence, a prime number is relatively prime with smaller numbers
If a prime p divides ab then it divides either a or b
#[
deprecated(
use=
Z.divide_prime_mul,
since="9.1")]
Lemma prime_mult :
forall p:
Z,
prime p -> forall a b:
Z,
(p | a * b) -> (p | a) \/ (p | b).
#[
deprecated(
use=
Z.not_prime_0,
since="9.1")]
Lemma not_prime_0:
~ prime 0.
#[
deprecated(
use=
Z.not_prime_1,
since="9.1")]
Lemma not_prime_1:
~ prime 1.
#[
deprecated(
use=
Z.prime_2,
since="9.1")]
Lemma prime_2:
prime 2.
#[
deprecated(
use=
Z.prime_3,
since="9.1")]
Theorem prime_3:
prime 3.
#[
deprecated(
use=
Z.prime_ge_2,
since="9.1")]
Theorem prime_ge_2 p :
prime p -> 2
<= p.
#[
deprecated(
use=
Z.prime,
since="9.1")]
Notation prime' :=
Z.prime (
only parsing).
#[
deprecated(
use=
Z.not_prime_square,
since="9.1")]
Theorem square_not_prime:
forall a,
~ prime (
a * a).
#[
deprecated(
use=
Z.divide_prime_prime,
since="9.1")]
Theorem prime_div_prime:
forall p q,
prime p -> prime q -> (p | q) -> p = q.
#[
deprecated(
use=
Z.gcd_nonneg ,
since="9.1")]
Notation Zgcd_is_pos :=
Z.gcd_nonneg (
only parsing).
#[
deprecated(
since="9.1")]
Theorem Zgcd_spec :
forall x y :
Z,
{z : Z | Zis_gcd x y z /\ 0
<= z}.
#[
deprecated(
use=
Z.gcd_greatest,
since="9.1")]
Theorem Zdivide_Zgcd:
forall p q r :
Z,
(p | q) -> (p | r) -> (p | Z.gcd q r).
#[
deprecated(
use=
Z.gcd,
since="9.1")]
Theorem Zis_gcd_gcd:
forall a b c :
Z,
0
<= c -> Zis_gcd a b c -> Z.gcd a b = c.
#[
deprecated(
use=
Z.gcd_eq_0_l ,
since="9.1")]
Notation Zgcd_inv_0_l :=
Z.gcd_eq_0_l (
only parsing).
#[
deprecated(
use=
Z.gcd_eq_0_r ,
since="9.1")]
Notation Zgcd_inv_0_r :=
Z.gcd_eq_0_r (
only parsing).
#[
deprecated(
use=
Z.gcd_div_swap,
since="9.1")]
Theorem Zgcd_div_swap0 :
forall a b :
Z,
0
< Z.gcd a b ->
0
< b ->
(a / Z.gcd a b) * b = a * (b/Z.gcd a b).
#[
deprecated(
use=
Z.gcd_div_swap,
since="9.1")]
Theorem Zgcd_div_swap :
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).
#[
deprecated(
use=
Z.gcd_assoc,
since="9.1")]
Lemma Zgcd_ass a b c :
Z.gcd (
Z.gcd a b)
c = Z.gcd a (
Z.gcd b c).
#[
deprecated(
use=
Z.gcd_abs_l,
since="9.1")]
Notation Zgcd_Zabs :=
Z.gcd_abs_l (
only parsing).
#[
deprecated(
use=
Z.gcd_0_r,
since="9.1")]
Notation Zgcd_0 :=
Z.gcd_0_r (
only parsing).
#[
deprecated(
use=
Z.gcd_1_r,
since="9.1")]
Notation Zgcd_1 :=
Z.gcd_1_r (
only parsing).
#[
global]
Hint Resolve Z.gcd_0_r Z.gcd_1_r :
zarith.
#[
deprecated(
note="Use Z.gcd_greatest, Z.gcd_divide_l, or Z.gcd_divide_r",
since="9.1")]
Theorem Zgcd_1_rel_prime :
forall a b,
Z.gcd a b = 1
<-> rel_prime a b.
#[
deprecated(
use=
Z.BoolSpec_coprime,
since="9.1")]
Definition rel_prime_dec:
forall a b,
{ rel_prime a b }+{ ~ rel_prime a b }.
#[
deprecated(
since="9.1")]
Definition prime_dec_aux:
forall p m,
{ forall n, 1
< n < m -> rel_prime n p } +
{ exists n, 1
< n < m /\ ~ rel_prime n p }.
Definition prime_dec:
forall p,
{ prime p }+{ ~ prime p }.
Theorem not_prime_divide:
forall p, 1
< p -> ~ prime p -> exists n, 1
< n < p /\ (n | p).