Introduction: prove it. Elimination: use it. Worked explanations →
This sheet covers the techniques in dayXX.lean and exXX.lean through Day 20, plus the function, subtype, and choice examples in project/solutions/. The snippets with ... are proof templates: replace each placeholder with the remaining proof.
Jump to logic, quantifiers, recursion, induction, functions, subtypes, choice, Lean tactics and techniques, or equality tools.
For the custom logical commands, load macros.lean (or copy the setup in the guide). For the natural-number examples, load natural_numbers.lean: use import natural_numbers locally, or paste its contents at the top of the web editor. It supplies our custom ℕ, plus, times, and their theorems. Type \N for ℕ. Write (2 : ℕ) when the type of a numeral needs to be explicit.
∧ And \and
Introduction
From P and Q, conclude P ∧ Q.
-
apply And.intro ...What Lean needsThe goal
P ∧ Q.What Lean doesReplaces it with two goals,
PandQ. -
conj_intro hpq from hp hqWhat Lean needs
hp : Pandhq : Qin the context.What Lean doesAdds
hpq : P ∧ Qto the context. -
have hpq : P ∧ Q := ⟨hp, hq⟩What Lean needs
hp : Pandhq : Qin the context.What Lean doesAdds
hpq : P ∧ Qto the context.
Elimination
From P ∧ Q, conclude P and conclude Q.
-
conj_elim hp hq from hpqWhat Lean needs
hpq : P ∧ Qin the context.What Lean doesAdds
hp : Pandhq : Qto the context. -
have ⟨hp, hq⟩ := hpqWhat Lean needs
hpq : P ∧ Qin the context.What Lean doesAdds
hp : Pandhq : Qto the context. -
apply And.elim _ hpq intro hp hq ...What Lean needs
hpq : P ∧ Qin the context.What Lean doesAdds
hp : Pandhq : Qto the context while retaining the current goal.
∨ Or \or
Introduction
From P, conclude P ∨ Q; from Q, conclude P ∨ Q.
-
disj_intro_left hpq from hp QWhat Lean needs
hp : Pin the context.What Lean doesAdds
hpq : P ∨ Qto the context. -
disj_intro_right hpq from P hqWhat Lean needs
hq : Qin the context.What Lean doesAdds
hpq : P ∨ Qto the context. -
apply Or.intro_left ...What Lean needsThe goal
P ∨ Q.What Lean doesReplaces it with the goal
P. -
apply Or.intro_right ...What Lean needsThe goal
P ∨ Q.What Lean doesReplaces it with the goal
Q. -
apply Or.inl ...What Lean needsThe goal
P ∨ Q.What Lean doesReplaces it with the goal
P. -
apply Or.inr ...What Lean needsThe goal
P ∨ Q.What Lean doesReplaces it with the goal
Q.
Elimination
From P ∨ Q, derive the same conclusion from P and from Q.
-
disj_elim hp hq from hpq ...What Lean needs
hpq : P ∨ Qin the context.What Lean doesCreates two copies of the current goal: one with
hp : Pin the context and one withhq : Q. -
cases hpq case inl hp => ... case inr hq => ...What Lean needs
hpq : P ∨ Qin the context.What Lean doesCreates a case with
hp : Pand a case withhq : Q; both retain the current goal. -
apply Or.elim hpq · intro hp ... · intro hq ...What Lean needs
hpq : P ∨ Qin the context.What Lean doesCreates two copies of the current goal: one under
hp : Pand one underhq : Q.
→ Implies \to
Introduction
To prove P → Q, assume P and derive Q.
-
intro hp ...What Lean needsThe goal
P → Q.What Lean doesAdds
hp : Pto the context and replaces the goal withQ.
Elimination
From P → Q and P, conclude Q.
-
impl_elim hq from hp hpqWhat Lean needs
hpq : P → Qandhp : Pin the context.What Lean doesAdds
hq : Qto the context. -
have hq := hpq hpWhat Lean needs
hpq : P → Qandhp : Pin the context.What Lean doesAdds
hq : Qto the context. -
apply hpq ...What Lean needs
hpq : P → Qin the context and the goalQ.What Lean doesReplaces the goal with
P.
¬ Not \neg
Introduction
To prove ¬P, assume P and derive a contradiction.
-
change P → FalseWhat Lean needsThe goal
¬ P.What Lean doesRewrites the goal as
P → False. -
change ¬ P at hWhat Lean needs
h : P → Falsein the context.What Lean doesRewrites the hypothesis as
h : ¬ P.
Elimination
From ¬P and P, derive a contradiction.
-
contradictionWhat Lean needsContradictory hypotheses, such as
hp : Pandhnp : ¬ P, in the context.What Lean doesCloses the current goal.
↔ If and only if \iff
Introduction
Prove P → Q and prove Q → P.
-
apply Iff.introWhat Lean needsThe goal
P ↔ Q.What Lean doesReplaces it with the goals
P → QandQ → P.
Elimination
Use either implication: P → Q or Q → P.
-
apply Iff.elim _ h intro hpq hqp ...What Lean needs
h : P ↔ Qin the context.What Lean doesAdds
hpq : P → Qandhqp : Q → Pto the context while retaining the current goal.
∀ For every \forall
Introduction
For arbitrary t : T, derive P t.
-
intro t ...What Lean needsThe goal
∀ x : T, P x.What Lean doesAdds an arbitrary
t : Tto the context and replaces the goal withP t.
Elimination
From ∀ x : T, P x, conclude P t for t : T.
-
have := h t ...What Lean needs
h : ∀ x : T, P xandt : Tin the context.What Lean doesAdds
this : P tto the context. -
have hpt := h t ...What Lean needs
h : ∀ x : T, P xandt : Tin the context.What Lean doesAdds
hpt : P tto the context.
∃ There exists \exists
Introduction
Choose t : T and prove P t.
-
apply Exists.intro t ...What Lean needsThe goal
∃ x : T, P xand an available termt : T.What Lean doesChooses
tas the witness and replaces the goal withP t.
Elimination
From ∃ x : T, P x, introduce a new t : T and assume P t.
-
obtain ⟨t, hpt⟩ := h -- Or: have ⟨t, hpt⟩ := h ...What Lean needs
h : ∃ x : T, P xin the context.What Lean doesAdds a new witness
t : Tandhpt : P tto the context. -
apply Exists.elim h intro t intro hpt ...What Lean needs
h : ∃ x : T, P xin the context.What Lean doesAdds a new
t : Tandhpt : P tto the context while retaining the current goal.
Recursively defined functions
Give the zero and successor values
-
def f : ℕ → ℕ | ℕ.zero => ℕ.zero | ℕ.succ n => (f n).succ.succWhat Lean needsA value at zero and a rule for computing the successor value from
f n.What Lean doesDefines a function that adds two successors at each step.
n.succmeansℕ.succ n. -
def f_match (n : ℕ) : ℕ := match n with | .zero => ℕ.zero | .succ k => (f_match k).succ.succWhat Lean needsThe same zero and successor rules, written with
matchas in Day 17.What Lean doesDefines the function by matching the input against the two cases.
Compute, or state the defining equations
-
#eval f 2What Lean needsA defined function and a concrete input.
What Lean doesComputes the value and displays it. Our custom
ℕmay display its zero/successor constructors. This is a computation, not a proof for all inputs. -
theorem f_zero : f ℕ.zero = ℕ.zero := by rfl theorem f_succ (n : ℕ) : f n.succ = (f n).succ.succ := by rflWhat Lean needsThe definition of
fabove.What Lean doesProves and names the defining equations so that later proofs can use
rewrite [f_zero]orrewrite [f_succ].
The course file already defines plus and times recursively on their first input. Write them as m + n and m * n; parentheses specify grouping when needed.
Induction on our natural numbers
The two cases
-
intro n -- If the goal starts with ∀ n : ℕ, ... induction n using ℕ.rec case zero => ... case succ n ih => ...What Lean needs
n : ℕand a goal aboutn, sayP n.What Lean doesCreates the base goal
P ℕ.zeroand the successor goalP n.succ, withih : P navailable in the successor case.
Use the induction hypothesis for n to prove the statement for n.succ. It is available only in the successor case. Choose the induction variable to match the input on which the function recurses.
A complete example from addition
-
example (n : ℕ) : n + ℕ.zero = n := by induction n using ℕ.rec case zero => unfold plus rfl case succ n ih => unfold plus rewrite [ih] rflWhat Lean needsThe course definition of
plus.What Lean doesIn the successor case, exposes
(n + ℕ.zero).succ = n.succ, replacesn + ℕ.zerousingih, then finishes the identical sides withrfl.
Functions: definitions and extensionality
These examples use the course definitions in project/solutions/functions.lean: compose g f := fun x => g (f x), written g ∘ f. Thus f is applied first. Load that file locally with import functions, or paste its contents into the web editor.
Define a function; prove functions equal
-
def subtype_value {S : Type} {P : S → Prop} : {a : S // P a} → S := by intro x exact x.valWhat Lean needsA function type
A → Bto construct.What Lean does
intro xintroduces the input; the remaining goal asks for an output of typeB. A direct definition can instead usefun x => x.val. -
example {S T U V : Type} (f : S → T) (g : T → U) (h : U → V) : h ∘ (g ∘ f) = (h ∘ g) ∘ f := by funext x unfold compose rflWhat Lean needsAn equality between functions with the same domain and codomain.
What Lean does
funext xintroduces an arbitrary input and reduces equality of functions to equality of their values at that input. Here both sides reduce toh (g (f x)).
Use injectivity, surjectivity, and inverse equations
-
unfold injective intro x y hxy ... -- For a surjectivity goal: unfold surjective intro t apply Exists.intro s ...What Lean needsA goal
injective f, orsurjective fand a chosen preimages.What Lean doesInjectivity leaves
x = ywithhxy : f x = f y. Surjectivity leavesf s = t. Forbijective f, unfoldbijectiveand prove both parts. Useunfold injective at hto expose a hypothesis;unfold injective at ⊢ hunfolds in both the goal andh. -
example {S T : Type} {f : S → T} {g : T → S} (h : g ∘ f = id) : surjective g := by unfold surjective intro x apply Exists.intro (f x) change (g ∘ f) x = id x rewrite [h] rflWhat Lean needsA function equality
h : g ∘ f = id.What Lean does
changedisplays the goal in a definitionally equal form whererewrite [h]can use the inverse equation.
Subtypes: values together with proofs
{a : S // P a} is the type of values a : S accompanied by a proof of P a. Unlike ∃ a : S, P a, it is a type of data. Course examples include ℕ_pos, Evens, and image f. Type \< and \> for ⟨ and ⟩.
Construct a member
-
example {S : Type} {P : S → Prop} (a : S) (ha : P a) : {x : S // P x} := by apply Subtype.mk case val => exact a case property => exact haWhat Lean needsA subtype goal, a candidate value
a, and a proofhaof its required property.What Lean does
Subtype.mkasks for the underlying value and then a proof that it satisfies the property. The second goal depends on the value supplied in the first. -
example {S : Type} {P : S → Prop} (a : S) (ha : P a) : {x : S // P x} := by exact ⟨a, ha⟩ -- Equivalently: exact Subtype.mk a haWhat Lean needsThe same value and property proof.
What Lean doesBuilds the subtype member directly. The expected type tells Lean what the angle brackets construct.
Unpack a member; prove members equal
-
example {S : Type} {P : S → Prop} (x : {a : S // P a}) : P x.val := by exact x.property example {S : Type} {P : S → Prop} (x : {a : S // P a}) : ∃ a : S, P a := by have ⟨a, ha⟩ := x exact ⟨a, ha⟩ example {S : Type} {P : S → Prop} : {a : S // P a} → S := by intro ⟨a, ha⟩ exact aWhat Lean needsA subtype member
x, or a function goal whose input is a subtype member.What Lean does
x.val : Sis its underlying value andx.property : P x.valis its proof.have ⟨a, ha⟩ := xunpacks an existing member;intro ⟨a, ha⟩unpacks an input as it is introduced. A named subtype may needunfold Evens at xfirst. -
example {S : Type} {P : S → Prop} (x y : {a : S // P a}) (h : x.val = y.val) : x = y := by apply Subtype.ext exact hWhat Lean needsAn equality goal between two members of the same subtype.
What Lean does
apply Subtype.extreduces the goal to equality of their underlying values. No equality of the property proofs is required. After constructing or unpacking members,dsimp(orsimp) can simplify projections such as(Subtype.mk a ha).val.
Axiom of choice: choose and choose_spec
Write open Classical to use the short names below; the full names are Classical.choose and Classical.choose_spec. Unpacking an existential with have ⟨a, ha⟩ := h suffices inside a proof of a proposition. Choice also lets us select data from existence proofs, such as a preimage for every output of a surjection.
Select a witness and its property
-
open Classical example {S : Type} {P : S → Prop} (h : ∃ a : S, P a) : P (choose h) := by let a := choose h have ha : P a := choose_spec h exact haWhat Lean needsAn existence proof
h : ∃ a : S, P a.What Lean does
choose h : Sselects a witness;choose_spec hprovesP (choose h).letnames a value, whilehavenames a proof. This is a termchoose h, rather than the separatechoosetactic.
Build a right inverse of a surjection
-
open Classical noncomputable def chosen_right_inverse {S T : Type} {f : S → T} (h : surjective f) : {g : T → S // f ∘ g = id} := by let g (t : T) := choose (h t) have hg (t : T) : f (g t) = t := choose_spec (h t) apply Subtype.mk case val => exact g case property => funext t change f (g t) = t exact hg tWhat Lean needsA surjectivity proof
h; for eacht,h t : ∃ s, f s = t.What Lean doesDefines
gby choosing a preimage for eacht. The parameterizedhave hg (t : T)records its property for every input.funextproves the right inverse equation. A definition that uses choice to produce data needsnoncomputable; a theorem asserting that such an inverse exists does not.
Lean tactics and techniques
Adding facts
Use assumptions to obtain new facts, prove an intermediate statement, or open the assumptions in each case.
-
have hpt := h t -- Without a name: have := h t exact thisWhat Lean needs
h : ∀ x : T, P xandt : T.What Lean doesAdds the specialized fact. An unnamed
havecalls the new factthis. -
have h₁ : ∃ x : T, P x := by apply Exists.intro t exact hpt ...What Lean needsAn available
t : Tandhpt : P t.What Lean doesProves an intermediate statement in an indented block, then adds
h₁and returns to the original goal. -
rcases hpq with hp | hq · ... · ...What Lean needs
hpq : P ∨ Q, as inex14.lean.What Lean doesCreates one branch with
hp : Pand another withhq : Q.
Simplifying goals
Work backward from the goal, split it into smaller goals, or finish it with a known fact. Dots and show help organize the proof; sorry is a temporary placeholder.
-
exact h -- For example: exact h t, or exact hpq hpWhat Lean needsThe fact or expression supplied has the type of the current goal.
What Lean doesCloses that goal. Arguments can specialize a universal statement or use an implication.
-
exact ⟨hp, hq⟩ -- For an existential: exact ⟨t, hpt⟩What Lean needsA conjunction goal with proofs of both parts, or an existential goal with a witness and its proof.
What Lean doesBuilds the required conjunction or existential statement and closes the goal.
-
apply And.intro · exact hp · exact hqWhat Lean needsThe goal
P ∧ Q, withhp : Pandhq : Q.What Lean doesEach
·focuses on one goal; its indented proof must finish that goal. Type\.for the dot. -
show P → Q intro hp ...What Lean needsA goal that can already be written as
P → Q.What Lean doesDisplays the intended goal explicitly before continuing the proof.
-
sorryWhat Lean needsAn unfinished proof while you are working.
What Lean doesAccepts a placeholder with a warning. Put the cursor here to inspect the goal; replace it to finish the proof.
-
apply h.mp -- In the other direction: apply h.mprWhat Lean needs
h : P ↔ Qand the goalQ(orPformpr).What Lean doesUses the forward implication and leaves
Pto prove;mpruses the reverse implication and leavesQ. -
simp [hp, hq]What Lean needsKnown truth values, such as
hp : Pandhq : Q, in a truth-table case (Day 12).What Lean doesSimplifies the logical goal using these facts and Lean's usual simplification rules; it closes the goal if the result is settled.
-
simp only [succ_times, times_succ] simp only [plus_assoc, plus_comm]What Lean needsA goal to simplify using the listed equalities, as in Days 19–20.
What Lean doesRepeatedly simplifies using the supplied rules. In these examples the second list rearranges sums into a common form. It may close the goal.
simp only keeps the theorem list explicit; simp [hp, hq] also uses Lean's usual simplification rules. Use rewrite when you want to control a particular substitution and its direction.
Equality: definitions and rewriting
Use a definition or equality
-
rflWhat Lean needsAn equality whose sides are the same after computing definitions, such as
f ℕ.zero = ℕ.zero.What Lean doesCloses the equality goal. An algebraic identity may need rewriting or induction first.
-
unfold fWhat Lean needsAn occurrence of the defined function
fin the goal.What Lean doesExpands its definition. At zero or a successor this exposes the corresponding rule.
-
rewrite [ih] rewrite [zero_plus, plus_zero] rewrite [← plus_assoc a b c]What Lean needsAn equality hypothesis or theorem and a matching expression. Supply arguments to select the instance; type
\lfor←.What Lean doesReplaces a matching left side by its right side.
←reverses the direction; a list performs the rewrites in order. Finish withrflwhen both sides match. -
change ℕ.zero.succ.succ * n = n + nWhat Lean needsThe goal
(2 : ℕ) * n = n + n.What Lean doesDisplays the same goal using the successor notation for two.
changemust preserve the goal by definitions alone. -
rewrite [show (2 : ℕ) = ℕ.zero.succ.succ by rfl]What Lean needsA matching numeral in the goal.
What Lean doesProves a small equality inline and uses it immediately to rewrite.
Focus on part of an equality
-
conv => lhs ; unfold plusWhat Lean needsAn equality with an occurrence of
pluson its left side.What Lean doesFocuses on the left side and unfolds there. Use
rhsto focus on the right side. -
conv => rhs ; arg 1 ; change (1 : ℕ) + nWhat Lean needsAn equality with right side
n.succ + t, as in Day 20.What Lean doesSelects the right side, then its first argument
n.succ, and writes that argument as(1 : ℕ) + n. -
apply congrArgWhat Lean needsAn equality with the same outer function on both sides, such as
a.succ = b.succorn + a = n + b.What Lean doesReduces the goal to equality of the inputs,
a = b, as in the multiplication proofs inex18.lean.