/-
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.Squarefree
public import FormalConjecturesForMathlib.Data.Nat.Factorization.Basic
public meta import Mathlib.Data.Nat.Factorization.Basic
import Mathlib.Tactic@[expose] public sectionnamespace Nat
n.squarefreePart is the unique a₀ : ℕ such that a₀ is squarefree and n = a₀ * b ^ 2,
for some b : ℕ. At 0 this property is not well defined because b must be 0 and a₀ can be
any squarefree number; we give the junk value 1 at n = 0 following the convention that the
squarefree part of any square is 1.
def squarefreePart (n : ℕ) : ℕ := n.factorization.prod fun (p e : ℕ) ↦ p ^ (e % 2)example : squarefreePart 2 = 2 := ⊢ squarefreePart 2 = 2
All goals completed! 🐙example : squarefreePart 5 = 5 := ⊢ squarefreePart 5 = 5
All goals completed! 🐙example : squarefreePart 4 = 1 := ⊢ squarefreePart 4 = 1
All goals completed! 🐙example : squarefreePart 8 = 2 := ⊢ squarefreePart 8 = 2
All goals completed! 🐙example : squarefreePart 16 = 1 := ⊢ squarefreePart 16 = 1
All goals completed! 🐙example : squarefreePart 24 = 6 := ⊢ squarefreePart 24 = 6
All goals completed! 🐙theorem squarefreePart_ne_zero (n : ℕ) : n.squarefreePart ≠ 0 := n:ℕ⊢ n.squarefreePart ≠ 0
All goals completed! 🐙theorem squarefreePart_zero : squarefreePart 0 = 1 := ⊢ squarefreePart 0 = 1
All goals completed! 🐙
If n is squarefree, then its squarefree part is itself.
All goals completed! 🐙
The squarefree part of any square is 1.
theorem squarefreePart_of_isSquare {n : ℕ} (hn : IsSquare n) :
squarefreePart n = 1 := by n:ℕhn:IsSquare n⊢ n.squarefreePart = 1
rcases eq_or_ne n 0 with (rfl | h₀) inl hn:IsSquare 0⊢ squarefreePart 0 = 1inr n:ℕhn:IsSquare nh₀:n ≠ 0⊢ n.squarefreePart = 1; exact squarefreePart_zero inr n:ℕhn:IsSquare nh₀:n ≠ 0⊢ n.squarefreePart = 1
obtain ⟨r, rfl⟩ := hn inr r:ℕh₀:r * r ≠ 0⊢ (r * r).squarefreePart = 1
rw [ne_eq, inr r:ℕh₀:¬r * r = 0⊢ (r * r).squarefreePart = 1 inr r:ℕh₀:¬r = 0⊢ (r * r).squarefreePart = 1 mul_eq_zero, inr r:ℕh₀:¬(r = 0 ∨ r = 0)⊢ (r * r).squarefreePart = 1 inr r:ℕh₀:¬r = 0⊢ (r * r).squarefreePart = 1 or_self inr r:ℕh₀:¬r = 0⊢ (r * r).squarefreePart = 1inr r:ℕh₀:¬r = 0⊢ (r * r).squarefreePart = 1] at h₀inr r:ℕh₀:¬r = 0⊢ (r * r).squarefreePart = 1
rw [squarefreePart, inr r:ℕh₀:¬r = 0⊢ ((r * r).factorization.prod fun p e ↦ p ^ (e % 2)) = 1 inr r:ℕh₀:¬r = 0⊢ ∏ p ∈ (r * r).primeFactors, p ^ ((r.factorization + r.factorization) p % 2) = 1 Finsupp.prod, inr r:ℕh₀:¬r = 0⊢ ∏ a ∈ (r * r).factorization.support, a ^ ((r * r).factorization a % 2) = 1inr r:ℕh₀:¬r = 0⊢ ∏ p ∈ (r * r).primeFactors, p ^ ((r.factorization + r.factorization) p % 2) = 1 support_factorization, inr r:ℕh₀:¬r = 0⊢ ∏ a ∈ (r * r).primeFactors, a ^ ((r * r).factorization a % 2) = 1inr r:ℕh₀:¬r = 0⊢ ∏ p ∈ (r * r).primeFactors, p ^ ((r.factorization + r.factorization) p % 2) = 1
Finset.prod_congr rfl fun p hp ↦ by r:ℕh₀:¬r = 0p:ℕhp:p ∈ (r * r).primeFactors⊢ p ^ ((r * r).factorization p % 2) = ?m.84 pinr r:ℕh₀:¬r = 0⊢ ∏ p ∈ (r * r).primeFactors, p ^ ((r.factorization + r.factorization) p % 2) = 1 rw [r.factorization_mul h₀ h₀ r:ℕh₀:¬r = 0p:ℕhp:p ∈ (r * r).primeFactors⊢ p ^ ((r.factorization + r.factorization) p % 2) = ?m.84 p All goals completed! 🐙inr r:ℕh₀:¬r = 0⊢ ∏ p ∈ (r * r).primeFactors, p ^ ((r.factorization + r.factorization) p % 2) = 1] All goals completed! 🐙inr r:ℕh₀:¬r = 0⊢ ∏ p ∈ (r * r).primeFactors, p ^ ((r.factorization + r.factorization) p % 2) = 1]inr r:ℕh₀:¬r = 0⊢ ∏ p ∈ (r * r).primeFactors, p ^ ((r.factorization + r.factorization) p % 2) = 1
simp [← two_mul] All goals completed! 🐙If $n = \prod_p p^{e_p}$ is the prime factorization of $n$, then $\prod_p p^{e_p \pmod{2}}$ is the prime factorization of the squarefree part of $n$.
theorem squarefreePart_factorization (n : ℕ) {p : ℕ} (hp : p.Prime) :
n.squarefreePart.factorization p = n.factorization p % 2 := by n:ℕp:ℕhp:Prime p⊢ n.squarefreePart.factorization p = n.factorization p % 2
rw [squarefreePart, n:ℕp:ℕhp:Prime p⊢ (n.factorization.prod fun p e ↦ p ^ (e % 2)).factorization p = n.factorization p % 2 All goals completed! 🐙 prod_factorization_eq_prod_primeFactors, n:ℕp:ℕhp:Prime p⊢ (∏ p ∈ n.primeFactors, p ^ (n.factorization p % 2)).factorization p = n.factorization p % 2 All goals completed! 🐙
n.prod_primeFactors_factorization_apply hp (f := fun p n ↦ n.factorization p % 2)
(fun _ _ h ↦ by n:ℕp:ℕhp:Prime px✝¹:ℕx✝:ℕh:¬x✝¹ ∣ x✝⊢ x✝.factorization x✝¹ % 2 = 0 All goals completed! 🐙 simp [factorization_eq_zero_of_not_dvd h] All goals completed! 🐙 All goals completed! 🐙) (by n:ℕp:ℕhp:Prime p⊢ ∀ (q : ℕ), (factorization 0) q % 2 = 0 All goals completed! 🐙 simp All goals completed! 🐙 All goals completed! 🐙)] All goals completed! 🐙theorem Prime.squarefree {p : ℕ} (hp : p.Prime) : Squarefree p := Irreducible.squarefree hptheorem squarefree_squarefreePart (n : ℕ) : Squarefree n.squarefreePart := by n:ℕ⊢ Squarefree n.squarefreePart
refine Nat.squarefree_iff_factorization_le_one n.squarefreePart_ne_zero |>.2 fun p ↦ ?_ n:ℕp:ℕ⊢ n.squarefreePart.factorization p ≤ 1
by_cases hp : p.Prime pos n:ℕp:ℕhp:Prime p⊢ n.squarefreePart.factorization p ≤ 1neg n:ℕp:ℕhp:¬Prime p⊢ n.squarefreePart.factorization p ≤ 1
· pos n:ℕp:ℕhp:Prime p⊢ n.squarefreePart.factorization p ≤ 1 linarith [n.squarefreePart_factorization hp, Nat.mod_lt (n.factorization p) two_pos] All goals completed! 🐙
· neg n:ℕp:ℕhp:¬Prime p⊢ n.squarefreePart.factorization p ≤ 1 linarith [factorization_eq_zero_of_not_prime n.squarefreePart hp] All goals completed! 🐙theorem squarefreePart_dvd (n : ℕ) : squarefreePart n ∣ n := by n:ℕ⊢ n.squarefreePart ∣ n
rcases eq_or_ne n 0 with (rfl | h₀) inl ⊢ squarefreePart 0 ∣ 0inr n:ℕh₀:n ≠ 0⊢ n.squarefreePart ∣ n; simp inr n:ℕh₀:n ≠ 0⊢ n.squarefreePart ∣ n
exact Nat.factorization_prime_le_iff_dvd n.squarefreePart_ne_zero h₀ |>.1 fun p hp ↦
squarefreePart_factorization _ hp ▸ Nat.mod_le _ _ All goals completed! 🐙
The square part is the value of b ^ 2 in the squarefree decomposition of n = a₀ * b ^ 2.
def squarePart (n : ℕ) : ℕ := n / n.squarefreeParttheorem squarePart_zero : squarePart 0 = 0 := by ⊢ squarePart 0 = 0 simp [squarePart] All goals completed! 🐙The squarefree decomposition of a natural number.
theorem squarefreePart_mul_squarePart (n : ℕ) : n.squarefreePart * n.squarePart = n :=
Nat.mul_div_eq_iff_dvd.2 n.squarefreePart_dvdtheorem squarefree_infinite : Set.Infinite { n : ℕ | Squarefree n } :=
Set.Infinite.mono (fun _ hp ↦ hp.squarefree) Nat.infinite_setOfPred_primeend Nat