THE DOMINATOR TABLE

which constants Mathlib's use of choice actually rests on

Asking which constant a theorem's classical dependence is responsible for is not the same as asking which constants its proof touches, and the answers are far apart. 116,766 theorems reach the order lemma lt_or_eq_of_le; 2,018 would stop being classical if it were rebuilt. Reachability overstates responsibility by 58x in that one case.

The column below is the second number. A constant's count is the theorems whose every route to Classical.choice passes through it, so repairing it repairs exactly them and nothing else.

Measured with gonzalgo · Lean 4.32.1 with Mathlib v4.32.1 · 790,171 declarations, 30,015,601 dependency edges, one dominator tree over all 766,564 constants

#constantkindareatheorems dominatedeligible
1Classical.propDecidabledefinitionclassical logic91,858yes
2Classical.byContradictiontheoremclassical logic23,550yes
3CategoryTheory.Functor.categorydefinitioncategory theory5,271yes
4Std.DHashMap.Internal.Raw₀.isHashSelf_updateBucket_altertheorem4,899
5Std.DHashMap.Internal.Raw₀.wfImp_alterₘtheorem4,896
6Std.DHashMap.Internal.Raw.WF.outtheoremStd: hash maps4,892yes
7Classical.indefiniteDescriptiondefinitionclassical logic4,711yes
8Set.instCompleteAtomicBooleanAlgebradefinitionsets3,430yes
9lt_or_eq_of_letheoremorder / root namespace2,018yes
10_private.Mathlib.Data.Set.Image.0.Set.image_univ._proof_1_1theorem1,484
11Set.image_univtheoremsets1,483yes
12GroupWithZero.toDivisionMonoiddefinitionGroupWithZero1,290yes
13eq_or_lt_of_letheoremorder / root namespace1,221yes
14LE.le.eq_or_lttheoremLE1,179yes
15CategoryTheory.Functor.compdefinitioncategory theory1,112yes
16String.Internal.toArraydefinition1,111
17String.toListdefinitionstrings1,109yes
18AddAction.orbitRel._proof_3theorem1,044
19AddAction.orbitReldefinitionAddAction1,041yes
20QuotientAddGroup.leftReldefinitionQuotientAddGroup1,009yes
21_private.Mathlib.Algebra.Group.Hom.Defs.0.map_sub'._proof_1_2theorem856
22map_sub'theorem855
23map_subtheoremorder / root namespace853yes
24Classical.not_nottheoremclassical logic792yes
25GeneralizedBooleanAlgebra.toGeneralizedCoheytingAlgebra._proof_8theorem722
26GeneralizedBooleanAlgebra.toGeneralizedCoheytingAlgebradefinitionGeneralizedBooleanAlgebra721yes
27String.comparedefinitionstrings702yes
28String.instOrddefinition702
29Filter.comap._proof_2theorem662
30Filter.comapdefinitionfilters660yes
31CategoryTheory.Functor.fromPUnitdefinitioncategory theory616yes
32LE.le.lt_or_eqtheoremLE583yes
33contravariant_le_iff_contravariant_lt_and_eqtheorem578
34_private.Init.Data.List.Nat.Range.0.List.pairwise_lt_range'._proof_1_4theorem534
35List.pairwise_lt_range'theorem533
36List.pairwise_lt_range'._fdefinition533
37List.nodup_range'theorem525
38_private.Init.Data.Nat.Bitwise.Lemmas.0.Nat.testBit_two_pow_sub_succ._proof_1_3theorem520
39Nat.testBit_two_pow_sub_succtheoremNat519yes
40_private.Init.Data.List.Nat.Range.0.List.nodup_range._simp_1_1theorem515
41List.nodup_rangetheoremlists514yes
42subset_interior_iff_isOpentheoremorder / root namespace511yes
43Classical.not_foralltheoremclassical logic497yes
44Classical.emtheoremclassical logic476yes
45CategoryTheory.instCompleteLatticePresievedefinitioncategory theory450yes
46_private.Init.Data.Nat.Mod.0.Nat.mul_lt_mul_left._proof_1_1theorem440
47Nat.mul_lt_mul_lefttheoremNat439yes
48MulAction.orbitRel._proof_3theorem423
49MulAction.orbitReldefinitionMulAction420yes
50Array.foldrM_congrtheoremarrays410yes
51Nat.rel_of_forall_rel_succ_of_le_of_letheorem405
52Nat.rel_of_forall_rel_succ_of_letheorem400
53monotone_nat_of_le_succtheoremorder / root namespace399yes
54WellFounded.extrinsicFixdefinitionWellFounded398yes
55IsUnit.unitdefinitionIsUnit397yes
56BooleanAlgebra.toBiheytingAlgebradefinitionBooleanAlgebra381yes
57Std.DHashMap.Internal.Raw.foldRev_eqtheoremStd: hash maps374yes
58Std.DHashMap.Internal.Raw.foldRev_cons_applytheorem373
59WellFounded.extrinsicFix₂definitionWellFounded366yes
60Multiset.add_right_injtheoremmultisets363yes
61List.eq_nil_iff_forall_not_memtheoremlists363yes
62Multiset.instAddCancelCommMonoid._proof_3theorem361
63Multiset.instAddCancelCommMonoiddefinition360
64LinearMap.range._proof_1theorem358
65LinearMap.rangedefinitionLinearMap357yes
66_private.Mathlib.Algebra.Group.Center.0.Set.mul_mem_center._proof_1_4theorem351
67Set.mul_mem_centertheoremsets350yes
68Std.IterM.toArray.godefinition348
69Std.IterM.toArraydefinitionStd: other347yes
70AddSubmonoid.instCompleteLattice._proof_1theoremAddSubmonoid337yes
71CategoryTheory.shiftFunctordefinitioncategory theory335yes
72Lean.Name.quickCmpAux._fdefinition333
73Lean.Name.quickCmpAuxdefinition333
74Lean.Name.quickCmpdefinitionLean333yes
75Submodule.completeLatticedefinitionSubmodule333yes
76Nat.mono_casttheoremNat328yes
77AddSubmonoid.instCompleteLatticedefinitionAddSubmonoid326yes
78CategoryTheory.Sieve.instCompleteLatticedefinitioncategory theory322yes
79Classical.ofNonemptydefinitionclassical logic321yes
80emtheoremorder / root namespace316yes
81QuotientGroup.leftReldefinitionQuotientGroup308yes
82GroupWithZero.noZeroDivisorstheoremGroupWithZero288yes
83CategoryTheory.MorphismProperty.instCompleteBooleanAlgebradefinitioncategory theory284yes
84[email protected]._hygCtx._hyg.8definition283
85[email protected]._hygCtx._hyg.8other282
86_private.Mathlib.Data.Real.Basic.0.Real.ltdefinition282
87Real.instLTdefinitionReal282yes
88LinearEquiv.ofBijectivedefinitionLinearEquiv281yes
89isOpen_iff_forall_mem_opentheorem279
90zpow_ne_zerotheoremorder / root namespace279yes
91IsLocallyConstant.tfaetheoremIsLocallyConstant278yes
92IsLocallyConstant.iff_eventually_eqtheorem272
93Set.biInter_rangetheoremsets270yes
94Std.DTreeMap.Internal.Impl.WF.orderedtheoremStd: other266yes
95FreeAlgebra.lift._proof_4theoremFreeAlgebra263yes
96DFinsupp.zipWith._proof_4theorem262
97DFinsupp.zipWithdefinitionDFinsupp261yes
98eq_or_netheoremorder / root namespace260yes
99Equiv.ofBijectivedefinitionEquiv258yes
100Equiv.Perm.permGroupdefinitionEquiv250yes

