Different Proofs

2. Infinitude of Primes🔗

Lean code for Definition2.11 definition
  • def InfinitudeOfPrimesInfinitudeOfPrimes : Prop : PropThe universe of propositions. `Prop ≡ Sort 0`.
    
    Every proposition is propositionally equal to either `True` or `False`. 
    def InfinitudeOfPrimesInfinitudeOfPrimes : Prop : PropThe universe of propositions. `Prop ≡ Sort 0`.
    
    Every proposition is propositionally equal to either `True` or `False`. 
Lean code for Definition2.21 definition
  • def InfinitudeOfPrimes'InfinitudeOfPrimes' : Prop : PropThe universe of propositions. `Prop ≡ Sort 0`.
    
    Every proposition is propositionally equal to either `True` or `False`. 
    def InfinitudeOfPrimes'InfinitudeOfPrimes' : Prop : PropThe universe of propositions. `Prop ≡ Sort 0`.
    
    Every proposition is propositionally equal to either `True` or `False`. 
Lean code for Theorem2.31 theorem
  • theorem InfinitudeOfPrimes_iff_InfinitudeOfPrimes'InfinitudeOfPrimes_iff_InfinitudeOfPrimes' : InfinitudeOfPrimes ↔ InfinitudeOfPrimes' :
      InfinitudeOfPrimesInfinitudeOfPrimes : Prop Iff (a b : Prop) : PropIf and only if, or logical bi-implication. `a ↔ b` means that `a` implies `b` and vice versa.
    By `propext`, this implies that `a` and `b` are equal and hence any expression involving `a`
    is equivalent to the corresponding expression with `b` instead.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `↔` in identifiers is `iff`.
    
     * The recommended spelling of `<->` in identifiers is `iff` (prefer `↔` over `<->`). InfinitudeOfPrimes'InfinitudeOfPrimes' : Prop
    theorem InfinitudeOfPrimes_iff_InfinitudeOfPrimes'InfinitudeOfPrimes_iff_InfinitudeOfPrimes' : InfinitudeOfPrimes ↔ InfinitudeOfPrimes' :
      InfinitudeOfPrimesInfinitudeOfPrimes : Prop Iff (a b : Prop) : PropIf and only if, or logical bi-implication. `a ↔ b` means that `a` implies `b` and vice versa.
    By `propext`, this implies that `a` and `b` are equal and hence any expression involving `a`
    is equivalent to the corresponding expression with `b` instead.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `↔` in identifiers is `iff`.
    
     * The recommended spelling of `<->` in identifiers is `iff` (prefer `↔` over `<->`). InfinitudeOfPrimes'InfinitudeOfPrimes' : Prop
Proof for Theorem 2.3

Specialize the general characterization of infinite subsets of a locally finite linear order to the set of natural primes.

First proof is by Euclid.

Lean code for Theorem2.41 theorem
  • theorem InfinitudeOfPrimes_Euclid'InfinitudeOfPrimes_Euclid' : InfinitudeOfPrimes : InfinitudeOfPrimesInfinitudeOfPrimes : Prop
    theorem InfinitudeOfPrimes_Euclid'InfinitudeOfPrimes_Euclid' : InfinitudeOfPrimes :
      InfinitudeOfPrimesInfinitudeOfPrimes : Prop
Proof for Theorem 2.4

If the set of primes were finite, a prime divisor of one plus their product would already lie in the set, and therefore divide both the product and the product plus one.

A variant of Euclid's proof uses n! + 1 instead of the product of all primes.

Lean code for Theorem2.51 theorem
  • theorem InfinitudeOfPrimes_EuclidInfinitudeOfPrimes_Euclid : InfinitudeOfPrimes : InfinitudeOfPrimesInfinitudeOfPrimes : Prop
    theorem InfinitudeOfPrimes_EuclidInfinitudeOfPrimes_Euclid : InfinitudeOfPrimes :
      InfinitudeOfPrimesInfinitudeOfPrimes : Prop
