Module docstring
{"# Prime numbers
This file deals with the factors of natural numbers.
Important declarations
Nat.factors n: the prime factorization ofnNat.factors_unique: uniqueness of the prime factorisation
"}
{"# Prime numbers
This file deals with the factors of natural numbers.
Nat.factors n: the prime factorization of nNat.factors_unique: uniqueness of the prime factorisation"}
Nat.primeFactorsList
definition
: ℕ → List ℕ
/-- `primeFactorsList n` is the prime factorization of `n`, listed in increasing order. -/
def primeFactorsList : ℕ → List ℕ
| 0 => []
| 1 => []
| k + 2 =>
let m := minFac (k + 2)
m :: primeFactorsList ((k + 2) / m)
decreasing_by exact factors_lemma
Nat.primeFactorsList_zero
theorem
: primeFactorsList 0 = []
@[simp]
theorem primeFactorsList_zero : primeFactorsList 0 = [] := by rw [primeFactorsList]
Nat.primeFactorsList_one
theorem
: primeFactorsList 1 = []
@[simp]
theorem primeFactorsList_one : primeFactorsList 1 = [] := by rw [primeFactorsList]
Nat.primeFactorsList_two
theorem
: primeFactorsList 2 = [2]
@[simp]
theorem primeFactorsList_two : primeFactorsList 2 = [2] := by simp [primeFactorsList]
Nat.prime_of_mem_primeFactorsList
theorem
{n : ℕ} : ∀ {p : ℕ}, p ∈ primeFactorsList n → Prime p
theorem prime_of_mem_primeFactorsList {n : ℕ} : ∀ {p : ℕ}, p ∈ primeFactorsList n → Prime p := by
match n with
| 0 => simp
| 1 => simp
| k + 2 =>
intro p h
let m := minFac (k + 2)
have : (k + 2) / m < (k + 2) := factors_lemma
have h₁ : p = m ∨ p ∈ primeFactorsList ((k + 2) / m) :=
List.mem_cons.1 (by rwa [primeFactorsList] at h)
exact Or.casesOn h₁ (fun h₂ => h₂.symm ▸ minFac_prime (by simp)) prime_of_mem_primeFactorsList
Nat.pos_of_mem_primeFactorsList
theorem
{n p : ℕ} (h : p ∈ primeFactorsList n) : 0 < p
theorem pos_of_mem_primeFactorsList {n p : ℕ} (h : p ∈ primeFactorsList n) : 0 < p :=
Prime.pos (prime_of_mem_primeFactorsList h)
Nat.prod_primeFactorsList
theorem
: ∀ {n}, n ≠ 0 → List.prod (primeFactorsList n) = n
theorem prod_primeFactorsList : ∀ {n}, n ≠ 0 → List.prod (primeFactorsList n) = n
| 0 => by simp
| 1 => by simp
| k + 2 => fun _ =>
let m := minFac (k + 2)
have : (k + 2) / m < (k + 2) := factors_lemma
show (primeFactorsList (k + 2)).prod = (k + 2) by
have h₁ : (k + 2) / m ≠ 0 := fun h => by
have : (k + 2) = 0 * m := (Nat.div_eq_iff_eq_mul_left (minFac_pos _) (minFac_dvd _)).1 h
rw [zero_mul] at this; exact (show k + 2 ≠ 0 by simp) this
rw [primeFactorsList, List.prod_cons, prod_primeFactorsList h₁,
Nat.mul_div_cancel' (minFac_dvd _)]
Nat.primeFactorsList_prime
theorem
{p : ℕ} (hp : Nat.Prime p) : p.primeFactorsList = [p]
theorem primeFactorsList_prime {p : ℕ} (hp : Nat.Prime p) : p.primeFactorsList = [p] := by
have : p = p - 2 + 2 := Nat.eq_add_of_sub_eq hp.two_le rfl
rw [this, primeFactorsList]
simp only [Eq.symm this]
have : Nat.minFac p = p := (Nat.prime_def_minFac.mp hp).2
simp only [this, primeFactorsList, Nat.div_self (Nat.Prime.pos hp)]
Nat.primeFactorsList_chain
theorem
{n : ℕ} : ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (primeFactorsList n)
theorem primeFactorsList_chain {n : ℕ} :
∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (primeFactorsList n) := by
match n with
| 0 => simp
| 1 => simp
| k + 2 =>
intro a h
let m := minFac (k + 2)
have : (k + 2) / m < (k + 2) := factors_lemma
rw [primeFactorsList]
refine List.Chain.cons ((le_minFac.2 h).resolve_left (by simp)) (primeFactorsList_chain ?_)
exact fun p pp d => minFac_le_of_dvd pp.two_le (d.trans <| div_dvd_of_dvd <| minFac_dvd _)
Nat.primeFactorsList_chain_2
theorem
(n) : List.Chain (· ≤ ·) 2 (primeFactorsList n)
theorem primeFactorsList_chain_2 (n) : List.Chain (· ≤ ·) 2 (primeFactorsList n) :=
primeFactorsList_chain fun _ pp _ => pp.two_le
Nat.primeFactorsList_chain'
theorem
(n) : List.Chain' (· ≤ ·) (primeFactorsList n)
theorem primeFactorsList_chain' (n) : List.Chain' (· ≤ ·) (primeFactorsList n) :=
@List.Chain'.tail _ _ (_ :: _) (primeFactorsList_chain_2 _)
Nat.primeFactorsList_sorted
theorem
(n : ℕ) : List.Sorted (· ≤ ·) (primeFactorsList n)
theorem primeFactorsList_sorted (n : ℕ) : List.Sorted (· ≤ ·) (primeFactorsList n) :=
List.chain'_iff_pairwise.1 (primeFactorsList_chain' _)
Nat.primeFactorsList_add_two
theorem
(n : ℕ) : primeFactorsList (n + 2) = minFac (n + 2) :: primeFactorsList ((n + 2) / minFac (n + 2))
/-- `primeFactorsList` can be constructed inductively by extracting `minFac`, for sufficiently
large `n`. -/
theorem primeFactorsList_add_two (n : ℕ) :
primeFactorsList (n + 2) = minFacminFac (n + 2) :: primeFactorsList ((n + 2) / minFac (n + 2)) := by
rw [primeFactorsList]
Nat.primeFactorsList_eq_nil
theorem
(n : ℕ) : n.primeFactorsList = [] ↔ n = 0 ∨ n = 1
@[simp]
theorem primeFactorsList_eq_nil (n : ℕ) : n.primeFactorsList = [] ↔ n = 0 ∨ n = 1 := by
constructor <;> intro h
· rcases n with (_ | _ | n)
· exact Or.inl rfl
· exact Or.inr rfl
· rw [primeFactorsList] at h
injection h
· rcases h with (rfl | rfl)
· exact primeFactorsList_zero
· exact primeFactorsList_one
Nat.mem_primeFactorsList_iff_dvd
theorem
{n p : ℕ} (hn : n ≠ 0) (hp : Prime p) : p ∈ primeFactorsList n ↔ p ∣ n
theorem mem_primeFactorsList_iff_dvd {n p : ℕ} (hn : n ≠ 0) (hp : Prime p) :
p ∈ primeFactorsList np ∈ primeFactorsList n ↔ p ∣ n where
mp h := prod_primeFactorsList hn ▸ List.dvd_prod h
mpr h := mem_list_primes_of_dvd_prod (prime_iff.mp hp)
(fun _ h ↦ prime_iff.mp (prime_of_mem_primeFactorsList h)) ((prod_primeFactorsList hn).symm ▸ h)
Nat.dvd_of_mem_primeFactorsList
theorem
{n p : ℕ} (h : p ∈ n.primeFactorsList) : p ∣ n
theorem dvd_of_mem_primeFactorsList {n p : ℕ} (h : p ∈ n.primeFactorsList) : p ∣ n := by
rcases n.eq_zero_or_pos with (rfl | hn)
· exact dvd_zero p
· rwa [← mem_primeFactorsList_iff_dvd hn.ne' (prime_of_mem_primeFactorsList h)]
Nat.mem_primeFactorsList
theorem
{n p} (hn : n ≠ 0) : p ∈ primeFactorsList n ↔ Prime p ∧ p ∣ n
Nat.mem_primeFactorsList'
theorem
{n p} : p ∈ n.primeFactorsList ↔ p.Prime ∧ p ∣ n ∧ n ≠ 0
@[simp] lemma mem_primeFactorsList' {n p} : p ∈ n.primeFactorsListp ∈ n.primeFactorsList ↔ p.Prime ∧ p ∣ n ∧ n ≠ 0 := by
cases n <;> simp [mem_primeFactorsList, *]
Nat.le_of_mem_primeFactorsList
theorem
{n p : ℕ} (h : p ∈ n.primeFactorsList) : p ≤ n
theorem le_of_mem_primeFactorsList {n p : ℕ} (h : p ∈ n.primeFactorsList) : p ≤ n := by
rcases n.eq_zero_or_pos with (rfl | hn)
· rw [primeFactorsList_zero] at h
cases h
· exact le_of_dvd hn (dvd_of_mem_primeFactorsList h)
Nat.primeFactorsList_unique
theorem
{n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) : l ~ primeFactorsList n
/-- **Fundamental theorem of arithmetic** -/
theorem primeFactorsList_unique {n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) :
l ~ primeFactorsList n := by
refine perm_of_prod_eq_prod ?_ ?_ ?_
· rw [h₁]
refine (prod_primeFactorsList ?_).symm
rintro rfl
rw [prod_eq_zero_iff] at h₁
exact Prime.ne_zero (h₂ 0 h₁) rfl
· simp_rw [← prime_iff]
exact h₂
· simp_rw [← prime_iff]
exact fun p => prime_of_mem_primeFactorsList
Nat.Prime.primeFactorsList_pow
theorem
{p : ℕ} (hp : p.Prime) (n : ℕ) : (p ^ n).primeFactorsList = List.replicate n p
theorem Prime.primeFactorsList_pow {p : ℕ} (hp : p.Prime) (n : ℕ) :
(p ^ n).primeFactorsList = List.replicate n p := by
symm
rw [← List.replicate_perm]
apply Nat.primeFactorsList_unique (List.prod_replicate n p)
intro q hq
rwa [eq_of_mem_replicate hq]
Nat.perm_primeFactorsList_mul
theorem
{a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) : (a * b).primeFactorsList ~ a.primeFactorsList ++ b.primeFactorsList
/-- For positive `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_primeFactorsList_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
(a * b).primeFactorsList ~ a.primeFactorsList ++ b.primeFactorsList := by
refine (primeFactorsList_unique ?_ ?_).symm
· rw [List.prod_append, prod_primeFactorsList ha, prod_primeFactorsList hb]
· intro p hp
rw [List.mem_append] at hp
rcases hp with hp' | hp' <;> exact prime_of_mem_primeFactorsList hp'
Nat.perm_primeFactorsList_mul_of_coprime
theorem
{a b : ℕ} (hab : Coprime a b) : (a * b).primeFactorsList ~ a.primeFactorsList ++ b.primeFactorsList
/-- For coprime `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_primeFactorsList_mul_of_coprime {a b : ℕ} (hab : Coprime a b) :
(a * b).primeFactorsList ~ a.primeFactorsList ++ b.primeFactorsList := by
rcases a.eq_zero_or_pos with (rfl | ha)
· simp [(coprime_zero_left _).mp hab]
rcases b.eq_zero_or_pos with (rfl | hb)
· simp [(coprime_zero_right _).mp hab]
exact perm_primeFactorsList_mul ha.ne' hb.ne'
Nat.primeFactorsList_sublist_right
theorem
{n k : ℕ} (h : k ≠ 0) : n.primeFactorsList <+ (n * k).primeFactorsList
theorem primeFactorsList_sublist_right {n k : ℕ} (h : k ≠ 0) :
n.primeFactorsList <+ (n * k).primeFactorsList := by
rcases n with - | hn
· simp [zero_mul]
apply sublist_of_subperm_of_sorted _ (primeFactorsList_sorted _) (primeFactorsList_sorted _)
simp only [(perm_primeFactorsList_mul (Nat.succ_ne_zero _) h).subperm_left]
exact (sublist_append_left _ _).subperm
Nat.primeFactorsList_sublist_of_dvd
theorem
{n k : ℕ} (h : n ∣ k) (h' : k ≠ 0) : n.primeFactorsList <+ k.primeFactorsList
theorem primeFactorsList_sublist_of_dvd {n k : ℕ} (h : n ∣ k) (h' : k ≠ 0) :
n.primeFactorsList <+ k.primeFactorsList := by
obtain ⟨a, rfl⟩ := h
exact primeFactorsList_sublist_right (right_ne_zero_of_mul h')
Nat.primeFactorsList_subset_right
theorem
{n k : ℕ} (h : k ≠ 0) : n.primeFactorsList ⊆ (n * k).primeFactorsList
theorem primeFactorsList_subset_right {n k : ℕ} (h : k ≠ 0) :
n.primeFactorsList ⊆ (n * k).primeFactorsList :=
(primeFactorsList_sublist_right h).subset
Nat.primeFactorsList_subset_of_dvd
theorem
{n k : ℕ} (h : n ∣ k) (h' : k ≠ 0) : n.primeFactorsList ⊆ k.primeFactorsList
theorem primeFactorsList_subset_of_dvd {n k : ℕ} (h : n ∣ k) (h' : k ≠ 0) :
n.primeFactorsList ⊆ k.primeFactorsList :=
(primeFactorsList_sublist_of_dvd h h').subset
Nat.dvd_of_primeFactorsList_subperm
theorem
{a b : ℕ} (ha : a ≠ 0) (h : a.primeFactorsList <+~ b.primeFactorsList) : a ∣ b
theorem dvd_of_primeFactorsList_subperm {a b : ℕ} (ha : a ≠ 0)
(h : a.primeFactorsList <+~ b.primeFactorsList) : a ∣ b := by
rcases b.eq_zero_or_pos with (rfl | hb)
· exact dvd_zero _
rcases a with (_ | _ | a)
· exact (ha rfl).elim
· exact one_dvd _
use (b.primeFactorsList.diff a.succ.succ.primeFactorsList).prod
nth_rw 1 [← Nat.prod_primeFactorsList ha]
rw [← List.prod_append,
List.Perm.prod_eq <| List.subperm_append_diff_self_of_count_le <| List.subperm_ext_iff.mp h,
Nat.prod_primeFactorsList hb.ne']
Nat.replicate_subperm_primeFactorsList_iff
theorem
{a b n : ℕ} (ha : Prime a) (hb : b ≠ 0) : replicate n a <+~ primeFactorsList b ↔ a ^ n ∣ b
theorem replicate_subperm_primeFactorsList_iff {a b n : ℕ} (ha : Prime a) (hb : b ≠ 0) :
replicatereplicate n a <+~ primeFactorsList breplicate n a <+~ primeFactorsList b ↔ a ^ n ∣ b := by
induction n generalizing b with
| zero => simp
| succ n ih =>
constructor
· rw [List.subperm_iff]
rintro ⟨u, hu1, hu2⟩
rw [← Nat.prod_primeFactorsList hb, ← hu1.prod_eq, ← prod_replicate]
exact hu2.prod_dvd_prod
· rintro ⟨c, rfl⟩
rw [Ne, pow_succ', mul_assoc, mul_eq_zero, _root_.not_or] at hb
rw [pow_succ', mul_assoc, replicate_succ,
(Nat.perm_primeFactorsList_mul hb.1 hb.2).subperm_left, primeFactorsList_prime ha,
singleton_append, subperm_cons, ih hb.2]
exact dvd_mul_right _ _
Nat.mem_primeFactorsList_mul
theorem
{a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) {p : ℕ} :
p ∈ (a * b).primeFactorsList ↔ p ∈ a.primeFactorsList ∨ p ∈ b.primeFactorsList
theorem mem_primeFactorsList_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) {p : ℕ} :
p ∈ (a * b).primeFactorsListp ∈ (a * b).primeFactorsList ↔ p ∈ a.primeFactorsList ∨ p ∈ b.primeFactorsList := by
rw [mem_primeFactorsList (mul_ne_zero ha hb), mem_primeFactorsList ha, mem_primeFactorsList hb,
← and_or_left]
simpa only [and_congr_right_iff] using Prime.dvd_mul
Nat.coprime_primeFactorsList_disjoint
theorem
{a b : ℕ} (hab : a.Coprime b) : List.Disjoint a.primeFactorsList b.primeFactorsList
/-- The sets of factors of coprime `a` and `b` are disjoint -/
theorem coprime_primeFactorsList_disjoint {a b : ℕ} (hab : a.Coprime b) :
List.Disjoint a.primeFactorsList b.primeFactorsList := by
intro q hqa hqb
apply not_prime_one
rw [← eq_one_of_dvd_coprimes hab (dvd_of_mem_primeFactorsList hqa)
(dvd_of_mem_primeFactorsList hqb)]
exact prime_of_mem_primeFactorsList hqa
Nat.mem_primeFactorsList_mul_of_coprime
theorem
{a b : ℕ} (hab : Coprime a b) (p : ℕ) : p ∈ (a * b).primeFactorsList ↔ p ∈ a.primeFactorsList ∪ b.primeFactorsList
theorem mem_primeFactorsList_mul_of_coprime {a b : ℕ} (hab : Coprime a b) (p : ℕ) :
p ∈ (a * b).primeFactorsListp ∈ (a * b).primeFactorsList ↔ p ∈ a.primeFactorsList ∪ b.primeFactorsList := by
rcases a.eq_zero_or_pos with (rfl | ha)
· simp [(coprime_zero_left _).mp hab]
rcases b.eq_zero_or_pos with (rfl | hb)
· simp [(coprime_zero_right _).mp hab]
rw [mem_primeFactorsList_mul ha.ne' hb.ne', List.mem_union_iff]
Nat.mem_primeFactorsList_mul_left
theorem
{p a b : ℕ} (hpa : p ∈ a.primeFactorsList) (hb : b ≠ 0) : p ∈ (a * b).primeFactorsList
/-- If `p` is a prime factor of `a` then `p` is also a prime factor of `a * b` for any `b > 0` -/
theorem mem_primeFactorsList_mul_left {p a b : ℕ} (hpa : p ∈ a.primeFactorsList) (hb : b ≠ 0) :
p ∈ (a * b).primeFactorsList := by
rcases eq_or_ne a 0 with (rfl | ha)
· simp at hpa
apply (mem_primeFactorsList_mul ha hb).2 (Or.inl hpa)
Nat.mem_primeFactorsList_mul_right
theorem
{p a b : ℕ} (hpb : p ∈ b.primeFactorsList) (ha : a ≠ 0) : p ∈ (a * b).primeFactorsList
/-- If `p` is a prime factor of `b` then `p` is also a prime factor of `a * b` for any `a > 0` -/
theorem mem_primeFactorsList_mul_right {p a b : ℕ} (hpb : p ∈ b.primeFactorsList) (ha : a ≠ 0) :
p ∈ (a * b).primeFactorsList := by
rw [mul_comm]
exact mem_primeFactorsList_mul_left hpb ha
Nat.four_dvd_or_exists_odd_prime_and_dvd_of_two_lt
theorem
{n : ℕ} (n2 : 2 < n) : 4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p
theorem four_dvd_or_exists_odd_prime_and_dvd_of_two_lt {n : ℕ} (n2 : 2 < n) :
4 ∣ n4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p := by
obtain ⟨_ | _ | k, rfl⟩ | ⟨p, hp, hdvd, hodd⟩ := n.eq_two_pow_or_exists_odd_prime_and_dvd
· contradiction
· contradiction
· simp [Nat.pow_succ, mul_assoc]
· exact Or.inr ⟨p, hp, hdvd, hodd⟩