A Lean 4 / Mathlib formalization of Euler's Pentagonal Number Theorem:
Two independent proof routes are formalized — a combinatorial proof via Franklin's involution and an algebraic/analytic proof via the Jacobi Triple Product identity.
- Landing page / overview: https://viazovska.github.io/PentagonalNumberTheorem/
- Web blueprint: https://viazovska.github.io/PentagonalNumberTheorem/blueprint/
- Dependency graph: https://viazovska.github.io/PentagonalNumberTheorem/blueprint/dep_graph_document.html
- PDF blueprint: https://viazovska.github.io/PentagonalNumberTheorem/blueprint.pdf
- Lean API docs: https://viazovska.github.io/PentagonalNumberTheorem/docs/
The site is built and deployed by .github/workflows/blueprint.yml on every push to main.
A combinatorial proof following Franklin's sign-reversing involution on partitions into distinct parts. Zero sorries. Key declarations:
distinctPartitions n— partitions ofninto distinct positive partsdistinctPartitionsAlpha n,distinctPartitionsBeta n,distinctPartitionsSpecial n— the three partition classespe n,po n— count of even/odd-size distinct partitions ofnalphaOp,betaOp— Franklin's involution operations, proved to be mutual inversesDPalpha_card_eq_DPbeta_card— the bijection between α- and β-partitionspe_minus_po_nonpent—pe(n) - po(n) = 0for non-pentagonalnpe_minus_po_pent_minus,pe_minus_po_pent_plus—pe(n) - po(n) = ±1at pentagonaln
An algebraic and analytic proof route through the Jacobi Triple Product identity. Zero sorries. Key declarations:
QSeries.FormalPowerSeries.euler_second_identity— Euler's second identity as formal power seriesQSeries.keySum_eq_one_div_qPochhammerInf_self—S_k = (q;q)_∞⁻¹for allkQSeries.FormalPowerSeries.jacobiTripleProduct— JTP inA⟦X⟧,A = LaurentPolynomial ℂQSeries.jacobiTripleProduct— analytic JTP for‖q‖ < 1,‖z‖ < 1,z ≠ 0, withQSeries.jacobiTripleProduct'extending it to the punctured discz ≠ 0QSeries.euler_pentagonal_number— Euler's pentagonal number theorem (corollary of JTP)
Supporting infrastructure: q-Pochhammer symbols qPoch, qPochInf; q-binomial
coefficients qBinom; summability and locally-uniform-convergence lemmas.
EulerPentagonalNumberTheorem_Franklin/ Franklin involution proof
├── Defs.lean Partition definitions and involution operations
├── Helpers.lean Helper lemmas
├── Lemmas.lean Main theorems (Franklin bijection, pe - po formula)
├── FormalPowerSeries.lean FPS statements (Lemmas 3, 5; Theorems 7, 25)
└── Main.lean Imports all components
Qseries_Formalization/ q-series / JTP proof route
└── QSeries/
├── Defs.lean q-Pochhammer and related definitions
├── FiniteBinomial.lean q-binomial (Gaussian binomial) coefficients
├── InfPochhammer.lean Infinite q-Pochhammer symbol (q;q)_∞
├── CauchyIdentity.lean Cauchy product diagonal coefficient identities
├── EulerIdentities.lean Euler's first and second FPS identities
├── FPS.lean FPS infrastructure and pi-topology summability
├── FPSEuler.lean FPS Euler second identity
├── FPSAlgebra.lean FPS JTP (FormalPowerSeries.jacobiTripleProduct), Cauchy coefficients
├── JTPCore.lean Core JTP infrastructure
├── JTPKeyIdentity.lean Key identity S_k = (q;q)_∞⁻¹
├── JTPAnalytic.lean Analytic JTP (jacobiTripleProduct')
├── JacobiTripleProduct.lean Top-level JTP and pentagonal number theorem
└── PentagonalNumber.lean pentagonal, euler_pentagonal_number
blueprint/
├── src/
│ ├── content_v2.tex Blueprint content (Franklin route)
│ ├── content_Jac.tex Blueprint content (JTP route)
│ ├── web.tex Master file for the web build
│ ├── print.tex Master file for the PDF build
│ └── macros/ Shared / web / print-only macros
├── make_standalone.py Builds the self-contained dep-graph HTML
└── build_web.sh Convenience wrapper: web build + standalone graph
home_page/ Jekyll source for the landing page
.github/workflows/blueprint.yml CI: build Lean, blueprint, deploy to Pages
- elan (the Lean toolchain manager)
- Python 3 with
leanblueprint:pip install leanblueprint - TeX Live (or equivalent) for the PDF build
lake exe cache get # download Mathlib cache
lake build # build the Lean code./blueprint/build_web.sh # web blueprint + standalone dep graph
leanblueprint pdf # PDF blueprintOpen blueprint/web/index.html in a browser to view the result locally.
build_web.sh runs leanblueprint web and then make_standalone.py, which
bundles a dependency graph that renders without sibling assets.
Every \lean{...} declaration in the blueprint links to the doc-gen4 API docs
at the \dochome URL set in blueprint/src/web.tex. Each doc-gen4 page in turn
carries a source link to the exact lines on GitHub, pinned to the commit the
docs were built from. Both the docs and the blueprint are built from the same
commit by .github/workflows/blueprint.yml, so the two stay in sync.
The blueprint is the proof; Lean fills it in. To contribute a formalization:
- Pick an unproved lemma from the dependency graph (look for nodes whose ancestors are all proved).
- Write the Lean statement and proof in the appropriate source folder.
- Add
\lean{your_decl_name}to the corresponding blueprint item inblueprint/src/content_v2.texorcontent_Jac.tex, and add the declaration name toblueprint/lean_decls. - Add
\leanokto mark the statement (or proof) as formalized. - Open a pull request.
The Lean proofs in both routes were largely generated by Aristotle (Harmonic). They differ in how much human direction and checking went into them:
| Blueprint | Lean proofs | Manual intervention | |
|---|---|---|---|
Franklin (EulerPentagonalNumberTheorem_Franklin/, 1264 lines) |
written by the authors | largely machine-generated, following that blueprint | substantial |
q-series / JTP (Qseries_Formalization/, 3318 lines) |
machine-generated | machine-generated | restructuring, API renaming, statement review |
Claude assisted with Lean proof development, blueprint maintenance and CI/deployment
infrastructure. Every result is machine-checked either way: no sorry, no axioms beyond
propext, Classical.choice and Quot.sound, and CI fails on any warning from Mathlib's
linter set.
Jonathan Conrad, Paula Muermann, Maryna Viazovska.