/- 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 n:ℕhn:1 < n + 2hlist:(n + 2).primeFactorsList ≠ []⊢ (n + 2).maxPrimeFac ∣ n + 2 n:ℕhn:1 < n + 2hlist:(n + 2).primeFactorsList ≠ []hmem:(n + 2).primeFactorsList.getLast hlist ∈ (n + 2).primeFactorsList⊢ (n + 2).maxPrimeFac ∣ n + 2 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 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 := n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ n⊢ p ≤ n.maxPrimeFac n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ nhmem:p ∈ n.primeFactorsList⊢ p ≤ n.maxPrimeFac n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ nhmem:p ∈ n.primeFactorsListhlist:n.primeFactorsList ≠ []⊢ p ≤ n.maxPrimeFac n:ℕp:ℕhn:n ≠ 0hp:Prime ph_dvd:p ∣ nhmem:p ∈ n.primeFactorsListhlist:n.primeFactorsList ≠ []hn_one:n ≠ 1⊢ p ≤ n.maxPrimeFac 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 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 := n:ℕp:ℕhn:0 < nhp:Prime ph_dvd:p ∣ nh_le:n.maxPrimeFac ≤ p⊢ n.maxPrimeFac = p 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 := p:ℕhp:Prime p⊢ p.maxPrimeFac = p p:ℕhp:Prime p⊢ p.maxPrimeFac ≤ p 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 := n:ℕ⊢ n.maxPrimeFac = n ↔ n ≤ 1 ∨ Prime n n:ℕ⊢ n.maxPrimeFac = n → n ≤ 1 ∨ Prime nn:ℕ⊢ n ≤ 1 ∨ Prime n → n.maxPrimeFac = n n:ℕ⊢ n.maxPrimeFac = n → n ≤ 1 ∨ Prime n n:ℕh:n.maxPrimeFac = n⊢ n ≤ 1 ∨ Prime n n:ℕh:n.maxPrimeFac = nhn:n ≤ 1⊢ n ≤ 1 ∨ Prime nn:ℕh:n.maxPrimeFac = nhn:¬n ≤ 1⊢ n ≤ 1 ∨ Prime n n:ℕh:n.maxPrimeFac = nhn:n ≤ 1⊢ n ≤ 1 ∨ Prime n All goals completed! 🐙 n:ℕh:n.maxPrimeFac = nhn:¬n ≤ 1⊢ n ≤ 1 ∨ Prime n All goals completed! 🐙 n:ℕ⊢ n ≤ 1 ∨ Prime n → n.maxPrimeFac = n n:ℕhn:n ≤ 1⊢ n.maxPrimeFac = nn:ℕhn:Prime n⊢ n.maxPrimeFac = n n:ℕhn:n ≤ 1⊢ n.maxPrimeFac = n hn:0 ≤ 1⊢ maxPrimeFac 0 = 0hn:1 ≤ 1⊢ maxPrimeFac 1 = 1 hn:0 ≤ 1⊢ maxPrimeFac 0 = 0hn:1 ≤ 1⊢ maxPrimeFac 1 = 1 All goals completed! 🐙 n:ℕhn:Prime n⊢ n.maxPrimeFac = n All goals completed! 🐙

The greatest prime factor of a product of nonzero natural numbers is the maximum of their greatest prime factors.

m:ℕhm:m ≠ 0hm_lt:1 < mhn:1 ≠ 0⊢ (m * 1).maxPrimeFac = max m.maxPrimeFac (maxPrimeFac 1)m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < n⊢ (m * n).maxPrimeFac = max m.maxPrimeFac n.maxPrimeFac m:ℕhm:m ≠ 0hm_lt:1 < mhn:1 ≠ 0⊢ (m * 1).maxPrimeFac = max m.maxPrimeFac (maxPrimeFac 1) m:ℕhm:m ≠ 0hm_lt:1 < mhn:1 ≠ 0hle:1 ≤ m.maxPrimeFac⊢ (m * 1).maxPrimeFac = max m.maxPrimeFac (maxPrimeFac 1) All goals completed! 🐙 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 m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ (m * n).maxPrimeFac ≤ max m.maxPrimeFac n.maxPrimeFacm:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ max m.maxPrimeFac n.maxPrimeFac ≤ (m * n).maxPrimeFac 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 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 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.maxPrimeFacm:ℕ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 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 All goals completed! 🐙 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 All goals completed! 🐙 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 m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ m.maxPrimeFac ≤ (m * n).maxPrimeFacm:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ n.maxPrimeFac ≤ (m * n).maxPrimeFac m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ m.maxPrimeFac ≤ (m * n).maxPrimeFac 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 m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime m.maxPrimeFac⊢ m.maxPrimeFac ∣ m * n All goals completed! 🐙 m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * n⊢ n.maxPrimeFac ≤ (m * n).maxPrimeFac 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 m:ℕn:ℕhm:m ≠ 0hn:n ≠ 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime n.maxPrimeFac⊢ n.maxPrimeFac ∣ m * n All goals completed! 🐙

