/-
Copyright 2025 The Formal Conjectures Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/
module
public import Mathlib.Data.Nat.PrimeFin
public import Mathlib.Order.Lattice.Nat@[expose] public sectionnamespace Nat
The greatest prime divisor of a natural number n > 1.
Takes the junk value 0 for n = 0 and 1 for n = 1.
def maxPrimeFac (n : ℕ) : ℕ := if n = 1 then 1 else n.primeFactorsList.getLastIexample : maxPrimeFac 0 = 0 := ⊢ maxPrimeFac 0 = 0 All goals completed! 🐙example : maxPrimeFac 1 = 1 := rflexample : maxPrimeFac 12 = 3 := ⊢ maxPrimeFac 12 = 3 All goals completed! 🐙example : maxPrimeFac 97 = 97 := ⊢ maxPrimeFac 97 = 97 All goals completed! 🐙example : maxPrimeFac 125 = 5 := ⊢ maxPrimeFac 125 = 5 All goals completed! 🐙example : maxPrimeFac 360 = 5 := ⊢ maxPrimeFac 360 = 5 All goals completed! 🐙@[simp]
lemma maxPrimeFac_zero :
maxPrimeFac 0 = 0 := ⊢ maxPrimeFac 0 = 0
All goals completed! 🐙@[simp]
lemma maxPrimeFac_one :
maxPrimeFac 1 = 1 := rfllemma prime_maxPrimeFac_of_one_lt (n : ℕ) (h : 1 < n) :
Prime (maxPrimeFac n) := n:ℕh:1 < n⊢ Prime n.maxPrimeFac
n:ℕh:1 < nhn:n.primeFactorsList ≠ []⊢ Prime n.maxPrimeFac
n:ℕh:1 < nhn:n.primeFactorsList ≠ []hmem:n.primeFactorsList.getLast hn ∈ n.primeFactorsList⊢ Prime n.maxPrimeFac
n:ℕh:1 < nhn:n.primeFactorsList ≠ []hmem:n.primeFactorsList.getLast hn ∈ n.primeFactorsListhprime:Prime (n.primeFactorsList.getLast hn)⊢ Prime n.maxPrimeFac
All goals completed! 🐙The greatest prime factor of a natural number divides it.
n:ℕhn:1 < n + 2⊢ (n + 2).maxPrimeFac ∣ n + 2
have hlist : (n + 2).primeFactorsList ≠ [] :=
(primeFactorsList_ne_nil (n + 2)).2 hn n:ℕhn:1 < n + 2hlist:(n + 2).primeFactorsList ≠ []⊢ (n + 2).maxPrimeFac ∣ n + 2
have hmem : (n + 2).primeFactorsList.getLast hlist ∈ (n + 2).primeFactorsList :=
List.getLast_mem hlist n:ℕhn:1 < n + 2hlist:(n + 2).primeFactorsList ≠ []hmem:(n + 2).primeFactorsList.getLast hlist ∈ (n + 2).primeFactorsList⊢ (n + 2).maxPrimeFac ∣ n + 2
have hdvd : (n + 2).primeFactorsList.getLast hlist ∣ n + 2 :=
dvd_of_mem_primeFactorsList hmem n:ℕhn:1 < n + 2hlist:(n + 2).primeFactorsList ≠ []hmem:(n + 2).primeFactorsList.getLast hlist ∈ (n + 2).primeFactorsListhdvd:(n + 2).primeFactorsList.getLast hlist ∣ n + 2⊢ (n + 2).maxPrimeFac ∣ n + 2
simpa [maxPrimeFac, hn.ne', List.getLastI_eq_getLast?_getD,
List.getLast?_eq_getLast_of_ne_nil hlist] using hdvd All goals completed! 🐙Every prime factor of a nonzero natural number is at most its greatest prime factor.
lemma le_maxPrimeFac
{n p : ℕ} (hn : n ≠ 0) (hp : p.Prime) (h_dvd : p ∣ n) :
p ≤ maxPrimeFac n := by n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ n⊢ p ≤ n.maxPrimeFac
have hmem : p ∈ n.primeFactorsList := (mem_primeFactorsList hn).2 ⟨hp, h_dvd⟩ n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ nhmem:p ∈ n.primeFactorsList⊢ p ≤ n.maxPrimeFac
have hlist : n.primeFactorsList ≠ [] := List.ne_nil_of_mem hmem n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ nhmem:p ∈ n.primeFactorsListhlist:n.primeFactorsList ≠ []⊢ p ≤ n.maxPrimeFac
have hn_one : n ≠ 1 := ((primeFactorsList_ne_nil n).1 hlist).ne' n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ nhmem:p ∈ n.primeFactorsListhlist:n.primeFactorsList ≠ []hn_one:n ≠ 1⊢ p ≤ n.maxPrimeFac
have hp_last : p ≤ n.primeFactorsList.getLast hlist :=
(primeFactorsList_sorted n).pairwise.rel_getLast hmem n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ nhmem:p ∈ n.primeFactorsListhlist:n.primeFactorsList ≠ []hn_one:n ≠ 1hp_last:p ≤ n.primeFactorsList.getLast hlist⊢ p ≤ n.maxPrimeFac
simpa [maxPrimeFac, hn_one, List.getLastI_eq_getLast?_getD,
List.getLast?_eq_getLast_of_ne_nil hlist] using hp_last All goals completed! 🐙lemma maxPrimeFac_eq_of_dvd_of_le
(n p : ℕ) (hn : 0 < n) (hp : p.Prime) (h_dvd : p ∣ n) (h_le : maxPrimeFac n ≤ p) :
maxPrimeFac n = p := by n:ℕp:ℕhn:0 < nhp:Prime ph_dvd:p ∣ nh_le:n.maxPrimeFac ≤ p⊢ n.maxPrimeFac = p
exact le_antisymm h_le (le_maxPrimeFac hn.ne' hp h_dvd) All goals completed! 🐙The greatest prime factor of a prime is the prime itself.
@[simp]
lemma Prime.maxPrimeFac_eq_self {p : ℕ} (hp : p.Prime) :
maxPrimeFac p = p := by p:ℕhp:Prime p⊢ p.maxPrimeFac = p
apply maxPrimeFac_eq_of_dvd_of_le p p hp.pos hp (dvd_refl p) p:ℕhp:Prime p⊢ p.maxPrimeFac ≤ p
exact Nat.le_of_dvd hp.pos maxPrimeFac_dvd All goals completed! 🐙
The fixed points of maxPrimeFac are zero, one, and the primes.
@[simp]
lemma maxPrimeFac_eq_self_iff {n : ℕ} :
maxPrimeFac n = n ↔ n ≤ 1 ∨ n.Prime := by n:ℕ⊢ n.maxPrimeFac = n ↔ n ≤ 1 ∨ Prime n
constructor mp n:ℕ⊢ n.maxPrimeFac = n → n ≤ 1 ∨ Prime nmpr n:ℕ⊢ n ≤ 1 ∨ Prime n → n.maxPrimeFac = n
· mp n:ℕ⊢ n.maxPrimeFac = n → n ≤ 1 ∨ Prime n intro h mp n:ℕh:n.maxPrimeFac = n⊢ n ≤ 1 ∨ Prime n
by_cases hn : n ≤ 1 pos n:ℕh:n.maxPrimeFac = nhn:n ≤ 1⊢ n ≤ 1 ∨ Prime nneg n:ℕh:n.maxPrimeFac = nhn:¬n ≤ 1⊢ n ≤ 1 ∨ Prime n
· pos n:ℕh:n.maxPrimeFac = nhn:n ≤ 1⊢ n ≤ 1 ∨ Prime n exact Or.inl hn All goals completed! 🐙
· neg n:ℕh:n.maxPrimeFac = nhn:¬n ≤ 1⊢ n ≤ 1 ∨ Prime n exact Or.inr <| h ▸ prime_maxPrimeFac_of_one_lt n (lt_of_not_ge hn) All goals completed! 🐙
· mpr n:ℕ⊢ n ≤ 1 ∨ Prime n → n.maxPrimeFac = n rintro (hn | hn) mpr.inl n:ℕhn:n ≤ 1⊢ n.maxPrimeFac = nmpr.inr n:ℕhn:Prime n⊢ n.maxPrimeFac = n
· mpr.inl n:ℕhn:n ≤ 1⊢ n.maxPrimeFac = n obtain rfl | rfl := Nat.le_one_iff_eq_zero_or_eq_one.mp hn mpr.inl.inl hn:0 ≤ 1⊢ maxPrimeFac 0 = 0mpr.inl.inr hn:1 ≤ 1⊢ maxPrimeFac 1 = 1 <;> mpr.inl.inl hn:0 ≤ 1⊢ maxPrimeFac 0 = 0mpr.inl.inr hn:1 ≤ 1⊢ maxPrimeFac 1 = 1 simp All goals completed! 🐙
· mpr.inr n:ℕhn:Prime n⊢ n.maxPrimeFac = n exact hn.maxPrimeFac_eq_self All goals completed! 🐙The greatest prime factor of a product of nonzero natural numbers is the maximum of their greatest prime factors.
lemma maxPrimeFac_mul {m n : ℕ} (hm : m ≠ 0) (hn : n ≠ 0) :
maxPrimeFac (m * n) = max (maxPrimeFac m) (maxPrimeFac n) := by m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFac
obtain rfl | hm_lt : m = 1 ∨ 1 < m := by m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0⊢ m = 1 ∨ 1 < m inl n:ℕhn:n ≠ 0hm:1 ≠ 0⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFacinr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < m⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFac omega inl n:ℕhn:n ≠ 0hm:1 ≠ 0⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFacinr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < m⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFacinl n:ℕhn:n ≠ 0hm:1 ≠ 0⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFacinr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < m⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFac
· inl n:ℕhn:n ≠ 0hm:1 ≠ 0⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFac have hle : 1 ≤ maxPrimeFac n := by m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFac inl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFac
obtain rfl | hn_lt : n = 1 ∨ 1 < n := by n:ℕhn:n ≠ 0hm:1 ≠ 0⊢ n = 1 ∨ 1 < n inl hm:1 ≠ 0hn:1 ≠ 0⊢ 1 ≤ maxPrimeFac 1inr n:ℕhn:n ≠ 0hm:1 ≠ 0hn_lt:1 < n⊢ 1 ≤ n.maxPrimeFacinl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFac omegainl hm:1 ≠ 0hn:1 ≠ 0⊢ 1 ≤ maxPrimeFac 1inr n:ℕhn:n ≠ 0hm:1 ≠ 0hn_lt:1 < n⊢ 1 ≤ n.maxPrimeFacinl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFacinl hm:1 ≠ 0hn:1 ≠ 0⊢ 1 ≤ maxPrimeFac 1inr n:ℕhn:n ≠ 0hm:1 ≠ 0hn_lt:1 < n⊢ 1 ≤ n.maxPrimeFacinl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFac
· inl hm:1 ≠ 0hn:1 ≠ 0⊢ 1 ≤ maxPrimeFac 1inl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFac simp All goals completed! 🐙inl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFac
· inr n:ℕhn:n ≠ 0hm:1 ≠ 0hn_lt:1 < n⊢ 1 ≤ n.maxPrimeFacinl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFac exact (prime_maxPrimeFac_of_one_lt n hn_lt).one_lt.leinl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFacinl n:ℕhn:n ≠ 0hm:1 ≠ 0hle:1 ≤ n.maxPrimeFac⊢ (1 * n).maxPrimeFac = max (maxPrimeFac 1) n.maxPrimeFac
simp [hle] All goals completed! 🐙
obtain rfl | hn_lt : n = 1 ∨ 1 < n := by m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < m⊢ n = 1 ∨ 1 < n inr.inl m:ℕhm:m ≠ 0hm_lt:1 < mhn:1 ≠ 0⊢ (m * 1).maxPrimeFac = max m.maxPrimeFac (maxPrimeFac 1)inr.inr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < n⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFac omegainr.inl m:ℕhm:m ≠ 0hm_lt:1 < mhn:1 ≠ 0⊢ (m * 1).maxPrimeFac = max m.maxPrimeFac (maxPrimeFac 1)inr.inr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < n⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFacinr.inl m:ℕhm:m ≠ 0hm_lt:1 < mhn:1 ≠ 0⊢ (m * 1).maxPrimeFac = max m.maxPrimeFac (maxPrimeFac 1)inr.inr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < n⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFac
· inr.inl m:ℕhm:m ≠ 0hm_lt:1 < mhn:1 ≠ 0⊢ (m * 1).maxPrimeFac = max m.maxPrimeFac (maxPrimeFac 1) have hle : 1 ≤ maxPrimeFac m := (prime_maxPrimeFac_of_one_lt m hm_lt).one_lt.le inr.inl m:ℕhm:m ≠ 0hm_lt:1 < mhn:1 ≠ 0hle:1 ≤ m.maxPrimeFac⊢ (m * 1).maxPrimeFac = max m.maxPrimeFac (maxPrimeFac 1)
simp [hle] All goals completed! 🐙
have hmn_lt : 1 < m * n := Nat.one_lt_mul_iff.mpr
⟨zero_lt_of_lt hm_lt, zero_lt_of_lt hn_lt, Or.inl hm_lt⟩ inr.inr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFac
apply le_antisymm inr.inr.a m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ (m * n).maxPrimeFac ≤ max m.maxPrimeFac n.maxPrimeFaca m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ max m.maxPrimeFac n.maxPrimeFac ≤ (m * n).maxPrimeFac
· inr.inr.a m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ (m * n).maxPrimeFac ≤ max m.maxPrimeFac n.maxPrimeFac have hp : Prime (maxPrimeFac (m * n)) := prime_maxPrimeFac_of_one_lt (m * n) hmn_lt inr.inr.a m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime (m * n).maxPrimeFac⊢ (m * n).maxPrimeFac ≤ max m.maxPrimeFac n.maxPrimeFac
rcases hp.dvd_mul.mp maxPrimeFac_dvd with hpm | hpn inr.inr.a.inl m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime (m * n).maxPrimeFachpm:(m * n).maxPrimeFac ∣ m⊢ (m * n).maxPrimeFac ≤ max m.maxPrimeFac n.maxPrimeFacinr.inr.a.inr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime (m * n).maxPrimeFachpn:(m * n).maxPrimeFac ∣ n⊢ (m * n).maxPrimeFac ≤ max m.maxPrimeFac n.maxPrimeFac
· inr.inr.a.inl m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime (m * n).maxPrimeFachpm:(m * n).maxPrimeFac ∣ m⊢ (m * n).maxPrimeFac ≤ max m.maxPrimeFac n.maxPrimeFac exact (le_maxPrimeFac hm hp hpm).trans (le_max_left _ _) All goals completed! 🐙
· inr.inr.a.inr m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime (m * n).maxPrimeFachpn:(m * n).maxPrimeFac ∣ n⊢ (m * n).maxPrimeFac ≤ max m.maxPrimeFac n.maxPrimeFac exact (le_maxPrimeFac hn hp hpn).trans (le_max_right _ _) All goals completed! 🐙
· a m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ max m.maxPrimeFac n.maxPrimeFac ≤ (m * n).maxPrimeFac apply max_le a.h₁ m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ m.maxPrimeFac ≤ (m * n).maxPrimeFach₂ m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ n.maxPrimeFac ≤ (m * n).maxPrimeFac
· a.h₁ m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ m.maxPrimeFac ≤ (m * n).maxPrimeFac have hp : Prime (maxPrimeFac m) := prime_maxPrimeFac_of_one_lt m hm_lt a.h₁ m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime m.maxPrimeFac⊢ m.maxPrimeFac ≤ (m * n).maxPrimeFac
apply le_maxPrimeFac (mul_ne_zero hm hn) hp a.h₁ m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime m.maxPrimeFac⊢ m.maxPrimeFac ∣ m * n
exact dvd_mul_of_dvd_left maxPrimeFac_dvd n All goals completed! 🐙
· h₂ m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ n.maxPrimeFac ≤ (m * n).maxPrimeFac have hp : Prime (maxPrimeFac n) := prime_maxPrimeFac_of_one_lt n hn_lt h₂ m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime n.maxPrimeFac⊢ n.maxPrimeFac ≤ (m * n).maxPrimeFac
apply le_maxPrimeFac (mul_ne_zero hm hn) hp h₂ m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime n.maxPrimeFac⊢ n.maxPrimeFac ∣ m * n
exact dvd_mul_of_dvd_right maxPrimeFac_dvd m All goals completed! 🐙The greatest prime factor of a nonzero power is the greatest prime factor of its base.
@[simp]
lemma maxPrimeFac_pow {k : ℕ} (hk : k ≠ 0) (n : ℕ) :
maxPrimeFac (n ^ k) = maxPrimeFac n :=
match k, hk with
| k + 1, _ => k✝:ℕhk:k✝ ≠ 0n:ℕk:ℕx✝:k + 1 ≠ 0⊢ (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFac by k✝:ℕhk:k✝ ≠ 0n:ℕk:ℕx✝:k + 1 ≠ 0⊢ (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFac
by_cases hn : n = 0 pos k✝:ℕhk:k✝ ≠ 0n:ℕk:ℕx✝:k + 1 ≠ 0hn:n = 0⊢ (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacneg k✝:ℕhk:k✝ ≠ 0n:ℕk:ℕx✝:k + 1 ≠ 0hn:¬n = 0⊢ (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFac
· pos k✝:ℕhk:k✝ ≠ 0n:ℕk:ℕx✝:k + 1 ≠ 0hn:n = 0⊢ (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFac subst n pos k✝:ℕhk:k✝ ≠ 0k:ℕx✝:k + 1 ≠ 0⊢ (0 ^ (k + 1)).maxPrimeFac = maxPrimeFac 0
simp All goals completed! 🐙
induction k with
| zero => neg.zero k:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0x✝:0 + 1 ≠ 0⊢ (n ^ (0 + 1)).maxPrimeFac = n.maxPrimeFac simp All goals completed! 🐙
| succ k ih => neg.succ k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ (n ^ (k + 1 + 1)).maxPrimeFac = n.maxPrimeFac
rw [pow_succ, neg.succ k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ (n ^ (k + 1) * n).maxPrimeFac = n.maxPrimeFac neg.succ k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ max n.maxPrimeFac n.maxPrimeFac = n.maxPrimeFac maxPrimeFac_mul (pow_ne_zero _ hn) hn, neg.succ k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ max (n ^ (k + 1)).maxPrimeFac n.maxPrimeFac = n.maxPrimeFac neg.succ k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ max n.maxPrimeFac n.maxPrimeFac = n.maxPrimeFac ih (by k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ k + 1 ≠ 0neg.succ k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ max n.maxPrimeFac n.maxPrimeFac = n.maxPrimeFac omega All goals completed! 🐙neg.succ k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ max n.maxPrimeFac n.maxPrimeFac = n.maxPrimeFac)]neg.succ k✝:ℕhk:k✝ ≠ 0n:ℕhn:¬n = 0k:ℕih:k + 1 ≠ 0 → (n ^ (k + 1)).maxPrimeFac = n.maxPrimeFacx✝:k + 1 + 1 ≠ 0⊢ max n.maxPrimeFac n.maxPrimeFac = n.maxPrimeFac
simp All goals completed! 🐙The greatest prime factor of a natural number is at most that number.
lemma maxPrimeFac_le : ∀ {n : ℕ}, maxPrimeFac n ≤ n
| 0 => ⊢ maxPrimeFac 0 ≤ 0 by ⊢ maxPrimeFac 0 ≤ 0 simp All goals completed! 🐙
| 1 => ⊢ maxPrimeFac 1 ≤ 1 by ⊢ maxPrimeFac 1 ≤ 1 simp All goals completed! 🐙
| n + 2 => Nat.le_of_dvd (by n:ℕ⊢ 0 < n + 2 omega All goals completed! 🐙) maxPrimeFac_dvdThe greatest prime factor of a natural number greater than one is the least upper bound of its prime factors.
lemma isLeast_maxPrimeFac {n : ℕ} (hn : 1 < n) :
IsLeast (upperBounds {p : ℕ | p.Prime ∧ p ∣ n}) (maxPrimeFac n) := by n:ℕhn:1 < n⊢ IsLeast (upperBounds {p | Prime p ∧ p ∣ n}) n.maxPrimeFac
constructor left n:ℕhn:1 < n⊢ n.maxPrimeFac ∈ upperBounds {p | Prime p ∧ p ∣ n}right n:ℕhn:1 < n⊢ n.maxPrimeFac ∈ lowerBounds (upperBounds {p | Prime p ∧ p ∣ n})
· left n:ℕhn:1 < n⊢ n.maxPrimeFac ∈ upperBounds {p | Prime p ∧ p ∣ n} rintro p ⟨hp, h_dvd⟩ left n:ℕhn:1 < np:ℕhp:Prime ph_dvd:p ∣ n⊢ p ≤ n.maxPrimeFac
exact le_maxPrimeFac (zero_lt_of_lt hn).ne' hp h_dvd All goals completed! 🐙
· right n:ℕhn:1 < n⊢ n.maxPrimeFac ∈ lowerBounds (upperBounds {p | Prime p ∧ p ∣ n}) intro b hb right n:ℕhn:1 < nb:ℕhb:b ∈ upperBounds {p | Prime p ∧ p ∣ n}⊢ n.maxPrimeFac ≤ b
exact hb ⟨prime_maxPrimeFac_of_one_lt n hn, maxPrimeFac_dvd⟩ All goals completed! 🐙
Away from n = 1, the computable greatest prime factor agrees with its supremum
characterization.
lemma maxPrimeFac_eq_sSup {n : ℕ} (hn_one : n ≠ 1) :
maxPrimeFac n = sSup {p : ℕ | p.Prime ∧ p ∣ n} := by n:ℕhn_one:n ≠ 1⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n}
obtain rfl | hn : n = 0 ∨ 1 < n := by n:ℕhn_one:n ≠ 1⊢ n = 0 ∨ 1 < n inl hn_one:0 ≠ 1⊢ maxPrimeFac 0 = sSup {p | Prime p ∧ p ∣ 0}inr n:ℕhn_one:n ≠ 1hn:1 < n⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n} lia inl hn_one:0 ≠ 1⊢ maxPrimeFac 0 = sSup {p | Prime p ∧ p ∣ 0}inr n:ℕhn_one:n ≠ 1hn:1 < n⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n}inl hn_one:0 ≠ 1⊢ maxPrimeFac 0 = sSup {p | Prime p ∧ p ∣ 0}inr n:ℕhn_one:n ≠ 1hn:1 < n⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n}
· inl hn_one:0 ≠ 1⊢ maxPrimeFac 0 = sSup {p | Prime p ∧ p ∣ 0} simpa using (Set.Infinite.Nat.sSup_eq_zero infinite_setOfPred_prime).symm All goals completed! 🐙
· inr n:ℕhn_one:n ≠ 1hn:1 < n⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n} have h_lub : IsLUB {p : ℕ | p.Prime ∧ p ∣ n} (maxPrimeFac n) :=
isLeast_maxPrimeFac hn inr n:ℕhn_one:n ≠ 1hn:1 < nh_lub:IsLUB {p | Prime p ∧ p ∣ n} n.maxPrimeFac⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n}
exact (h_lub.csSup_eq
⟨maxPrimeFac n, prime_maxPrimeFac_of_one_lt n hn, maxPrimeFac_dvd⟩).symm All goals completed! 🐙@[simp]
lemma one_lt_maxPrimeFac_iff (n : ℕ) :
1 < maxPrimeFac n ↔ 1 < n := by n:ℕ⊢ 1 < n.maxPrimeFac ↔ 1 < n
rcases lt_trichotomy n 1 with hn | rfl | hn inl n:ℕhn:n < 1⊢ 1 < n.maxPrimeFac ↔ 1 < ninr.inl ⊢ 1 < maxPrimeFac 1 ↔ 1 < 1inr.inr n:ℕhn:1 < n⊢ 1 < n.maxPrimeFac ↔ 1 < n
· inl n:ℕhn:n < 1⊢ 1 < n.maxPrimeFac ↔ 1 < n simp only [lt_one_iff] at hn inl n:ℕhn:n = 0⊢ 1 < n.maxPrimeFac ↔ 1 < n
simp [hn] All goals completed! 🐙
· inr.inl ⊢ 1 < maxPrimeFac 1 ↔ 1 < 1 simp All goals completed! 🐙
· inr.inr n:ℕhn:1 < n⊢ 1 < n.maxPrimeFac ↔ 1 < n simpa [hn] using (prime_maxPrimeFac_of_one_lt n hn).one_lt All goals completed! 🐙end Nat