Proof for Theorem 2.5

If all primes were bounded by n, a prime divisor of n! + 1 would both divide n! and divide n! + 1, hence divide 1, impossible; so the primes are infinite Definition 2.1.

Second proof is by Goldbach, using Fermat numbers F_n = 2^{2^n} + 1 and their pairwise coprimality.

Lean code for Definition2.61 definition
  • def FermatFermat (n : ℕ) : ℕ (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    
    def FermatFermat (n : ℕ) : ℕ (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    
Lean code for Lemma2.71 theorem
  • theorem Fermat_gt_twoFermat_gt_two (n : ℕ) : Fermat n ≥ 2 (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : FermatFermat (n : ℕ) : ℕ n GE.ge.{u} {α : Type u} [LE α] (a b : α) : Prop`a ≥ b` is an abbreviation for `b ≤ a`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≥` in identifiers is `ge`. 2
    theorem Fermat_gt_twoFermat_gt_two (n : ℕ) : Fermat n ≥ 2 (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : FermatFermat (n : ℕ) : ℕ n GE.ge.{u} {α : Type u} [LE α] (a b : α) : Prop`a ≥ b` is an abbreviation for `b ≤ a`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≥` in identifiers is `ge`. 2
Proof for Lemma 2.7

Since 2^{2^n} \ge 1, adding one gives F_n \ge 2.

Lean code for Lemma2.81 theorem
  • theorem Fermat_oddFermat_odd (n : ℕ) : Odd (Fermat n) (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : OddOdd.{u_2} {α : Type u_2} [Semiring α] (a : α) : PropAn element `a` of a semiring is odd if there exists `k` such `a = 2*k + 1`.  (FermatFermat (n : ℕ) : ℕ n)
    theorem Fermat_oddFermat_odd (n : ℕ) : Odd (Fermat n) (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : OddOdd.{u_2} {α : Type u_2} [Semiring α] (a : α) : PropAn element `a` of a semiring is odd if there exists `k` such `a = 2*k + 1`.  (FermatFermat (n : ℕ) : ℕ n)
Proof for Lemma 2.8

The exponent 2^n is positive, so 2^{2^n} is even and 2^{2^n}+1 is odd.

Lean code for Lemma2.91 theorem
  • theorem Fermat_recurrenceFermat_recurrence (n : ℕ) : Fermat (n + 1) = ∏ k ∈ Finset.range (n + 1), Fermat k + 2 (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) :
      FermatFermat (n : ℕ) : ℕ (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.  k  Finset.rangeFinset.range (n : ℕ) : Finset ℕ`range n` is the set of natural numbers less than `n`.  (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`., FermatFermat (n : ℕ) : ℕ k +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 2
    theorem Fermat_recurrenceFermat_recurrence (n : ℕ) : Fermat (n + 1) = ∏ k ∈ Finset.range (n + 1), Fermat k + 2 (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) :
      FermatFermat (n : ℕ) : ℕ (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`.
         k  Finset.rangeFinset.range (n : ℕ) : Finset ℕ`range n` is the set of natural numbers less than `n`.  (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`., FermatFermat (n : ℕ) : ℕ k +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.
          2
Proof for Lemma 2.9

Inductively prove that \prod_{k<n} F_k = F_n - 2, then rewrite the next product using the difference-of-squares identity.

Lean code for Lemma2.101 theorem
  • theorem Fermat_coprimeFermat_coprime (n : ℕ) : (Fermat (n + 1)).Coprime (∏ k ∈ Finset.range (n + 1), Fermat k) (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) :
      (FermatFermat (n : ℕ) : ℕ (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.).CoprimeNat.Coprime (m n : ℕ) : Prop`m` and `n` are coprime, or relatively prime, if their `gcd` is 1.  (∏ k  Finset.rangeFinset.range (n : ℕ) : Finset ℕ`range n` is the set of natural numbers less than `n`.  (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`., FermatFermat (n : ℕ) : ℕ k)
    theorem Fermat_coprimeFermat_coprime (n : ℕ) : (Fermat (n + 1)).Coprime (∏ k ∈ Finset.range (n + 1), Fermat k) (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) :
      (FermatFermat (n : ℕ) : ℕ (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.).CoprimeNat.Coprime (m n : ℕ) : Prop`m` and `n` are coprime, or relatively prime, if their `gcd` is 1. 
        (∏ k  Finset.rangeFinset.range (n : ℕ) : Finset ℕ`range n` is the set of natural numbers less than `n`.  (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`., FermatFermat (n : ℕ) : ℕ k)
Proof for Lemma 2.10

The recurrence writes F_{n+1} as the product plus 2. The product is odd, so the only possible common divisor with 2 is 1.

Lean code for Lemma2.111 theorem
  • theorem Fermat_pairwise_coprimeFermat_pairwise_coprime : Pairwise fun m n ↦ (Fermat m).Coprime (Fermat n) :
      PairwisePairwise.{u_1} {α : Type u_1} (r : α → α → Prop) : PropA relation `r` holds pairwise if `r i j` for all `i ≠ j`.  fun m n  (FermatFermat (n : ℕ) : ℕ m).CoprimeNat.Coprime (m n : ℕ) : Prop`m` and `n` are coprime, or relatively prime, if their `gcd` is 1.  (FermatFermat (n : ℕ) : ℕ n)
    theorem Fermat_pairwise_coprimeFermat_pairwise_coprime : Pairwise fun m n ↦ (Fermat m).Coprime (Fermat n) :
      PairwisePairwise.{u_1} {α : Type u_1} (r : α → α → Prop) : PropA relation `r` holds pairwise if `r i j` for all `i ≠ j`.  fun m n 
        (FermatFermat (n : ℕ) : ℕ m).CoprimeNat.Coprime (m n : ℕ) : Prop`m` and `n` are coprime, or relatively prime, if their `gcd` is 1.  (FermatFermat (n : ℕ) : ℕ n)
Proof for Lemma 2.11

For m<n, the number F_m divides the product of the earlier Fermat numbers, which is coprime to F_n.

Lean code for Theorem2.121 theorem
  • theorem InfinitudeOfPrimes_GoldbachInfinitudeOfPrimes_Goldbach : InfinitudeOfPrimes : InfinitudeOfPrimesInfinitudeOfPrimes : Prop
    theorem InfinitudeOfPrimes_GoldbachInfinitudeOfPrimes_Goldbach : InfinitudeOfPrimes :
      InfinitudeOfPrimesInfinitudeOfPrimes : Prop
Proof for Theorem 2.12

Each Fermat number has a prime divisor. Pairwise coprimality Lemma 2.11 makes the chosen prime divisors pairwise distinct, producing infinitely many primes.

Third proof is by Euler, using the divergence of the harmonic series and the Euler product formula.

Lean code for Theorem2.131 theorem
  • theorem harmonic_unboundedharmonic_unbounded (M : ℝ) : ∃ n, ↑(harmonic n) > M (M : Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. ) :  n, (harmonicharmonic : ℕ → ℚThe nth-harmonic number defined as a finset sum of consecutive reciprocals.  n) >GT.gt.{u} {α : Type u} [LT α] (a b : α) : Prop`a > b` is an abbreviation for `b < a`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `>` in identifiers is `gt`. M
    theorem harmonic_unboundedharmonic_unbounded (M : ℝ) : ∃ n, ↑(harmonic n) > M (M : Real : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational
    numbers. ) :
       n, (harmonicharmonic : ℕ → ℚThe nth-harmonic number defined as a finset sum of consecutive reciprocals.  n) >GT.gt.{u} {α : Type u} [LT α] (a b : α) : Prop`a > b` is an abbreviation for `b < a`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `>` in identifiers is `gt`. M
Proof for Theorem 2.13

Use the inequality \log(n+1) \le H_n and the fact that the logarithm is unbounded.

Lean code for Theorem2.141 theorem
  • theorem prod_prime_div_prime_sub_one_ge_harmonicprod_prime_div_prime_sub_one_ge_harmonic (n : ℕ) :
      ∏ p ∈ Finset.range (n + 1) with Nat.Prime p, ↑p / (↑p - 1) ≥ harmonic n (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) :
       p  Finset.rangeFinset.range (n : ℕ) : Finset ℕ`range n` is the set of natural numbers less than `n`.  (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. with Nat.PrimeNat.Prime (p : ℕ) : Prop`Nat.Prime p` means that `p` is a prime number, that is, a natural number
    at least 2 whose only divisors are `p` and `1`.
    The theorem `Nat.prime_def` witnesses this description of a prime number.  p, p /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).p -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). 1)HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). GE.ge.{u} {α : Type u} [LE α] (a b : α) : Prop`a ≥ b` is an abbreviation for `b ≤ a`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≥` in identifiers is `ge`.
        harmonicharmonic : ℕ → ℚThe nth-harmonic number defined as a finset sum of consecutive reciprocals.  n
    theorem prod_prime_div_prime_sub_one_ge_harmonicprod_prime_div_prime_sub_one_ge_harmonic (n : ℕ) :
      ∏ p ∈ Finset.range (n + 1) with Nat.Prime p, ↑p / (↑p - 1) ≥ harmonic n
      (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) :
       p  Finset.rangeFinset.range (n : ℕ) : Finset ℕ`range n` is the set of natural numbers less than `n`.  (HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`.n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1)HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. with
          Nat.PrimeNat.Prime (p : ℕ) : Prop`Nat.Prime p` means that `p` is a prime number, that is, a natural number
    at least 2 whose only divisors are `p` and `1`.
    The theorem `Nat.prime_def` witnesses this description of a prime number.  p, p /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`.
    The meaning of this notation is type-dependent.
    * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
    * For `Nat`, `a / b` rounds downwards.
    * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
      It is implemented as `Int.ediv`, the unique function satisfying
      `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
      Other rounding conventions are available using the functions
      `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
    * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
      usually resulting in `inf` or `nan`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `/` in identifiers is `div`. (HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator).p -HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). 1)HSub.hSub.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HSub α β γ] : α → β → γ`a - b` computes the difference of `a` and `b`.
    The meaning of this notation is type-dependent.
    * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `-` in identifiers is `sub` (when used as a binary operator). GE.ge.{u} {α : Type u} [LE α] (a b : α) : Prop`a ≥ b` is an abbreviation for `b ≤ a`. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≥` in identifiers is `ge`.
        harmonicharmonic : ℕ → ℚThe nth-harmonic number defined as a finset sum of consecutive reciprocals.  n
Proof for Theorem 2.14

Expand each factor p/(p-1) as a finite geometric sum. The resulting product contains terms corresponding to reciprocals of positive integers up to n.

Lean code for Theorem2.151 theorem
  • theorem InfinitudeOfPrimes_EulerInfinitudeOfPrimes_Euler : InfinitudeOfPrimes : InfinitudeOfPrimesInfinitudeOfPrimes : Prop
    theorem InfinitudeOfPrimes_EulerInfinitudeOfPrimes_Euler : InfinitudeOfPrimes :
      InfinitudeOfPrimesInfinitudeOfPrimes : Prop
Proof for Theorem 2.15

If there were only finitely many primes, the Euler product over all of them would be fixed. But the product over primes below a sufficiently large bound Theorem 2.14 dominates arbitrarily large harmonic sums Theorem 2.13, a contradiction.

Fourth proof is by Saidak, using the sequence a_0 = 2 and a_{n+1} = a_n(a_n+1).

Lean code for Definition2.161 definition
  • def aa : ℕ → ℕ : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
      Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    
    def aa : ℕ → ℕ : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
      Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    
Lean code for Lemma2.171 theorem
  • theorem a_ge_twoa_ge_two (n : ℕ) : 2 ≤ a n (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : 2 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`. aa : ℕ → ℕ n
    theorem a_ge_twoa_ge_two (n : ℕ) : 2 ≤ a n (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : 2 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`. aa : ℕ → ℕ n
Proof for Lemma 2.17

The base case is 2; the inductive step multiplies two positive factors and stays at least 2.

Lean code for Lemma2.181 theorem
  • theorem a_primeFactors_card_gea_primeFactors_card_ge (n : ℕ) : n + 1 ≤ (a n).primeFactors.card (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) : n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`. (aa : ℕ → ℕ n).primeFactorsNat.primeFactors (n : ℕ) : Finset ℕThe prime factors of a natural number as a finset. .cardFinset.card.{u_1} {α : Type u_1} (s : Finset α) : ℕ`s.card` is the number of elements of `s`, aka its cardinality.
    
    The notation `#s` can be accessed in the `Finset` locale. 
    theorem a_primeFactors_card_gea_primeFactors_card_ge (n : ℕ) : n + 1 ≤ (a n).primeFactors.card (n : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    ) :
      n +HAdd.hAdd.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HAdd α β γ] : α → β → γ`a + b` computes the sum of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `+` in identifiers is `add`. 1 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`. (aa : ℕ → ℕ n).primeFactorsNat.primeFactors (n : ℕ) : Finset ℕThe prime factors of a natural number as a finset. .cardFinset.card.{u_1} {α : Type u_1} (s : Finset α) : ℕ`s.card` is the number of elements of `s`, aka its cardinality.
    
    The notation `#s` can be accessed in the `Finset` locale. 
Proof for Lemma 2.18

Consecutive numbers a_n and a_n+1 are coprime, so the prime factors of a_{n+1} split as a disjoint union of the prime factors of the two factors.

Lean code for Theorem2.191 theorem
  • theorem InfinitudeOfPrimes_SaidakInfinitudeOfPrimes_Saidak : InfinitudeOfPrimes : InfinitudeOfPrimesInfinitudeOfPrimes : Prop
    theorem InfinitudeOfPrimes_SaidakInfinitudeOfPrimes_Saidak : InfinitudeOfPrimes :
      InfinitudeOfPrimesInfinitudeOfPrimes : Prop
Proof for Theorem 2.19

If only finitely many primes existed, the number of prime factors of any a_n would be bounded by that finite set, contradicting the previous lemma Lemma 2.18 for large n.

Fifth proof is by Wunderlich, using Fibonacci numbers, their coprimality, and the fact that F_{37} has three distinct prime factors.

Lean code for Lemma2.201 theorem
  • theorem fib_37fib_37 : Nat.fib 37 = 73 * 149 * 2221 : Nat.fibNat.fib (n : ℕ) : ℕImplementation of the Fibonacci sequence satisfying
    `fib 0 = 0, fib 1 = 1, fib (n + 2) = fib n + fib (n + 1)`.
    
    *Note:* We use a stream iterator for better performance when compared to the naive recursive
    implementation.
     37 =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. 73 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. 149 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. 2221
    theorem fib_37fib_37 : Nat.fib 37 = 73 * 149 * 2221 : Nat.fibNat.fib (n : ℕ) : ℕImplementation of the Fibonacci sequence satisfying
    `fib 0 = 0, fib 1 = 1, fib (n + 2) = fib n + fib (n + 1)`.
    
    *Note:* We use a stream iterator for better performance when compared to the naive recursive
    implementation.
     37 =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`.
    We use `a = b` as notation for `Eq a b`.
    A fundamental property of equality is that it is an equivalence relation.
    ```
    variable (α : Type) (a b c d : α)
    variable (hab : a = b) (hcb : c = b) (hcd : c = d)
    
    example : a = d :=
      Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
    ```
    Equality is much more than an equivalence relation, however. It has the important property that every assertion
    respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
    That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
    Example:
    ```
    example (α : Type) (a b : α) (p : α → Prop)
            (h1 : a = b) (h2 : p a) : p b :=
      Eq.subst h1 h2
    
    example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
      h1 ▸ h2
    ```
    The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
    For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `=` in identifiers is `eq`. 73 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. 149 *HMul.hMul.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HMul α β γ] : α → β → γ`a * b` computes the product of `a` and `b`.
    The meaning of this notation is type-dependent. 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `*` in identifiers is `mul`. 2221
Proof for Lemma 2.20

This is a direct computation.

Lean code for Lemma2.211 theorem
  • theorem fib_prime_ge_twofib_prime_ge_two {p : ℕ} (hp : Nat.Prime p) (hp2 : p ≠ 2) : 2 ≤ Nat.fib p {p : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    } (hpNat.Prime p : Nat.PrimeNat.Prime (p : ℕ) : Prop`Nat.Prime p` means that `p` is a prime number, that is, a natural number
    at least 2 whose only divisors are `p` and `1`.
    The theorem `Nat.prime_def` witnesses this description of a prime number.  p) (hp2p ≠ 2 : p Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. 2) :
      2 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`. Nat.fibNat.fib (n : ℕ) : ℕImplementation of the Fibonacci sequence satisfying
    `fib 0 = 0, fib 1 = 1, fib (n + 2) = fib n + fib (n + 1)`.
    
    *Note:* We use a stream iterator for better performance when compared to the naive recursive
    implementation.
     p
    theorem fib_prime_ge_twofib_prime_ge_two {p : ℕ} (hp : Nat.Prime p) (hp2 : p ≠ 2) : 2 ≤ Nat.fib p {p : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    }
      (hpNat.Prime p : Nat.PrimeNat.Prime (p : ℕ) : Prop`Nat.Prime p` means that `p` is a prime number, that is, a natural number
    at least 2 whose only divisors are `p` and `1`.
    The theorem `Nat.prime_def` witnesses this description of a prime number.  p) (hp2p ≠ 2 : p Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. 2) :
      2 LE.le.{u} {α : Type u} [self : LE α] : α → α → PropThe less-equal relation: `x ≤ y` 
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≤` in identifiers is `le`. Nat.fibNat.fib (n : ℕ) : ℕImplementation of the Fibonacci sequence satisfying
    `fib 0 = 0, fib 1 = 1, fib (n + 2) = fib n + fib (n + 1)`.
    
    *Note:* We use a stream iterator for better performance when compared to the naive recursive
    implementation.
     p
Proof for Lemma 2.21

An odd prime is at least 3, and the Fibonacci sequence is monotone, so F_p \ge F_3 = 2.

Lean code for Lemma2.221 theorem
  • theorem fib_coprime_of_distinct_primesfib_coprime_of_distinct_primes {p q : ℕ} (hp : Nat.Prime p) (hq : Nat.Prime q) (hpq : p ≠ q) :
      (Nat.fib p).Coprime (Nat.fib q) {p q : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    } (hpNat.Prime p : Nat.PrimeNat.Prime (p : ℕ) : Prop`Nat.Prime p` means that `p` is a prime number, that is, a natural number
    at least 2 whose only divisors are `p` and `1`.
    The theorem `Nat.prime_def` witnesses this description of a prime number.  p)
      (hqNat.Prime q : Nat.PrimeNat.Prime (p : ℕ) : Prop`Nat.Prime p` means that `p` is a prime number, that is, a natural number
    at least 2 whose only divisors are `p` and `1`.
    The theorem `Nat.prime_def` witnesses this description of a prime number.  q) (hpqp ≠ q : p Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. q) : (Nat.fibNat.fib (n : ℕ) : ℕImplementation of the Fibonacci sequence satisfying
    `fib 0 = 0, fib 1 = 1, fib (n + 2) = fib n + fib (n + 1)`.
    
    *Note:* We use a stream iterator for better performance when compared to the naive recursive
    implementation.
     p).CoprimeNat.Coprime (m n : ℕ) : Prop`m` and `n` are coprime, or relatively prime, if their `gcd` is 1.  (Nat.fibNat.fib (n : ℕ) : ℕImplementation of the Fibonacci sequence satisfying
    `fib 0 = 0, fib 1 = 1, fib (n + 2) = fib n + fib (n + 1)`.
    
    *Note:* We use a stream iterator for better performance when compared to the naive recursive
    implementation.
     q)
    theorem fib_coprime_of_distinct_primesfib_coprime_of_distinct_primes {p q : ℕ} (hp : Nat.Prime p) (hq : Nat.Prime q) (hpq : p ≠ q) :
      (Nat.fib p).Coprime (Nat.fib q) {p q : Nat : TypeThe natural numbers, starting at zero.
    
    This type is special-cased by both the kernel and the compiler, and overridden with an efficient
    implementation. Both use a fast arbitrary-precision arithmetic library (usually
    [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
    }
      (hpNat.Prime p : Nat.PrimeNat.Prime (p : ℕ) : Prop`Nat.Prime p` means that `p` is a prime number, that is, a natural number
    at least 2 whose only divisors are `p` and `1`.
    The theorem `Nat.prime_def` witnesses this description of a prime number.  p) (hqNat.Prime q : Nat.PrimeNat.Prime (p : ℕ) : Prop`Nat.Prime p` means that `p` is a prime number, that is, a natural number
    at least 2 whose only divisors are `p` and `1`.
    The theorem `Nat.prime_def` witnesses this description of a prime number.  q)
      (hpqp ≠ q : p Ne.{u} {α : Sort u} (a b : α) : Prop`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
    and asserts that `a` and `b` are not equal.
    
    
    Conventions for notations in identifiers:
    
     * The recommended spelling of `≠` in identifiers is `ne`. q) :
      (Nat.fibNat.fib (n : ℕ) : ℕImplementation of the Fibonacci sequence satisfying
    `fib 0 = 0, fib 1 = 1, fib (n + 2) = fib n + fib (n + 1)`.
    
    *Note:* We use a stream iterator for better performance when compared to the naive recursive
    implementation.
     p).CoprimeNat.Coprime (m n : ℕ) : Prop`m` and `n` are coprime, or relatively prime, if their `gcd` is 1.  (Nat.fibNat.fib (n : ℕ) : ℕImplementation of the Fibonacci sequence satisfying
    `fib 0 = 0, fib 1 = 1, fib (n + 2) = fib n + fib (n + 1)`.
    
    *Note:* We use a stream iterator for better performance when compared to the naive recursive
    implementation.
     q)
Proof for Lemma 2.22

Distinct primes are coprime, and \gcd(F_m,F_n) = F_{\gcd(m,n)} reduces the result to F_1=1.

Lean code for Theorem2.231 theorem
  • theorem InfinitudeOfPrimes_WunderlichInfinitudeOfPrimes_Wunderlich : InfinitudeOfPrimes : InfinitudeOfPrimesInfinitudeOfPrimes : Prop
    theorem InfinitudeOfPrimes_WunderlichInfinitudeOfPrimes_Wunderlich : InfinitudeOfPrimes :
      InfinitudeOfPrimesInfinitudeOfPrimes : Prop
Proof for Theorem 2.23

Assuming finitely many primes, look at Fibonacci numbers indexed by odd primes, each at least 2 Lemma 2.21. They are pairwise coprime Lemma 2.22, but F_{37} already has three distinct prime factors Lemma 2.20, contradicting the finite counting bound.