The greatest prime factor of a nonzero power is the greatest prime factor of its base.

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 All goals completed! 🐙

The greatest prime factor of a natural number is at most that number.

lemma maxPrimeFac_le : ∀ {n : ℕ}, maxPrimeFac n ≤ n ⊢ maxPrimeFac 0 ≤ 0 ⊢ maxPrimeFac 0 ≤ 0 All goals completed! 🐙 ⊢ maxPrimeFac 1 ≤ 1 ⊢ maxPrimeFac 1 ≤ 1 All goals completed! 🐙 | n + 2 => Nat.le_of_dvd (n:ℕ⊢ 0 < n + 2 All goals completed! 🐙) maxPrimeFac_dvd

The 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) := n:ℕhn:1 < n⊢ IsLeast (upperBounds {p | Prime p ∧ p ∣ n}) n.maxPrimeFac n:ℕhn:1 < n⊢ n.maxPrimeFac ∈ upperBounds {p | Prime p ∧ p ∣ n}n:ℕhn:1 < n⊢ n.maxPrimeFac ∈ lowerBounds (upperBounds {p | Prime p ∧ p ∣ n}) n:ℕhn:1 < n⊢ n.maxPrimeFac ∈ upperBounds {p | Prime p ∧ p ∣ n} n:ℕhn:1 < np:ℕhp:Prime ph_dvd:p ∣ n⊢ p ≤ n.maxPrimeFac All goals completed! 🐙 n:ℕhn:1 < n⊢ n.maxPrimeFac ∈ lowerBounds (upperBounds {p | Prime p ∧ p ∣ n}) n:ℕhn:1 < nb:ℕhb:b ∈ upperBounds {p | Prime p ∧ p ∣ n}⊢ n.maxPrimeFac ≤ b All goals completed! 🐙

Away from n = 1, the computable greatest prime factor agrees with its supremum characterization.

hn_one:0 ≠ 1⊢ maxPrimeFac 0 = sSup {p | Prime p ∧ p ∣ 0}n:ℕhn_one:n ≠ 1hn:1 < n⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n} hn_one:0 ≠ 1⊢ maxPrimeFac 0 = sSup {p | Prime p ∧ p ∣ 0} All goals completed! 🐙 n:ℕhn_one:n ≠ 1hn:1 < n⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n} n:ℕhn_one:n ≠ 1hn:1 < nh_lub:IsLUB {p | Prime p ∧ p ∣ n} n.maxPrimeFac⊢ n.maxPrimeFac = sSup {p | Prime p ∧ p ∣ n} All goals completed! 🐙@[simp] lemma one_lt_maxPrimeFac_iff (n : ℕ) : 1 < maxPrimeFac n ↔ 1 < n := n:ℕ⊢ 1 < n.maxPrimeFac ↔ 1 < n n:ℕhn:n < 1⊢ 1 < n.maxPrimeFac ↔ 1 < n⊢ 1 < maxPrimeFac 1 ↔ 1 < 1n:ℕhn:1 < n⊢ 1 < n.maxPrimeFac ↔ 1 < n n:ℕhn:n < 1⊢ 1 < n.maxPrimeFac ↔ 1 < n n:ℕhn:n = 0⊢ 1 < n.maxPrimeFac ↔ 1 < n All goals completed! 🐙 ⊢ 1 < maxPrimeFac 1 ↔ 1 < 1 All goals completed! 🐙 n:ℕhn:1 < n⊢ 1 < n.maxPrimeFac ↔ 1 < n All goals completed! 🐙end Nat