cases & induction
cases performs case analysis on inductive types.induction proves properties by mathematical induction. Both are built into Lean 4 core.
cases — Case Analysis
cases splits a goal based on the constructors of an inductive type:
lean
1-- Boolean case analysis2example (b : Bool) : b = true ∨ b = false := by3 cases b with4 | true => left; rfl5 | false => right; rfl67-- Natural number cases8example (n : Nat) : n = 0 ∨ n > 0 := by9 cases n with10 | zero => left; rfl11 | succ m => right; omegaKey Takeaway
cases x creates one goal for each constructor of x's type. Use | constructor =>to name each case.Case Analysis on Propositions
lean
1-- Disjunction has two constructors: Or.inl and Or.inr2example (P Q R : Prop) (h : P ∨ Q) (hpr : P → R) (hqr : Q → R) : R := by3 cases h with4 | inl hp => exact hpr hp5 | inr hq => exact hqr hq67-- Conjunction has one constructor with two fields8example (P Q : Prop) (h : P ∧ Q) : Q := by9 cases h with10 | intro left right => exact rightinduction — Mathematical Induction
induction proves properties by the induction principle of inductive types:
lean
1-- Prove for all natural numbers2theorem add_zero (n : Nat) : n + 0 = n := by3 induction n with4 | zero => 5 -- Base case: 0 + 0 = 06 rfl7 | succ m ih => 8 -- Inductive case: assume m + 0 = m, prove (m+1) + 0 = m+19 -- ih : m + 0 = m (induction hypothesis)10 simp [ih]Induction on Lists
lean
1theorem length_append (xs ys : List α) : 2 (xs ++ ys).length = xs.length + ys.length := by3 induction xs with4 | nil => 5 -- Base: ([] ++ ys).length = [].length + ys.length6 simp7 | cons h t ih =>8 -- ih : (t ++ ys).length = t.length + ys.length9 -- Goal: ((h :: t) ++ ys).length = (h :: t).length + ys.length10 simp [ih]The Induction Hypothesis
lean
1-- The key: you get to ASSUME the property for smaller values2theorem add_assoc (a b c : Nat) : (a + b) + c = a + (b + c) := by3 induction c with4 | zero => 5 -- (a + b) + 0 = a + (b + 0)6 simp7 | succ n ih =>8 -- ih : (a + b) + n = a + (b + n)9 -- Goal: (a + b) + succ n = a + (b + succ n)10 simp [Nat.add_succ, ih]ℹ
The induction hypothesis
ih is your key tool in the inductive case. It lets you assume the theorem holds for smaller values.match in Tactic Mode
lean
1-- match works in tactic mode too2example (n : Nat) : n = 0 ∨ n > 0 := by3 match n with4 | 0 => left; rfl5 | n + 1 => right; omegaDeep Dive: cases vs match
Both cases and matchperform case analysis, but:
casesuses constructor names explicitlymatchuses pattern syntax (liken + 1)casescan do things match cannot (like eliminating equalities)
Examples
Boolean Negation
lean
1example (b : Bool) : !!b = b := by2 cases b with3 | true => rfl4 | false => rflList Reverse
lean
1theorem reverse_reverse (xs : List α) : xs.reverse.reverse = xs := by2 induction xs with3 | nil => simp4 | cons h t ih => simp [ih]Option Analysis
lean
1example (o : Option Nat) : o = none ∨ ∃ n, o = some n := by2 cases o with3 | none => left; rfl4 | some val => right; exact ⟨val, rfl⟩