Lean 4 and Mathlib
A Lean proof is only as good as its statement. sorry compiles; a theorem about the wrong
object compiles; a theorem with an unsatisfiable hypothesis compiles. The work is statement
fidelity first, search before proving, build, then audit the axioms.
Project layout
- A Mathlib-dependent project has
lakefile.leanorlakefile.toml(withrequire mathlib from git "https://github.com/leanprover-community/mathlib4"),lean-toolchain(the exact Lean version; it must match Mathlib's ownlean-toolchainor the cache will not apply), andlake-manifest.json(locked dependency revisions).lake new <name> mathscaffolds this. Do not runlake updatecasually: it moves the Mathlib revision and forces a full rebuild. lake exe cache getdownloads prebuilt Mathlib.oleanfiles; without itlake buildcompiles Mathlib for hours. Thenlake buildbuilds the project,lake build My.Moduleone module, andlake env lean path/File.leanchecks a single file with the project's search path. Read the build output to the end: warnings aboutsorryappear there.import Mathlibis fine for exploration in a single file (slow to load); trim to the needed modules once the proof is stable.
Statement fidelity
- Write the informal claim as a docstring above the theorem, then translate each
quantifier, hypothesis and domain deliberately. Traps: subtraction on
ℕtruncates (2 - 3 = 0),/onℕandℤrounds,x / 0 = 0in fields,Finset.range nis{0, ..., n - 1},Nat.PrimeversusPrime, strict versus non-strict inequalities, "for all sufficiently large n" is∃ N, ∀ n ≥ N, ....#checkthe statement,#printevery borrowed definition, and confirm the meaning on a concrete instance withexampleplusdecideornorm_num. - Test the hypotheses for satisfiability: from
h : 0 < 0anything follows, and a theorem quantified over an empty type is vacuous. Provide one witness that satisfies all hypotheses as anexample. - Put
set_option autoImplicit falseat the top of the file (or in the lakefile'sleanOptions) so a misspelled identifier cannot silently become a new universally quantified variable.
Search before proving
- Loogle (https://loogle.lean-lang.org) searches by type pattern or constant name
(
List ?a → ?a,Real.sqrt, _ * _); Mathlib ships the#loogleand#leansearchcommands from LeanSearchClient for the same queries inside the editor. The Mathlib docs (https://leanprover-community.github.io/mathlib4_docs) and the naming convention (add_comm,mul_le_mul_left,Nat.succ_le_iff) find the rest. - Inside a goal:
exact?closes it with one library lemma when possible,apply?lists candidates,rw?suggests rewrites,simp?shows which simp lemmas fired so you can replacesimpwithsimp only [...],hinttries several finishers. Domain closers:omega(linear arithmetic onℕandℤ),linarith,nlinarith,positivity,norm_num,ring,field_simp,gcongr,decide,aesop.
Tactic hygiene
- Replace mid-proof
simpwith thesimp only [...]thatsimp?reports; a bare non-terminalsimpbreaks when Mathlib changes. Name hypotheses (intro n hn,obtain ⟨x, hx⟩ := h), avoid chains ofthis, and structure withhave,calcandrefine ⟨?_, ?_⟩. Paste the termexact?produced and delete the search call. - Keep a
byblock under a screen; split into lemmas with the informal statement as a docstring on each. Nosorryin a finished file: the build printsdeclaration uses 'sorry'for every one. Avoidnative_decideunless the user accepts trusting the compiler; it adds theLean.ofReduceBoolaxiom.
Audit
#print axioms theoremNameafter every finished proof. The expected set ispropext,Classical.choice,Quot.sound.sorryAxmeans an unfinished proof somewhere in the dependency chain;Lean.ofReduceBoolmeansnative_decidewas used. Quote the output verbatim in the report.- Deliver the file, the exact
lake buildcommand with its clean output, the#print axiomsline, and a line-by-line mapping from the informal claim to the formal hypotheses and conclusion, naming every translation choice.
Checklist
-
lean-toolchainmatches Mathlib;lake exe cache getthenlake buildsucceed. - Informal claim quoted above the theorem; each clause mapped to a hypothesis.
- Hypotheses shown satisfiable by an
example. - Searched before proving;
exact?andsimp?output pasted, not left in place. - No
sorry, no unexplainednative_decide. -
#print axiomsoutput recorded.
Sources
- Lean 4 documentation: https://lean-lang.org/documentation/
- Lake (build system) README: https://github.com/leanprover/lean4/tree/master/src/lake
- Mathlib, using Mathlib in a project: https://leanprover-community.github.io/install/project.html
- Mathlib tactic reference: https://leanprover-community.github.io/mathlib4_docs/tactics.html
- Loogle: https://loogle.lean-lang.org
- LeanSearchClient (
#loogle,#leansearch): https://github.com/leanprover-community/LeanSearchClient - Theorem Proving in Lean 4: https://lean-lang.org/theorem_proving_in_lean4/
- Mathematics in Lean: https://leanprover-community.github.io/mathematics_in_lean/