Lean 4 for mathematicians: a teacher's guide
Introduction
Who it is for. This guide is aimed at teachers who want to introduce Lean 4 to mathematics students who are used to writing proofs on paper but have no previous programming experience. No prior knowledge of computer science is required.
Philosophy of the course.
- Lean is a proof notebook that talks back. You write an argument and the computer tells you, step by step, what is missing. It is presented as a patient interlocutor, not as a programming language.
- Mathematics first, syntax later. Each topic starts from a proof the student already knows how to do on paper and translates it into Lean.
- No installation at the beginning. The first three sessions can be done in the browser. Local installation comes when the student already wants to carry on alone.
- You learn by reading the proof state. The central skill is not memorizing tactics, but reading the goals window (the infoview) the way one reads a blackboard.
- Making mistakes is cheap. The red error is information, not a failure.
Structure. Eight topics of about 2 hours each (theory and practice mixed). Each topic has two parts: the content (what the student sees) and the teaching tips (notes for the teacher with key ideas, typical mistakes, ...).
Convention. All the examples start with import Mathlib.Tactic, Lean's library of tactics. The code blocks can be pasted as they are into the editor.
| Topic | Title | Central idea |
|---|---|---|
| 1 | First contact | A theorem is a type; a proof is a term |
| 2 | Propositional logic | Connectives and the tactics that handle them |
| 3 | Quantifiers and sets | ∀, ∃, membership, inclusion |
| 4 | Equality and calculation |
rw, calc, ring, linarith
|
| 5 | Induction and recursion | Natural numbers, sums, recursive definitions |
| 6 | Your own definitions |
def, structure, limits |
| 7 | Finding your way around Mathlib | Looking up lemmas without knowing them by heart |
| 8 | Final project | Formalizing a result of your own |
Topic 1. First contact
Content
Objectives. Open Lean, write a statement, read the proof state and close a very simple proof.
1.1 What Lean is (in three sentences). Lean is a proof assistant: it checks that every step of an argument is logically correct. Statements are written in a language very close to the mathematical one. A proof accepted by Lean has no gaps.
1.2 Where to write. To start, the Lean web editor is enough. You write on the left; on the right appears the infoview, which shows what Lean answers. To work locally, use Visual Studio Code with the Lean 4 extension, which guides the installation.
1.3 Your first statement
import Mathlib.Tactic example : 2 + 2 = 4 := by norm_num
Reading: “Example: 2 + 2 = 4. Proof: compute with norm_num.” The word example introduces an unnamed statement; by announces that we are going to prove with tactics, which are commands of the kind “apply this result”, “compute”, “split into cases”.
1.4 Hypotheses and goal. Place the cursor after by in the following example:
example (a b : ℕ) (h : a = b) : b = a := by exact h.symm
The infoview shows:
a b : ℕ h : a = b ⊢ b = a
Above the ⊢ line are the hypotheses (what we have); after ⊢ is the goal (what we want). The whole technique of Lean consists in transforming the goal until it is closed. exact h.symm says: “the goal is obtained exactly from h by turning it around”.
1.5 Named theorems.
theorem my_add_comm (a b : ℕ) : a + b = b + a := by exact Nat.add_comm a b theorem my_add_comm' (a b : ℕ) : a + b = b + a := by ring
ℕ is typed \N and the editor converts it automatically; likewise \R for ℝ, \to for →, \forall for ∀, \ex for ∃. Two proofs of the same fact: one citing a lemma, the other computing. Both are valid.
1.6 The underlying idea, without drama. In Lean, statements are types and proofs are elements of those types. You do not need to understand type theory to start: it is enough to know that h : a = b means “h is a proof that a = b” and that it is used like any other piece of data.
Exercises.
- Prove
example (a b c : ℕ) (h1 : a = b) (h2 : b = c) : a = c
with `exact h1.trans h2`.
- Prove
example (x : ℝ) : x + 0 = x
with `ring`, and then with `exact add_zero x`.
- Change the statement of
my_add_commto something false (for examplea + b = b + a + 1) and read the error. What does Lean tell you is missing? - Put
sorryin place of a proof. What difference is there in the color and in the message?
Teaching tips
- Idea that must be clear. The infoview is the blackboard. If the student gets lost, the answer is almost always “look at the goal”.
-
How to present it. Start with a paper proof of
a = b → b = aand do it in parallel in Lean. The student must see that the reasoning is the same. -
Common mistakes.
- Forgetting
import Mathlib.Tactic. - Typing ASCII (
->) and not understanding why it changes: both are valid, but it is best to stick to one. - Indentation: after
by, the lines must be indented and aligned. - Confusing
=with:=.
- Forgetting
- On type theory. Keep the discourse to a minimum. If they ask, answer briefly and postpone the discussion to Topic 6.
- A trick to remove fear. Let them break things on purpose. A Lean error is almost never serious, and seeing one early works like a vaccine.
Topic 2. Propositional logic
Content
Objectives. Handle →, ∧, ∨, ¬, ↔ with the basic tactics. Each connective has one way to construct it and another to use it.
2.1 Propositions. P Q : Prop declares two arbitrary propositions. A hypothesis hP : P says that P is true.
2.2 Table of tactics.
| Connective | To prove it (goal) | To use it (hypothesis) |
|---|---|---|
| P → Q | intro h |
h hp (apply) |
| P ∧ Q | constructor |
obtain ⟨h1, h2⟩ := h |
| P ∨ Q |
left / right
|
rcases h with h1 | h2
|
| ¬P | intro hp |
h hp produces False
|
| P ↔ Q | constructor |
h.1, h.2
|
2.3 Examples.
example (P Q : Prop) : P ∧ Q → Q ∧ P := by intro h -- h : P ∧ Q -- ⊢ Q ∧ P obtain ⟨hp, hq⟩ := h -- hp : P -- hq : Q exact ⟨hq, hp⟩ example (P Q : Prop) (hP : P) (hQ : Q) : P ∧ Q := by constructor · -- ⊢ P exact hP · -- ⊢ Q exact hQ example (P Q : Prop) : P ∨ Q → Q ∨ P := by intro h -- h : P ∨ Q -- ⊢ Q ∨ P rcases h with hp | hq · -- hp : P right -- ⊢ P exact hp · -- hq : Q left -- ⊢ Q exact hq example (P Q : Prop) (h : P → Q) (hnq : ¬ Q) : ¬ P := by intro hp -- hp : P -- ⊢ False exact hnq (h hp)
After each step I have annotated, as a comment starting with --, the changes that step produces in the hypotheses or in the goal. These comments are optional and are not part of the proof.
The dot · opens a subgoal: after constructor there are two goals and each dot deals with one of them.
2.4 Mathematical reading. The first example is “suppose P and Q; then we have Q and P”. intro is suppose; obtain is let us decompose the hypothesis; exact is we conclude.
Exercises.
-
P ∧ (Q ∧ R) → (P ∧ Q) ∧ R. -
(P → Q) → (Q → R) → (P → R). -
P ∨ Q → (P → R) → (Q → R) → R. -
¬ (P ∧ ¬ P). - Challenge:
(P ↔ Q) → (Q ↔ P).
Teaching tips
- Strategy. Always present the construct / use pair. It is the common thread of the whole course and it will reappear with ∀ and ∃.
-
Common mistakes.
- Trying
exactwhen anintrois missing. - Not seeing that
¬ PisP → False. - Forgetting the dot
·or indenting it badly; Lean warns with “unsolved goals”.
- Trying
-
Useful resource. Teach
assumption(closes the goal if it matches a hypothesis) andtauto(solves tautologies) only after they have done the exercises by hand. Otherwisetautodefeats the learning. -
Classical logic. Mathlib is classical:
by_contra,by_casesandpush_negare available. Mention it without going into constructivism, unless the group asks for it.
Topic 3. Quantifiers and sets
Content
Objectives. Use ∀ and ∃, and work with sets through membership, inclusion and equality by double inclusion.
3.1 Quantifiers. They follow the same construct / use pattern.
| To prove it | To use it | |
|---|---|---|
| ∀ x, P x | intro x |
h a (instantiate at a) |
| ∃ x, P x |
use a (give a witness) |
obtain ⟨x, hx⟩ := h |
example : ∃ n : ℕ, n * n = 16 := by use 4 example (f : ℝ → ℝ) (hf : ∀ x, f x = 2 * x + 1) : f 3 = 7 := by rw [hf] -- ⊢ 2 * 3 + 1 = 7 norm_num example (P : ℕ → Prop) (h : ∃ n, P n) : ¬ ∀ n, ¬ P n := by intro h1 -- h1 : ∀ (n : ℕ), ¬P n -- ⊢ False obtain ⟨n, hn⟩ := h -- n : ℕ -- hn : P n exact h1 n hn
3.2 Sets. Set ℕ is the type of subsets of ℕ. x ∈ A ∩ B is, by definition, x ∈ A ∧ x ∈ B, so the tactics from Topic 2 work directly.
example (A B : Set ℕ) : A ∩ B ⊆ A := by intro x hx -- x : ℕ -- hx : x ∈ A ∩ B -- ⊢ x ∈ A exact hx.1 example (A B : Set ℕ) : A ∩ B = B ∩ A := by ext x -- ⊢ x ∈ A ∩ B ↔ x ∈ B ∩ A constructor · -- ⊢ x ∈ A ∩ B → x ∈ B ∩ A rintro ⟨hA, hB⟩ -- hA : x ∈ A -- hB : x ∈ B -- ⊢ x ∈ B ∩ A exact ⟨hB, hA⟩ · -- ⊢ x ∈ B ∩ A → x ∈ A ∩ B rintro ⟨hB, hA⟩ -- hB : x ∈ B -- hA : x ∈ A -- ⊢ x ∈ A ∩ B exact ⟨hA, hB⟩
ext x is the extensionality principle: “let x be an element; let us prove that it is in one side if and only if it is in the other”. rintro is intro plus obtain in a single step.
Exercises.
-
∃ x : ℝ, x + 3 = 5. -
(∀ x, P x ∧ Q x) → ∀ x, P x. -
A ⊆ B → B ⊆ C → A ⊆ Cfor sets of ℕ. -
A ∩ (B ∪ C) = (A ∩ B) ∪ (A ∩ C). It is long; do it on paper first. - Challenge:
(∃ x, ∀ y, R x y) → ∀ y, ∃ x, R x y.
Teaching tips
- Delicate point. The order of the quantifiers. Ask them to read the statement and the goal aloud after each tactic.
-
Common mistake. Giving the witness too early or too late: in
∀ ε, ∃ δ, …firstintro ε, thenuse; if the order is reversed, the proof is no longer possible. It is an excellent occasion for them to see why the order matters. -
On
Set. Many students expectx ∈ A ∩ Bto be opaque. Show them that it is transparent:hx.1works. -
Double inclusion. It is worth teaching
Set.Subset.antisymmas an alternative toext, but only as a curiosity.
Topic 4. Equality and calculation
Content
Objectives. Rewrite with rw, chain equalities with calc and let Lean do the routine algebra.
4.1 Rewriting. rw [h] replaces in the goal each occurrence of the left-hand side of h by the right-hand side.
example (a b c : ℕ) (h1 : a = b) (h2 : b = c) : a = c := by rw [h1] -- ⊢ b = c rw [h2] example (a b c : ℕ) (h1 : a = b) (h2 : b = c) : a = c := by rw [h1, h2]
4.2 Chains of calculations. Lean lets you write the proof the way we would on a blackboard:
example (a b : ℝ) (h : a = 2 * b) (hb : b = 3) : a = 6 := by calc a = 2 * b := h _ = 2 * 3 := by rw [hb] _ = 6 := by norm_num
Each line is an equality with its justification. The underscore _ means “what was on the previous line”.
4.3 Automatic proofs.
| Tactic | What it is for |
|---|---|
ring |
Identities in commutative rings |
norm_num |
Concrete numerical calculations |
linarith |
Linear inequalities from the hypotheses |
nlinarith |
Inequalities with products; accepts hints |
positivity |
Proving that something is ≥ 0 or > 0 |
simp |
Simplifying with Mathlib's list of lemmas |
example (a b : ℝ) : (a + b)^2 = a^2 + 2*a*b + b^2 := by ring example (a b : ℝ) (h : a ≤ b) : a + 1 ≤ b + 1 := by linarith example (a b : ℝ) : a * b ≤ (a^2 + b^2) / 2 := by nlinarith [sq_nonneg (a - b)]
In the last example, sq_nonneg (a - b) is the hint: the fact 0 ≤ (a - b)^2. It is exactly what we would say on paper.
Exercises.
-
(a + b) * (a - b) = a^2 - b^2in ℝ withring. - Prove 4.2 with
rwandnorm_numwithoutcalc. -
a ≤ b → c ≤ d → a + c ≤ b + dwithlinarith. -
0 ≤ a^2 + b^2withpositivity. - Challenge:
2*a*b ≤ a^2 + b^2withnlinarithand the right hint.
Teaching tips
-
Balance. Many students discover
ringandlinarithand use them for everything. That is fine: they are arithmetic provers, not cheap shortcuts. What is worth ensuring is that they know how to do the long version withcalcwhen the automatic one fails. -
When
linarithfails. When there are products of variables. It is the occasion to introducenlinarithand hints. Make it explicit that the hint is the mathematical idea. -
Common mistakes.
-
rwrewrites all the occurrences, not just the desired one; if you need to control it, userw [h] at h2ornth_rewrite. -
rwfails with “motive is not type correct” or “did not find instance”; it is almost always a problem of syntactic form, not of mathematics. - Alignment of
calc.
-
- Key message. Automation closes obvious steps; the human work lies in choosing the steps.
Topic 5. Induction and recursion
Content
Objectives. Do induction on ℕ, work with finite sums and define recursive functions.
5.1 Induction. The scheme is the one from paper: base case and inductive step.
theorem gauss_sum (n : ℕ) : 2 * (∑ i ∈ Finset.range (n + 1), i) = n * (n + 1) := by induction n with | zero => -- ⊢ 2 * ∑ i ∈ Finset.range (0 + 1), i = 0 * (0 + 1) simp | succ k ih => -- k : ℕ -- ih : 2 * ∑ i ∈ Finset.range (k + 1), i = k * (k + 1) -- ⊢ 2 * ∑ i ∈ Finset.range (k + 1 + 1), i = (k + 1) * (k + 1 + 1) rw [Finset.sum_range_succ, mul_add, ih] -- ⊢ k * (k + 1) + 2 * (k + 1) = (k + 1) * (k + 1 + 1) ring
In succ k ih there appear k (the value for which we already know the result) and ih, the induction hypothesis. Finset.range (n + 1) is {0, 1, …, n} and Finset.sum_range_succ says that summing up to k+1 is summing up to k and adding the last term.
5.2 Recursive definitions.
def fact : ℕ → ℕ | 0 => 1 | n + 1 => (n + 1) * fact n theorem fact_pos (n : ℕ) : 0 < fact n := by induction n with | zero => -- ⊢ 0 < fact 0 simp [fact] | succ k ih => -- k : ℕ -- ih : 0 < fact k -- ⊢ 0 < fact (k + 1) show 0 < (k + 1) * fact k -- ⊢ 0 < (k + 1) * fact k exact Nat.mul_pos (Nat.succ_pos k) ih #eval fact 5 -- 120
#eval computes: it is the “programming” part, and here it only serves to check that the definition does what is expected (it returns 120).
Exercises.
- Prove by induction that
∑ i ∈ Finset.range (n + 1), (2 * i + 1) = (n + 1)^2. - Define
double : ℕ → ℕby recursion and provedouble n = 2 * n. - Prove that
fact n ≥ 1without usingfact_pos. - Challenge:
2^n ≥ n + 1by induction (hint:omegaornlinarithin the step).
Teaching tips
-
Key idea. Lean's induction is literally the induction principle. Stress that
ihis the hypothesis that on paper we would write as “suppose it true for k”. -
Summation notation. Students get blocked by
Finset. It is enough to say thatFinset.range nis {0,…,n−1} and that∑ i ∈ S, f iis the usual sum. No further explanation is needed. -
Common mistakes.
- Confusing
nandn + 1in the cases. - Expecting
simpto close the inductive step, when it usually needs the sum lemma. -
rwfails because the goal showsk + 1 + 1and notk + 2.
- Confusing
- Debugging trick. When the inductive step does not work out, ask them to write the goal and the hypothesis on paper and to ask themselves which equality connects them.
Topic 6. Your own definitions
Content
Objectives. Define new mathematical concepts (properties, structures) and prove statements about them.
6.1 Defining a property. Lean does not know what “injective” means in our text until we write it down (Mathlib already has Function.Injective, but defining it yourself is the best way to understand it).
def MyInjective (f : ℕ → ℕ) : Prop := ∀ a b, f a = f b → a = b example : MyInjective (fun n => n + 1) := by intro a b h -- a b : ℕ -- h : (fun n => n + 1) a = (fun n => n + 1) b -- ⊢ a = b simpa using h
After intro, h says (fun n => n + 1) a = (fun n => n + 1) b; simpa simplifies and concludes.
6.2 Limit of a sequence.
def Converges (a : ℕ → ℝ) (l : ℝ) : Prop := ∀ ε > 0, ∃ N : ℕ, ∀ n ≥ N, |a n - l| < ε example (c : ℝ) : Converges (fun _ => c) c := by intro ε hε -- ε : ℝ -- hε : ε > 0 -- ⊢ ∃ N, ∀ n ≥ N, |(fun x => c) n - c| < ε use 0 -- ⊢ ∀ n ≥ 0, |(fun x => c) n - c| < ε intro n hn -- n : ℕ -- hn : n ≥ 0 -- ⊢ |(fun x => c) n - c| < ε simpa using hε
It is the ε-N definition from Analysis courses, written almost identically. The proof also follows the paper script: given ε, we choose N, and for each n the absolute value is 0 < ε.
6.3 Structures. They are used to group data.
structure Point where x : ℝ y : ℝ def Point.norm2 (p : Point) : ℝ := p.x^2 + p.y^2 theorem Point.norm2_nonneg (p : Point) : 0 ≤ p.norm2 := by unfold Point.norm2 -- ⊢ 0 ≤ p.x ^ 2 + p.y ^ 2 positivity
6.4 Types and universes, only what is essential. ℕ, ℝ, Set ℕ and ℕ → ℝ are types; x : ℕ is read “x is an element of ℕ”. That is enough. Mathlib uses classes (Group, Field, …) for algebraic structures, which will be seen in passing.
Exercises.
- Define
Increasing (a : ℕ → ℝ)and prove thatfun n => (n : ℝ)is increasing. - Prove
Converges a l → Converges a l' → l = l'(the limit is unique). It is a challenge; start by writing the proof on paper with ε/2. - Define the structure
MyRatwith a numerator and a denominator and a functionadd. (Only the definition; proving properties is optional.)
Teaching tips
- What matters. That the student sees that their mathematical vocabulary is translated literally. Analysis students usually get hooked here.
-
Common mistake. A definition that looks correct but is not (for example, forgetting
ε > 0). Lean does not warn: the definition compiles. The lesson is that Lean verifies proofs, not that the definitions are the ones we intended. -
Frequent questions. “Why not use Mathlib's definition?” Because learning to define is part of the craft; later it is replaced by Mathlib's, with
Filter.Tendsto, and the difference is discussed. - Types and functions. If doubts about type theory arise, answer with the motto “a type is like a set, except that each element has a single type”.
Topic 7. Finding your way around Mathlib
Content
Objectives. Find lemmas you do not know, read their statements and apply them.
7.1 The real problem. Nobody memorizes Mathlib. The skill trained here is searching.
7.2 Tools.
| Tool | Use |
|---|---|
#check name |
Shows the statement of a lemma |
exact? |
Tries to close the goal with a lemma from Mathlib |
apply? |
Suggests lemmas that fit the goal |
rw? |
Suggests rewrites |
simp? |
Says which lemmas simp has used |
| Mathlib documentation | Web search for all the lemmas |
| Loogle | Searches for lemmas by the shape of the statement |
| Lean Zulip | Forum where you can ask questions |
#check Nat.add_comm -- Nat.add_comm (n m : ℕ) : n + m = m + n example (a b : ℕ) (hb : 0 < b) (h : a ∣ b) : a ≤ b := by exact?
Lean proposes Nat.le_of_dvd hb h. Good practice is to copy the suggestion instead of leaving exact?.
7.3 Naming conventions. Mathlib's names are descriptive: add_comm, mul_pos, sq_nonneg, Finset.sum_range_succ. With time you learn to guess them: a_lt_b_iff usually means “a < b if and only if…”.
7.4 Working locally. When the student wants to carry on alone: install Lean and VS Code following the official instructions, and create a project with Mathlib (lake new my_project math). For the course it is enough to provide a ready-made template and a written start-up procedure, to prevent anyone from getting stuck on the installation.
Exercises.
- For each of these statements, find the Mathlib lemma that solves it:
-
0 < a → 0 < b → 0 < a * b; -
|a + b| ≤ |a| + |b|; -
a ≤ b → a ≤ b + cif0 ≤ c.
-
- Use
#checkto read the statement ofFinset.sum_command explain in your own words what it says. - Challenge: prove
Nat.Prime 7in two ways (norm_numanddecide).
Teaching tips
- Pedagogical goal. Demystify. The student should understand that looking for the lemma is a normal part of the work, just like looking up a theorem in a book.
- Installation. If it is done locally, set aside a separate session and keep close company. It is the point where most students get lost. A shared template saves hours.
-
Common mistakes.
- Leaving
exact?in the submission: it is slow and not a stable proof. - Generic names (
add_comm) work for several types; if the student gives a wrong type, Lean complains with long messages. Teach them to read the last line of the error first.
- Leaving
-
Good practices. Save often, comment with
--, split long proofs into named auxiliary lemmas.
Topic 8. Final project
Content
Objective. Formalize a complete elementary result and present it.
Project options (choose one).
- Set theory. De Morgan's laws and distributivity for sets and families of sets.
- Arithmetic. Sum of the first n odd numbers, Gauss's formula, Bernoulli's inequality.
- Analysis. Uniqueness of the limit and limit of the sum of two convergent sequences, with the ε-N definition from Topic 6.
-
Algebra. In a group, uniqueness of the identity and of the inverse, using Mathlib's
Group. - Free choice. A proposition from a course the student is taking, agreed with the teacher.
Deliverables. A .lean file without sorry, with comments explaining the strategy, plus a page with the paper proof and a short reflection on what was hardest in Lean.
Teaching tips
-
What to assess.
- That it compiles.
- That the statements are faithful to the mathematical text.
- That the structure (auxiliary lemmas) is clear.
- That the student can explain their own proof.
- Advice. Require them to first write the paper proof divided into lemmas; the Lean version is the translation. Projects improvised directly in Lean end in frustration.
- Extensions. For advanced groups: basic topology, a little Galois theory, or contributing a small lemma to Mathlib.
Appendix A. Tactics cheat sheet
| Tactic | What it does |
|---|---|
intro x |
Introduces a hypothesis or a variable |
exact t |
Closes the goal with the term t
|
apply h |
Uses h to reduce the goal |
constructor |
Splits a ∧, ↔ or ∃ into parts |
left / right
|
Chooses one side of a ∨
|
use a |
Gives a witness for ∃
|
obtain ⟨x, hx⟩ := h |
Decomposes a hypothesis |
rcases h with a | b
|
Splits into cases |
by_contra h |
Proves by contradiction |
by_cases h : P |
Cases according to P or ¬ P
|
rw [h] |
Rewrites with an equality |
simp |
Simplifies |
ring, linarith, positivity
|
Arithmetic automation |
induction n with |
Induction |
ext x |
Equality of sets or functions |
have h : P := … |
Introduces an intermediate result |
sorry |
Leaves a gap (does not count as a proof) |
Appendix B. How to read an error
- Read first the line marked in red, not the whole message.
- “unsolved goals” means the proof is not finished: look at which goal remains.
- “type mismatch” indicates that you have given something that does not fit the goal: compare the two types.
- “unknown identifier” is usually a spelling mistake or a missing
import. - If you do not understand the message, put
sorryin the step, check that the rest compiles and move on.
Appendix C. Resources
- The Natural Number Game (Kevin Buzzard): a playful entry point to Lean, perfect as an activity before Topic 1.
- Lean Game Server (the same server as the Natural Number Game): includes other games, such as the ones on set theory, logic or the integers. They are a natural continuation of the first one.
- The mechanics of proof (Heather Macbeth): an introduction to Lean for mathematicians.
- Mathematics in Lean (Jeremy Avigad and Patrick Massot): the reference interactive text for mathematicians, ideal as complementary reading.
- Theorem Proving in Lean 4: a more technical text, useful for understanding the type-theory background.
- Matemáticas Lean 4 (José A. Alonso): a book (in Spanish) on elementary mathematics using Lean 4.
- Lean 4 proof challenges (José A. Alonso): a collection of Lean 4 proof exercises with several solutions, from the most automatic to the most detailed, and with links to Lean 4 Web to experiment with the code from the browser. Some exercises also include a video explaining how to build the solutions.
- Calculemus (José A. Alonso): a blog of Lean exercises.
- Glimpse of Lean (Patrick Massot): Lean 4 exercises designed for mathematicians who already know the basics, with a very practical approach.
- Formalising Mathematics (Kevin Buzzard): a repository of notes and exercises for formalizing mathematics in Lean.
- 100 Theorems in Lean: an archive of classical formalized theorems, which gives a realistic idea of how hard formalization is.
- Mathlib documentation and the Lean Zulip forum: resources for asking questions and looking up definitions and results.
- Learning Lean on the community's official page: the general index of resources.
Appendix D. Suggested schedules
- Short course (4 sessions). Topics 1, 2, 3 and 4, with a mini-project on sets.
- Standard course (8 sessions). One topic per session, with the final project as the work of the last week.
- Intensive course (2 days). Morning: Topics 1 to 3. Afternoon: Topics 4 and 5. Second day: Topics 6 and 7, and a mini-project in groups.