lawvere_fixed_pointtheoremProved here from basic factsNo axioms
lawvere_fixed_pointLean 4Proved here from basic factsFormally verified
/-- **Lawvere's fixed-point theorem** (1969), the abstract core of the diagonal arguments ofCantor, Russell, Gödel, Tarski and Turing. If `e : A → (A → B)` hits *every* function`A → B`, then every map `f : B → B` has a fixed point.Proof: the diagonal function `g a = f (e a a)` is `e a₀` for some `a₀`, and then`e a₀ a₀ = g a₀ = f (e a₀ a₀)`. -/theorem lawvere_fixed_point {A B : Type*} (e : A → A → B) (he : Function.Surjective e) (f : B → B) : ∃ b, f b = b := by obtain ⟨a₀, ha₀⟩ := he (fun a => f (e a a)) -- Evaluate the equation `e a₀ = g` at the diagonal point `a₀`. exact ⟨e a₀ a₀, (congrFun ha₀ a₀).symm⟩
cantor_from_lawveretheoremProved here from basic factsNo axioms
cantor_from_lawvereLean 4Proved here from basic factsFormally verified
/-- Cantor's theorem as a corollary: there is no surjection from `A` onto the predicates`A → Prop`, because negation `¬ : Prop → Prop` has no fixed point (`P ↔ ¬P` is absurd).Mathlib's version for sets is `Function.cantor_surjective`. -/theorem cantor_from_lawvere {A : Type*} (e : A → A → Prop) : ¬ Function.Surjective e := by intro he obtain ⟨P, hP⟩ := lawvere_fixed_point e he Not exact iff_not_self (Iff.of_eq hP.symm)
/-- An abstract **diagonalisable system**, after R. M. Smullyan, *Gödel's IncompletenessTheorems* (1992), chapter 1. It has formulas with one free variable, sentences, Gödel numbersfor both, the substitution `subst φ n = φ(n̄)` of a numeral, a negation, and two predicates onsentences: truth (in the intended model) and provability (in the theory). The number`diag (code ψ)` is the Gödel number of the *diagonalisation* `ψ(⌜ψ⌝)`. For first-orderarithmetic all of this is real: Gödel numbers are natural numbers and `diag` is primitiverecursive. -/structure DiagSystem where /-- Formulas with one free variable. -/ Formula : Type /-- Sentences (no free variables). -/ Sentence : Type /-- The Gödel number `⌜ψ⌝` of a formula. -/ code : Formula → ℕ /-- The Gödel number of a sentence. -/ scode : Sentence → ℕ /-- Different sentences have different Gödel numbers. -/ scode_injective : Function.Injective scode /-- `subst ψ n` is the sentence `ψ(n̄)`. -/ subst : Formula → ℕ → Sentence /-- Negation of sentences. -/ neg : Sentence → Sentence /-- Truth in the intended model. -/ True : Sentence → Prop /-- Provability in the theory. -/ Provable : Sentence → Prop true_neg : ∀ s, True (neg s) ↔ ¬ True s /-- The diagonal function on Gödel numbers. -/ diag : ℕ → ℕ diag_code : ∀ ψ, diag (code ψ) = scode (subst ψ (code ψ))
/-- A set `A` of natural numbers is **expressible** if some formula `ψ` defines it:`ψ(n̄)` is true exactly when `n ∈ A`. -/def Expressible (A : Set ℕ) : Prop := ∃ ψ : S.Formula, ∀ n, S.True (S.subst ψ n) ↔ n ∈ A
DiagSystem.diagonal_lemmatheoremProved here from basic factsNo axioms
diagonal_lemmaLean 4Proved here from basic factsFormally verified
/-- **The diagonal lemma (semantic form).** Suppose that whenever `A` is expressible, so is`diag⁻¹(A) = {n | diag n ∈ A}` (in arithmetic: substitution is definable). Then for everyexpressible `A` there is a sentence `G` that is true iff its own Gödel number lies in `A`.Proof: let `ψ` express `diag⁻¹(A)` and put `G = ψ(⌜ψ⌝)`. Then`G` true ⟺ `⌜ψ⌝ ∈ diag⁻¹(A)` ⟺ `diag ⌜ψ⌝ ∈ A` ⟺ `⌜G⌝ ∈ A`. -/theorem diagonal_lemma (hdiag : ∀ A : Set ℕ, S.Expressible A → S.Expressible (S.diag ⁻¹' A)) {A : Set ℕ} (hA : S.Expressible A) : ∃ G : S.Sentence, S.True G ↔ S.scode G ∈ A := by obtain ⟨ψ, hψ⟩ := hdiag A hA refine ⟨S.subst ψ (S.code ψ), ?_⟩ calc S.True (S.subst ψ (S.code ψ)) ↔ S.code ψ ∈ S.diag ⁻¹' A := hψ (S.code ψ) _ ↔ S.diag (S.code ψ) ∈ A := Iff.rfl _ ↔ S.scode (S.subst ψ (S.code ψ)) ∈ A := by rw [S.diag_code ψ]
DiagSystem.tarski_undefinabilitytheoremProved here from basic factspropext, Classical.choice, Quot.sound
tarski_undefinabilityLean 4Proved here from basic factsFormally verified
/-- **Tarski's undefinability of truth (abstract form).** If expressible sets are closed undercomplements (negation is definable) and under `diag⁻¹` (substitution is definable), then the setof Gödel numbers of *true* sentences is not expressible.Proof: otherwise its complement is expressible, and the diagonal lemma gives a sentence `G`that is true iff `⌜G⌝` is not the number of a true sentence, i.e. iff `G` is false. -/theorem tarski_undefinability (hcompl : ∀ A : Set ℕ, S.Expressible A → S.Expressible Aᶜ) (hdiag : ∀ A : Set ℕ, S.Expressible A → S.Expressible (S.diag ⁻¹' A)) : ¬ S.Expressible (S.scode '' {s | S.True s}) := by intro hT obtain ⟨G, hG⟩ := S.diagonal_lemma hdiag (hcompl _ hT) -- `⌜G⌝` is the code of a true sentence iff `G` is true, by injectivity of the coding. have hcode : S.scode G ∈ S.scode '' {s | S.True s} ↔ S.True G := S.scode_injective.mem_set_image have : S.True G ↔ ¬ S.True G := hG.trans (not_congr hcode) exact iff_not_self this
DiagSystem.first_incompletenesstheoremProved here from basic factspropext, Classical.choice, Quot.sound
first_incompletenessLean 4Proved here from basic factsFormally verified
/-- **The first incompleteness theorem (abstract, semantic form).** Suppose the theory is*sound* (it proves only true sentences), that the set of Gödel numbers of provable sentences isexpressible (Gödel's arithmetisation), and that expressible sets are closed under complementsand `diag⁻¹`. Then there is a sentence `G` that is true but unprovable, and whose negation isunprovable too: the theory is incomplete.Proof: the diagonal lemma applied to the non-provable codes gives `G` with"`G` true ⟺ `G` unprovable". If `G` were provable it would be true, hence unprovable; so `G`is unprovable, hence true. If `¬G` were provable it would be true, so `G` would be false. -/theorem first_incompleteness (sound : ∀ s, S.Provable s → S.True s) (hprov : S.Expressible (S.scode '' {s | S.Provable s})) (hcompl : ∀ A : Set ℕ, S.Expressible A → S.Expressible Aᶜ) (hdiag : ∀ A : Set ℕ, S.Expressible A → S.Expressible (S.diag ⁻¹' A)) : ∃ G : S.Sentence, S.True G ∧ ¬ S.Provable G ∧ ¬ S.Provable (S.neg G) := by obtain ⟨G, hG⟩ := S.diagonal_lemma hdiag (hcompl _ hprov) have hcode : S.scode G ∈ S.scode '' {s | S.Provable s} ↔ S.Provable G := S.scode_injective.mem_set_image -- The fixed-point property: `G` is true iff `G` is not provable. have hfix : S.True G ↔ ¬ S.Provable G := hG.trans (not_congr hcode) have hunprov : ¬ S.Provable G := fun hp => hfix.mp (sound G hp) hp have htrue : S.True G := hfix.mpr hunprov refine ⟨G, htrue, hunprov, fun hneg => ?_⟩ exact (S.true_neg G).mp (sound _ hneg) htrue
halting_undecidabletheoremApplies a library theorempropext, Classical.choice, Quot.sound
halting_undecidableLean 4Applies a library theoremFormally verified
/-- **Turing (1936):** the halting problem is undecidable — no computable procedure decides,for every program `c`, whether `c` halts on input `n`. Here programs are Mathlib's codes`Nat.Partrec.Code` for partial recursive functions; this applies`ComputablePred.halting_problem`. -/theorem halting_undecidable (n : ℕ) : ¬ ComputablePred fun c : Nat.Partrec.Code => (c.eval n).Dom := ComputablePred.halting_problem n
halting_incompletenesstheoremProved here from basic factspropext, Classical.choice, Quot.sound
halting_incompletenessLean 4Proved here from basic factsFormally verified
/-- **Incompleteness from the halting problem** (after Turing 1936 and Kleene). Let `Provable`be any set of (Gödel numbers of) sentences whose members can be computably listed — as thetheorems of every recursively axiomatised theory can — and let `nonHalt c` be a computableassignment, to each program `c`, of a sentence meaning "`c` does not halt on input `n`". If thetheory is sound for these sentences, then some program never halts but the theory cannot proveit. Proof: otherwise "`c` does not halt" would be semi-decidable — list the theorems and waitfor `nonHalt c` — and Mathlib's `ComputablePred.halting_problem_not_re` says it is not. -/theorem halting_incompleteness (n : ℕ) (Provable : ℕ → Prop) (hre : REPred Provable) (nonHalt : Nat.Partrec.Code → ℕ) (hc : Computable nonHalt) (sound : ∀ c, Provable (nonHalt c) → ¬ (c.eval n).Dom) : ∃ c : Nat.Partrec.Code, ¬ (c.eval n).Dom ∧ ¬ Provable (nonHalt c) := by by_contra h push Not at h -- `h : ∀ c, ¬ (c.eval n).Dom → Provable (nonHalt c)`: the theory would be complete for -- non-halting, so non-halting would be semi-decidable. have hcomp : REPred fun c => Provable (nonHalt c) := hre.comp hc exact ComputablePred.halting_problem_not_re n (hcomp.of_eq fun c => ⟨sound c, h c⟩)
formulas_countabletheoremApplies a library theorempropext, Classical.choice, Quot.sound
formulas_countableLean 4Applies a library theoremFormally verified
/-- The first step of arithmetisation: over a countable language, the first-order formulas(with variables indexed by `ℕ`) form a countable set, so they can be numbered. This is theinstance `FirstOrder.Language.Formula`'s `Countable` from `Mathlib.ModelTheory.Encoding`. -/theorem formulas_countable (L : FirstOrder.Language) [Countable L.Symbols] : Countable (L.Formula ℕ) := inferInstance
presburger_mul_not_definabletheoremApplies a library theorempropext, Classical.choice, Quot.sound
presburger_mul_not_definableLean 4Applies a library theoremFormally verified
/-- Incompleteness needs multiplication. In the language `(0, 1, +)` of Presburger arithmeticthe graph of multiplication `{(a, b, c) | a = b * c}` is **not definable** in `ℕ`, even withany set `A` of parameters — and Presburger arithmetic is complete and decidable. This appliesMathlib's `FirstOrder.Language.presburger.mul_not_definable` (the definable sets are exactly thesemilinear ones). -/theorem presburger_mul_not_definable (A : Set ℕ) : ¬ A.Definable FirstOrder.Language.presburger {v : Fin 3 → ℕ | v 0 = v 1 * v 2} := FirstOrder.Language.presburger.mul_not_definable
/-- Derive Cantor's theorem from Lawvere's fixed-point theorem: there is no surjection from `A`onto the predicates on `A`.Hint: apply `lawvere_fixed_point e he Not` and show that `¬P = P` is impossible(`iff_not_self` and `Iff.of_eq` help). -/theorem cantor_from_lawvere {A : Type*} (e : A → A → Prop) : ¬ Function.Surjective e := by sorry
Show the compiled solution
cantor_from_lawvereLean 4Proved here from basic factsFormally verified
/-- Cantor's theorem as a corollary: there is no surjection from `A` onto the predicates`A → Prop`, because negation `¬ : Prop → Prop` has no fixed point (`P ↔ ¬P` is absurd).Mathlib's version for sets is `Function.cantor_surjective`. -/theorem cantor_from_lawvere {A : Type*} (e : A → A → Prop) : ¬ Function.Surjective e := by intro he obtain ⟨P, hP⟩ := lawvere_fixed_point e he Not exact iff_not_self (Iff.of_eq hP.symm)
/-- In a sound diagonalisable system in which provability is expressible, some true sentence isunprovable. Hint: use `S.diagonal_lemma` with the complement of the provable codes, and argue asin the lesson: a provable `G` would be true, hence unprovable. -/theorem true_but_unprovable (S : DiagSystem) (sound : ∀ s, S.Provable s → S.True s) (hprov : S.Expressible (S.scode '' {s | S.Provable s})) (hcompl : ∀ A : Set ℕ, S.Expressible A → S.Expressible Aᶜ) (hdiag : ∀ A : Set ℕ, S.Expressible A → S.Expressible (S.diag ⁻¹' A)) : ∃ G : S.Sentence, S.True G ∧ ¬ S.Provable G := by sorry
Show the compiled solution
first_incompletenessLean 4Proved here from basic factsFormally verified
/-- **The first incompleteness theorem (abstract, semantic form).** Suppose the theory is*sound* (it proves only true sentences), that the set of Gödel numbers of provable sentences isexpressible (Gödel's arithmetisation), and that expressible sets are closed under complementsand `diag⁻¹`. Then there is a sentence `G` that is true but unprovable, and whose negation isunprovable too: the theory is incomplete.Proof: the diagonal lemma applied to the non-provable codes gives `G` with"`G` true ⟺ `G` unprovable". If `G` were provable it would be true, hence unprovable; so `G`is unprovable, hence true. If `¬G` were provable it would be true, so `G` would be false. -/theorem first_incompleteness (sound : ∀ s, S.Provable s → S.True s) (hprov : S.Expressible (S.scode '' {s | S.Provable s})) (hcompl : ∀ A : Set ℕ, S.Expressible A → S.Expressible Aᶜ) (hdiag : ∀ A : Set ℕ, S.Expressible A → S.Expressible (S.diag ⁻¹' A)) : ∃ G : S.Sentence, S.True G ∧ ¬ S.Provable G ∧ ¬ S.Provable (S.neg G) := by obtain ⟨G, hG⟩ := S.diagonal_lemma hdiag (hcompl _ hprov) have hcode : S.scode G ∈ S.scode '' {s | S.Provable s} ↔ S.Provable G := S.scode_injective.mem_set_image -- The fixed-point property: `G` is true iff `G` is not provable. have hfix : S.True G ↔ ¬ S.Provable G := hG.trans (not_congr hcode) have hunprov : ¬ S.Provable G := fun hp => hfix.mp (sound G hp) hp have htrue : S.True G := hfix.mpr hunprov refine ⟨G, htrue, hunprov, fun hneg => ?_⟩ exact (S.true_neg G).mp (sound _ hneg) htrue