Lean 4 and Mathlib
Lean's kernel as the first-class proof checker: how the engine invokes it, junk values for square roots of negatives, and four ways a Lean file can look finished without being proved.
Put $v=2$ into $\gamma^2(1-v^2)$ with $\gamma = 1/\sqrt{1-v^2}$. What do you get?
SymPy says $1$ (Chapter 9). Lean says $0$. Re-executed on 2026-11-09 with Lean 4.35.0 and Mathlib v4.35.0, using the example from Chapter 2:
Real.sqrt (1 - 2^2) = 0 (1 - 2^2 = -3, sqrt of a negative)
(1 / Real.sqrt (1 - 2^2))^2 * (1 - 2^2) = 0 (gamma = 1/0 = 0)
Lean has a junk value for division by zero and for the square root of a negative number: both are $0$. SymPy instead takes $\sqrt{-3}$ to be the imaginary $i\sqrt3$, and the algebra closes. Two tools disagree about the same expression at the same point, because each defines the square root of a negative number differently. Neither is wrong; they are different encodings. It is a small, concrete case of the cross-system problem that Chapter 15 takes on.
For Lean, the consequence is that the gamma-bridge theorem would be false
without its side condition, and Lean knows it: the theorem takes
hv : |v| < 1 as a hypothesis.
Lean’s kernel is the engine’s main proof checker. This chapter shows how the engine runs it, what its acceptance covers, and four ways a Lean file can look finished and not be. It builds on the status ladder of Chapter 3.
The Lean theorems
| Claim | Lean theorem | Source |
|---|---|---|
lorentz-interval-invariance-1d-algebraic |
AdversarialMath.lorentzIntervalInvariantAlgebraic |
formal/lean/LorentzInterval.lean |
lorentz-gamma-relation-1d |
AdversarialMath.gammaRelationOfDefinition |
formal/lean/GammaBridge.lean |
lorentz-interval-invariance-1d-physical@1.1.0 |
AdversarialMath.lorentzIntervalInvariantPhysical |
formal/lean/PhysicalComposition.lean |
pythagorean-coordinate-2d |
AdversarialMath.pythagoreanCoordinate |
formal/lean/EuclidI47Coordinate.lean |
squared-distance-decomposition-2d and the vacuous candidate C |
squaredDistanceDecomposition, pythagoreanVacuousImplication |
formal/lean/PythagoreanRepair.lean |
How the engine runs Lean
The Lean package is formal/lean/. Its lakefile.lean pins Mathlib to the git
tag v4.35.0, and its lean-toolchain is leanprover/lean4:v4.35.0. The default
library lists the roots LorentzInterval, GammaBridge, AlgebraicInterface,
BridgeInterface and PhysicalComposition.
For each formal obligation, the adapter:
- reads the source as UTF-8 and computes its LF-normalized SHA-256;
- screens for placeholders with the patterns
\bsorry\b,\badmit\band a leadingaxiom; a match returnsunsupportedwithout running Lean; - runs
lake env lean <file>fromformal/lean/with a bounded timeout; - records
formally_verifiedonly if the return code is0and the run was actual. A timeout or failure isinconclusive. A simulated run that “passes” isnot_evaluated.
The result stores the resolved executable, the command, the version, the
duration, the output and the source hash. Qualification CI never runs
lake update; it uses the committed lake-manifest.json.
Four files that look finished and are not
All four were executed on 2026-10-27 against the pinned Mathlib.
1. A sorry.
theorem withSorry (x : ℝ) : x = x := by sorry
#print axioms withSorry
Lean accepts it with warning: declaration uses sorry and reports
'withSorry' depends on axioms: [propext, sorryAx, Classical.choice, Quot.sound].
sorryAx is the giveaway. The file compiles, which is why the adapter cannot
rely on the return code alone and screens the text first.
2. A hidden sorry. A theorem that imports a lemma proved with sorry in
another file has no sorry in its own text, so the text screen passes it. The
#print axioms audit would show sorryAx. That is what the formal-dependency
audit is for, and why it enforces exact expected axiom sets. (This is reasoning
from how Lean tracks axioms; this edition did not construct the two-file case.)
3. A false statement that the kernel rejects.
example : (1:ℕ) = 2 := by rfl
Executed: error: Tactic rfl failed: ... 1 is not definitionally equal to 2.
This is the negative control the repository keeps as
fixtures/KernelRejected.lean. A pipeline that has never watched Lean say no
has not shown that it can.
4. A true statement about the wrong thing. The gamma bridge without hv is not
provable, as the opening showed. But a different statement might be provable for
a reason that has nothing to do with the physics, for example one that uses
gamma = 1 / Real.sqrt (1 - v^2) with no domain condition and relies on the junk
values. Kernel acceptance cannot catch a mismatch between statement and intent.
That is the job of Chapter 1 and Chapter 15.
Tactics are not what you trust
The proofs use ring, rw, linarith, nlinarith, abs_lt, Real.sq_sqrt and
div_mul_cancel₀. These are tools that build a proof term. If a tactic is buggy
or surprising, the kernel still checks the term it produced. Trust sits in the
kernel and in the statement; a tactic that “proved” something false would fail at
the kernel.
Two executed examples. ring proves the shear residual identity from
Chapter 5:
example (t x v : ℝ) :
t^2 - (x + v*t)^2 - (t^2 - x^2) = -(v*t*(2*x + v*t)) := by ring
And Lean confirms that the gamma hypothesis is needed (as in Chapter 2 and Chapter 10), by exhibiting $\gamma=0$, $x=-1$, $t=0$, $v=0$ as an instance where the unconditioned identity fails:
example : ¬ (∀ (t x v gamma : ℝ),
(gamma * (t - v * x)) ^ 2 - (gamma * (x - v * t)) ^ 2 = t ^ 2 - x ^ 2) := by
intro h
have := h 0 (-1) 0 0
norm_num at this
What kernel acceptance covers
The committed audit records, for the pinned versions:
| Theorem | Kernel axioms |
|---|---|
lorentzIntervalInvariantAlgebraic |
propext, Classical.choice, Quot.sound |
gammaRelationOfDefinition |
propext, Classical.choice, Quot.sound |
Executed again on 2026-10-27 with formal/lean/AxiomAudit.lean: both lines read
depends on axioms: [propext, Classical.choice, Quot.sound].
So “accepted” means: this proposition, about Mathlib’s real numbers, is derivable from these three axioms. It says nothing about Rocq’s reals, SymPy’s square root or physics.
What this establishes
Lean tells us that the formal statement follows from its axioms. It cannot tell us that the statement is the one we meant. The $v=2$ example shows the risk concretely: a Lean theorem can be true or false for reasons rooted in library conventions, such as junk values, that a physicist never intended.
The Lean bridge proof reads in the same order as the derivation in
Chapter 2: first the positivity of $1-v^2$, then Real.sq_sqrt,
then cancellation. A reader can check that order; no independent review is
recorded.
Lean’s ℝ and Real.sqrt come from Mathlib, and the Rocq theorem uses the Rocq
standard library’s. The R3 audit shows the statements aligned (level L1) and the
algebraic theorem derivable from a commutative-ring interface (L2), and records
equivalence of the two real-number models (L3) as not established.
Chapter 12 covers the second kernel, and
Chapter 15 the ladder.
Try it yourself
cd formal/lean
lake exe cache get
lake env lean LorentzInterval.lean
lake env lean AxiomAudit.lean
lake env lean ../../content/examples/math/tool-chapters/ch11_lean_demo.lean
The last command
(download the file)
should print one sorry warning, the withSorry axiom line, and exactly one
error: the deliberate rfl control.
Seeded error. In LorentzInterval.lean, replace the ring expansion’s factor
1 - v ^ 2 with 1 + v ^ 2. The first ring step should fail.
Open questions.
- The text screen would pass a
sorryhidden by a macro or in another file. What exactly does the axiom audit cover, and what does it miss? - Pinning Mathlib to a tag freezes conventions such as the junk values. What if
a later Mathlib changed
Real.sqrtof a negative number? Would any recorded result change? - Lean’s kernel is small, and the elaborator around it is large. For a claim the book relies on, is a second kernel (Chapter 12) a better safeguard than more Lean audits?
Evidence record
From the accepted R2 report (2026-10-23): Lean 4.35.0, succeeded,
formally_verified for the algebraic and gamma-bridge theorems
(math01-lean4-algebraic-kernel-check-v1,
math01-lean4-gamma-bridge-kernel-check-v1). R4 adds the composed physical
theorem, P6 the Pythagorean coordinate theorem and P7 the repair theorems.
Chapter 8 records how these were qualified on hosted runners.
In CI, Lean runs on Ubuntu via elan.
Sources
- Leonardo de Moura and Sebastian Ullrich, “The Lean 4 Theorem Prover and Programming Language”, CADE 28 (2021), https://doi.org/10.1007/978-3-030-79876-5_37
- The mathlib Community, “The Lean Mathematical Library”, CPP 2020 (2020), https://doi.org/10.1145/3372885.3373824
- Mathlib4: The Mathematics Library of Lean 4, https://github.com/leanprover-community/mathlib4
No specific documentation page is cited for sorry, the junk values,
Real.sqrt or ring. In the repository: formal/lean/,
src/math_engine/adapters/external.py and docs/methodology/reproducibility.md.