Lean theorem prover/Foundations/The three axioms: Difference between revisions
Published from the Principia Machina source |
Published from the Principia Machina source |
||
| Line 1: | Line 1: | ||
{{DISPLAYTITLE:The three axioms}} | {{DISPLAYTITLE:The three axioms}} | ||
{{Plebeian|Lean theorem prover/Explainers/What the axioms are}} | {{Plebeian|Lean theorem prover/Explainers/What the axioms are}} | ||
{{Lean theorem prover map}} | |||
Lean's type theory, with its dependent functions, universes, inductive types and quotients, | Lean's type theory, with its dependent functions, universes, inductive types and quotients, | ||
Latest revision as of 19:34, 15 October 2026
| Lean theorem prover: map |
|---|
| Reading the edition Three levels of reading Glossary Notation Chronology |
| Reading by level Start here: What a proof assistant does The type theory: Terms, types and judgments How Lean works: Elaboration The history: Automath The applications: Research mathematics |
| Sources Sources Bibliography Further reading |
| Related The move to Lean |
Lean's type theory, with its dependent functions, universes, inductive types and quotients,
is extended in the core library by three axioms: propositional extensionality
(propext), the soundness of quotients (Quot.sound) and global
choice (Classical.choice). An axiom is a constant with a type and no
definition; it does not reduce, and the compiler cannot generate code for it.[1] Lean records, for every
definition and theorem, which axioms it depends on, and prints the list on request. This
page states the three as Lean prints them, says what each makes possible, shows the
dependency audit on examples, and sets out the further axioms that are not mathematics at
all.
As Lean prints them
#print propext #print Quot.sound #print Classical.choice
axiom propext : ∀ {a b : Prop}, (a ↔ b) → a = b
axiom Quot.sound.{u} : ∀ {α : Sort u} {r : α → α → Prop} {a b : α}, r a b → Quot.mk r a = Quot.mk r b
axiom Classical.choice.{u} : {α : Sort u} → Nonempty α → α
In Lean 4.34.1 propext is stated in the file Init/Core.lean, and
the other two in Init/Prelude.lean.[2] As rules, with
:
The first two conclude equations, which are propositions. The third concludes an element of an arbitrary type. That difference decides how each one interacts with computation.
What each makes possible
Propositional extensionality says that logically equivalent propositions are equal,
so that one may be replaced by the other in any context. The reference manual notes that
the ordinary connectives respect logical equivalence provably, without the axiom, but that
it is needed for an unknown predicate P : Prop → Prop applied to equivalent
arguments, and for equality between propositions itself.[3] It is
valid intuitionistically.[3] Theorem Proving in Lean 4 adds that
it agrees with set-theoretic readings in which every proposition is either empty or a
one-element set.[4]
Quotient soundness identifies the classes of related elements in a
quotient type. It is also the only
axiom behind function extensionality, which Lean proves as a theorem from quotients; the
proof is on propositional equality. With propext it gives an extensional theory of sets represented as
predicates: two predicates true of the same elements are equal.[4]
Global choice turns a proof that a type is inhabited into an element of it.
Nonempty α is a proposition, and a proof of it carries no information about
which element exists. Classical.choice nevertheless returns one, and returns the
same one for any proof, since all proofs of a proposition are equal. Theorem Proving in
Lean 4 derives from it the principle of indefinite description, and, with the other two
axioms, excluded middle, the decidability of every proposition and Hilbert's epsilon
operator.[4] That derivation is
classical logic from choice.
The first two can block evaluation in Lean's kernel, because a cast along an equation proved by
an axiom does not reduce, but they are compatible with compiled code, which erases proofs.
Choice is not: it manufactures data from a proposition, and definitions that use it for data
must be marked noncomputable.[4]
The audit: #print axioms
#print axioms lists every axiom a constant depends on, directly or through the
definitions and theorems it uses.[1] Five small theorems show
the range from none to all three:
theorem two_add_two : 2 + 2 = 4 := rfl theorem and_swap (p q : Prop) : p ∧ q ↔ q ∧ p := ⟨fun ⟨hp, hq⟩ => ⟨hq, hp⟩, fun ⟨hq, hp⟩ => ⟨hp, hq⟩⟩ theorem and_swap_eq (p q : Prop) : (p ∧ q) = (q ∧ p) := propext (and_swap p q) theorem add_zero_fun : (fun n : Nat => n + 0) = (fun n => n) := funext fun _ => rfl theorem em' (p : Prop) : p ∨ ¬p := Classical.em p #print axioms two_add_two #print axioms and_swap #print axioms and_swap_eq #print axioms add_zero_fun #print axioms em'
'two_add_two' does not depend on any axioms 'and_swap' does not depend on any axioms 'and_swap_eq' depends on axioms: [propext] 'add_zero_fun' depends on axioms: [Quot.sound] 'em'' depends on axioms: [propext, Classical.choice, Quot.sound]
Here the computation checked by rfl and the logical equivalence need nothing, the
equation between propositions needs propext, and the equation between functions
needs Quot.sound, through funext. Excluded middle needs all three,
because the proof of Classical.em in the core library uses choice,
propext and funext.[2]
sorry and sorryAx
The term sorry closes any goal. It elaborates to the axiom
sorryAx, which inhabits every type, and so it is used for unfinished work and
never belongs in a finished proof.[1]
#print sorryAx theorem unfinished : 1 = 2 := sorry theorem uses_unfinished : 2 = 3 := congrArg (· + 1) unfinished #print axioms uses_unfinished
axiom sorryAx.{u} : (α : Sort u) → Bool → α
'uses_unfinished' depends on axioms: [sorryAx]
Lean warns once, with declaration uses `sorry`, at unfinished,
where sorry is written. The
theorem uses_unfinished raises no warning of its own, yet it proves a falsehood,
and only the axiom list shows why. The reference manual makes the same point about the
editor's check marks: they appear even when a dependency uses sorry, and
printing the axioms is what detects it.[5]
Axioms that are not mathematics
Any user can write an axiom, and Lean accepts it. Lean cannot check that a new axiom is consistent with the others.[1]
axiom everything_is_equal : ∀ (a b : Nat), a = b theorem one_eq_two : 1 = 2 := everything_is_equal 1 2 #print axioms one_eq_two
The last line prints 'one_eq_two' depends on axioms: [everything_is_equal].
The theorem is checked and accepted; the audit is what exposes its premise.
An axiom can also be harmless on its own and inconsistent with the standard three. The
reference manual's example is a "free theorem" of parametricity, which says that a function
polymorphic in the element type of a list commutes with mapping over the list. With excluded
middle every proposition is decidable, so a function can test whether its type argument is
Nat and behave differently when it is. That function is not parametric, and
together with the free theorem it proves False.[1]
The core library itself states three further axioms, Lean.trustCompiler,
Lean.ofReduceBool and Lean.ofReduceNat. The reference manual
describes them as mathematically trivial: they mark proofs that depend on the correctness of
the whole compiler rather than only on Lean's small kernel.[1] The
tactic native_decide, which settles a decidable statement by running compiled
code, creates a dedicated axiom for each use, stating exactly the fact the compiled code
asserted:[1]
theorem big : 123456 * 654321 = 80779853376 := by native_decide #print axioms big
Lean 4.34.1 prints 'big' depends on axioms: [big._native.native_decide.ax_1_1].
Such a theorem rests on the correctness of the whole compiler, not only on Lean's kernel and
the three axioms: each use of the tactic widens what has to be trusted.[5]
Why audit per theorem
The three standard axioms are, in the reference manual's words, "known to be
consistent".[1] Carneiro's model of Lean's type theory in set
theory, published in 2019, covers all three axioms together;[6] it is described, with its limits, in
consistency and the metatheory.
Every other axiom is a premise the reader has to accept separately. The manual's guide to
validating a proof therefore asks that #print axioms report only
propext, Classical.choice and Quot.sound: a
sorryAx means an incomplete proof, Lean.trustCompiler means trust in
native evaluation, and anything else means a custom axiom on which the result is
conditional.[5]
A list of axioms also says what kind of result a theorem is. A theorem whose list omits
Classical.choice uses no classical reasoning obtained from it, and one with an
empty list holds in the type theory alone. The check can be made permanent. The manual suggests pairing #print axioms with
#guard_msgs, so that a change in a library one depends on cannot silently add
an axiom:[1]
/-- info: 'two_add_two' does not depend on any axioms -/ #guard_msgs in #print axioms two_add_two
If the proof of two_add_two ever came to depend on an axiom, the message would
change, and this command would fail.
Next
Classical logic from choice follows the third axiom into excluded middle.
References
- ↑ 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 The Lean Language Reference, version 4.34.0, chapter 8 "Axioms": the introduction, §8.2 "Consistency", §8.3 "Reduction", §8.4 "Standard Axioms" and §8.5 "Displaying Axiom Dependencies". https://lean-lang.org/doc/reference/4.34.0/Axioms/
- ↑ 2.0 2.1 Lean 4 source, version 4.34.1: files
src/Init/Core.lean(propext),src/Init/Prelude.lean(Quot.sound,Classical.choice,sorryAx) andsrc/Init/Classical.lean(the proof ofClassical.em). Apache License 2.0. https://github.com/leanprover/lean4/tree/v4.34.1/src/Init - ↑ 3.0 3.1 The Lean Language Reference, version 4.34.0, §4.2 "Propositions" (the axiom
propextand its documentation). https://lean-lang.org/doc/reference/4.34.0/The-Type-System/Propositions/ - ↑ 4.0 4.1 4.2 4.3 Jeremy Avigad, Leonardo de Moura, Soonho Kong and Sebastian Ullrich, Theorem Proving in Lean 4, chapter 12 "Axioms and Computation". https://lean-lang.org/theorem_proving_in_lean4/Axioms-and-Computation/
- ↑ 5.0 5.1 5.2 The Lean Language Reference, version 4.34.0, "Validating a Lean Proof", sections "The Blue Double Check Marks", "Printing Axioms" and "On Lean.trustCompiler (up to Lean 4.28.0)". https://lean-lang.org/doc/reference/4.34.0/ValidatingProofs/
- ↑ Mario Carneiro, The Type Theory of Lean, Master's thesis, Carnegie Mellon University, 2019; abstract, §2.7 (pp. 12–13) and Corollary 6.8 (p. 41). https://github.com/digama0/lean-type-theory/releases/tag/v1.0