Theorem Proving in Lean 4
#lean
This post contains my notes of the Theorem Proving in Lean 4 book by Jeremy Avigad, Leonardo de Moura, Soonho Kong and Sebastian Ullrich, with contributions from the Lean Community.
Chapter 3: Propositions and Proofs
Implication
-- term-style --
example : p → q :=
fun h : p => sorry -- proof of q given h
-- tactic --
example : p → q := by
intro hp -- hp is of type `p`
q -- proof of q goes here
Conjunction, a.k.a. and
-- elimination --
fun h : p ∧ q =>
have hp := h.left
have hq := h.right
sorry -- rest of proof using hp and hq
-- introduction --
⟨hp, hq⟩ : p ∧ q -- as proof of p ∧ q
-- tactic to use `p ∧ q` --
intro ⟨hp, hq⟩
-- tactic to prove `p ∧ q` --
apply And.intro
. ??? -- to prove `p`
. ??? -- to prove `q`
Disjunction, a.k.a. or
-- elimination --
fun h : p ∨ q =>
h.elim
(fun hp => sorry) -- proof using hp
(fun hq => sorry) -- proof using hq
-- introduction --
Or.inl hp : p ∨ q -- prove (p ∨ q) using hp
Or.inr hr : p ∨ q -- prove (p ∨ q) using hq
-- tactic elimination to use `p ∨ q` --
example : p ∨ q → r := by
intro
| Or.inl hp => ??? -- prove r using (hp: p)
| Or.inr hq => ??? -- prove r using (hq: q)
-- tactic elimination to use `hpq : p ∨ q` --
match hpq with
| Or.inl hp => ??? -- prove using (hp: p)
| Or.inr hq => ??? -- prove using (hq: q)
-- tactic elimination to prove `p ∨ q` --
apply Or.inl h
apply Or.inr h
Equivalence, a.k.a. iff
example : p ↔ q :=
Iff.intro
(fun hp : p => sorry) -- proof of q given p
(fun hq : q => sorry) -- proof of p given q
fun h : p ↔ q =>
have hl : p → q := h.mp
have hr : q → p := h.mpr
-- tactic --
apply Iff.intro
. ??? -- proof of p → q
. ??? -- proof of q → p
Negation, a.k.a. not
Negation ¬p
is defined as p → False
. We prove ¬p
by deriving a contradiction from p
.
-- Prove ¬p with definition.
example : ¬p :=
fun hp : p => show False from sorry
-- Falsity can be derived from a contradiction
example (hp : p) (hnp : ¬p) : False := False.elim (hnp hp)
-- Falsity can imply anything
example (hf : False) : p := False.elim hf
example (hp : p) (hnp : ¬p) : q := absurd hp hnp
Auxiliary subgoals
suffices hp : p from sorry -- Proof of original proposition assuming p is true
show p from sorry -- Proof of p
Classical logic: excluded middle
open Classical
Or.elim (em p)
(fun hp : p => sorry)
(fun hnp : ¬p => sorry)
example (h : ¬p) : q :=
byContradiction
(fun h1 : ¬q =>
have h2 : p := ... -- given ¬q, prove p
show False from h h2)
Chapter 4: Quantifiers and Equality
The universal quantifier ∀
-- introduction --
example : ∀ x : α, p x :=
fun x : α => -- prove (p x) here
-- elimination --
fun h : ∀ x : α, p x => -- Given (y : α), we can now use (h y) as a proof of (p y)
The existential quantifier ∃
-- introduction --
example : ∃ x : α, p x := Exists.intro w hw -- w is a particular value in α, hw is a proof of (p w)
example : ∃ x, p x := ⟨w, hw⟩
-- elimination --
example (h : ∃ x : α, p x) : q :=
match h with
| ⟨w, (hw : p w)⟩ => q -- w is a particular value in α, hw is of type (p w)
example : (∃ x : α, p x) → q :=
fun ⟨w, (hw : p w)⟩ => q
Chapter 5: Tactics
intro
moves things to the left of ⊢
(makes it an assumption),
while revert
moves them to the right of ⊢
(removes an assumption).
example (x : Nat) : x = x := by -- [Goal] (x : Nat) ⊢ x = x
revert x -- [Goal] ⊢ ∀ (x : Nat), x = x
intro y -- [Goal] (y : Nat) ⊢ y = y
rfl
To use have
in tactic mode:
have hp : p := by ??? -- tactic proof of `p`
?????? -- remaining of the proof using `hp : p`