File: Mathlib/NumberTheory/FermatPsp.lean

full_name: Nat.ProbablePrime
code: /--
`n` is a probable prime to base `b` if `n` passes the Fermat primality test; that is, `n` divides
`b ^ (n - 1) - 1`.
This definition implies that all numbers are probable primes to base 0 or 1, and that 0 and 1 are
probable primes to any base.
-/
def ProbablePrime (n b : ℕ) : Prop 
goal: Prop

full_name: Nat.FermatPsp
code: /--
`n` is a Fermat pseudoprime to base `b` if `n` is a probable prime to base `b` and is composite. By
this definition, all composite natural numbers are pseudoprimes to base 0 and 1. This definition
also permits `n` to be less than `b`, so that 4 is a pseudoprime to base 5, for example.
-/
def FermatPsp (n b : ℕ) : Prop 
goal: Prop

full_name: Nat.decidableProbablePrime
code: instance decidableProbablePrime (n b : ℕ) : Decidable (ProbablePrime n b) 
goal: Decidable (n.ProbablePrime b)

full_name: Nat.decidablePsp
code: instance decidablePsp (n b : ℕ) : Decidable (FermatPsp n b) 
goal: Decidable (n.FermatPsp b)

full_name: Nat.coprime_of_probablePrime
code: /-- If `n` passes the Fermat primality test to base `b`, then `n` is coprime with `b`, assuming that
`n` and `b` are both positive.
-/
theorem coprime_of_probablePrime {n b : ℕ} (h : ProbablePrime n b) (h₁ : 1 ≤ n) (h₂ : 1 ≤ b) :
    Nat.Coprime n b 
goal: n.Coprime b

full_name: Nat.probablePrime_iff_modEq
code: theorem probablePrime_iff_modEq (n : ℕ) {b : ℕ} (h : 1 ≤ b) :
    ProbablePrime n b ↔ b ^ (n - 1) ≡ 1 [MOD n] 
goal: n.ProbablePrime b ↔ b ^ (n - 1) ≡ 1 [MOD n]

full_name: Nat.coprime_of_fermatPsp
code: /-- If `n` is a Fermat pseudoprime to base `b`, then `n` is coprime with `b`, assuming that `b` is
positive.

This lemma is a small wrapper based on `coprime_of_probablePrime`
-/
theorem coprime_of_fermatPsp {n b : ℕ} (h : FermatPsp n b) (h₁ : 1 ≤ b) : Nat.Coprime n b 
goal: n.Coprime b

full_name: Nat.fermatPsp_base_one
code: /-- All composite numbers are Fermat pseudoprimes to base 1.
-/
theorem fermatPsp_base_one {n : ℕ} (h₁ : 1 < n) (h₂ : ¬n.Prime) : FermatPsp n 1 
goal: n.FermatPsp 1

full_name: _private.Mathlib.NumberTheory.FermatPsp.0.Nat.a_id_helper
code: private theorem a_id_helper {a b : ℕ} (ha : 2 ≤ a) (hb : 2 ≤ b) : 2 ≤ (a ^ b - 1) / (a - 1) 
goal: 2 ≤ (a ^ b - 1) / (a - 1)

full_name: _private.Mathlib.NumberTheory.FermatPsp.0.Nat.b_id_helper
code: private theorem b_id_helper {a b : ℕ} (ha : 2 ≤ a) (hb : 2 < b) : 2 ≤ (a ^ b + 1) / (a + 1) 
goal: 2 ≤ (a ^ b + 1) / (a + 1)

full_name: _private.Mathlib.NumberTheory.FermatPsp.0.Nat.AB_id_helper
code: private theorem AB_id_helper (b p : ℕ) (_ : 2 ≤ b) (hp : Odd p) :
    (b ^ p - 1) / (b - 1) * ((b ^ p + 1) / (b + 1)) = (b ^ (2 * p) - 1) / (b ^ 2 - 1) 
goal: 2 ≤ b → Odd p → (b ^ p - 1) / (b - 1) * ((b ^ p + 1) / (b + 1)) = (b ^ (2 * p) - 1) / (b ^ 2 - 1)

