/- 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 < nPrime n.maxPrimeFac n:h:1 < nhn:n.primeFactorsList []Prime n.maxPrimeFac n:h:1 < nhn:n.primeFactorsList []hmem:n.primeFactorsList.getLast hn n.primeFactorsListPrime 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 np n.maxPrimeFac n:p:hn:n 0hp:Prime ph_dvd:p nhmem:p n.primeFactorsListp 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 1p 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 hlistp 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 pn.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 pp.maxPrimeFac = p p:hp:Prime pp.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 = nn 1 Prime n n:h:n.maxPrimeFac = nhn:n 1n 1 Prime nn:h:n.maxPrimeFac = nhn:¬n 1n 1 Prime n n:h:n.maxPrimeFac = nhn:n 1n 1 Prime n All goals completed! 🐙 n:h:n.maxPrimeFac = nhn:¬n 1n 1 Prime n All goals completed! 🐙 n:n 1 Prime n n.maxPrimeFac = n n:hn:n 1n.maxPrimeFac = nn:hn:Prime nn.maxPrimeFac = n n:hn:n 1n.maxPrimeFac = n hn:0 1maxPrimeFac 0 = 0hn:1 1maxPrimeFac 1 = 1 hn:0 1maxPrimeFac 0 = 0hn:1 1maxPrimeFac 1 = 1 All goals completed! 🐙 n:hn:Prime nn.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 * nmax 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 * nmax m.maxPrimeFac n.maxPrimeFac (m * n).maxPrimeFac m:n:hm:m 0hn:n 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nm.maxPrimeFac (m * n).maxPrimeFacm:n:hm:m 0hn:n 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nn.maxPrimeFac (m * n).maxPrimeFac m:n:hm:m 0hn:n 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nm.maxPrimeFac (m * n).maxPrimeFac m:n:hm:m 0hn:n 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime m.maxPrimeFacm.maxPrimeFac (m * n).maxPrimeFac m:n:hm:m 0hn:n 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime m.maxPrimeFacm.maxPrimeFac m * n All goals completed! 🐙 m:n:hm:m 0hn:n 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nn.maxPrimeFac (m * n).maxPrimeFac m:n:hm:m 0hn:n 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime n.maxPrimeFacn.maxPrimeFac (m * n).maxPrimeFac m:n:hm:m 0hn:n 0hm_lt:1 < mhn_lt:1 < nhmn_lt:1 < m * nhp:Prime n.maxPrimeFacn.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 0max 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 < nIsLeast (upperBounds {p | Prime p p n}) n.maxPrimeFac n:hn:1 < nn.maxPrimeFac upperBounds {p | Prime p p n}n:hn:1 < nn.maxPrimeFac lowerBounds (upperBounds {p | Prime p p n}) n:hn:1 < nn.maxPrimeFac upperBounds {p | Prime p p n} n:hn:1 < np:hp:Prime ph_dvd:p np n.maxPrimeFac All goals completed! 🐙 n:hn:1 < nn.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 1maxPrimeFac 0 = sSup {p | Prime p p 0}n:hn_one:n 1hn:1 < nn.maxPrimeFac = sSup {p | Prime p p n} hn_one:0 1maxPrimeFac 0 = sSup {p | Prime p p 0} All goals completed! 🐙 n:hn_one:n 1hn:1 < nn.maxPrimeFac = sSup {p | Prime p p n} n:hn_one:n 1hn:1 < nh_lub:IsLUB {p | Prime p p n} n.maxPrimeFacn.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 < 11 < n.maxPrimeFac 1 < n1 < maxPrimeFac 1 1 < 1n:hn:1 < n1 < n.maxPrimeFac 1 < n n:hn:n < 11 < n.maxPrimeFac 1 < n n:hn:n = 01 < n.maxPrimeFac 1 < n All goals completed! 🐙 1 < maxPrimeFac 1 1 < 1 All goals completed! 🐙 n:hn:1 < n1 < n.maxPrimeFac 1 < n All goals completed! 🐙end Nat