Showing the first 100 of 3,000 rows. The tail is long and flat — rank 3,000 dominates 10 theorems. The full set is in the JSON and the CSV.

theorems dominated counts theorems for which this constant is the sole route to the axiom. eligible is false when the constant's own type is classical, so no constructive replacement for it can exist; it is false for only 2 of the 1,500 constants where it was computed, which is the negative result in the eligibility note — the test does not discriminate among load-bearing constants. area and eligible were computed for the top 1,500 only; below that they are blank rather than guessed.

Get the data

dominator-table.json · dominator-table.csv · CC-BY-4.0 · version 2026-08-11

One of the gonzalgo indexes — standing measurements of what formal libraries rest on, remeasured as the libraries move.

Reproduce it

# regenerate the declaration graph (~3 min, ~600 MB)
lake env lean -D maxErrors=4000 lean/Dump.lean
python analysis/dominators.py

ConstantInfo.value? must be passed allowOpaque := true or theorem proofs read as empty and every statement-versus-proof figure is wrong rather than imprecise. Code and derived data: 10.5281/zenodo.21883963.

Two results worth reading off it

60.1% of classically dependent theorems have no responsible constant at all. Their immediate dominator is the axiom itself, so no local repair anywhere in the library reaches them. That is the ceiling on what this kind of work can do, and it was not previously known.

Outside classical logic proper, the largest sites are infrastructure rather than mathematics: a functor category instance at 5,271, hash-map well-formedness at 4,899, the powerset Boolean algebra at 3,430, string conversion at 1,111. The places where choice is load-bearing are not the places anyone would have pointed at.

A disagreement in the source data

The reproduction archive carries two files with a count per constant, and they disagree on 137 of the 1,500 they share — hash-map well-formedness is 4,899 in one and 4,892 in the other. The published note reports 4,899, so that file is used here for every count and the other only for the categorical columns. Where they differ, the row carries a count_in_eligibility_file field so the disagreement is visible in the data rather than resolved out of sight.

What is not here yet

A reach column. The 58x figure above is one measured pair; computing reach for every row means a second traversal of the full graph and it has not been run. It is missing rather than estimated.