full_name: _private.Mathlib.NumberTheory.FermatPsp.0.Nat.bp_helper
code: /-- Used in the proof of `psp_from_prime_psp`
-/
private theorem bp_helper {b p : ℕ} (hb : 0 < b) (hp : 1 ≤ p) :
    b ^ (2 * p) - 1 - (b ^ 2 - 1) = b * (b ^ (p - 1) - 1) * (b ^ p + b) 
goal: b ^ (2 * p) - 1 - (b ^ 2 - 1) = b * (b ^ (p - 1) - 1) * (b ^ p + b)

full_name: _private.Mathlib.NumberTheory.FermatPsp.0.Nat.psp_from_prime
code: /-- Given a prime `p` which does not divide `b * (b ^ 2 - 1)`, we can produce a number `n` which is
larger than `p` and pseudoprime to base `b`. We do this by defining
`n = ((b ^ p - 1) / (b - 1)) * ((b ^ p + 1) / (b + 1))`

The primary purpose of this definition is to help prove `exists_infinite_pseudoprimes`. For a proof
that `n` is actually pseudoprime to base `b`, see `psp_from_prime_psp`, and for a proof that `n` is
greater than `p`, see `psp_from_prime_gt_p`.

This lemma is intended to be used when `2 ≤ b`, `2 < p`, `p` is prime, and `¬p ∣ b * (b ^ 2 - 1)`,
because those are the hypotheses for `psp_from_prime_psp`.
-/
private def psp_from_prime (b : ℕ) (p : ℕ) : ℕ 
goal: ℕ

full_name: _private.Mathlib.NumberTheory.FermatPsp.0.Nat.psp_from_prime_psp
code: /--
This is a proof that the number produced using `psp_from_prime` is actually pseudoprime to base `b`.
The primary purpose of this lemma is to help prove `exists_infinite_pseudoprimes`.

We use <https://primes.utm.edu/notes/proofs/a_pseudoprimes.html> as a rough outline of the proof.
-/
private theorem psp_from_prime_psp {b : ℕ} (b_ge_two : 2 ≤ b) {p : ℕ} (p_prime : p.Prime)
    (p_gt_two : 2 < p) (not_dvd : ¬p ∣ b * (b ^ 2 - 1)) : FermatPsp (psp_from_prime b p) b 
goal: (Nat.psp_from_prime b p).FermatPsp b

full_name: _private.Mathlib.NumberTheory.FermatPsp.0.Nat.psp_from_prime_gt_p
code: /--
This is a proof that the number produced using `psp_from_prime` is greater than the prime `p` used
to create it. The primary purpose of this lemma is to help prove `exists_infinite_pseudoprimes`.
-/
private theorem psp_from_prime_gt_p {b : ℕ} (b_ge_two : 2 ≤ b) {p : ℕ} (p_prime : p.Prime)
    (p_gt_two : 2 < p) : p < psp_from_prime b p 
goal: p < Nat.psp_from_prime b p

full_name: Nat.exists_infinite_pseudoprimes
code: /-- For all positive bases, there exist infinite **Fermat pseudoprimes** to that base.
Given in this form: for all numbers `b ≥ 1` and `m`, there exists a pseudoprime `n` to base `b` such
that `m ≤ n`. This form is similar to `Nat.exists_infinite_primes`.
-/
theorem exists_infinite_pseudoprimes {b : ℕ} (h : 1 ≤ b) (m : ℕ) :
    ∃ n : ℕ, FermatPsp n b ∧ m ≤ n 
goal: ∃ n, n.FermatPsp b ∧ m ≤ n

full_name: Nat.frequently_atTop_fermatPsp
code: theorem frequently_atTop_fermatPsp {b : ℕ} (h : 1 ≤ b) : ∃ᶠ n in Filter.atTop, FermatPsp n b 
goal: ∃ᶠ (n : ℕ) in Filter.atTop, n.FermatPsp b

full_name: Nat.infinite_setOf_pseudoprimes
code: /-- Infinite set variant of `Nat.exists_infinite_pseudoprimes`
-/
theorem infinite_setOf_pseudoprimes {b : ℕ} (h : 1 ≤ b) :
    Set.Infinite { n : ℕ | FermatPsp n b } 
goal: {n | n.FermatPsp b}.Infinite