Ismail's Glossary
A complete guide to Lean 4 and Mathlib —
from your first proof to the full mathematical library.
Four tools. One site. Everything you need to learn, navigate, and work with Mathlib4.
Who Is This For?
▶ New to Lean or Mathlib
Start with Getting Started to install your environment on Windows or macOS, check your system requirements, and run your first proof. Then use Lean 4 References as a progressive guide from orientation through advanced tactics.
✪ Learning to navigate Mathlib
Open the Atlas first — see how the 32 domains relate and where they diverge from shared foundations. Once you know roughly where you are, switch to the Glossary to drill down to the exact file and read its full description.
∀ Working with Mathlib daily
Search all 9,150 modules by name, path, or description in the Glossary and copy import or local paths in one click. Use the Lean 4 References as a quick-lookup for tactics, attributes, and automation — the decision guide tells you exactly which tactic to reach for.
The Atlas and the Glossary
✪ Atlas
A visual survey of how Mathlib's domains relate and diverge from shared foundations — measure theory sits near both analysis and probability; follow each deep enough and they part ways. Drag to pan, scroll to zoom, hover a territory to read what it contains.
▦ Glossary
Every file and directory in Mathlib4, as a searchable, drillable index. Click a domain to expand its sub-modules inline, all the way down to individual files. Each entry shows a full description and instant copy buttons for its import path and local path.
∀ Lean 4 References
A 16-section progressive reference built for the learning journey: orientation and the Lean Infoview first, then Unicode symbols, then querying tools, then your first proof — all before a single tactic. Core tactics are grouped by what they do to the proof state, not alphabetically. Automation, attributes, type class hierarchy, Mathlib idioms, and a full error-message guide follow.
▶ Getting Started
A complete setup guide, OS-first. Choose Windows or macOS at the top; system requirements appear immediately so you know whether your device can run Lean before touching the installer. Step-by-step installation of Git, VS Code, elan, the Lean 4 extension, and Mathlib follows, tailored to your chosen platform.
The map before the territory
Mathlib4 is the world's largest library of formally verified mathematics — over 9,150 modules spanning nearly every area of modern mathematics: algebra, analysis, topology, number theory, category theory, and far beyond. For anyone meeting it for the first time, that's a lot to take in. Module names are precise but opaque. Dependencies run deep. The only documentation has traditionally been the source code itself.
This project exists to make that first meeting a good one. Every module gets a plain-language description — no assumed background required. The Glossary makes the library navigable. The Atlas makes its shape visible. The References make Lean learnable. Getting Started makes the toolchain approachable. Together, they're the friendly way in that should have existed from the beginning.
Inside the Repository
Descriptions are community-maintained, and the data and tooling behind this site now live in the open. Here's what each piece is for.
The canonical dataset: one JSON array covering all 9,150 modules, each entry carrying Path, Name, Type, Parent Path, Depth, and Description. Every other file here — the RAG export, the Skill, the spreadsheet — is generated from it.
A flattened, embedding-ready export for retrieval-augmented-generation pipelines. Each entry merges path, type, and description into one text field, plus a metadata block recording the exact Lean, Mathlib, and glossary versions it was built against.
A Claude Skill bundle: a SKILL.md, the full glossary embedded so it needs no network access, and a Python search script that retrieves entries by path, keyword, or depth. Install it once and Claude answers Mathlib navigation questions on its own.
A static, offline snapshot of the contributor workbook — the same document the community proposes new descriptions and corrections through. This file freezes it at the reference release, for anyone who needs a stable copy to cite.
▦ Glossary
The gazetteer. Browse every module by layer, or search instantly. Click any directory card to expand its sub-modules inline. Files open a detail panel.
✪ The Atlas
32 domains, surveyed to three layers of depth. For individual files, switch to the Glossary.
Click a territory to open its districts
Files live in the Glossary — this map surveys structure, not individual modules.
Domains radiate from Mathlib at the centre; districts orbit within each domain. Distance from the centre is depth in the library, not importance.
∀ Lean 4 + Mathlib Reference
A progressive reference — from your very first encounter with Lean through to advanced Mathlib idioms. Read top-to-bottom as a guided journey, or jump to any section as a lookup tool. Items marked (M) require a Mathlib import.
✪ Orientation
Before you begin proving — understand what Lean 4 is, what Mathlib adds, and how they relate to each other.
Lean 4 is simultaneously a dependently-typed functional programming language and an interactive proof assistant. You write programs and proofs in the same language. The Lean kernel checks every proof mechanically — if it compiles without sorry, it is correct.
Mathlib is the community-maintained library of formalised mathematics written in Lean 4. It contains over 9,150 modules covering algebra, analysis, topology, number theory, category theory, and more. Most users write import Mathlib to access all of it at once.
Lean 4 is the language and proof engine. Mathlib is the mathematical content built on top. You can use Lean without Mathlib for pure logic and computation, but most mathematical work imports Mathlib for its tactics, type class instances, and theorems.
In Lean, every mathematical statement is a type, and every proof is a term of that type. Writing theorem h : 1 + 1 = 2 declares a type; the proof body constructs a term inhabiting it. The kernel verifies the term fits the type.
⎕ The Environment
Your workspace — learn to read the Lean Infoview before writing a single line of proof. Most early confusion comes from not knowing where to look.
In VS Code: Ctrl+Shift+P (or Cmd+Shift+P on Mac) → type Lean 4: Open Infoview. The panel updates live as you move your cursor through a file or proof.
Hypotheses above the line, goal below. The ⊢ symbol means “goal to prove”.
h : n > 0 ⊢ n + 1 > 0
h is a hypothesis; the goal is to prove n + 1 > 0.
- ■ Red — error. Lean cannot type-check this expression.
- ■ Yellow — warning. Usually
sorryor an unused variable. - ■ Blue / spinning — elaboration in progress. Wait.
- ■ No squiggle — clean. Proof or definition accepted.
Ctrl+Shift+P— Command Palette (all Lean commands)Ctrl+Space— trigger autocomplete / suggestionsF12— go to definition of any identifierShift+F12— find all referencesCtrl+.— quick fix / code actions- Hover any identifier — shows its type inline
✍ How to Type Symbols
The first thing you will need — Lean uses Unicode mathematics throughout. In VS Code with the Lean extension, type a backslash, the symbol name, then Space or Tab to insert.
\forall→ ∀\exists→ ∃\to→ →\iff→ ↔\and→ ∧\or→ ∨\not→ ¬\ne→ ≠\langle \rangle→ ⟨⟩
\N→ ℕ\Z→ ℤ\Q→ ℚ\R→ ℝ\C→ ℂ
\in→ ∈\notin→ ∉\sub→ ⊆\subs→ ⊂\union→ ∪\inter→ ∩\empty→ ∅\le→ ≤\ge→ ≥
\sum→ ∑\prod→ ∏\int→ ∫\partial→ ∂\circ→ ∘\cdot→ ·\times→ ×\otimes→ ⊗\norm→ ‖\mapsto→ ↦
\alphaα\betaβ\gammaγ\deltaδ\epsilonε\thetaθ\lambdaλ\muμ\nuν\piπ\sigmaσ\phiφ\omegaω\OmegaΩ
\lfloor \rfloor→ ⌊⌋\lceil \rceil→ ⌈⌉\gets→ ←\comp→ ∘\^2→ ²\_1→ ₁
-- text— single-line comment/- text -/— block comment/-- text -/— doc comment (shown on hover)/-! text -/— module-level doc comment
⌬ Querying Lean
Your daily tools from day one — ask Lean what anything is before you try to prove it. These commands work anywhere in a file and update live as you type.
#check exprShow the type of any expression. The most-used command — use it constantly. #check Nat.add_comm shows the full statement of that lemma.
#check @nameShow the fully explicit type with all implicit arguments visible. Essential for understanding exactly what arguments a function expects.
#eval exprEvaluate any computable expression and print the result. #eval Nat.gcd 12 8 prints 4.
#print namePrint the full definition, type, and implementation of a declaration. Use it to understand how Mathlib defines things internally.
#print axioms nameList all axioms a declaration depends on. Verify that no sorry or native_decide crept into a proof you care about.
exact?In tactic mode, search the environment for a term that closes the current goal. Comprehensive but slow — the best first thing to try when completely stuck.
apply?Find lemmas whose conclusion matches the current goal shape. More targeted than exact? — use when you know the shape but not the lemma name.
simp?Run simp and report exactly which lemmas it used. Lets you replace a bare simp with a precise simp only [...] for long-term stability.
▷ Your First Expressions
Start here — the simplest things you can write in Lean. Types, terms, and the interactive feedback loop you will use from now on.
Every value in Lean has a type. 2 : Nat, true : Bool, (1 + 1 = 2) : Prop. Use #check to see any type instantly. Types themselves have types: Nat : Type.
Nat— natural numbers ℕ (non-negative)Int— integers ℤ (positive and negative)Bool—true/false(computable)String— textProp— the type of mathematical statementsType— the type of types
#eval 2 + 2 -- 4 #eval "hello".length -- 5 #check Nat.succ -- Nat → Nat #eval List.range 5 -- [0,1,2,3,4]
Lean uses space for application: f x y not f(x,y). Parentheses only group: f (g x). Left-associative: f x y = (f x) y.
Tell Lean the expected type with (expr : Type). Useful when inference picks the wrong type: (0 : Int) vs (0 : Nat) are different values.
fun x => x + 1 maps Nat to Nat. fun x y => x * y is two-argument. These are first-class values you can pass around.
★ Your First Proof (annotated)
Line by line — your first real Lean proof explained word by word. Once this makes sense, every other proof is a variation on this same structure.
import Mathlib example : 1 + 1 = 2 := by norm_num
import MathlibLoad the entire Mathlib library. Every tactic, theorem, and type class instance becomes available. Place at the very top of any file that uses Mathlib.
exampleAn anonymous theorem statement. The proof is checked but not added to the environment. Use for practice and exploration without polluting the namespace.
: 1 + 1 = 2The proposition — the type of the proof we are building. In Lean, = is a Prop. We are claiming this equality holds and must construct a proof.
:= byEnter tactic mode. The := means “is defined as” and by opens a tactic block where commands manipulate the proof state step by step.
norm_numA tactic that normalises numeric expressions. It knows 1 + 1 = 2 directly — one of the most useful one-liners for any concrete numeric goal.
After this runs, the Infoview shows No goals — proof complete. If goals remain, a tactic did not fully close what it was given.
▶ Declaration Forms
Naming things — every way to introduce a definition, theorem, or type into the Lean environment. Each form has a distinct purpose and a convention about when to reach for it.
theorem name : P := proofNamed proof of P. Convention: major results. Identical to lemma to the kernel — distinction is purely human.
lemma name : P := proofNamed proof, convention for auxiliary helper facts. Use lemma for intermediate steps and theorem for the main result.
example : P := proofAnonymous proof — checked but not added to the environment. Essential for exploration and tests. No namespace pollution.
def name : T := exprDefine a named value of type T. Semireducible by default. The workhorse for all non-propositional definitions.
abbrev name : T := exprLike def but marked @[reducible] — unfolds eagerly in unification. Use for type synonyms where Lean should see through the name automatically.
noncomputable defFor definitions that depend on Classical.choice or non-constructive axioms. Cannot be #eval’d but perfectly usable in proofs.
structure Name whereA record type with named fields. Auto-generates projections, the constructor Name.mk, and extensionality infrastructure.
class Name whereA type class. Fields become the interface; use instance to provide implementations. The foundation of Lean’s algebraic hierarchy.
inductive Name whereAn inductive type. Auto-generates the recursor Name.rec, casesOn, and recOn. The basis for Nat, List, Or.
instance : TC args := ...Registers a type class instance for synthesis. Lean finds instances automatically by type. Equivalent to @[instance] def.
private / protectedprivate: visible only in the current file. protected: must use full qualified name even after open.
partial defA definition without a verified termination proof. Use for IO, parsers, and cases where proving termination is genuinely hard.
◆ Scope & Namespaces
Keeping things organised — how Lean groups declarations, controls visibility, and lets you avoid writing fully-qualified names every time you reference something.
namespace Name … end NameOpens a named scope. All declarations inside are prefixed Name.. Namespaces can be reopened anywhere — Mathlib uses this extensively.
section … endAn anonymous scope for grouping variable and open commands. Does not prefix names. Variables and opens declared inside no longer apply after end.
open NameBrings all non-protected names from Name into scope without qualification. Scoped to the nearest enclosing section or namespace.
open Name in exprOpens a namespace for a single expression or tactic block only. The cleanest way to use a namespace without polluting the surrounding scope.
open scoped NameActivates only the scoped notations of Name. Classic: open scoped BigOperators to enable ∑ and ∏ notation.
variable (x : T) / {x} / [TC]Declares a parameter auto-added to subsequent declarations that mention it. () explicit, {} implicit, [] typeclass instance.
universe u vDeclares universe-level variables for universe-polymorphic definitions. Lean’s type theory is stratified: Type 0 : Type 1 : …
termination_by exprProvides the well-founded termination measure for a recursive definition. Lean checks this measure strictly decreases on every recursive call.
▶▶ Core Proof Tactics (inside a by block)
The moves — tactics you will use in almost every proof, grouped by what they do to the proof state. Learn these in order: introduce, close, work backwards, split, case-split, structure.
Introducing hypotheses
intro h / introsAssumes the next hypothesis from a → or ∀ in the goal, naming it h. intros introduces all available hypotheses at once.
rintro ⟨a, b⟩ (M)Like intro but with immediate pattern-matching. ⟨a, b⟩ for conjunctions, h | k for disjunctions, ⟨a, rfl⟩ to substitute equalities on arrival.
Closing goals
exact eClose the goal if e has exactly the goal’s type. The most direct closer — if you know the term, use it.
rflClose a = a by reflexivity. Works when both sides are definitionally equal — Lean verifies by computation.
assumptionClose the goal if it exactly matches any hypothesis in context. Lean searches all hypotheses automatically.
trivialTries rfl, assumption, decide, and True.intro in sequence. A lightweight closer for genuinely trivial goals.
contradictionClose when context contains contradictory hypotheses (e.g. h : P and h’ : ¬P). Searches automatically.
doneSucceeds only if no goals remain. A sentinel to confirm a proof is complete — a failing done means you missed a goal.
Working backwards
apply hIf h : A → B and the goal is B, the new goal becomes A. Backward reasoning — reduce the goal to something you know.
refine ?_Build a proof term with holes ?_. Each hole becomes a new sub-goal. More controlled than apply when you want to specify partial structure explicitly.
Splitting goals
constructorSplit P ∧ Q or P ↔ Q into two sub-goals. Also works on any inductive type with a single constructor.
left / rightChoose a branch of P ∨ Q. After left the goal becomes P; after right it becomes Q.
use e (M)Provide the witness for ∃ x, P x. After use e the goal becomes P e. Accepts multiple arguments for nested existentials.
Case analysis & induction
cases hCase-split on an inductive hypothesis or value h. Produces one goal per constructor.
rcases e with pat (M)Recursive deconstruction: ⟨a, b⟩ for products, h | k for sums, ⟨a, rfl⟩ to substitute. The richest destructuring tactic.
obtain pat := e (M)obtain ⟨a, ha⟩ := h destructs h : ∃ x, P x into witness a and proof ha.
induction xProve by induction on x. One goal per constructor with the induction hypothesis (IH) available.
induction x using rUse a custom recursor r instead of the default. Useful for strong induction and domain-specific induction principles.
Intermediate claims & proof structure
have h : P := proofProve an intermediate claim P and name it h. The primary way to break long proofs into readable labelled steps.
suffices h : P by ...Declare it suffices to prove P. The by ... closes the original goal using h. Then you prove P.
calcChained equalities or inequalities with justifications at each step:calc a = b := h1
_ ≤ c := h2
Context manipulation
revert hMove h back into the goal as ∀ or →. The inverse of intro. Useful to generalise before induction.
generalize e = xReplace all occurrences of expression e with a fresh variable x. Makes a goal induction-ready.
subst hWhen h : x = e, substitute x everywhere in the goal and context, then remove both.
specialize h a bApply hypothesis h to arguments a b in place. Replaces h with the specialised version.
clear hRemove hypothesis h from context when it is no longer needed.
sorryAdmit any goal as true. Emits a yellow warning. Invaluable for top-down proof development — sketch structure first, fill sorrys second.
⚙ Rewriting & Simplification
Changing what the goal looks like — these tactics transform the goal by applying equalities and simplification rules without closing it outright.
rw [h]Rewrite left-to-right using h : a = b. Use rw [←h] for right-to-left. Use at hyp to rewrite in a hypothesis instead of the goal.
rw [h₁, h₂, h₃]Chain multiple rewrites in sequence. Order matters — each rewrite happens after the previous transformation.
simpSimplify using all @[simp]-tagged lemmas. Closes many goals but is non-deterministic — avoid bare simp in finished proofs; use simp only.
simp only [h₁, h₂]Run simp restricted to listed lemmas only. More predictable, faster, and stable across Mathlib updates. The standard for polished proofs.
simp_rw [h] (M)Like rw but works under binders (∀, fun, ∃). The correct tool when rw fails because the pattern appears inside a lambda.
simp_allApply simp to the goal and all hypotheses simultaneously until fixpoint. Powerful but slow — use for hard goals or as a last resort.
nth_rw n [h]Rewrite only the nth occurrence of the pattern. Essential when the same expression appears multiple times.
unfold f / delta funfold: unfold definition of f once. delta: force-unfold even @[irreducible] definitions. Use sparingly — prefer lemmas about f.
convFocused rewriting inside a specific sub-term. Enter with conv =>, navigate with lhs / rhs / ext x, then rw or simp at that exact position.
⚡ Automation & Decision Procedures
Let Lean do the work — these tactics close goals automatically. Know what each one is good at and you will spend far less time on routine proof steps.
| Tactic | What it solves | Notes |
|---|---|---|
ring | Polynomial equalities in commutative rings | Works over any CommRing. Does not handle inequalities. |
ring_nf | Ring normalisation without closing | Simplifies toward normal form; combine with other tactics. |
linarith | Linear arithmetic over ordered fields | Add hints: linarith [h1, sq_nonneg x]. |
nlinarith (M) | Nonlinear arithmetic (products of hypotheses) | Slower than linarith; tries products of pairs. |
norm_num | Concrete numeric computations | Evaluates 2^10 = 1024, primality, floor, ceiling. |
omega | Linear arithmetic over ℤ and ℕ | Decision procedure. Handles Nat.mod, Nat.div, bounded quantifiers. |
decide | Any decidable proposition | Kernel-evaluated. Correct but slow for large computations. |
native_decide | Decidable propositions (fast) | Compiles natively. Much faster; adds an extra axiom. |
positivity (M) | Non-negativity and positivity goals | Proves 0 ≤ f x or 0 < f x by structural analysis. |
gcongr (M) | Goal congruence for monotone functions | Proves f a ≤ f b from a ≤ b when f is monotone. |
field_simp (M) | Clear denominators in field goals | Combine with ring to finish field equalities. |
push_neg (M) | Push negation through quantifiers | ¬ ∀ x, P x → ∃ x, ¬ P x. Also pull_neg. |
contrapose! (M) | Switch to contrapositive + push_neg | contrapose without ! does not push negation. |
by_contra h | Proof by contradiction | Adds h : ¬ P to context; goal changes to False. |
by_cases h : P | Case split on any decidable P | Two goals: h : P and h : ¬ P. |
tauto | Propositional tautologies | Decides pure propositional logic (∧, ∨, ¬, →, ↔). |
aesop (M) | Automated search using registered rules | Applies @[aesop]-tagged lemmas. Configurable depth. |
fun_prop (M) | Continuity, measurability, differentiability | Proves structural function properties via registered lemmas. |
◆ When to Use Which Tactic
The decision guide — when you are unsure which tactic to reach for, the goal’s shape tells you. Follow these patterns and most routine goals resolve quickly.
You have an equality h : a = b and want to replace a specific occurrence. Fails under binders — use simp_rw if the pattern appears inside a fun or ∀.
In finished proofs, always use simp only with an explicit list. Use bare simp only during exploration. Run simp? to discover the right list.
The goal matches the conclusion of a known lemma. Use apply? to find h. Use exact when no new premises arise. Use refine to fill sub-goals manually.
Goal involves ℕ or ℤ with addition, subtraction, mul by literals, mod, or div. Faster than linarith for discrete arithmetic.
Goal is a linear inequality over an ordered field (ℝ, ℚ). Add hints when needed: linarith [sq_nonneg x, h1].
Goal involves concrete numbers: 2^8 = 256, Nat.Prime 97. Much faster and more reliable than decide for numeric goals.
Goal is a polynomial identity in a ring. For fractions: first field_simp to clear denominators, then ring.
You have no idea where to start. Let Lean search everything. Slow but comprehensive. Try apply? as a faster targeted alternative.
◆ Key Attributes (@[name])
Marking declarations — attributes change how Lean’s tactics and elaborator treat a lemma. They go immediately before the declaration they annotate.
| Attribute | Purpose | When to use |
|---|---|---|
@[simp] | Add to the simp lemma set | Equalities simplifying toward a normal form. Avoid on lemmas that could loop. |
@[ext] | Register extensionality lemma | On structures; enables the ext tactic to apply it automatically. |
@[norm_cast] | Register cast lemma | For lemmas about coercions between numeric types (ℕ→ℤ→ℚ→ℝ). |
@[gcongr] | Register congruence rule | For monotone operations; extends the gcongr tactic. |
@[positivity] | Register positivity lemma | Extends the positivity tactic to handle a new operation. |
@[measurability] | Register for measurability tactic | For measurable function constructors in measure theory. |
@[fun_prop] | Register for fun_prop tactic | For continuity, differentiability, and measurability lemmas. |
@[aesop] | Register rule for aesop | Specify safe / unsafe and rule type. |
@[reducible] | Mark as fully transparent | For type synonyms. Makes unification see through the name automatically. |
@[irreducible] | Prevent unfolding except with delta | For implementation details hidden from the elaborator. |
@[instance priority n] | Set instance synthesis priority | Resolve diamond ambiguities. Higher number = higher priority. |
@[deprecated] | Emit deprecation warning on use | When renaming; include the replacement name. |
∀ Type Classes & Instances
The hierarchy — how Lean knows that ℝ is a field and ℤ is a ring without you saying so every time. Understanding this unlocks Mathlib’s generality.
A type class is an interface (like Add, Ring, MetricSpace). An instance provides the implementation for a specific type. Lean finds instances automatically through instance synthesis — you write [Ring R] and Lean finds the right implementation silently.
- Semigroup → Monoid → Group → CommGroup
- Semiring → Ring → CommRing
- CommRing + IsDomain → integral domain
- DivisionRing → Field → LinearOrderedField
- Module R M → Algebra R A
- Preorder → PartialOrder → LinearOrder
- SemilatticeSup / SemilatticeInf → Lattice
- Lattice → CompleteLattice
- OrderedAddCommMonoid → OrderedField
- LinearOrderedField (ℝ, ℚ, etc.)
- TopologicalSpace → T0, T1, T2Space
- MetricSpace → NormedAddCommGroup
- NormedSpace → InnerProductSpace
- CompleteSpace (Banach / Hilbert)
- MeasurableSpace → MeasureSpace
#check (inferInstance : Ring ℤ) #check (inferInstance : Field ℝ) example : CommRing ℤ := inferInstance
instance : Add MyType where
add x y := ...
instance : Ring MyType :=
{ add := ..., mul := ..., ... }✈ Useful Mathlib Patterns
Beyond basics — the imports, notations, and idioms you will reach for in real Mathlib work. Each area has its own conventions and key files worth bookmarking.
Enable with open scoped BigOperators. Then write ∑ i ∈ s, f i and ∏ i ∈ s, f i. Key file: Mathlib.Algebra.BigOperators.Group.Finset.
|x| for ordered groups. ‖x‖ (type \norm) for normed spaces. Key lemmas: abs_add, abs_mul, norm_add_le, norm_sub_le.
Finset.sum, Finset.prod, Finset.card. Filter: Finset.filter. Image: Finset.image. Key: Mathlib.Data.Finset.Basic.
Filter.Tendsto f (nhds a) (nhds b) means f(x) → b as x → a. ContinuousAt f a is syntactic sugar. Key: Mathlib.Topology.Basic.
HasDerivAt f f’ x: f has derivative f’ at x. deriv f x returns it (0 if not differentiable). fderiv for Fréchet derivatives.
open MeasureTheory. Write ∫ x, f x ∂μ for integrals. Key: Mathlib.MeasureTheory.Measure.MeasureSpace.
Module R M, Submodule R M, LinearMap R M N, LinearEquiv R M N. Basis: Basis ι R M. Key: Mathlib.LinearAlgebra.Basic.
Lean inserts coercions automatically: ℕ→ℤ→ℚ→ℝ. Use push_cast to move casts inward, norm_cast to normalise, @[norm_cast] on your own cast lemmas.
⚠ Common Error Messages
When things go wrong — a reference for the errors you will encounter most often. Read the message, find it here, follow the fix.
| Error | What it means | Typical fix |
|---|---|---|
type mismatch | Provided a term of the wrong type | Use #check to compare types. Look for coercion mismatches between ℕ, ℤ, ℚ, ℝ. |
unsolved goals | Proof block did not close all goals | Check remaining goals in Infoview. Use sorry to isolate, then fill each goal. |
failed to synthesize instance | Lean can’t find a type class instance | Check imports and open statements. Use #check (inferInstance : ...) to test. |
unknown identifier | Name does not exist in scope | Check spelling, imports, namespace. Use #check Namespace.Name to confirm. |
application type mismatch | Function applied to wrong argument type | Use @f to see all explicit arguments. Add type annotations (arg : T). |
function expected at X | Used X as a function but it’s a value | Check for missing parentheses. Check if X is a type constructor needing arguments. |
linarith failed | linarith could not prove the goal | Check hypotheses are in context. Try linarith [h1, h2, sq_nonneg x] with hints. |
simp made no progress | None of the simp lemmas applied | Check lemma direction (try ←h). Run simp? to find what would fire. Try rw. |
omega could not find a contradiction | The ℕ/ℤ arithmetic claim is not provable | Verify the claim is true. Check for hidden casts. Use norm_cast first. |
maximum recursion depth reached | Type class synthesis or unification looped | Add explicit type annotations to break the loop. Look for circular instances. |
tactic failed, there are unsolved goals | A tactic left goals open unexpectedly | Common with rw. Check Infoview after each tactic step to see what’s remaining. |
declaration uses 'sorry' | A sorry is present in the proof chain | Search the file for all sorrys. Replace each with a valid proof step. |
▶ Getting Started
Select your operating system first — check that your device meets the requirements, then follow the installation steps below.
■ System Requirements
Before installing anything, verify your Windows device meets these requirements. Lean is a compiled proof assistant — RAM and storage matter more than on most software.
| OS | Windows 10 64-bit (version 1903+) or Windows 11 |
| CPU | x86-64 processor — 4+ cores strongly recommended for parallel compilation |
| RAM | 8 GB minimum — 16 GB strongly recommended. VS Code with the Lean extension uses 1–2 GB actively while checking a file. |
| Storage | 10 GB free space for toolchain, prebuilt .olean cache, and Mathlib source. SSD strongly preferred over HDD. |
| Internet | Required for first setup — roughly 4–6 GB downloaded for the prebuilt cache alone. |
| Software | Git for Windows, VS Code, winget (pre-installed on Windows 11; available for Windows 10 via the App Installer) |
Surface Pro X, Snapdragon-based laptops, and other Windows ARM devices are not officially supported. WSL2 (Ubuntu 22.04+) running inside Windows is the recommended workaround on these devices.
- Always run
lake exe cache getbeforelake build— it downloads prebuilt objects instead of compiling from scratch. - More CPU cores = significantly faster builds. Close other heavy apps when building on 8 GB RAM.
- Lean reads and writes thousands of small
.oleanfiles — an SSD makes a noticeable difference.
▶ Installation (Windows)
Download from git-scm.com. During setup, choose Git Bash as the default terminal.
Download from code.visualstudio.com. Accept all defaults.
Open PowerShell and run:
winget install elan
Accept all prompts. elan installs and manages the Lean toolchain automatically.
In VS Code, open Extensions (Ctrl+Shift+X), search lean4, and install the extension by the Lean FRO.
In PowerShell or Git Bash:
git clone --depth 1 https://github.com/leanprover-community/mathlib4.git
cd mathlib4lake exe cache getlake build
First run takes 30–60 min depending on your connection and machine.
Open the mathlib4 folder in VS Code. Create Test.lean containing:
import Mathlib#eval 2 + 2
The Lean Infoview panel should show 4. If it does, you’re set.
◆ Daily Commands (Windows PowerShell)
| Action | Command |
|---|---|
| ▶ Navigation | |
| Go to Mathlib | cd $env:USERPROFILE\mathlib4 |
| Go to your project | cd $env:USERPROFILE\YourProject |
| Go up one level | cd .. |
| List files | Get-ChildItem (aliases: dir, ls) |
| ▶ Searching | |
| Find pattern in a file | git grep "HasSum.add" -- Mathlib/Probability/ |
| Case-insensitive search | git grep -i "hasSum" |
| Show matching filenames only | git grep -l "pattern" |
| Show line numbers | git grep -n "pattern" |
| ▶ File Checks | |
| Check if a file exists | Test-Path "Mathlib\Algebra\Order\Floor\Defs.lean" |
| ▶ Building & Updating | |
| Update dependency manifest | lake update |
| Download prebuilt cache | lake exe cache get |
| Build project | lake build |
| Clean build artifacts | lake clean |
| ▶ Version Checking | |
| Current Lean version | lean --version |
| Pinned toolchain version | Get-Content lean-toolchain |
| Latest Mathlib commit | git -C $env:USERPROFILE\mathlib4 log -1 --oneline |
| Dependency versions | Get-Content lake-manifest.json |
| ▶ Git Basics | |
| Show status | git status |
| Pull latest Mathlib | git pull (then lake build) |
| Discard all local changes | git checkout . |
| Restore a single file | git checkout HEAD -- path/to/file |
| See recent commits | git log --oneline -5 |
| ▶ Launch VS Code | |
| Open a project folder | code $env:USERPROFILE\YourProject |
| Open current directory | code . |
■ System Requirements
Before installing anything, verify your Mac meets these requirements. Apple Silicon Macs are among the best machines for Lean development.
| OS | macOS 12 Monterey or later (Intel or Apple Silicon) |
| CPU | Intel x86-64 or Apple Silicon (M1 / M2 / M3 / M4) — both are fully supported natively |
| RAM | 8 GB minimum — 16 GB recommended. M-series chips handle Lean very efficiently due to unified memory; 8 GB M-series often outperforms 16 GB Intel. |
| Storage | 10 GB free space for toolchain, prebuilt .olean cache, and Mathlib source. SSD (standard on all Macs since 2013). |
| Internet | Required for first setup — roughly 4–6 GB downloaded for the prebuilt cache alone. |
| Software | Xcode Command Line Tools (free via Terminal), Homebrew (optional, helpful), VS Code |
M-series Macs (M1 through M4) run Lean natively and are among the best machines available for Lean development — fast compilation, excellent memory efficiency, and silent operation under sustained load.
- Always run
lake exe cache getbeforelake build— downloads prebuilt objects instead of compiling from scratch. - More CPU cores = faster builds. Close other heavy apps when building on 8 GB RAM.
- Linux (Ubuntu 22.04+, Debian 12+, Fedora 38+) is fully supported and often the fastest option for server or CI use.
▶ Installation (macOS / Linux)
Open Terminal and run:
xcode-select --install
A dialog will appear. Click Install and wait for it to complete.
Already included with Xcode Command Line Tools. Verify with git --version. Optionally update via git-scm.com or brew install git.
Download from code.visualstudio.com. After opening, run Shell Command: Install ‘code’ in PATH from the Command Palette (Cmd+Shift+P).
In Terminal:
curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh
Restart Terminal after install so the lean and lake commands are available.
In VS Code, open Extensions (Cmd+Shift+X), search lean4, and install the extension by the Lean FRO.
git clone --depth 1 https://github.com/leanprover-community/mathlib4.git
cd mathlib4lake exe cache getlake build
First run takes ~20–40 min on Apple Silicon, longer on Intel. Use the prebuilt cache — it saves hours.
Open the mathlib4 folder in VS Code. Create Test.lean containing:
import Mathlib#eval 2 + 2
The Lean Infoview panel should show 4. If it does, you’re set.
◆ Daily Commands (macOS / Linux Terminal)
| Action | Command |
|---|---|
| ▶ Navigation | |
| Go to Mathlib | cd ~/mathlib4 |
| Go to your project | cd ~/YourProject |
| Go up one level | cd .. |
| List files | ls (or ls -la for full detail) |
| ▶ Searching | |
| Find pattern in directory | git grep "HasSum.add" -- Mathlib/Probability/ |
| Case-insensitive search | git grep -i "hasSum" |
| Show matching filenames only | git grep -l "pattern" |
| Show line numbers | git grep -n "pattern" |
| ▶ File Checks | |
| Check if a file exists | [ -f "Mathlib/Algebra/Order/Floor/Defs.lean" ] && echo "exists" |
| ▶ Building & Updating | |
| Update dependency manifest | lake update |
| Download prebuilt cache | lake exe cache get |
| Build project | lake build |
| Clean build artifacts | lake clean |
| ▶ Version Checking | |
| Current Lean version | lean --version |
| Pinned toolchain version | cat lean-toolchain |
| Latest Mathlib commit | git -C ~/mathlib4 log -1 --oneline |
| Dependency versions | cat lake-manifest.json |
| ▶ Git Basics | |
| Show status | git status |
| Pull latest Mathlib | git pull (then lake build) |
| Discard all local changes | git checkout . |
| Restore a single file | git checkout HEAD -- path/to/file |
| See recent commits | git log --oneline -5 |
| ▶ Launch VS Code | |
| Open a project folder | code ~/YourProject |
| Open current directory | code . |
Ask the community for help
The Lean community is welcoming and active on Zulip — a chat platform where beginners and experts discuss proofs, share projects, and help each other. Whether you’re stuck on an error message or just saying hello, the #new members stream is the right place to start.
Join the Lean ZulipMuhammed Ismail
Self-taught in mathematics, economics, the mechanics of business — and enough psychology to notice a pattern worth proving.
This Glossary exists because of a proof that wasn’t the plan when any of this started. Here’s how one produced the other.
From a Personal Habit to a Kernel-Checked Proof
In September 2025, while trying to understand his own decision-making rather than anyone else’s, Ismail noticed his reasoning kept passing through the same six-step pattern — no matter what the decision was about. For a while that stayed a personal heuristic. What changed was realizing the pattern wasn’t just useful. It looked like it could be proven. He had no formal training in mathematics before that point, and taught himself what a proof at this level required, in roughly the order he needed it.
Proving it, though, made something else clear: this wasn’t shaping up to be a simple theorem. The same structure kept holding as Ismail tested it against a wide range of industries and disciplines — not as a loose analogy, but as what the finished paper’s own title now calls it: a Unified Functional Theory. Unified, because the same handful of structural failures recur across investing, operations, public policy, and reinforcement learning alike, with one proof serving all of them at once. Functional, because what’s being characterized is what a decision process has to do under uncertainty — never which field it happens to sit in. The claim is a deliberately narrow one, though: it holds for a specific, defined class of environments — what the papers call Class C — sequential decisions made under real uncertainty, where information is incomplete, conditions shift, and mistakes aren’t always reversible. No more, no less.
Notices the pattern
The same six steps, recurring across every decision, unrelated to its subject.
Teaches himself the math
No formal background going in — learns proof-writing in the order the work demands it.
First companion paper
Tests the six primitives against Erikson, Maslow, and Bowlby’s stage theories.
A second companion paper follows
This one on emotional adaptation in therapy. The prose corpus is now largely complete — already reaching well past mathematics.
Realizes it’s a Unified Functional Theory
The pattern holds up independently in psychology and therapy — this isn’t one theorem anymore. A claim that size, from an unaffiliated researcher, isn’t going to be taken on faith.
The pivot to Lean
No institution, no realistic path through peer review — so the proof gets rebuilt in Lean 4, where a kernel checks it directly.
Everything ships
Ismail’s Primitives (12,700 lines, zero admitted axioms) and Ismail’s Glossary publish together, alongside the Economic Adaptation paper and updated companion work.
Peer Review Doesn’t Work for This — So a Kernel Does
An independent researcher with no institutional affiliation, presenting a result that needs specialists in formal logic and decision theory just to evaluate it — and separate specialists again for each field it reaches — has no realistic route through traditional peer review on any usable timeline. So the mathematics was rebuilt instead as a Lean 4 formalization: something a kernel checks deterministically, without needing to check the author first.
Learning Mathlib well enough to do that produced two things at once. The proof itself — and, as a byproduct of the learning, the beginnings of the glossary you’re using right now.
More From Muhammed Ismail
This Glossary is the byproduct. The main project is a proof — that six primitives are necessary, mutually irreplaceable, and sufficient for any sequential decision under uncertainty. Two companion threads extend it further.
Six primitives, proven necessary — and mutually irreplaceable — for any sequential decision under uncertainty. Machine-checked in Lean 4, zero admitted axioms.
Erikson, Maslow, and Bowlby’s stage theories, read as three independent confirmations of the same six-stage structure.
The same six primitives, applied to psychotherapy and emotional adaptation in the clinical setting.
Extending the primitives to economic coordination under uncertainty, Lean-verified.