## Proofs in Lean 27 May 2025 Harry Richman
## Example proof There are infinitely many prime numbers Proof. Suppose there are finitely many prime numbers. Consider the product of these primes, and then add one. This number has a prime factor because it is larger than one. But, it is not divisible by any prime on our original list. Therefore, there are more prime numbers than we supposed.
## Example proof in Lean ```lean theorem primes_infinite : ∀ s : Finset Nat, ∃ p, Nat.Prime p ∧ p ∉ s := by intro s by_contra h push_neg at h set s' := s.filter Nat.Prime with s'_def have mem_s' : ∀ {n : ℕ}, n ∈ s' ↔ n.Prime := by intro n simp [s'_def] apply h have : 2 ≤ (∏ i ∈ s', i) + 1 := by sorry rcases exists_prime_factor this with ⟨p, pp, pdvd⟩ have : p ∣ ∏ i ∈ s', i := by sorry have : p ∣ 1 := by convert Nat.dvd_sub pdvd this simp show False sorry ``` Q: Why does the syntax look like that?
## Programs with types ```lean 3 : Int ``` ```lean 3.14 : Float ``` ```lean "hello world" : String ``` In words: `3` is a *term* of *type* `Int` ```lean term : Type ```
## Types from other types ```lean def f (x : Int) := x^2 ``` The type signature of a function records its input-type and its output-type ```lean f : Int -> Int ``` ```lean printIntName : Int -> String ``` ```lean add : Int -> Int -> Int ```
## Programs as math ---- Type-theory instead of set-theory "3 is an element of $\mathbb N$" or "$3 \in \mathbb N$" becomes ```lean 3 : Nat ``` "f is a continuous function on the manifold M" or "$f \in \mathrm{Hom}(M, \mathbb R)$" becomes ``` f : M -> Reals ```
## PAT principle ---- ### "PAT" = "Propositions as Types" ### "PAT" = "Proofs as Terms" ```lean theorem primes_infinite : ∀ (s : Finset Nat), ∃ p, (Nat.Prime p) ∧ (p ∉ s) := by intro s by_contra h push_neg at h ... sorry ```
## PAT principle ---- ```lean theorem primes_infinite : ∀ (s : Finset Nat), ∃ p, (Nat.Prime p) ∧ (p ∉ s) := by intro s by_contra h push_neg at h ... sorry ``` Type = (`∀ s ... ∃ p, Nat.Prime p ∧ p ∉ s`) Term = (`by intro s; by_contra h; ... sorry`)
## PAT principle ----
In Lean, each proposition *is* a type. A proof of `P` *is* a term whose type is `P`. Checking whether a proof proves `P` is a type checking operation.
```lean theorem primes_infinite : ∀ (s : Finset Nat), ∃ p, (Nat.Prime p) ∧ (p ∉ s) := by intro s by_contra h push_neg at h ... sorry ``` Type = (`∀ s ... ∃ p, Nat.Prime p ∧ p ∉ s`) Term = (`by intro s; by_contra h; ... sorry`)
## PAT principle ---- If `P` is a true proposition, then there exists a proof, i.e. there is at least one *term* with type `P` ```lean theorem some_prop : P := by <... some argument> ``` If `P` is a false proposition, then there is no term with type `P`
## PAT principle ---- Recall: `A→B` is the type of functions with input `A` and output `B` If `P` and `Q` are propositions, what is `P→Q`?
## PAT principle