Propositions as Types
Lean represents logical propositions as types. Understanding this representation is key to understanding how proofs work.
The Universe of Propositions
Lean has different "universes" for different kinds of types:
1-- Data types live in Type2#check Nat -- Nat : Type3#check String -- String : Type4#check List Nat -- List Nat : Type56-- Propositions live in Prop7#check True -- True : Prop8#check False -- False : Prop9#check 2 + 2 = 4 -- 2 + 2 = 4 : PropProp is special: it's the universe of things that are either true or false. Every proposition is a type, but a type specifically designed to express a logical claim.
Equality
The most common proposition is equality:
1-- Equality is a proposition2#check (5 = 5) -- 5 = 5 : Prop3#check (1 + 1 = 2) -- 1 + 1 = 2 : Prop4#check (1 + 1 = 3) -- 1 + 1 = 3 : Prop (still a valid Prop, just false)56-- Equality for any type7#check ("hello" = "hello") -- "hello" = "hello" : Prop8#check ([1,2] = [1,2]) -- [1, 2] = [1, 2] : PropNote that 1 + 1 = 3 is a valid proposition—it's just false. You can state it, but you can't prove it.
True and False
1-- True: a proposition that's trivially provable2#check True -- True : Prop3example : True := trivial45-- False: a proposition with no proof6#check False -- False : Prop7-- example : False := ??? -- Impossible! No term has type FalseTrue is a type with exactly one term (trivial).False is a type with no terms—that's what makes it false.
Implication: Functions
The logical "implies" (→) is represented as a function type:
1-- "If A then B" is the type A → B2-- A proof is a function from proofs of A to proofs of B34example : True → True := fun _ => trivial56-- "If 1 = 1, then 2 = 2"7example : (1 = 1) → (2 = 2) := fun _ => rfl89-- Read: given a proof of 1 = 1, return a proof of 2 = 210-- The proof of 1 = 1 isn't even used—2 = 2 is independently trueTo prove an implication, you write a function. The function takes a proof of the hypothesis and produces a proof of the conclusion.
Conjunction: Products
"A and B" is represented as a pair:
1-- And is defined like a structure2-- structure And (a b : Prop) : Prop where3-- left : a4-- right : b56-- To prove A ∧ B, provide proofs of both7example : True ∧ True := ⟨trivial, trivial⟩89example : (1 = 1) ∧ (2 = 2) := ⟨rfl, rfl⟩1011-- Access parts with .left and .right (or .1 and .2)12example (h : True ∧ (1 = 1)) : True := h.left13example (h : True ∧ (1 = 1)) : 1 = 1 := h.rightDisjunction: Sum Types
"A or B" is represented as a sum (tagged union):
1-- Or has two constructors2-- inductive Or (a b : Prop) : Prop where3-- | inl : a → Or a b4-- | inr : b → Or a b56-- Prove left side7example : True ∨ False := Or.inl trivial89-- Prove right side10example : False ∨ True := Or.inr trivial1112-- Either side works13example : (1 = 1) ∨ (1 = 2) := Or.inl rflNegation
"Not A" is defined as "A implies False":
1-- ¬A is defined as A → False2#print Not -- def Not (a : Prop) : Prop := a → False34-- To prove ¬A, assume A and derive a contradiction5example : ¬False := fun h => h -- If False, then False (trivially)67-- 1 ≠ 2 means (1 = 2) → False8example : 1 ≠ 2 := by decide≠ is notation for ¬(... = ...), which expands to (... = ...) → False.Quantifiers
Universal: For All (∀)
1-- ∀ x : T, P x is a dependent function type2-- A proof is a function that works for any x34example : ∀ n : Nat, n = n := fun n => rfl56example : ∀ n : Nat, 0 + n = n := fun n => rfl78-- Multiple quantifiers9example : ∀ a b : Nat, a + b = b + a := Nat.add_commExistential: There Exists (∃)
1-- ∃ x : T, P x is a dependent pair (witness + proof)2-- Provide a specific x and prove P holds for it34example : ∃ n : Nat, n > 5 := ⟨10, by decide⟩56example : ∃ n : Nat, n + n = 10 := ⟨5, rfl⟩78-- The witness and proof are bundled together9example : ∃ s : String, s.length = 5 := ⟨"hello", rfl⟩Deep Dive: Proof Irrelevance
In Prop, all proofs of the same proposition are considered equal. This is called "proof irrelevance."
1-- Two different proofs of the same thing2example (p q : 1 = 1) : p = q := rfl34-- This is why Prop is special: only truth matters, not how you proved itThis makes sense logically: if you know something is true, you don't carehow it was proven. The fact that it's true is what matters.
Summary Table
| Logic | Lean Type | To Prove |
|---|---|---|
| A implies B | A → B | Write a function |
| A and B | A ∧ B | Provide both proofs |
| A or B | A ∨ B | Provide one proof |
| Not A | ¬A (= A → False) | Derive contradiction |
| For all x, P(x) | ∀ x, P x | Function over all x |
| Exists x, P(x) | ∃ x, P x | Witness + proof |