← Adversarial Math From First Principles

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:

  1. reads the source as UTF-8 and computes its LF-normalized SHA-256;
  2. screens for placeholders with the patterns \bsorry\b, \badmit\b and a leading axiom; a match returns unsupported without running Lean;
  3. runs lake env lean <file> from formal/lean/ with a bounded timeout;
  4. records formally_verified only if the return code is 0 and the run was actual. A timeout or failure is inconclusive. A simulated run that “passes” is not_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.

  1. The text screen would pass a sorry hidden by a macro or in another file. What exactly does the axiom audit cover, and what does it miss?
  2. Pinning Mathlib to a tag freezes conventions such as the junk values. What if a later Mathlib changed Real.sqrt of a negative number? Would any recorded result change?
  3. 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

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.