|
import Mathlib |
|
|
|
/- |
|
This file formalizes a finite-prime-test version of Euclid's theorem using |
|
Mathlib's sigma algebras, represented by `MeasurableSpace`. |
|
|
|
Fix a finite set `P` of proposed prime tests. The basic observable questions |
|
are the divisibility events |
|
|
|
`DivEvent p = {n : ℕ | p ∣ n}` |
|
|
|
for `p ∈ P`; the full collection of questions available to the test is the |
|
measurable space generated by these events, |
|
`TestMeasurableSpace P = MeasurableSpace.generateFrom (DivGenerators P)`. |
|
|
|
The key topological/sigma-algebraic idea is shift invariance. A set `B` is |
|
`M`-shift invariant if membership in `B` is unchanged by replacing `n` with |
|
`n + M`. If every `p ∈ P` divides `M`, then each divisibility event |
|
`DivEvent p` is `M`-shift invariant. Since the `M`-shift invariant sets form |
|
a sigma algebra, every question generated by the finite test is also |
|
`M`-shift invariant. |
|
|
|
Now suppose `P` were a complete finite list of all primes, and choose a |
|
positive common shift `M` divisible by every `p ∈ P`. The failure event |
|
|
|
`Failure P = {n | no p ∈ P divides n}` |
|
|
|
is measurable for the finite test. Completeness of `P` makes this event |
|
exactly `{1}`: no prime divides `1`, while every `n ≥ 2` has some prime |
|
divisor from `P`. But `{1}` is not invariant under any positive shift. This |
|
contradicts the fact that every testable event is `M`-shift invariant. |
|
|
|
The final theorem `infinite_setOf_prime` packages this contradiction as the |
|
standard statement that the set `{p : ℕ | Nat.Prime p}` is infinite. |
|
-/ |
|
|
|
open Set |
|
open Classical |
|
open scoped MeasureTheory |
|
|
|
namespace MathlibSigmaPrimeTest |
|
|
|
/-- Membership in `B` is invariant under the forward shift `n ↦ n + N`. -/ |
|
def ShiftInvariant (N : ℕ) (B : Set ℕ) : Prop := |
|
∀ n : ℕ, n ∈ B ↔ n + N ∈ B |
|
|
|
/-- The singleton `{1}` is not shift invariant under any positive shift. -/ |
|
theorem not_shiftInvariant_singleton_one {N : ℕ} (hN : 0 < N) : |
|
¬ ShiftInvariant N ({1} : Set ℕ) := by |
|
intro h |
|
have hmem : 1 + N ∈ ({1} : Set ℕ) := (h 1).mp (by simp) |
|
have hEq : 1 + N = 1 := by simpa using hmem |
|
omega |
|
|
|
/-- The measurable space whose measurable sets are exactly the sets invariant |
|
under the forward shift by `N`. -/ |
|
@[implicit_reducible] |
|
def ShiftInvariantMeasurableSpace (N : ℕ) : MeasurableSpace ℕ where |
|
MeasurableSet' := ShiftInvariant N |
|
measurableSet_empty := by |
|
intro n |
|
simp |
|
measurableSet_compl := by |
|
intro B hB n |
|
constructor |
|
· intro hnB |
|
change n + N ∉ B |
|
intro hnNB |
|
exact hnB ((hB n).mpr hnNB) |
|
· intro hnNB |
|
change n ∉ B |
|
intro hnB0 |
|
exact hnNB ((hB n).mp hnB0) |
|
measurableSet_iUnion := by |
|
intro B hB n |
|
constructor |
|
· intro hn |
|
rcases Set.mem_iUnion.mp hn with ⟨j, hj⟩ |
|
exact Set.mem_iUnion.mpr ⟨j, (hB j n).mp hj⟩ |
|
· intro hn |
|
rcases Set.mem_iUnion.mp hn with ⟨j, hj⟩ |
|
exact Set.mem_iUnion.mpr ⟨j, (hB j n).mpr hj⟩ |
|
|
|
/-- The divisibility event associated with `p`. -/ |
|
def DivEvent (p : ℕ) : Set ℕ := |
|
{n | p ∣ n} |
|
|
|
/-- Divisibility by `p` is shift invariant under adding `M` when `p ∣ M`. -/ |
|
theorem divEvent_shiftInvariant_of_dvd {p M : ℕ} (h : p ∣ M) : |
|
ShiftInvariant M (DivEvent p) := by |
|
intro n |
|
constructor |
|
· intro hn |
|
exact Nat.dvd_add hn h |
|
· intro hn |
|
exact (Nat.dvd_add_iff_right h).2 (by simpa [Nat.add_comm] using hn) |
|
|
|
/-- The generators available to the finite divisibility test. -/ |
|
def DivGenerators (P : Finset ℕ) : Set (Set ℕ) := |
|
{E | ∃ p ∈ P, E = DivEvent p} |
|
|
|
/-- The Mathlib measurable space generated by the finite divisibility test. -/ |
|
@[implicit_reducible] |
|
def TestMeasurableSpace (P : Finset ℕ) : MeasurableSpace ℕ := |
|
MeasurableSpace.generateFrom (DivGenerators P) |
|
|
|
/-- The success event: some listed divisor divides the input. -/ |
|
def Success (P : Finset ℕ) : Set ℕ := |
|
{n | ∃ p ∈ P, p ∣ n} |
|
|
|
/-- The failure event: no listed divisor divides the input. -/ |
|
def Failure (P : Finset ℕ) : Set ℕ := |
|
(Success P)ᶜ |
|
|
|
/-- The success event is measurable for the finite divisibility test. -/ |
|
theorem success_measurable_testMeasurableSpace (P : Finset ℕ) : |
|
MeasurableSet[TestMeasurableSpace P] (Success P) := by |
|
let A : ℕ → Set ℕ := fun p => if hp : p ∈ P then DivEvent p else ∅ |
|
have hA : ∀ p, MeasurableSet[TestMeasurableSpace P] (A p) := by |
|
intro p |
|
by_cases hp : p ∈ P |
|
· have hgen : DivEvent p ∈ DivGenerators P := ⟨p, hp, rfl⟩ |
|
simpa [A, hp, TestMeasurableSpace] using |
|
(MeasurableSpace.measurableSet_generateFrom hgen) |
|
· simp [A, hp] |
|
have hUnion : MeasurableSet[TestMeasurableSpace P] (⋃ p, A p) := |
|
MeasurableSet.iUnion hA |
|
convert hUnion using 1 |
|
ext n |
|
constructor |
|
· rintro ⟨p, hpP, hpdvd⟩ |
|
exact Set.mem_iUnion.mpr ⟨p, by simp [A, hpP, DivEvent, hpdvd]⟩ |
|
· intro hn |
|
rcases Set.mem_iUnion.mp hn with ⟨p, hp⟩ |
|
by_cases hpP : p ∈ P |
|
· exact ⟨p, hpP, by simpa [A, hpP, DivEvent] using hp⟩ |
|
· simp [A, hpP] at hp |
|
|
|
/-- The failure event is measurable for the finite divisibility test. -/ |
|
theorem failure_measurable_testMeasurableSpace (P : Finset ℕ) : |
|
MeasurableSet[TestMeasurableSpace P] (Failure P) := by |
|
exact (success_measurable_testMeasurableSpace P).compl |
|
|
|
/-- If the listed divisibility events are `M`-shift invariant, then the |
|
test-generated measurable space is below the `M`-shift-invariant measurable |
|
space. -/ |
|
theorem testMeasurableSpace_le_shiftInvariantMeasurableSpace |
|
{P : Finset ℕ} {M : ℕ} |
|
(hShift : ∀ p, p ∈ P → ShiftInvariant M (DivEvent p)) : |
|
TestMeasurableSpace P ≤ ShiftInvariantMeasurableSpace M := by |
|
apply MeasurableSpace.generateFrom_le |
|
intro E hE |
|
rcases hE with ⟨p, hpP, rfl⟩ |
|
change ShiftInvariant M (DivEvent p) |
|
exact hShift p hpP |
|
|
|
/-- Hence every event measurable for the finite test is `M`-shift invariant. -/ |
|
theorem shiftInvariant_of_testMeasurableSpace |
|
{P : Finset ℕ} {M : ℕ} |
|
(hShift : ∀ p, p ∈ P → ShiftInvariant M (DivEvent p)) |
|
{B : Set ℕ} (hB : MeasurableSet[TestMeasurableSpace P] B) : |
|
ShiftInvariant M B := by |
|
have hMeas : MeasurableSet[ShiftInvariantMeasurableSpace M] B := |
|
testMeasurableSpace_le_shiftInvariantMeasurableSpace hShift B hB |
|
exact hMeas |
|
|
|
/-- If `P` consists of primes and every `n ≥ 2` has a divisor from `P`, then |
|
the failure event is exactly `{1}`. -/ |
|
theorem failure_eq_singleton_one_of_complete |
|
(P : Finset ℕ) |
|
(hPrimeP : ∀ p, p ∈ P → Nat.Prime p) |
|
(hComplete : ∀ n, 2 ≤ n → ∃ p ∈ P, p ∣ n) : |
|
Failure P = ({1} : Set ℕ) := by |
|
ext n |
|
constructor |
|
· intro hnFail |
|
have hNo : ¬ ∃ p, p ∈ P ∧ p ∣ n := by |
|
simpa [Failure, Success] using hnFail |
|
by_cases h0 : n = 0 |
|
· rcases hComplete 2 (by norm_num) with ⟨p, hpP, _⟩ |
|
have hpdvdn : p ∣ n := by |
|
rw [h0] |
|
exact Nat.dvd_zero p |
|
exact False.elim (hNo ⟨p, hpP, hpdvdn⟩) |
|
· by_cases h1 : n = 1 |
|
· simp [h1] |
|
· have hn2 : 2 ≤ n := by omega |
|
rcases hComplete n hn2 with ⟨p, hpP, hpdvdn⟩ |
|
exact False.elim (hNo ⟨p, hpP, hpdvdn⟩) |
|
· intro hnOne |
|
have h1 : n = 1 := by simpa using hnOne |
|
rw [h1] |
|
change ¬ ∃ p, p ∈ P ∧ p ∣ 1 |
|
rintro ⟨p, hpP, hpdvd1⟩ |
|
have hp : Nat.Prime p := hPrimeP p hpP |
|
have hp_eq_one : p = 1 := Nat.eq_one_of_dvd_one hpdvd1 |
|
exact hp.ne_one hp_eq_one |
|
|
|
/-- The sigma-algebraic contradiction, using Mathlib's measurable spaces. -/ |
|
theorem no_finite_complete_prime_test_shiftInvariant |
|
(P : Finset ℕ) {M : ℕ} (hM : 0 < M) |
|
(hShift : ∀ p, p ∈ P → ShiftInvariant M (DivEvent p)) |
|
(hPrimeP : ∀ p, p ∈ P → Nat.Prime p) |
|
(hComplete : ∀ n, 2 ≤ n → ∃ p ∈ P, p ∣ n) : |
|
False := by |
|
have hFailMem : MeasurableSet[TestMeasurableSpace P] (Failure P) := |
|
failure_measurable_testMeasurableSpace P |
|
have hFailEq : Failure P = ({1} : Set ℕ) := |
|
failure_eq_singleton_one_of_complete P hPrimeP hComplete |
|
have hFailShiftInvariant : ShiftInvariant M (Failure P) := |
|
shiftInvariant_of_testMeasurableSpace hShift hFailMem |
|
have hSingletonShiftInvariant : ShiftInvariant M ({1} : Set ℕ) := by |
|
simpa [hFailEq] using hFailShiftInvariant |
|
exact not_shiftInvariant_singleton_one hM hSingletonShiftInvariant |
|
|
|
/-- There is no finite set containing exactly all primes. -/ |
|
theorem no_finite_set_of_all_primes : |
|
¬ ∃ P : Finset ℕ, ∀ p : ℕ, Nat.Prime p ↔ p ∈ P := by |
|
rintro ⟨P, hP⟩ |
|
let M := P.prod id |
|
have hPrimeP : ∀ p, p ∈ P → Nat.Prime p := by |
|
intro p hpP |
|
exact (hP p).mpr hpP |
|
have hM : 0 < M := by |
|
exact Finset.prod_pos (fun p hpP => (hPrimeP p hpP).pos) |
|
have hShift : ∀ p, p ∈ P → ShiftInvariant M (DivEvent p) := by |
|
intro p hpP |
|
exact divEvent_shiftInvariant_of_dvd (Finset.dvd_prod_of_mem id hpP) |
|
have hComplete : ∀ n, 2 ≤ n → ∃ p ∈ P, p ∣ n := by |
|
intro n hn |
|
have hn_ne_one : n ≠ 1 := by omega |
|
rcases Nat.exists_prime_and_dvd hn_ne_one with ⟨p, hpPrime, hpdvd⟩ |
|
exact ⟨p, (hP p).mp hpPrime, hpdvd⟩ |
|
exact no_finite_complete_prime_test_shiftInvariant P hM hShift hPrimeP hComplete |
|
|
|
/-- The set of prime natural numbers is infinite. -/ |
|
theorem infinite_setOf_prime : Set.Infinite {p : ℕ | Nat.Prime p} := by |
|
intro hFinite |
|
exact no_finite_set_of_all_primes ⟨hFinite.toFinset, by |
|
intro p |
|
exact (hFinite.mem_toFinset (a := p)).symm⟩ |
|
|
|
end MathlibSigmaPrimeTest |