Checker "con-leche"
Version: c26f793 · 📄 Declaration · 🔗 Source
con-leche is an external
Lean checker with a consistency proof: if it accepts a set of
declarations, then they have a model in set theory (ZFC with enough
inaccessibles) — one set per constant under which every constant is a
member of its type — and in particular no theorem of False is accepted.
The proof is done directly against a set-theoretic model, not against
an abstract typing relation.
Written in Lean, entirely by Claude under close human guidance. It runs in verified mode here (the mode the theorem is about) with four worker threads for the check phase. It accepts only the three standard axioms and declines streams that use others.
69 ✅ 0 ❌ 3 🚫
130 ✅ 0 ❌ 6 🚫
26 ✅ 0 🚫
| Test | Expected | Result | ⏱️ | 🧠 | |||
|---|---|---|---|---|---|---|---|
| cedar | 👍 | 🚫 | 15.9 s | 870.2 MB | |||
| con-leche | 👍 | 👍 | 1.8 m | (0%) | 674.4 MB | (-21%) | |
| cslib | 👍 | 👍 | 7.0 m | (-19%) | 2.0 GB | (-42%) | |
| init | 👍 | 👍 | 1.2 m | (+9%) | 533.4 MB | (-5%) | |
| init-prelude | 👍 | 👍 | 400 ms | (+10%) | 45.4 MB | (-39%) | |
| mathlib | 👍 | 👍 | 22.0 m | (-32%) | 5.1 GB | (-49%) | |
| navier-stokes-euler | 👍 | 👍 | 7.6 m | (-32%) | 1.4 GB | (-43%) | |
| std | 👍 | 👍 | 1.9 m | (0%) | 696.8 MB | (-25%) | |
| 19 | 134 ms | 35.4 MB | |||||
| constlevels | ✋ | ✋ | 4 ms | 21.0 MB | |||
| ctor-num-fields | ✋ | ✋ | 4 ms | 20.1 MB | |||
| eta-ctor-alias | ✋ | ✋ | 4 ms | 21.0 MB | |||
| k-rec-conv | ✋ | ✋ | 4 ms | 21.4 MB | |||
| large-elim-param | ✋ | ✋ | 4 ms | 20.9 MB | |||
| large-elim-prop-bool | ✋ | ✋ | 4 ms | 20.9 MB | |||
| level-imax-leq | ✋ | ✋ | 3 ms | 20.2 MB | |||
| level-imax-normalization | ✋ | ✋ | 4 ms | 21.3 MB | |||
| nat-rec-k-lie | ✋ | ✋ | 3 ms | 20.1 MB | |||
| nat-rec-rules | ✋ | ✋ | 3 ms | 20.3 MB | |||
| nested-unused-param | ✋ | ✋ | 6 ms | 21.0 MB | |||
| orphan-rec | ✋ | ✋ | 3 ms | 17.9 MB | |||
| proj-non-structure | ✋ | ✋ | 4 ms | 21.0 MB | |||
| proj-of-imax-prop | ✋ | ✋ | 5 ms | 20.9 MB | |||
| proj-of-stuck-prop | ✋ | ✋ | 14 ms | 31.4 MB | |||
| proj-of-subst-prop | ✋ | ✋ | 23 ms | 33.6 MB | |||
| rec-k-lie | ✋ | ✋ | 3 ms | 20.1 MB | |||
| rec-missing-ih | ✋ | ✋ | 15 ms | 35.4 MB | |||
| rec-of-subst-prop | ✋ | ✋ | 23 ms | 33.4 MB | |||
| 1 | 136 ms | 23.3 MB | |||||
| alg-conv-trans-acc | 🤷 | ✋ | 9 ms | 23.3 MB | |||
| alg-conv-trans-acc-left | 🤷 | 👍 | 9 ms | 23.2 MB | |||
| alg-conv-trans-acc-right | 🤷 | 👍 | 9 ms | 23.0 MB | |||
| alg-conv-trans-quot | 🤷 | ✋ | 4 ms | 21.1 MB | |||
| alg-conv-trans-quot-left | 🤷 | ✋ | 4 ms | 23.3 MB | |||
| alg-conv-trans-quot-left-def | 🤷 | 👍 | 4 ms | 21.1 MB | |||
| alg-conv-trans-quot-right | 🤷 | 👍 | 4 ms | 21.1 MB | |||
| eta-ctor | 🤷 | ✋ | 4 ms | 21.1 MB | |||
| eta-rec-struct | 🤷 | ✋ | 4 ms | 23.0 MB | |||
| eta-rule-k | 🤷 | ✋ | 4 ms | 20.9 MB | |||
| eta-struct-major-and | 🤷 | 👍 | 4 ms | 21.4 MB | |||
| eta-struct-major-and-no-whnf | 🤷 | 👍 | 5 ms | 22.8 MB | |||
| eta-struct-major-no-whnf | 🤷 | 👍 | 6 ms | 23.1 MB | |||
| eta-unit-like-nested | 🤷 | ✋ | 5 ms | 21.1 MB | |||
| eta-unit-like-pi | 🤷 | ✋ | 4 ms | 21.3 MB | |||
| eta-unit-like-proof-field | 🤷 | ✋ | 4 ms | 21.0 MB | |||
| eta-unit-like-struct | 🤷 | ✋ | 4 ms | 21.1 MB | |||
| imax-right-successor | 🤷 | 👍 | 4 ms | 21.0 MB | |||
| let-value-type-mismatch | 🤷 | ✋ | 4 ms | 20.9 MB | |||
| nested-nonuniform-param | 🤷 | ✋ | 4 ms | 21.1 MB | |||
| positivity-whnf | 🤷 | ✋ | 4 ms | 20.8 MB | |||
| proj-maybe-prop | 🤷 | 👍 | 4 ms | 21.1 MB | |||
| proj-maybe-prop-past | 🤷 | 👍 | 4 ms | 20.8 MB | |||
| proof-param-ok | 👍 | 👍 | 4 ms | 21.3 MB | |||
| proof-param-swap | 🤷 | ✋ | 4 ms | 21.0 MB | |||
| subject-reduction-redex | 🤷 | ✋ | 9 ms | 22.7 MB | |||
| subject-reduction-reduct | 🤷 | ✋ | 9 ms | 23.0 MB | |||
| 7 | 39 ms | 23.1 MB | |||||
| extra-rec | ✋ | ✋ | 3 ms | 18.1 MB | |||
| level-index-out-of-order | 👍 | 🚫 | 4 ms | 20.5 MB | |||
| nat-lit-add | 👍 | 👍 | 5 ms | 21.2 MB | |||
| nat-lit-add-bad | ✋ | ✋ | 5 ms | 22.9 MB | |||
| nat-lit-ble | 👍 | 👍 | 5 ms | 20.9 MB | |||
| nat-lit-sub | 👍 | 👍 | 6 ms | 23.1 MB | |||
| orphan-ctor | ✋ | ✋ | 3 ms | 18.0 MB | |||
| proj-of-prop | ✋ | ✋ | 4 ms | 21.2 MB | |||
| sparse-name-index | 👍 | 🚫 | 4 ms | 20.9 MB | |||
| 30 | 1.9 m | (+42%) | 7.3 GB | ||||
| app-lam | 👍 | 👍 | 4.1 s | (-16%) | 1.2 GB | (-12%) | |
| args-before-unfold | 👍 | 👍 | 14 ms | (÷2.5) | 24.2 MB | (÷2.7) | |
| beta-ladder | 👍 | 👍 | 905 ms | (-46%) | 393.9 MB | (-21%) | |
| church-numerals | 👍 | 👍 | 53 ms | (+13%) | 46.1 MB | (-41%) | |
| discarded-argument | 👍 | 👍 | 13 ms | (÷13) | 25.1 MB | (÷2.6) | |
| discarded-argument-match | 👍 | 👍 | 37 ms | (÷3.8) | 25.3 MB | (÷2.7) | |
| folded-constant-first | 👍 | 👍 | 20 ms | (÷2.1) | 24.4 MB | (÷2.8) | |
| folded-constant-last | 👍 | 👍 | 20 ms | (÷2.1) | 24.6 MB | (÷2.8) | |
| fueled-chain | 👍 | 👍 | 70 ms | (-45%) | 45.5 MB | (-40%) | |
| grind-ring-5 | 👍 | 👍 | 4.3 s | (×2.0) | 179.5 MB | (-21%) | |
| identical-nesting | 👍 | 👍 | 4 ms | (÷6.8) | 21.0 MB | (÷3.1) | |
| irrelevance-before-evaluation | 👍 | 👍 | 5 ms | (÷6.2) | 21.4 MB | (÷3.1) | |
| irrelevance-refutes | 👍 | 👍 | 4 ms | (÷6.6) | 20.8 MB | (÷3.2) | |
| let-fold | 👍 | 👍 | 2.5 s | (×44) | 351.4 MB | (×5.3) | |
| let-ladder | 👍 | 👍 | 487 ms | (÷2.1) | 225.7 MB | (-29%) | |
| magma-list-deep-n21 | 👍 | 👍 | 4.1 s | (+51%) | 596.3 MB | (-11%) | |
| magma-list-deep-n36 | 👍 | 👍 | 47.0 s | (+33%) | 7.3 GB | (-7%) | |
| magma-list-pair-n21 | 👍 | 👍 | 31.1 s | (+68%) | 5.1 GB | (+28%) | |
| magma-list-pair-n7 | 👍 | 👍 | 2.8 s | (+67%) | 475.8 MB | (+12%) | |
| magma-string-n4 | 👍 | 👍 | 5.2 s | (+46%) | 138.0 MB | (+14%) | |
| magma-string-pair-n9 | 👍 | 👍 | 12.1 s | (+47%) | 968.2 MB | (-3%) | |
| proj-cheap-struct | 👍 | 👍 | 10 ms | (÷3.6) | 23.1 MB | (÷2.9) | |
| proj-lazy-struct | 👍 | 👍 | 7 ms | (÷4.7) | 23.1 MB | (÷2.8) | |
| proj-stuck-struct | 👍 | 👍 | 7 ms | (÷4.6) | 21.3 MB | (÷3.1) | |
| refute-cheap-first | ✋ | ✋ | 5 ms | (÷8.6) | 21.2 MB | (÷3.2) | |
| refute-cheap-last | ✋ | ✋ | 16 ms | (÷11) | 23.1 MB | (÷3.0) | |
| repeated-subproblem | 👍 | 👍 | 4 ms | (÷6.4) | 21.1 MB | (÷3.1) | |
| shared-subterm | 👍 | 👍 | 39 ms | (-32%) | 28.8 MB | (÷2.5) | |
| shift-cascade | 👍 | 👍 | 13 ms | (÷3.6) | 33.2 MB | (÷2.0) | |
| unroll-versus-evaluate | 👍 | 👍 | 7 ms | (÷4.2) | 23.7 MB | (÷2.8) | |
| 135 | 553 ms | 23.3 MB | |||||
| 001_basicDef | 👍 | 👍 | 4 ms | 21.3 MB | |||
| 002_badDef | ✋ | ✋ | 4 ms | 21.2 MB | |||
| 003_arrowType | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 004_dependentType | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 005_constType | 👍 | 👍 | 4 ms | 20.8 MB | |||
| 006_betaReduction | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 007_betaReduction2 | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 008_forallSortWhnf | 👍 | 👍 | 4 ms | 20.7 MB | |||
| 009_forallSortBad | ✋ | ✋ | 4 ms | 20.6 MB | |||
| 010_nonTypeType | ✋ | ✋ | 4 ms | 23.2 MB | |||
| 011_nonTypeAxiom | ✋ | ✋ | 4 ms | 20.7 MB | |||
| 012_nonPropThm | ✋ | ✋ | 4 ms | 20.8 MB | |||
| 013_thmProof | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 014_selfProof | ✋ | ✋ | 4 ms | 20.7 MB | |||
| 015_levelComp1 | 👍 | 👍 | 4 ms | 20.7 MB | |||
| 016_levelComp2 | 👍 | 👍 | 4 ms | 20.8 MB | |||
| 017_levelComp3 | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 018_levelParams | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 019_tut06_bad01 | ✋ | ✋ | 4 ms | 20.9 MB | |||
| 020_levelComp4 | 👍 | 👍 | 4 ms | 20.8 MB | |||
| 021_levelComp5 | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 022_imax1 | 👍 | 👍 | 4 ms | 21.3 MB | |||
| 023_imax2 | 👍 | 👍 | 4 ms | 20.6 MB | |||
| 024_levelMaxComm | 👍 | 👍 | 4 ms | 20.7 MB | |||
| 025_levelMaxAssoc | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 026_levelMaxIdem | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 027_levelMaxAbsorb | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 028_inferVar | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 029_defEqLambda | 👍 | 👍 | 4 ms | 20.8 MB | |||
| 030_peano1 | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 031_peano2 | 👍 | 👍 | 4 ms | 23.1 MB | |||
| 032_peano3 | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 033_letType | 👍 | 👍 | 4 ms | 20.8 MB | |||
| 034_letTypeDep | 👍 | 🚫 | 4 ms | 20.5 MB | |||
| 035_letRed | 👍 | 🚫 | 4 ms | 21.0 MB | |||
| 036_empty | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 037_boolType | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 038_twoBool | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 039_andType | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 040_prodType | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 041_pprodType | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 042_pUnitType | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 043_eqType | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 044_natDef | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 045_rbTreeDef | 👍 | 👍 | 5 ms | 21.0 MB | |||
| 046_inductBadNonSort | ✋ | ✋ | 4 ms | 21.0 MB | |||
| 047_inductBadNonSort2 | ✋ | 🚫 | 4 ms | 21.2 MB | |||
| 048_inductLevelParam | ✋ | ✋ | 4 ms | 21.0 MB | |||
| 049_inductTooFewParams | ✋ | ✋ | 4 ms | 20.9 MB | |||
| 050_inductWrongCtorParams | ✋ | ✋ | 3 ms | 19.8 MB | |||
| 051_inductWrongCtorResParams | ✋ | ✋ | 3 ms | 20.1 MB | |||
| 052_inductWrongCtorResLevel | ✋ | ✋ | 3 ms | 20.1 MB | |||
| 053_inductInIndex | ✋ | ✋ | 3 ms | 18.0 MB | |||
| 054_indNeg | ✋ | ✋ | 3 ms | 18.1 MB | |||
| 055_reduceCtorParam.mk | 👍 | 👍 | 4 ms | 21.3 MB | |||
| 056_reduceCtorType.mk | ✋ | ✋ | 3 ms | 17.9 MB | |||
| 057_indNegReducible | ✋ | ✋ | 3 ms | 18.2 MB | |||
| 058_predWithTypeField | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 059_typeWithTypeField | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 060_typeWithTypeFieldPoly | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 061_typeWithTooHighTypeField.mk | ✋ | ✋ | 3 ms | 20.0 MB | |||
| 062_emptyRec | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 063_boolRec | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 064_twoBoolRec | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 065_andRec | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 066_prodRec | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 067_pprodRec | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 068_punitRec | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 069_eqRec | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 070_nRec | 👍 | 👍 | 4 ms | 20.8 MB | |||
| 071_rbTreeRef | 👍 | 👍 | 6 ms | 21.1 MB | |||
| 072_boolPropRec | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 073_BogusRecursor | ✋ | ✋ | 3 ms | 17.9 MB | |||
| 074_existsRec | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 075_typeSingletonRecReduction | 👍 | 👍 | 4 ms | 21.3 MB | |||
| 076_sortElimPropRec | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 077_sortElimProp2Rec | 👍 | 👍 | 4 ms | 20.7 MB | |||
| 078_boolRecEqns | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 079_prodRecEqns | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 080_nRecReduction | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 081_listRecReduction | 👍 | 👍 | 5 ms | 21.2 MB | |||
| 082_RBTree.id_spec | 👍 | 👍 | 7 ms | 21.2 MB | |||
| 083_And.right | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 084_Prod.snd | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 085_PProd.snd | 👍 | 👍 | 4 ms | 21.3 MB | |||
| 086_PSigma.snd | 👍 | 👍 | 4 ms | 21.3 MB | |||
| 087_projOutOfRange | ✋ | ✋ | 4 ms | 21.4 MB | |||
| 088_projNotStruct | ✋ | ✋ | 4 ms | 23.2 MB | |||
| 089_projProp1 | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 090_projProp2 | ✋ | ✋ | 4 ms | 21.0 MB | |||
| 091_projProp3 | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 092_projProp4 | ✋ | ✋ | 4 ms | 20.8 MB | |||
| 093_projProp5 | ✋ | ✋ | 4 ms | 21.1 MB | |||
| 094_projProp6 | ✋ | ✋ | 4 ms | 21.2 MB | |||
| 095_projDataIndexRec | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 096_projIndexData | ✋ | ✋ | 5 ms | 21.0 MB | |||
| 097_projIndexData2 | ✋ | ✋ | 5 ms | 21.1 MB | |||
| 098_projRed | 👍 | 👍 | 4 ms | 23.3 MB | |||
| 099_ruleK | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 100_ruleKbad | ✋ | ✋ | 4 ms | 21.1 MB | |||
| 101_ruleKAcc | ✋ | ✋ | 4 ms | 21.3 MB | |||
| 102_aNatLit | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 103_natLitEq | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 104_proofIrrelevance | 👍 | 👍 | 4 ms | 21.3 MB | |||
| 105_proofIrrelevanceBad | ✋ | ✋ | 4 ms | 21.1 MB | |||
| 106_proofIrrelevanceWhnf | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 107_proofIrrelevanceUnderBinder | 👍 | 🚫 | 4 ms | 20.8 MB | |||
| 108_unitEta1 | 👍 | 👍 | 4 ms | 20.9 MB | |||
| 109_unitEta2 | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 110_unitEta3 | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 111_indexedUnitEta | ✋ | ✋ | 4 ms | 21.2 MB | |||
| 112_structEta | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 113_indexedStructEta | ✋ | ✋ | 4 ms | 20.8 MB | |||
| 114_funEta | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 115_funEtaDep | 👍 | 👍 | 4 ms | 23.2 MB | |||
| 116_funEtaBad | ✋ | ✋ | 4 ms | 21.1 MB | |||
| 117_reflOccLeft | ✋ | ✋ | 3 ms | 20.1 MB | |||
| 118_reflOccInIndex | ✋ | ✋ | 3 ms | 19.9 MB | |||
| 119_reduceCtorParamRefl.mk | 👍 | 👍 | 4 ms | 23.3 MB | |||
| 120_reduceCtorParamRefl2.mk | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 121_rTreeRec | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 122_rtreeRecReduction | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 123_accRecType | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 124_accRecReduction | 👍 | 👍 | 5 ms | 21.2 MB | |||
| 125_accRecNoEta | ✋ | ✋ | 4 ms | 21.3 MB | |||
| 126_quotMkType | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 127_quotIndType | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 128_quotLiftType | 👍 | 👍 | 4 ms | 21.2 MB | |||
| 129_quotSoundType | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 130_quotLiftReduction | 👍 | 👍 | 4 ms | 21.0 MB | |||
| 131_quotIndReduction | 👍 | 👍 | 4 ms | 21.1 MB | |||
| 132_dup_defs | ✋ | ✋ | 4 ms | 20.8 MB | |||
| 133_dup_ind_def | ✋ | ✋ | 4 ms | 21.0 MB | |||
| 134_dup_ctor_def | ✋ | ✋ | 4 ms | 21.2 MB | |||
| 135_dup_rec_def | ✋ | ✋ | 4 ms | 21.1 MB | |||
| 136_misnamed_rec_user | ✋ | ✋ | 4 ms | 21.0 MB | |||
| 137_dup_rec_def2 | ✋ | ✋ | 4 ms | 20.8 MB | |||
| 138_dup_ctor_rec | ✋ | ✋ | 4 ms | 21.1 MB | |||
| 139_DupConCon | ✋ | ✋ | 3 ms | 18.1 MB | |||
| 140_falseFromUnsafe | ✋ | 🚫 | 3 ms | 20.2 MB | |||
| 141_falseFromPartial | ✋ | 🚫 | 3 ms | 18.2 MB |
Detailed results
Test "bugs/constlevels"
Expected: ✋ reject · Size: 15.3 KB · Lines: 283 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Regression test for undefined behavior in lazy_delta_reduction_step in the official kernel
In the function lazy_delta_reduction_step, the official kernel expects unfold_definition
to always succeed. However, if the constant has an incorrect number of level parameters, it
actually fails, which leads to memory corruption in lazy_delta_reduction_step.
This test is to check that the official kernel and also other kernels that closely follow the logic of the official kernel correctly handle this unfolding failure.
The issue in the official kernel was originally reported as https://github.com/leanprover/lean4/issues/10577.
Test result: ✋ rejected · exit code 1 · wall time: 25 ms · instructions: 25.8 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 20 records, busy 0.000s (28.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive True (#13); 0.000s inductive Bool (#10); 0.000s def Not (#11); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 4 workers, 8 records, busy 0.000s (30.6%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (40.6%) con-leche: stats: slowest checks: 0.000s theorem Eq.symm (#16); 0.000s theorem false_ne_true (#17); 0.000s definition Ne (#12); 0.000s definition Not (#11); 0.000s definition Eq.casesOn (#18) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: let value type mismatch [at theorem _test, fold position 19] (--verified) t=0.0s
Test "bugs/ctor-num-fields"
Expected: ✋ reject · Size: 34.1 KB · Lines: 622 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof of False via trusted numFields on a constructor.
Define a wrapper structure S with one field, and lie by saying it has 0 fields, making
it look unit-like. Then definitional eta means all inhabitants are equal.
Derive a contradiction from S.mk false = S.mk true.
Nanoda and its descendants accepted this until it was fixed.
Test result: ✋ rejected · exit code 1 · wall time: 8 ms · instructions: 22.3 M · max rss memory: 20.1 MB
stderr:
con-leche: invalid: constructor _private.Test.0.S.mk declares 0 fields at 0 parameters; its type has 1 binders (--verified)
Test "bugs/eta-ctor-alias"
Expected: ✋ reject · Size: 7.2 KB · Lines: 122 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Bogus proof that f = Box.mk for every f : BoxFn, where BoxFn is a
reducible alias for Bool → Box.
A checker that eta-expands a partially applied constructor (see
corner-cases/eta-ctor) has to take the missing arguments from the type of
the constructor application. Taking them from the type of the other side
without unfolding it, here BoxFn, finds no arguments to add, then compares
the (zero) given fields only, and accepts.
This bug was found by phiferd in a draft of https://github.com/leanprover/lean4/pull/15373 to the official kernel, and fixed before it was merged.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 24.0 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (29.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (8.7%) con-leche: stats: slowest installs: 0.000s inductive Box (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (26.5%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (49.8%) con-leche: stats: slowest checks: 0.000s theorem etaCtorAlias (#13); 0.000s definition BoxFn (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem etaCtorAlias [at theorem etaCtorAlias, fold position 13] (--verified) t=0.0s
Test "bugs/k-rec-conv"
Expected: ✋ reject · Size: 12.6 KB · Lines: 232 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Bogus proof that tests for incorrectly implemented K-like reduction.
fun x => x and fun _ => y are not convertible, but a checker that does treat them
as convertible would accept the resulting theorem bad, which is true propositionally, but not definitionally.
Regression test for sokonanoda.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 25.9 M · max rss memory: 21.4 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 18 records, busy 0.000s (18.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (3.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive OfNat (#12); 0.000s inductive Bool (#10); 0.000s def T (#11); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 4 workers, 6 records, busy 0.000s (27.6%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (31.7%) con-leche: stats: slowest checks: 0.000s theorem bad (#17); 0.000s definition t1 (#15); 0.000s definition T (#11); 0.000s definition instOfNatNat (#14); 0.000s definition t2 (#16) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem bad [at theorem bad, fold position 17] (--verified) t=0.0s
Test "bugs/large-elim-param"
Expected: ✋ reject · Size: 6.2 KB · Lines: 88 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False via incorrect large elimination restriction.
If the check for whether a level is surely not zero is implemented wrong, in particular if it incorrectly returns true for params, we can create a universe-polymorphic
inductive MyBool.{u} : Sort u | tt | ff
where the recursor MyBool.rec.{1,0} can do large elimination of a Prop.
Because of proof irrelevance we have tt = ff, so we can derive a
contradiction.
Found by Anthony Wang using Aristotle, breaking the mini checker for the
T-shirt bounty; it was
fixed the same day.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 23.7 M · max rss memory: 20.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 6 records, busy 0.000s (2.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4); 0.000s inductive Empty (#2); 0.000s inductive False (#3) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: generated recursor: large eliminator on a block whose sort may be Prop (official: elim_only_at_universe_zero) [at inductive MyBool, fold position 12] (--verified) t=0.0s
Test "bugs/large-elim-prop-bool"
Expected: ✋ reject · Size: 22.6 KB · Lines: 438 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof of False by allowing a Prop inductive to have the same recursor
that the corresponding Type inductive would have.
Proof irrelevance makes .tt = .ff, but pick distinguishes between them.
Kiota accepted this until it was fixed.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 25.0 M · max rss memory: 20.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (3 still running, not counted): 0.000s wall, 4 workers + the commit thread, 18 records, busy 0.000s (17.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (25.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive NewBool (#16); 0.000s inductive Eq (#0); 0.000s def Eq.ndrec (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: generated recursor: large eliminator on a block whose sort may be Prop (official: elim_only_at_universe_zero) [at inductive NewBool, fold position 16] (--verified) t=0.0s
Test "bugs/level-imax-leq"
Expected: ✋ reject · Size: 5.6 KB · Lines: 93 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False via incorrect universe level comparison for imax.
A correct kernel must reject leq(imax(u,v)+1, imax(u,v)), since at u=0, v=0 this becomes
leq(1, 0) which is false. However, a checker that only compares the imax arguments
structurally (without accounting for an accumulated successor offset) will incorrectly accept it.
This allows defining a universe-collapsing identity function
down.{u,v} : Sort (succ (imax u v)) → Sort (imax u v), which is used to cast between
True and False via Bool.rec at Sort (imax 0 0) = Prop.
Nanoda incorrectly accepted this proof until it was fixed.
Test result: ✋ rejected · exit code 1 · wall time: 8 ms · instructions: 19.7 M · max rss memory: 20.2 MB
stderr:
con-leche: invalid: recursor False.rec declares k := true; the generated recursor of this block is not K-like (--verified)
Test "bugs/level-imax-normalization"
Expected: ✋ reject · Size: 5.8 KB · Lines: 96 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False via incorrect universe level normalization for imax.
A correct kernel must distinguish imax 0 v from succ(imax 0 v), since at v=0 these
evaluate to 0 and 1 respectively. However, a level normalization algorithm that drops an
accumulated successor offset when decomposing imax u (param v) will produce identical normal
forms for both, causing the equivalence check to incorrectly return true.
This allows defining a universe-collapsing identity function
down.{v} : Sort (succ (imax 0 v)) → Sort (imax 0 v), and then
myProp : Prop := down.{0} Bool (a Prop that is computationally Bool). Proof irrelevance on
myProp equates Bool.true and Bool.false, and Bool.rec maps this into False.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 24.0 M · max rss memory: 21.3 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.001s (31.5%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (10.3%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive True (#11); 0.000s def myProp (#13); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (24.8%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (32.6%) con-leche: stats: slowest checks: 0.000s definition proof_of_false (#14); 0.000s definition down (#12); 0.000s definition myProp (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in definition down [at def down, fold position 12] (--verified) t=0.0s
Test "bugs/nat-rec-k-lie"
Expected: ✋ reject · Size: 6.3 KB · Lines: 106 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False via trusted k on Nat.rec.
Lie by claiming Nat.rec is K-like. Then replace the major premise by Nat.zero,
but nat literals bypasses K-like reduction, so two reduction rules disagree.
∀ n, g n holds by the first, and g 1 is False by the second.
A variant of bugs/rec-k-lie, which nanoda and its descendants accepted until it
was fixed; at that time, nanoda
itself rejected this variant, as it had no literal path for Nat.rec.
Test result: ✋ rejected · exit code 1 · wall time: 8 ms · instructions: 19.8 M · max rss memory: 20.1 MB
stderr:
con-leche: invalid: recursor Nat.rec declares k := true; the generated recursor of this block is not K-like (--verified)
Test "bugs/nat-rec-rules"
Expected: ✋ reject · Size: 8.1 KB · Lines: 128 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False via incorrect recursor rule validation.
When processing an inductive type declaration, a correct kernel must verify that the generated recursor rules match the ones provided in the export data. A checker that accidentally compares the imported rules against themselves (instead of against independently constructed rules) will accept arbitrary recursor reduction behavior.
This test defines Nat with a wrong Nat.rec succ rule that always returns hzero (ignoring
the induction hypothesis). Combined with a nat literal extension that hardcodes correct
arithmetic for concrete nat literals but falls back to the wrong Nat.rec rules for symbolic
arguments, this creates an inconsistency that yields a proof of False.
Nanoda incorrectly accepted this proof until it was fixed.
Test result: ✋ rejected · exit code 1 · wall time: 9 ms · instructions: 20.0 M · max rss memory: 20.3 MB
stderr:
con-leche: invalid: recursor False.rec declares k := true; the generated recursor of this block is not K-like (--verified)
Test "bugs/nested-unused-param"
Expected: ✋ reject · Size: 61.1 KB · Lines: 1.1 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Checks that the parameters of a nested inductive application are type-checked even when they do not appear in the auxiliary type generated during nested-inductive compilation.
When an inductive E has a constructor whose type contains a nested
application L (E w) b, the elaboration of nested inductives replaces that
occurrence with an auxiliary type. The argument b does not occur in the
auxiliary declaration, so a checker that only checks the auxiliary type never
sees b. A correct checker must still ensure b is well-typed; this test
rejects if it is not.
Here b is a malformed projection C.0 (C.0 w) (applying a C projection to
a value of the unrelated structure W), disguised by a hash collision. If the
parameter is not checked, the bogus projection slips through and the resulting
E can be used to build an axiom-free proof of False (boom). The
projection is merely the payload; the property under test is that the
nested-inductive parameter is checked.
Origin: reported as leanprover/lean4#14576 by @kiranandcode, with the original source recorded by @xrchz (https://github.com/xrchz/collatzlean); fixed in leanprover/lean4#14577.
Test result: ✋ rejected · exit code 1 · wall time: 14 ms · instructions: 36.5 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (2 still running, not counted): 0.002s wall, 4 workers + the commit thread, 41 records, busy 0.002s (19.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (71.7%) con-leche: stats: slowest installs: 0.000s inductive T (#11); 0.000s def Nat.beq (#26); 0.000s inductive HEq (#14); 0.000s inductive PProd (#17); 0.000s inductive P (#36) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: invalid projection: the node names another structure [at inductive E, fold position 40] (--verified) t=0.0s
Test "bugs/orphan-rec"
Expected: ✋ reject · Size: 1.4 KB · Lines: 21 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False from a recursor that claims not to belong to any inductive
type.
The export contains False exactly as the prelude has it — an empty
Prop-valued inductive with no constructors — together with its ordinary
False.rec. Smuggled into the same inductive block is a second recursor,
named rogue, whose type is False itself, which has no motives, no minor
premises and no rules, and whose all field is the empty list. The theorem
inconsistent : False is then simply rogue.
This is the sibling of other/extra-rec, and it defeats the obvious fix for it. A
checker that associates each exported recursor with the inductive type named
in its all field, and then requires the recursors so associated with an
inductive type to be exactly the ones it derives from that declaration, still
accepts rogue: False is associated with False.rec and nothing else, and
rogue is associated with nothing at all, so no comparison ever looks at it —
yet it is added to the environment and inhabits the genuine empty type.
A checker must therefore reject any recursor it did not itself derive from an
inductive declaration, rather than only checking the recursors that point at
one. The same hole is reachable by pointing all at a name that has no
declaration in the export (that variant is what other/orphan-ctor does on the
constructor side).
Nanoda accepted this export until it was fixed.
Test result: ✋ rejected · exit code 1 · wall time: 8 ms · instructions: 19.3 M · max rss memory: 17.9 MB
stderr:
con-leche: invalid: recursor rogue declares 0 motives; the block has 1 inductive types (--verified)
Test "bugs/proj-non-structure"
Expected: ✋ reject · Size: 5.0 KB · Lines: 75 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Bad has two constructors, so projections should not be allowed.
Prove false by using the second constructor, then projecting, hoping that the
first constructor is used when inferring the type of the projection.
Nanoda and its descendants accepted this until it was fixed.
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 24.3 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (31.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (7.9%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive True (#11); 0.000s inductive Bad (#12); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (28.2%) con-leche: stats: slowest checks: 0.000s theorem bad (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: invalid projection: not a structure-like type, or no such field [at theorem bad, fold position 13] (--verified) t=0.0s
Test "bugs/proj-of-imax-prop"
Expected: ✋ reject · Size: 19.3 KB · Lines: 321 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A closed proof of False, with no axioms, via a data projection out of a
proposition whose sort is Prop only up to universe level normalization.
ImaxProp : Sort (imax 1 0) is a proposition, since imax 1 0 normalizes to 0.
The exploit uses two definitionally equal spellings of that type. Proof
irrelevance is stated through ImaxAsProp : Prop := ImaxProp, whose type is the
literal Sort 0, so it is accepted; the data projection imaxProjBool is stated
on ImaxProp, whose type is the literal Sort (imax 1 0). A kernel that tests
sorts for Prop syntactically does not recognize the latter as a proposition and
wrongly allows projecting its Bool field out of a proof. Congruence on the
proof-irrelevance equation then equates false and true, giving False.
This is https://github.com/leanprover/lean4/pull/14613, a bug in the official kernel.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 27.2 M · max rss memory: 20.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 27 records, busy 0.001s (27.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (1.5%) con-leche: stats: slowest installs: 0.000s inductive ImaxPropDummy (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive PUnit (#14); 0.000s inductive True (#21) con-leche: stats: check pool: 0.000s wall, 4 workers, 9 records, busy 0.000s (23.2%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (31.2%) con-leche: stats: slowest checks: 0.000s definition cond.match_1 (#18); 0.000s definition imaxLeft (#13); 0.000s definition cond (#19); 0.000s definition Bool.casesOn (#16); 0.000s definition Unit.unit (#17) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: projection from a propositional structure must be a proposition [at def imaxProjBool, fold position 20] (--verified) t=0.0s
Test "bugs/proj-of-stuck-prop"
Expected: ✋ reject · Size: 275.7 KB · Lines: 5.3 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof of False by projecting the Bool field out of a proposition, exploiting
that a kernel can disagree with itself about whether the structure lives in
Prop.
Same underlying defect as bugs/rec-missing-ih, but with a different consequence.
Mechanism
-
Definitional equality is not transitive here. Three functions
Bool → Boolare built fromAcc.recsuch that a kernel reportsrcA ≡ rcBandrcB ≡ rcC— both by proof irrelevance on theAccargument — whilercA ≢ rcC, because there the twoAccproofs have different types. -
In the affected kernels, the defeq cache closes that relation transitively, but only for hash-equal terms. Established equalities are kept in a union-find structure, and the comparison returns early, without consulting it, when the hashes differ:
~~~cpp if (is_eqp(a, b)) return true; if (m_use_hash && hash(a) != hash(b)) return false; // skips the union-find ... node_ref r1 = find(to_node(a)); node_ref r2 = find(to_node(b)); if (r1 == r2) return true; ~~~
So whether
rcA ≡ rcCholds depends on the hash of the surrounding term. The constants and paddings are chosen so that the hashes collide exactly when the argument is the free variable_kernel_fresh.0, and not for the closed instantiation used later. -
That comparison decides a result sort.
Native64ResultSortGateis a K-like inductive predicate, and its recursor is used as the result sort of the inductive familyNative64ResultSortOwner: the sortGate.rec x … Prop requested hreduces toProponly if the requested indices are definitionally equal to the ones ofGate.intro. HenceOwner x his a proposition in one context and a stuck sort in another:Native64ResultSort.asPropis checked against a constant standing for∀ x h, Prop, so the kernel introduces_kernel_fresh.0forx, the hashes collide,Owner x h : Propis accepted, andNative64ResultSortLeak.propositionis aPropfor every later declaration — including for proof irrelevance.Native64ResultSortLeak.observeprojects field 0 out of that proposition. There the sort of the closed termOwner false closedGateis needed, and that one is stuck — the affected kernels answerfalsewhen asked whether it is definitionally equal toProp— so they do not see a proposition and permit projecting out theBoolfield.
Proof irrelevance then identifies two Owner.mk applications carrying
different Bool fields, and observing them yields False. The affected
kernels rejected Native64ResultSortOwner with type expected as soon as the
hashes no longer collided.
This was accepted by the official kernel at v4.28.0, v4.29.1, v4.33.0 and
nightly-2026-08-01. Other kernels reject the export in one of two places:
either they refuse Native64ResultSortOwner because its result type does not
reduce to a sort, or they accept the type but refuse the projection of a data
field out of a proposition.
Both steps are ruled out now: the projection by
leanprover/lean4#14807, which
makes the kernel's is_prop check require the inferred type to reduce to a
sort, and the hash-gated transitivity of step 2 by
leanprover/lean4#14806, which
replaces the union-find defeq cache with an order-independent one. The same
projection, reached without any help from that cache, is bugs/proj-of-subst-prop.
Test result: ✋ rejected · exit code 1 · wall time: 15 ms · instructions: 84.5 M · max rss memory: 31.4 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (1 still running, not counted): 0.003s wall, 4 workers + the commit thread, 108 records, busy 0.004s (29.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (-) con-leche: stats: slowest installs: 0.000s def Bool.casesOn (#13); 0.000s inductive Nat.le.below (#71); 0.000s inductive Or (#69); 0.000s inductive Acc (#21); 0.000s inductive OfNat (#27) con-leche: stats: peak RSS 0.03 GiB con-leche: invalid: direct sum: type former does not reduce to a sort after its parameters and indices [at inductive Native64ResultSortOwner, fold position 112] (--verified) t=0.0s
Test "bugs/proj-of-subst-prop"
Expected: ✋ reject · Size: 254.9 KB · Lines: 4.8 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof of False by projecting the Bool field out of a proposition, reached by
substituting a proof of one proposition for a proof of a definitionally equal
one.
Mechanism
-
Definitional equality is not transitive here.
a,bandcare threeBools built fromAcc.recsuch that a kernel reportsa ≡ bandb ≡ c— both by proof irrelevance on theAccargument, the latter after some iota steps — whilea ≢ c, because there the twoAccproofs have different types (Acc (· < ·) 1vs.Acc (· < ·) 0). -
So
P := a = bandQ := a = care definitionally equal types whose proofs behave differently.gate h := Eq.rec (motive := fun _ _ => Type) Prop hK-reduces toPropforh : P, because that reduction only needs the type ofhto be definitionally equal to the typea = aofEq.refl a, i.e.b ≡ a. For the closedwitness : Qit stays stuck, since that would needc ≡ a. -
An inductive family is declared over the reducing side and used on the stuck one.
Owner : ∀ (h : P), gate his accepted as a family of propositions — its recursor only eliminates intoProp.Owner witnessis well-typed, sinceQ ≡ P, but its sort does not reduce toProp, so the projectionobserveis permitted to extract theBoolfield from an inhabitant.
Proof irrelevance then identifies two Owner.mk applications carrying
different Bool fields, and observing them yields False, with no axioms
involved.
Unlike bugs/rec-missing-ih and bugs/proj-of-stuck-prop, this needs no interference
from the definitional-equality cache: every comparison above comes out the same
way in a fresh type-checker session, so it is independent of whether, and how,
such a cache is keyed. What it does need is that the sort of an inductive
family is re-examined after a substitution that definitional equality permits.
The projection in the last step is ruled out by
leanprover/lean4#14807, which
makes the kernel's is_prop check require the inferred type to reduce to a
sort: a stuck sort then raises (kernel) type expected instead of answering
that the type is not a proposition.
Test result: ✋ rejected · exit code 1 · wall time: 18 ms · instructions: 135.9 M · max rss memory: 33.6 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.003s wall, 4 workers + the commit thread, 120 records, busy 0.005s (31.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (1.6%) con-leche: stats: slowest installs: 0.000s inductive Nat.le.below (#69); 0.000s inductive Or (#67); 0.000s inductive And (#9); 0.000s inductive Nat.le (#24); 0.000s inductive Acc (#21) con-leche: stats: check pool: 0.002s wall, 4 workers, 89 records, busy 0.006s (76.8%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (30.0%) con-leche: stats: slowest checks: 0.000s theorem PR14806Subst.run_eq (#113); 0.000s definition _private.Init.Prelude.0.Nat.le_trans.match_1_10 (#85); 0.000s definition _private.Init.Prelude.0.Nat.succ_le_succ.match_1_7 (#77); 0.000s definition Nat.eq_or_lt_of_le._f (#92); 0.000s definition PR14806Subst.step.match_1 (#46) con-leche: stats: peak RSS 0.03 GiB con-leche: invalid: application type mismatch [at def PR14806Subst.proposition, fold position 115] (--verified) t=0.0s
Test "bugs/rec-k-lie"
Expected: ✋ reject · Size: 5.3 KB · Lines: 87 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
False theorem via trusted k on a recursor.
Define MyBool with two constructors, and lie by claiming its recursor is K-like,
so the major premise is replaced by the first constructor without being examined.
disc MyBool.true is then True rather than False.
MyBool rather than Bool because a module that overwrites an imported constant
cannot be re-imported by the exporter.
Nanoda and its descendants accepted this until it was fixed.
Test result: ✋ rejected · exit code 1 · wall time: 8 ms · instructions: 19.7 M · max rss memory: 20.1 MB
stderr:
con-leche: invalid: recursor MyBool.rec declares k := true; the generated recursor of this block is not K-like (--verified)
Test "bugs/rec-missing-ih"
Expected: ✋ reject · Size: 289.6 KB · Lines: 5.5 k · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False from a generated recursor whose reduction rule drops the
induction hypothesis.
Mechanism
-
Definitional equality is not transitive here. The test builds three functions
Bool → BoolfromAcc.recfor which a kernel reportsrcA ≡ rcBandrcB ≡ rcC— both by proof irrelevance on theAccargument, the latter after some iota steps — butrcA ≢ rcC, because there the twoAccproofs have different types (Acc (· < ·) 1vs.Acc (· < ·) 0). -
In the affected kernels, the defeq cache closes that relation transitively, but only for hash-equal terms. Established equalities are kept in a union-find structure, and the comparison returns early, without consulting it, when the hashes differ:
~~~cpp if (is_eqp(a, b)) return true; if (m_use_hash && hash(a) != hash(b)) return false; // skips the union-find ... node_ref r1 = find(to_node(a)); node_ref r2 = find(to_node(b)); if (r1 == r2) return true; ~~~
So whether
rcA ≡ rcCholds depends on the hash of the surrounding term. The three constants and the two paddings are picked so that the hashes collide for the free variables that the affected implementations create while building the minor premises of the recursor (_ind_fresh.3,_ind_fresh.9), but not for the pass that builds the recursor rules (_ind_fresh.14). -
A K-like reduction is made to depend on that comparison.
Native64TwoHashGateis a K-like inductive predicate (one parameter, fourBoolindices, one field-less constructor pinning the indices), so reducingGate.rec … hrequires the indices ofh's type to be definitionally equal to the ones ofGate.intro's result type.Native64TwoHashOwner.stephas a recursive argument whose type is such aGate.recapplication, which therefore reduces toOwnerin one pass but not in the other.
The resulting Native64TwoHashOwner.rec has a step minor premise expecting
four arguments (including the induction hypothesis) but a rule that applies it
to only three, so the ih binder swallows the next argument. That makes the
Prop-valued badProp reduce to Bool, and a Prop with two
distinguishable inhabitants gives False.
Affected kernels not only accept these declarations, they also re-derive the
same broken recursor when replaying the export data. This was the case for
the official kernel at v4.28.0, v4.29.1, v4.33.0 and nightly-2026-08-01.
Kernels that construct the recursor independently reject the export, mostly
with an error about Native64TwoHashOwner.step having an invalid occurrence of
the datatype being declared — which is also what the affected kernels reported
as soon as one of the hashes no longer collided.
Fixed by leanprover/lean4#14806, which replaces the union-find defeq cache with an order-independent one, so that a hash collision can no longer make a comparison succeed that fails on its own.
Test result: ✋ rejected · exit code 1 · wall time: 17 ms · instructions: 88.3 M · max rss memory: 35.4 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.004s wall, 4 workers + the commit thread, 17 records, busy 0.001s (7.3%); tail 0.001s after the last start, 1 busy then, 0.000s worker-time in it (0.4%) con-leche: stats: slowest installs: 0.000s inductive HAdd (#35); 0.000s inductive OfNat (#31); 0.000s def Nat.add (#47); 0.000s quot Quot.lift (#6); 0.000s inductive Eq (#0) con-leche: stats: peak RSS 0.03 GiB con-leche: invalid: nested positivity: non valid occurrence of the datatypes being declared [at inductive Native64TwoHashOwner, fold position 111] (--verified) t=0.0s
Test "bugs/rec-of-subst-prop"
Expected: ✋ reject · Size: 269.2 KB · Lines: 5.1 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof of False from a Prop that carries a Type field, recovered through
the recursor instead of a projection.
A second variant of bugs/proj-of-subst-prop, sharing its first two steps:
-
Definitional equality is not transitive on three
Bools built fromAcc.rec—gateA ≡ gateBandgateB ≡ gateCby proof irrelevance on theAccargument, butgateA ≢ gateC— soGateP := gateA = gateBandGateQ := gateA = gateCare definitionally equal types whose proofs behave differently underEq.rec.resultSort hK-reduces toPropfor a variableh : GatePand stays stuck for the closedgateWitness : GateQ. -
Issue.Owner : ∀ (h : GateP), resultSort his therefore accepted as a family of propositions whose constructor carries a fieldA : Type, whileOwner gateWitness— well-typed, sinceGateQ ≡ GateP— has a sort that does not reduce toProp.
Where bugs/proj-of-subst-prop then projects the field out, this variant eliminates
Owner with its own Prop-only recursor into Fiber X := Acc emptyTypeRel X,
which is a proposition, and recovers the data from there: Acc.rec eliminates
Acc into Type, and propext transports an Acc proof between two Fiber
types. Proof irrelevance identifies Owner.mk gateWitness Empty with
Owner.mk gateWitness Unit, so the identity function of one type is applied to
a value of the other, and Empty becomes inhabited. The proof of False uses
propext and no other axiom.
Because no projection is involved, the guard that stops bugs/proj-of-subst-prop —
refusing to project a data field out of a proposition — never fires here. A
checker has to refuse the substitution, or the stuck result sort of
Issue.Owner, instead.
Both variants are ruled out by
leanprover/lean4#14807, which
makes the kernel's is_prop check require the inferred type to reduce to a
sort: Issue.Owner is then rejected with (kernel) type expected.
The exploit is by Daniel Selsam (OpenAI), generated with OpenAI's internal models, and is the regression test added in leanprover/lean4#14847.
Test result: ✋ rejected · exit code 1 · wall time: 16 ms · instructions: 139.1 M · max rss memory: 33.4 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 136 records, busy 0.004s (37.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (3.5%) con-leche: stats: slowest installs: 0.000s inductive Nat.le.below (#68); 0.000s inductive Acc (#11); 0.000s inductive Or (#66); 0.000s inductive Iff (#129); 0.000s inductive And (#9) con-leche: stats: check pool: 0.001s wall, 4 workers, 91 records, busy 0.005s (80.1%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (26.9%) con-leche: stats: slowest checks: 0.000s theorem Issue.gateRun_eq (#111); 0.000s definition _private.Init.Prelude.0.Nat.le_trans.match_1_10 (#83); 0.000s definition Nat.eq_or_lt_of_le._f (#90); 0.000s definition _private.Init.Prelude.0.Nat.succ_le_succ.match_1_7 (#75); 0.000s definition Issue.gateStep.match_1 (#43) con-leche: stats: peak RSS 0.03 GiB con-leche: invalid: application type mismatch [at def Issue.proposition, fold position 114] (--verified) t=0.0s
Test "cedar"
Expected: 👍 accept · Size: 832.0 MB · Lines: 15.3 M · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Lean formalization of, and proofs about, Cedar.
Auto-generated documentation is available at https://cedar-policy.github.io/cedar-spec/docs/.
This test case exports the whole Cedar module and as such contains even unused parts Init and
Batteries.
Test result: 🚫 declined · exit code 2 · wall time: 3.2 s · instructions: 95.5 G · max rss memory: 870.2 MB
stderr:
con-leche: stats: phases: parse 1.7s, install 1.3s, check not reached con-leche: stats: install pool (1 still running, not counted): 0.976s wall, 4 workers + the commit thread, 46093 records, busy 3.251s (66.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (-) con-leche: stats: slowest installs: 0.476s def String.instInhabited (#1254); 0.474s theorem Int.sub_add_cancel (#1344); 0.405s def Nat.xor (#850); 0.371s def Nat.lor (#4614); 0.316s def Nat.land (#373) con-leche: stats: peak RSS 0.84 GiB con-leche: not implemented yet: non-standard axiom (_private.Cedar.Thm.SymCC.Data.Ext.0.Cedar.Thm.msPerDay_toInt._native.native_decide.ax_1_1) [at axiom _private.Cedar.Thm.SymCC.Data.Ext.0.Cedar.Thm.msPerDay_toInt._native.native_decide.ax_1_1, fold position 39109] (--verified) t=3.0s
Test "con-leche"
Expected: 👍 accept · Size: 525.9 MB · Lines: 10.0 M · lean4export: 3.1.0 · Lean: 4.33.0 · 📄 Declaration · 🔗 Source
The con-leche development's
three theorems: the consistency proof of its verified checker —
model_exists, every environment the checker accepts has a
set-theoretic model, and its corollary no_proof_of_False, no proof of
False is accepted — and the equivalence of its byte-level parser with
a naive reference (scanLineSpec_eq_scanLineFwd), each with its
dependency cone.
Test result: 👍 accepted · exit code 0 · wall time: 19.5 s · instructions: 664.4 G · max rss memory: 674.4 MB
stdout:
con-leche: accepted 26819 declarations (--verified)
stderr:
con-leche: stats: phases: parse 1.0s, install 1.7s, check 16.6s con-leche: stats: install pool: 1.689s wall, 4 workers + the commit thread, 26820 records, busy 3.728s (44.1%); tail 0.012s after the last start, 4 busy then, 0.001s worker-time in it (2.2%) con-leche: stats: slowest installs: 0.723s inductive ConLeche.Rules.Red.below (#12934); 0.338s def Nat.xor (#3364); 0.316s def Nat.lor (#966); 0.305s def _private.Init.Data.Nat.Bitwise.Lemmas.0.Nat.exists_testBit_ne_of_ne.match_1_1 (#1024); 0.266s inductive ConLeche.Rules.Red (#12922) con-leche: stats: check pool: 16.663s wall, 4 workers, 26464 records, busy 66.082s (99.1%); tail 0.191s after the last start, 4 busy then, 0.213s worker-time in it (27.7%) con-leche: stats: slowest checks: 0.380s theorem _private.Init.Data.Array.Extract.0.Array.extract_append._proof_1_1 (#4384); 0.261s theorem ConLeche.Frontend.keyAt_eq (#26124); 0.253s theorem _private.ConLeche.Model.IndBottomNested.0.ConLeche.Model.indBottomNested._proof_1_62 (#19129); 0.244s theorem _private.ConLeche.Model.IndBottomPlain.0.ConLeche.Model.indBottomPlain._proof_1_69 (#18605); 0.233s theorem ConLeche.Model.divMod_install (#17009) con-leche: stats: peak RSS 0.65 GiB
Test "corner-cases/alg-conv-trans-acc"
Expected: 🤷 either · Size: 66.4 KB · Lines: 1.2 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
As Lean's type theory has undecidable conversion (a.k.a. definitional equality), there are bound to be gaps between so called "algorithmic" conversion (that which is implemented by a typechecker), and the "declarative" conversion.
In the official kernel, algorithmic conversion fails to be transitive. f 1 a
is a normal form: a is a variable, so Acc.rec cannot fire on it. Proof
irrelevance admits any other proof of Acc (· < ·) 1 in its place, and
Acc.intro 1 fun _ => Acc.inv a carries a constructor at the head, so it
reduces. left is that substitution, right the reduction it unblocks, and
trans chains the two.
acc asks for the endpoints on their own, which means inventing the middle
term: choosing, among the proofs of a proposition, the one that happens to
reduce the right way. The kernel has no reason to go looking, the left side
being normal already, and unfolding regardless does not terminate here, as
each step makes the term larger.
References:
- Mario Carneiro, The Type Theory of Lean, MSc thesis
Test result: ✋ rejected · exit code 1 · wall time: 14 ms · instructions: 53.7 M · max rss memory: 23.3 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 48 records, busy 0.002s (23.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (6.0%) con-leche: stats: slowest installs: 0.000s inductive Acc (#11); 0.000s inductive And (#9); 0.000s inductive HAdd (#21); 0.000s inductive OfNat (#17); 0.000s inductive Nat.le (#14) con-leche: stats: check pool: 0.000s wall, 4 workers, 27 records, busy 0.002s (59.1%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (30.2%) con-leche: stats: slowest checks: 0.000s definition step.match_1 (#36); 0.000s theorem trans (#47); 0.000s theorem Nat.lt_succ_self (#42); 0.000s theorem Nat.le_refl (#40); 0.000s definition Nat.brecOn.go (#29) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem trans [at theorem trans, fold position 47] (--verified) t=0.0s
Test "corner-cases/alg-conv-trans-acc-left"
Expected: 🤷 either · Size: 67.4 KB · Lines: 1.2 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The creative half of corner-cases/alg-conv-trans-acc. Acc.rec is stuck
on the variable a, and proof irrelevance admits any other proof of
Acc (· < ·) 1 in its place, including one with a constructor at the head.
Given both sides, a checker verifies this immediately; producing the
right-hand side unprompted is the step no algorithm takes.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 53.8 M · max rss memory: 23.2 MB
stdout:
con-leche: accepted 41 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 49 records, busy 0.002s (23.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (14.5%) con-leche: stats: slowest installs: 0.000s inductive Acc (#11); 0.000s inductive And (#9); 0.000s inductive Nat.le (#14); 0.000s inductive HAdd (#21); 0.000s def Nat.add (#34) con-leche: stats: check pool: 0.000s wall, 4 workers, 28 records, busy 0.001s (49.0%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (11.4%) con-leche: stats: slowest checks: 0.000s definition step.match_1 (#36); 0.000s theorem Nat.lt_add_one (#41); 0.000s definition step (#43); 0.000s theorem Nat.lt_succ_self (#42); 0.000s definition Nat.brecOn.go (#29) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/alg-conv-trans-acc-right"
Expected: 🤷 either · Size: 67.6 KB · Lines: 1.2 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The mechanical half of corner-cases/alg-conv-trans-acc. With a
constructor in the major premise, Acc.rec fires and step descends to the
predecessor 0.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 54.6 M · max rss memory: 23.0 MB
stdout:
con-leche: accepted 41 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 49 records, busy 0.002s (24.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (6.3%) con-leche: stats: slowest installs: 0.000s inductive Acc (#11); 0.000s inductive And (#9); 0.000s inductive HAdd (#21); 0.000s inductive Nat.le (#14); 0.000s def Nat.add (#34) con-leche: stats: check pool: 0.000s wall, 4 workers, 28 records, busy 0.001s (55.8%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (29.3%) con-leche: stats: slowest checks: 0.000s definition step.match_1 (#36); 0.000s theorem right (#48); 0.000s definition step (#43); 0.000s theorem Nat.lt_add_one (#41); 0.000s definition Nat.brecOn.go (#29) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/alg-conv-trans-quot"
Expected: 🤷 either · Size: 8.5 KB · Lines: 169 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
left composed with right. Quotients of propositions cause
algorithmic conversion transitivity to fail because the typechecker must
creatively synthesise the representative of the quotient, and
proof irrelevance is definitional.
References:
- Mario Carneiro, The Type Theory of Lean, MSc thesis
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 23.9 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (6.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (55.0%) con-leche: stats: slowest checks: 0.000s theorem trans (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem trans [at theorem trans, fold position 11] (--verified) t=0.0s
Test "corner-cases/alg-conv-trans-quot-left"
Expected: 🤷 either · Size: 8.6 KB · Lines: 173 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Quot r is a Prop, so proof irrelevance relates q and Quot.mk r z.
However the official kernel does WHNF first, reducing the right side to f z,
so congruence never compares the arguments.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 24.0 M · max rss memory: 23.3 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (20.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (15.3%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s theorem left (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (48.8%) con-leche: stats: slowest checks: 0.000s theorem left (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem left [at theorem left, fold position 11] (--verified) t=0.0s
Test "corner-cases/alg-conv-trans-quot-left-def"
Expected: 🤷 either · Size: 10.5 KB · Lines: 208 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
left with Quot.lift behind a definition. WHNF does not unfold lift, so
the arguments are compared and proof irrelevance applies.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.5 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 8 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (16.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def lift (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (23.7%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (41.9%) con-leche: stats: slowest checks: 0.000s theorem left' (#13); 0.000s definition lift (#11); 0.000s definition rfl (#12) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/alg-conv-trans-quot-right"
Expected: 🤷 either · Size: 9.0 KB · Lines: 180 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Quotient computation rule.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.1 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 7 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (18.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot (#4); 0.000s inductive False (#3); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (37.0%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (56.2%) con-leche: stats: slowest checks: 0.000s theorem right (#12); 0.000s definition rfl (#11) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/eta-ctor"
Expected: 🤷 either · Size: 9.0 KB · Lines: 148 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Function eta between a partially applied constructor and a free variable.
The official kernel does not trigger eta expansion here, but a checker may
accept the equality by expanding the functions.
See https://github.com/leanprover/lean4/issues/12520 for a discussion; the
official kernel may adopt eta-expansion of partially applied constructors,
see https://github.com/leanprover/lean4/pull/15373. For a bug in a draft
of that change, see bugs/eta-ctor-alias.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 24.7 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.000s (18.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (8.6%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive T (#12); 0.000s inductive True (#11); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (32.5%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (49.3%) con-leche: stats: slowest checks: 0.000s definition etaCtor (#14); 0.000s definition T.val (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in definition etaCtor [at def etaCtor, fold position 14] (--verified) t=0.0s
Test "corner-cases/eta-rec-struct"
Expected: 🤷 either · Size: 9.5 KB · Lines: 174 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Function eta between a recursor of a structure that is missing its major premise and a free variable.
Prod.rec (fun b c => a (b, c)) and a are convertible: eta-expanding
the former gives fun p => Prod.rec (fun b c => a (b, c)) p, whose body
reduces, by structure eta on p, to a (p.1, p.2), and that is convertible
to a p. The official kernel eta-expands only when the other side is a
lambda, so it rejects this, while it accepts the equation of each side with
fun p => a p.
The same issue with a recursor with rule K is corner-cases/eta-rule-k. The
official kernel may adopt eta-expansion of such partial recursor
applications, see https://github.com/leanprover/lean4/pull/15374 and
https://github.com/leanprover/lean4/issues/12520.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 24.9 M · max rss memory: 23.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (31.2%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (27.5%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s theorem etaRecStruct (#12); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (76.6%) con-leche: stats: slowest checks: 0.000s theorem etaRecStruct (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem etaRecStruct [at theorem etaRecStruct, fold position 12] (--verified) t=0.0s
Test "corner-cases/eta-rule-k"
Expected: 🤷 either · Size: 6.5 KB · Lines: 121 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Function eta between a partially applied recursor with rule K and a free
variable. The official kernel does not trigger eta expansion here, but a
checker may accept the equality by expanding the functions.
See https://github.com/leanprover/lean4/issues/12520 for a discussion; the
official kernel may adopt eta-expansion of such partial recursor
applications, see https://github.com/leanprover/lean4/pull/15374. The same
issue for a structure recursor is corner-cases/eta-rec-struct.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 23.4 M · max rss memory: 20.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.001s (35.3%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (34.8%) con-leche: stats: slowest installs: 0.000s def etaRuleK (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot.lift (#6) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (51.7%) con-leche: stats: slowest checks: 0.000s definition etaRuleK (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in definition etaRuleK [at def etaRuleK, fold position 11] (--verified) t=0.0s
Test "corner-cases/eta-struct-major-and"
Expected: 🤷 either · Size: 9.4 KB · Lines: 175 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Structure eta on a recursor's major premise, for a structure in Prop.
And.rec f ⟨x.1, x.2⟩ reduces to f x.1 x.2. And.rec f x, with a
variable x : P ∧ Q, also reduces to that if the major premise is expanded
by structure eta, but the official kernel does not perform structure eta on
majors whose type is a proposition, so it is stuck, and conversion is not
transitive (or congruent) here.
Eta for such majors is fine for structures that eliminate into every sort,
like And, whose fields are all proofs. It must not be done for
propositions that eliminate only into Prop, like Exists, which have no
projections. The official kernel may adopt this, see
https://github.com/leanprover/lean4/pull/15371,
https://github.com/leanprover/lean4/issues/3213 and the overall plan in
https://github.com/leanprover/lean4/issues/14977.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.4 M · max rss memory: 21.4 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (30.9%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (19.2%) con-leche: stats: slowest installs: 0.000s theorem And.left (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot.lift (#6); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (21.8%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (29.7%) con-leche: stats: slowest checks: 0.000s theorem andMajorEta (#13); 0.000s theorem And.left (#11); 0.000s theorem And.right (#12) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/eta-struct-major-and-no-whnf"
Expected: 🤷 either · Size: 24.0 KB · Lines: 421 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The combination of corner-cases/eta-struct-major-and and
corner-cases/eta-struct-major-no-whnf.
andConst h is And.rec (fun _ _ => 1) h, applied here to a proof of
True ∧ True that has no weak head normal form (built from Coquand's
paradox, via propext). A checker that eta-expands the And major premise
before reducing it accepts the equation with 1 immediately. A checker
that first reduces the major premise does not terminate, and the official
kernel today, which reduces the major and then does not eta-expand
propositions, does not terminate either.
This shows why, once eta applies to majors in Prop, the expansion has to
happen before reduction: proofs need not normalize, and otherwise that
non-termination leaks into the conversion of data. See
https://github.com/leanprover/lean4/pull/15351,
https://github.com/leanprover/lean4/pull/15371 and
https://github.com/leanprover/lean4/issues/14977.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 29.0 M · max rss memory: 22.8 MB
stdout:
con-leche: accepted 18 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 26 records, busy 0.001s (32.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (5.4%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive True (#11); 0.000s inductive Bool (#10); 0.000s inductive OfNat (#12); 0.000s inductive Iff (#20) con-leche: stats: check pool: 0.000s wall, 4 workers, 11 records, busy 0.000s (37.2%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (46.1%) con-leche: stats: slowest checks: 0.000s definition delta (#18); 0.000s theorem andMajorNoWhnf (#25); 0.000s definition andConst (#15); 0.000s definition cast (#19); 0.000s definition OfNat.ofNat (#13) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/eta-struct-major-no-whnf"
Expected: 🤷 either · Size: 32.2 KB · Lines: 582 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Structure eta on a recursor's major premise, applied before trying to reduce the major to a constructor.
prodConst loopPair is Prod.rec (fun _ _ => 1) loopPair, and loopPair
is an Acc.rec whose major premise is a proof with no weak head normal form
(built from Coquand's paradox, via propext). A checker that first reduces
the major premise to weak head normal form, as the official kernel does
today, does not terminate here. Expanding the major premise to
(loopPair.1, loopPair.2) first lets the recursor fire without ever looking
at loopPair, and the equation with 1 holds.
The result of the reduction is the same either way (structure eta is part of the theory), so the question is only one of termination of the algorithm. The official kernel may adopt this order, see https://github.com/leanprover/lean4/pull/15351 and the overall plan in https://github.com/leanprover/lean4/issues/14977.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 33.8 M · max rss memory: 23.1 MB
stdout:
con-leche: accepted 22 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 30 records, busy 0.001s (26.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.9%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive Acc (#16); 0.000s inductive Iff (#21); 0.000s inductive OfNat (#12) con-leche: stats: check pool: 0.000s wall, 4 workers, 14 records, busy 0.000s (38.6%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (40.5%) con-leche: stats: slowest checks: 0.000s definition instOfNatNat (#14); 0.000s definition OfNat.ofNat (#13); 0.000s theorem prodMajorNoWhnf (#29); 0.000s definition prodConst (#15); 0.000s theorem tautext (#23) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/eta-unit-like-nested"
Expected: 🤷 either · Size: 16.0 KB · Lines: 256 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Unit-like eta for a structure whose fields are proofs, Unit, and (after
instantiating the parameters) a function into a unit-like structure.
The official kernel applies eta for unit-like types (any two inhabitants are
convertible) only to structures without fields. With that criterion,
conversion is not transitive: both p and q are convertible to the
same canonical inhabitant (e.g. fun _ => () or ⟨()⟩), but not to each
other. Extending the criterion to Pi types whose codomain is unit-like and
to structures whose fields are all proofs or unit-like fixes that. The
official kernel may adopt this, see https://github.com/leanprover/lean4/pull/15372,
https://github.com/leanprover/lean4/issues/2258 and the overall plan in
https://github.com/leanprover/lean4/issues/14977.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 27.1 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 17 records, busy 0.001s (27.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (7.7%) con-leche: stats: slowest installs: 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s inductive Mixed (#14); 0.000s inductive Bool (#10); 0.000s inductive UnitField (#15) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (21.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (41.8%) con-leche: stats: slowest checks: 0.000s theorem unitLikeNested (#16); 0.000s definition Unit (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem unitLikeNested [at theorem unitLikeNested, fold position 16] (--verified) t=0.0s
Test "corner-cases/eta-unit-like-pi"
Expected: 🤷 either · Size: 5.6 KB · Lines: 101 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Unit-like eta for a function type: any two p q : α → Unit are equal.
The official kernel applies eta for unit-like types (any two inhabitants are
convertible) only to structures without fields. With that criterion,
conversion is not transitive: both p and q are convertible to the
same canonical inhabitant (e.g. fun _ => () or ⟨()⟩), but not to each
other. Extending the criterion to Pi types whose codomain is unit-like and
to structures whose fields are all proofs or unit-like fixes that. The
official kernel may adopt this, see https://github.com/leanprover/lean4/pull/15372,
https://github.com/leanprover/lean4/issues/2258 and the overall plan in
https://github.com/leanprover/lean4/issues/14977.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 23.8 M · max rss memory: 21.3 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (23.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (11.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PUnit (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (16.9%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (45.3%) con-leche: stats: slowest checks: 0.000s theorem unitLikePi (#13); 0.000s definition Unit (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem unitLikePi [at theorem unitLikePi, fold position 13] (--verified) t=0.0s
Test "corner-cases/eta-unit-like-proof-field"
Expected: 🤷 either · Size: 6.5 KB · Lines: 111 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Unit-like eta for a structure in Type whose only field is a proof of True.
The official kernel applies eta for unit-like types (any two inhabitants are
convertible) only to structures without fields. With that criterion,
conversion is not transitive: both p and q are convertible to the
same canonical inhabitant (e.g. fun _ => () or ⟨()⟩), but not to each
other. Extending the criterion to Pi types whose codomain is unit-like and
to structures whose fields are all proofs or unit-like fixes that. The
official kernel may adopt this, see https://github.com/leanprover/lean4/pull/15372,
https://github.com/leanprover/lean4/issues/2258 and the overall plan in
https://github.com/leanprover/lean4/issues/14977.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 24.2 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (24.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (15.6%) con-leche: stats: slowest installs: 0.000s inductive True (#11); 0.000s inductive And (#9); 0.000s inductive ProofField (#12); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (54.5%) con-leche: stats: slowest checks: 0.000s theorem unitLikeProofField (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem unitLikeProofField [at theorem unitLikeProofField, fold position 13] (--verified) t=0.0s
Test "corner-cases/eta-unit-like-struct"
Expected: 🤷 either · Size: 6.7 KB · Lines: 115 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Unit-like eta for a structure whose only field is of type Unit.
The official kernel applies eta for unit-like types (any two inhabitants are
convertible) only to structures without fields. With that criterion,
conversion is not transitive: both p and q are convertible to the
same canonical inhabitant (e.g. fun _ => () or ⟨()⟩), but not to each
other. Extending the criterion to Pi types whose codomain is unit-like and
to structures whose fields are all proofs or unit-like fixes that. The
official kernel may adopt this, see https://github.com/leanprover/lean4/pull/15372,
https://github.com/leanprover/lean4/issues/2258 and the overall plan in
https://github.com/leanprover/lean4/issues/14977.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 24.3 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.000s (28.9%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (16.1%) con-leche: stats: slowest installs: 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s inductive UnitField (#13); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (28.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (42.2%) con-leche: stats: slowest checks: 0.000s theorem unitLikeStruct (#14); 0.000s definition Unit (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem unitLikeStruct [at theorem unitLikeStruct, fold position 14] (--verified) t=0.0s
Test "corner-cases/imax-right-successor"
Expected: 🤷 either · Size: 806 B · Lines: 21 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Universe-level normalization corner cases. The declarations use imax u 1
and imax u (v + 1) where their declared types use the corresponding
max levels. A checker may reject these hand-crafted exports using a more
conservative normalization, or accept them by recognizing that the right
operand is nonzero.
Test result: 👍 accepted · exit code 0 · wall time: 10 ms · instructions: 22.7 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (17.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (15.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def imaxRightOne (#11); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (5.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (1.3%) con-leche: stats: slowest checks: 0.000s definition imaxRightOne (#11); 0.000s definition imaxRightSucc (#12) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/let-value-type-mismatch"
Expected: 🤷 either · Size: 601 B · Lines: 13 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
A let has a mismatched annotation, but substitution removes the mismatch.
In readable notation, the exported declaration is:
def EcosystemCase : Sort 2 := let u : Sort 1 := Sort 1; u
The value Sort 1 has type Sort 2, rather than the annotated Sort 1.
Checking the supplied let can therefore reject it. Substituting its value
for u gives def EcosystemCase : Sort 2 := Sort 1, whose types match.
This records the choice to check the supplied annotation or first simplify the let. The discussion of this exact example supports allowing either outcome as practical checker policy, while leaving a completely authoritative answer open. This is not a false-theorem example.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 22.7 M · max rss memory: 20.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (15.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.3%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (26.5%) con-leche: stats: slowest checks: 0.000s definition EcosystemCase (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: let value type mismatch [at def EcosystemCase, fold position 11] (--verified) t=0.0s
Test "corner-cases/nested-nonuniform-param"
Expected: 🤷 either · Size: 9.2 KB · Lines: 142 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Checks that a parameter supplied to a nested inductive occurrence really acts as the datatype's parameter, i.e. that it is the parameter itself and does not change between recursive occurrences (as is already enforced for non-nested occurrences).
The inductive E : W → Type has constructor
E.mk : (w : W) → L (E ⟨false⟩) → E w, where L (α : Type) is nested. The
occurrence E ⟨false⟩ inside the nested L uses the constant ⟨false⟩ in
the position of E's parameter, instead of the actual parameter w. That
argument is type-correct, so it is not caught by merely type-checking the
nested application (leanprover/lean4#14577); a correct checker must also
verify that it is the expected parameter.
This particular declaration is not known to yield a proof of False: here L
stores no value of type α, so the nested occurrence is phantom and E w is
isomorphic to Unit for every w. The variant where L actually stores an
α (so recursion would descend into an E ⟨false⟩ while the motive is fixed
at E w) is already rejected by the kernel's positivity check ("non valid
occurrence"). Since it is not a demonstrated unsoundness, it is not settled
whether a checker should accept or reject it, so the expected outcome is
either and the test does not count towards completeness or soundness.
Origin: raised by @arthur-adjedj on leanprover/lean4#14577 (https://github.com/leanprover/lean4/pull/14577#issuecomment-5101819377) as a case not covered by that PR's fix; related to leanprover/lean4#14576.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 24.9 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.001s wall, 4 workers + the commit thread, 3 records, busy 0.000s (0.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.0%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s inductive Empty (#2) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: invalid occurrence of a datatype being declared in the type of E.mk: it must be applied to the parameters and universe levels of the mutual declaration [at inductive E, fold position 13] (--verified) t=0.0s
Test "corner-cases/positivity-whnf"
Expected: 🤷 either · Size: 4.7 KB · Lines: 81 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
A recursive occurrence appears in an unused argument of a reducible definition in a constructor field.
The declaration has the following shape:
def Ignore (A B : Type) : Type := A
inductive T : Type where
| mk (f : Ignore Unit T -> T) : T
Ignore takes a second type argument but does not use it, so Ignore Unit T reduces to Unit. A checker that inspects the unreduced constructor field may reject the syntactic occurrence of T in the domain of the arrow. A checker that first weak-head-normalizes the field type may instead see (Unit -> T) -> T and accept it. The test therefore has outcome eithe r.
A checker may reject it syntactically or accept it after reducing the field type.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 23.7 M · max rss memory: 20.8 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (3 still running, not counted): 0.000s wall, 4 workers + the commit thread, 6 records, busy 0.000s (1.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.0%) con-leche: stats: slowest installs: 0.000s quot Quot (#4); 0.000s inductive Eq (#0); 0.000s quot Quot.ind (#7); 0.000s axiom Quot.sound (#8); 0.000s quot Quot.mk (#5) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: nested positivity: non positive occurrence of the datatypes being declared [at inductive LALReduciblePositivity, fold position 14] (--verified) t=0.0s
Test "corner-cases/proj-maybe-prop"
Expected: 🤷 either · Size: 8.1 KB · Lines: 131 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out of a structure that may or may not be a proposition.
MaybeProp is a structure whose sort is a bare level parameter: a
proposition for u := 0 and a data type for every other u. Lean's
inductive command refuses to declare one ("the resulting universe is not
Prop, but it may be Prop for some parameter values"), but the kernel
accepts it. The exported definition projects out its first field,
field : PUnit.{u}.
The official kernel accepts this. The field is not a proof for every u,
but the projection is sound at every instantiation: MaybeProp.{u} is a
proposition only for u := 0, and there the field's type PUnit.{0} is a
proposition too. That is no coincidence. A structure that is not a Prop
had every constructor field's universe checked against its resulting
universe (see the tutorial's typeWithTooHighTypeField), here u ≤ u, and
such an inequality survives instantiation — so wherever the structure does
turn out to be a proposition, so do all of its fields.
At the same time, the official kernel here allows more projections than the
recursor allows: MaybeProp.rec eliminates into Prop only, so this
projection cannot be expressed through the recursor. The elaborator does not
currently rely on this extra power, so for now it is reasonable for a
checker to be more restrictive here and reject the projection — for example
by asking "could this be a proposition?" and then demanding that the field
be definitely a proof. See
https://github.com/leanprover/lean4/issues/7637 for discussion.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 25.1 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.000s (17.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (10.0%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive MaybeProp (#13); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive PUnit (#11) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (25.2%) con-leche: stats: slowest checks: 0.000s definition projMaybeProp (#14) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/proj-maybe-prop-past"
Expected: 🤷 either · Size: 8.1 KB · Lines: 131 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The same as corner-cases/proj-maybe-prop, for a projection that only has
to step over such a field.
MaybeProp.tail is a proof for every u, so the field asked for here is
unobjectionable even under the restrictive reading. But reaching it means
walking past field, which proof depends on, and that is where the check
on a genuine proposition (the tutorial's projProp6) fires. A checker that
rejects corner-cases/proj-maybe-prop therefore rejects this one as well,
at field 0 rather than at field 2, and that remains a reasonable choice for
the same reason. See https://github.com/leanprover/lean4/issues/7637 for
discussion.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 25.1 M · max rss memory: 20.8 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (2 still running, not counted): 0.000s wall, 4 workers + the commit thread, 10 records, busy 0.000s (12.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (9.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s axiom Quot.sound (#8) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (22.4%) con-leche: stats: slowest checks: 0.000s definition projMaybePropPast (#14) con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/proof-param-ok"
Expected: 👍 accept · Size: 2.9 KB · Lines: 53 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Keeps two proof parameters in their declared order in an inductive constructor result.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.7 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 10 records, busy 0.000s (13.7%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (13.6%) con-leche: stats: slowest installs: 0.000s inductive LALProofParameterSwap (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1); 0.000s axiom Quot.sound (#8) con-leche: stats: check pool: 0.000s wall, 1 worker, 0 records, busy 0.000s (0.0%) con-leche: stats: slowest checks: con-leche: stats: peak RSS 0.02 GiB
Test "corner-cases/proof-param-swap"
Expected: 🤷 either · Size: 2.9 KB · Lines: 53 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Swaps two proof parameters in an inductive constructor result. Checkers may either reject the swap or accept it using proof irrelevance.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 22.8 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (3 still running, not counted): 0.000s wall, 4 workers + the commit thread, 0 records, busy 0.000s (0.0%) con-leche: stats: slowest installs: con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: direct sum: invalid constructor return type [at inductive LALProofParameterSwap, fold position 11] (--verified) t=0.0s
Test "corner-cases/subject-reduction-redex"
Expected: 🤷 either · Size: 66.6 KB · Lines: 1.2 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Test for subject reduction, as in Carneiro's thesis.
The annotation on the lambda writes the middle term of
corner-cases/alg-conv-trans-acc down by hand, sparing the kernel from
having to invent it. The body checks against right, the argument against
left, and the two endpoints are never compared.
References:
- Mario Carneiro, The Type Theory of Lean, MSc thesis
Test result: ✋ rejected · exit code 1 · wall time: 14 ms · instructions: 55.1 M · max rss memory: 22.7 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 51 records, busy 0.002s (22.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (15.3%) con-leche: stats: slowest installs: 0.000s inductive Acc (#11); 0.000s inductive And (#9); 0.000s inductive HAdd (#21); 0.000s inductive LT (#12); 0.000s inductive Nat.le (#14) con-leche: stats: check pool: 0.000s wall, 4 workers, 30 records, busy 0.002s (61.3%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (43.8%) con-leche: stats: slowest checks: 0.000s definition step.match_1 (#36); 0.000s definition step (#43); 0.000s theorem Nat.lt_add_one (#41); 0.000s definition redex (#50); 0.000s definition Nat.brecOn.go (#29) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: application type mismatch [at def redex, fold position 50] (--verified) t=0.0s
Test "corner-cases/subject-reduction-reduct"
Expected: 🤷 either · Size: 65.5 KB · Lines: 1.2 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Beta erases the annotation of corner-cases/subject-reduction-redex, and
with it the middle term, leaving the two endpoints to compare: the conversion
of corner-cases/alg-conv-trans-acc. A term the kernel accepts thus
reduces to one it rejects.
References:
- Mario Carneiro, The Type Theory of Lean, MSc thesis
Test result: ✋ rejected · exit code 1 · wall time: 16 ms · instructions: 54.3 M · max rss memory: 23.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 50 records, busy 0.002s (23.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (7.0%) con-leche: stats: slowest installs: 0.000s inductive Acc (#11); 0.000s inductive And (#9); 0.000s inductive Nat.le (#14); 0.000s inductive HAdd (#21); 0.000s def Nat.add (#34) con-leche: stats: check pool: 0.000s wall, 4 workers, 29 records, busy 0.002s (63.0%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (66.8%) con-leche: stats: slowest checks: 0.000s definition step.match_1 (#36); 0.000s theorem Nat.lt_add_one (#41); 0.000s theorem Nat.lt_succ_self (#42); 0.000s definition step (#43); 0.000s definition Nat.brecOn.go (#29) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: application type mismatch [at def reduct, fold position 49] (--verified) t=0.0s
Test "cslib"
Expected: 👍 accept · Size: 2.3 GB · Lines: 42.7 M · lean4export: 3.1.0 · Lean: 4.34.0 · 📄 Declaration · 🔗 Source
The Lean Computer Science Library (CSLib).
Test result: 👍 accepted · exit code 0 · wall time: 1.1 m · instructions: 2.5 T · max rss memory: 2.0 GB
stdout:
con-leche: accepted 383976 declarations (--verified)
stderr:
con-leche: 2 declarations hoisted ahead of the pinned Nat operations they ground: Nat.mul._f, Nat.mul con-leche: stats: phases: parse 6.3s, install 4.3s, check 56.7s con-leche: stats: install pool: 3.056s wall, 4 workers + the commit thread, 383976 records, busy 12.179s (79.7%); tail 0.019s after the last start, 1 busy then, 0.000s worker-time in it (0.0%) con-leche: stats: slowest installs: 0.453s def Nat.xor (#9301); 0.426s inductive Lean.Name (#1475); 0.425s def String.instInhabited (#1453); 0.418s theorem Lean.Omega.Constraint.addInequality_sat (#1536); 0.379s def Nat.lor (#7971) con-leche: stats: check pool: 56.616s wall, 4 workers, 379926 records, busy 226.081s (99.8%); tail 0.088s after the last start, 4 busy then, 0.085s worker-time in it (24.2%) con-leche: stats: slowest checks: 0.447s theorem _private.Init.Data.Array.Extract.0.Array.extract_append._proof_1_1 (#14232); 0.341s theorem _private.Init.Data.Vector.Extract.0.Vector.extract_append._proof_1 (#288510); 0.319s theorem _private.Cslib.Computability.Automata.NA.Loop.0.Cslib.Automata.NA.loop_fin_run_exists._proof_1_179 (#110807); 0.298s theorem Algebra.TensorProduct.tensorTensorTensorComm._proof_2 (#280503); 0.267s theorem _private.Init.Data.Vector.Extract.0.Vector.extract_extract._proof_1 (#169266) con-leche: stats: peak RSS 1.98 GiB
Test "init"
Expected: 👍 accept · Size: 331.5 MB · Lines: 6.5 M · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The Init module export from Lean 4 core.
This test contains the fundamental building blocks of Lean 4, including:
- Basic data types (Nat, List, Array, String, etc.)
- Core tactics and syntax
- Foundational mathematical structures
- Essential metaprogramming infrastructure
This is one of the smallest meaningful test cases, making it ideal for initial checker validation and debugging.
Test result: 👍 accepted · exit code 0 · wall time: 12.0 s · instructions: 431.1 G · max rss memory: 533.4 MB
stdout:
con-leche: accepted 58170 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.5s, install 1.0s, check 10.3s con-leche: stats: install pool: 0.937s wall, 4 workers + the commit thread, 58170 records, busy 3.238s (69.0%); tail 0.034s after the last start, 4 busy then, 0.000s worker-time in it (0.0%) con-leche: stats: slowest installs: 0.482s def Nat.xor (#5984); 0.431s def Nat.lor (#2479); 0.315s def Nat.land (#591); 0.307s def List.get!Internal._f (#1363); 0.289s def Ordering.isLE._sparseCasesOn_1 (#2290) con-leche: stats: check pool: 10.368s wall, 4 workers, 57527 records, busy 41.241s (99.4%); tail 0.071s after the last start, 4 busy then, 0.070s worker-time in it (24.9%) con-leche: stats: slowest checks: 0.403s theorem _private.Init.Data.Vector.Extract.0.Vector.extract_append._proof_1 (#42191); 0.384s theorem _private.Init.Data.Array.Extract.0.Array.extract_append._proof_1_1 (#4399); 0.259s theorem _private.Init.Data.Vector.Extract.0.Vector.extract_extract._proof_1 (#49769); 0.219s theorem _private.Init.Data.Vector.Extract.0.Vector.extract_append_extract._proof_1 (#35884); 0.209s theorem _private.Init.Data.Array.Extract.0.Array.extract_append_extract._proof_1_1 (#3985) con-leche: stats: peak RSS 0.52 GiB
Test "init-prelude"
Expected: 👍 accept · Size: 3.6 MB · Lines: 64.1 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The Init.Prelude module export.
Test result: 👍 accepted · exit code 0 · wall time: 132 ms · instructions: 2.4 G · max rss memory: 45.4 MB
stdout:
con-leche: accepted 1824 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.081s wall, 4 workers + the commit thread, 1824 records, busy 0.330s (81.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.8%) con-leche: stats: slowest installs: 0.076s def Lean.Name.hasMacroScopes._f (#680); 0.076s def SMul.ctorIdx (#834); 0.069s def _private.Init.Prelude.0.Lean.MacroScopesView.review.match_1 (#705); 0.035s def Nat.mod (#219); 0.020s def Nat.div (#270) con-leche: stats: check pool: 0.024s wall, 4 workers, 1682 records, busy 0.096s (97.2%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (32.8%) con-leche: stats: slowest checks: 0.002s definition Lean.ParserDescr.noConfusion (#971); 0.001s definition Lean.ParserDescr.ctorElim (#467); 0.001s definition Trans.noConfusion (#617); 0.001s theorem Nat.modCore_lt (#244); 0.000s theorem Lean.ParserDescr.brecOn.eq (#1790) con-leche: stats: peak RSS 0.04 GiB
Test "mathlib"
Expected: 👍 accept · Size: 5.8 GB · Lines: 109.8 M · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The complete Mathlib library export.
This test contains all the mathematical definitions, theorems, and proofs from Mathlib, representing the largest and most comprehensive test case in the Lean kernel arena.
Test result: 👍 accepted · exit code 0 · wall time: 3.7 m · instructions: 7.9 T · max rss memory: 5.1 GB
stdout:
con-leche: accepted 702040 declarations (--verified)
stderr:
con-leche: 2 declarations hoisted ahead of the pinned Nat operations they ground: Nat.mul._f, Nat.mul con-leche: stats: phases: parse 17.7s, install 10.8s, check 195.3s con-leche: stats: install pool: 7.129s wall, 4 workers + the commit thread, 702040 records, busy 28.867s (80.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (6.7%) con-leche: stats: slowest installs: 0.634s inductive Lean.Name (#1475); 0.633s def String.instInhabited (#1453); 0.624s theorem Lean.Omega.Constraint.addInequality_sat (#1536); 0.508s def Nat.land (#636); 0.435s def Nat.xor (#10984) con-leche: stats: check pool: 194.957s wall, 4 workers, 695214 records, busy 779.293s (99.9%); tail 0.079s after the last start, 4 busy then, 0.072s worker-time in it (22.7%) con-leche: stats: slowest checks: 6.431s theorem _private.Mathlib.AlgebraicGeometry.EllipticCurve.Affine.AddSubMap.0.WeierstrassCurve.Affine.Point.sym2x_add_sub_eq_addSubMap_sym2x._proof_1_8 (#440037); 1.470s theorem _private.Mathlib.Combinatorics.SimpleGraph.Regularity.Chunk.0.SzemerediRegularity.edgeDensity_star_not_uniform._proof_1_10 (#215811); 1.185s definition QuadraticModuleCat.instMonoidalCategoryStruct (#276667); 1.155s theorem QuadraticModuleCat.hom_hom_associator (#276668); 1.070s theorem QuadraticModuleCat.hom_inv_associator (#277682) con-leche: stats: peak RSS 5.09 GiB
Test "navier-stokes-euler"
Expected: 👍 accept · Size: 1.5 GB · Lines: 28.6 M · lean4export: 3.1.0 · Lean: 4.34.0-rc2 · 📄 Declaration · 🔗 Source
OpenAI's Lean formalization of finite-time blowup for the three-dimensional incompressible Navier–Stokes equations with smooth forcing (on Euclidean space and on the periodic torus), and of unforced Euler blowup. See https://github.com/openai/NavierStokesAndEuler/.
This test exports the main results listed in the project's formalization.yaml,
together with their dependencies.
Test result: 👍 accepted · exit code 0 · wall time: 1.7 m · instructions: 2.8 T · max rss memory: 1.4 GB
stdout:
con-leche: accepted 126468 declarations (--verified)
stderr:
con-leche: stats: phases: parse 4.1s, install 3.5s, check 92.1s con-leche: stats: install pool: 2.837s wall, 4 workers + the commit thread, 126468 records, busy 11.987s (84.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (2.4%) con-leche: stats: slowest installs: 0.381s def Nat.land (#1659); 0.202s inductive EulerMeanVariationalInverse.StrongMeanEvolution (#95851); 0.171s inductive EulerPacketMovingFrame.PhysicalGeometryData (#104023); 0.171s inductive EulerTransversePacketJoin.Budget (#104861); 0.168s inductive EulerMeanPacketProvider.Data (#95680) con-leche: stats: check pool: 92.116s wall, 4 workers, 124834 records, busy 368.336s (99.9%); tail 0.009s after the last start, 4 busy then, 0.012s worker-time in it (34.4%) con-leche: stats: slowest checks: 1.145s theorem NavierStokes.FiveProfileMoments.quadraticBilin._proof_6 (#50132); 0.762s theorem NavierStokes.FiveProfileMoments.quadraticBilin._proof_9 (#50135); 0.529s theorem NavierStokes.TerminalCompensation.quadraticBilin._proof_6 (#57739); 0.432s theorem _private.Mathlib.Analysis.ODE.ExistUnique.0.ODE_solution_unique_univ._proof_1_2 (#110301); 0.386s theorem EulerTransversePacketJoin.derivative_match (#103261) con-leche: stats: peak RSS 1.40 GiB
Test "other/extra-rec"
Expected: ✋ reject · Size: 1.4 KB · Lines: 21 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False from an extra recursor that no inductive declaration could
produce.
The export contains False exactly as the prelude has it — an empty
Prop-valued inductive with no constructors — together with its ordinary
False.rec. Smuggled into the same inductive group is a second recursor,
named rogue, whose type is False itself and which has no motives, no minor
premises and no rules. The theorem inconsistent : False is then simply
rogue.
A checker must derive the recursors of an inductive group from the inductive
declaration and reject any exported recursor that is not one of them; here that
fails on the name (rogue is not False.rec) as well as on the type. A
checker that instead registers exported recursors as given ends up with an
inhabitant of the genuine empty type.
This is a different gap from bugs/nat-rec-rules, which perturbs the rules of a
legitimate recursor: here an entire recursor constant is fabricated, so
validating only the rules of the recursors one expects does not catch it.
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 19.3 M · max rss memory: 18.1 MB
stderr:
con-leche: invalid: recursor rogue declares 0 motives; the block has 1 inductive types (--verified)
Test "other/level-index-out-of-order"
Expected: 👍 accept · Size: 328 B · Lines: 6 · lean4export: 0.1.0 · Lean: 4.29.1 · 📄 Declaration
Lean4export will create internalization-table references contiguously in
order: in references for names, il references for levels, and ie
references for expressions all work this way.
However, the spec merely requires that these are integers. It's reasonable for an implementation to assume these are approximately dense (and to treat them as array indices instead of hashtable entries), but a kernel should handle skipped indices or out-of-order indices.
This test checks that the kernel doesn't require internaliation-table
references to be presented in ascending order. If the level referenes 2 and
1 were swapped, this would be the expected encoding of axiom foo : Sort 2.
This encoding should be equivalent.
Test result: 🚫 declined · exit code 2 · wall time: 26 ms · instructions: 22.5 M · max rss memory: 20.5 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (3 still running, not counted): 0.001s wall, 4 workers + the commit thread, 5 records, busy 0.000s (2.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s inductive False (#3); 0.000s quot Quot.lift (#6); 0.000s inductive Empty (#2) con-leche: stats: peak RSS 0.02 GiB con-leche: not implemented yet: non-standard axiom (foo) [at axiom foo, fold position 11] (--verified) t=0.0s
Test "other/nat-lit-add"
Expected: 👍 accept · Size: 26.0 KB · Lines: 478 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The kernel's Nat extension reduces Nat.add applied to two literals to a
literal, instead of unfolding the numerals to Nat.succ chains. The
arguments here are large enough that unfolding is not a practical
alternative, so a checker that only implements natLitEq-style
literal↔succ conversion will not get this for free.
Exported as natAddLit : Nat.add 123456789 987654321 = 1111111110 := rfl.
The application is Nat.add on .lits (not HAdd/OfNat).
Test result: 👍 accepted · exit code 0 · wall time: 24 ms · instructions: 31.6 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 16 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 25 records, busy 0.002s (25.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (9.2%) con-leche: stats: slowest installs: 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s def Nat.add (#19); 0.000s inductive PProd (#12); 0.000s inductive OfNat (#20) con-leche: stats: check pool: 0.000s wall, 4 workers, 10 records, busy 0.000s (35.2%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (26.3%) con-leche: stats: slowest checks: 0.000s definition Nat.brecOn.go (#14); 0.000s theorem natAddLit (#24); 0.000s definition Nat.casesOn (#16); 0.000s definition Nat.below (#13); 0.000s definition Nat.add._f (#18) con-leche: stats: peak RSS 0.02 GiB
Test "other/nat-lit-add-bad"
Expected: ✋ reject · Size: 25.3 KB · Lines: 465 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The claimed result of Nat.add on two literals does not match the
kernel's literal arithmetic:
natAddLitBad : Nat.add 123456789 987654321 = 1111111111
:= Eq.refl (Nat.add 123456789 987654321)
The value is well-typed as @Eq Nat (Nat.add …) (Nat.add …) and is
injected with debug.skipKernelTC. A sound checker must reject the
declaration type mismatch against the claimed = 1111111111.
Test result: ✋ rejected · exit code 1 · wall time: 27 ms · instructions: 31.4 M · max rss memory: 22.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 24 records, busy 0.003s (26.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (8.4%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PUnit (#11); 0.000s def Nat.add (#19); 0.000s inductive PProd (#12); 0.000s inductive OfNat (#20) con-leche: stats: check pool: 0.001s wall, 4 workers, 9 records, busy 0.001s (32.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (13.1%) con-leche: stats: slowest checks: 0.000s definition Nat.brecOn.go (#14); 0.000s theorem natAddLitBad (#23); 0.000s definition Nat.below (#13); 0.000s definition Nat.add._f (#18); 0.000s definition Nat.add.match_1 (#17) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem natAddLitBad [at theorem natAddLitBad, fold position 23] (--verified) t=0.0s
Test "other/nat-lit-ble"
Expected: 👍 accept · Size: 28.8 KB · Lines: 520 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Nat.ble on two literals reduces to a Bool constructor:
Nat.ble 1000000 1000001 = true. Same Nat-literal extension as
nat-lit-add; the result is Bool rather than Nat.
Test result: 👍 accepted · exit code 0 · wall time: 26 ms · instructions: 32.2 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 17 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 25 records, busy 0.003s (24.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (9.4%) con-leche: stats: slowest installs: 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s def Nat.ble (#19); 0.000s inductive OfNat (#20); 0.000s inductive PProd (#12) con-leche: stats: check pool: 0.000s wall, 4 workers, 10 records, busy 0.001s (35.6%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (41.5%) con-leche: stats: slowest checks: 0.000s definition Nat.brecOn.go (#14); 0.000s definition Nat.casesOn (#16); 0.000s definition Nat.below (#13); 0.000s definition Nat.ble._f (#18); 0.000s definition Nat.brecOn (#15) con-leche: stats: peak RSS 0.02 GiB
Test "other/nat-lit-sub"
Expected: 👍 accept · Size: 30.0 KB · Lines: 561 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Nat.sub on two literals truncates at zero: Nat.sub 1000000 1000001 = 0.
Same Nat-literal extension as nat-lit-add; the numerals are large enough
that unfolding Nat.sub to a Nat.succ recursor is not a practical path.
Test result: 👍 accepted · exit code 0 · wall time: 29 ms · instructions: 33.2 M · max rss memory: 23.1 MB
stdout:
con-leche: accepted 20 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 29 records, busy 0.002s (25.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (9.6%) con-leche: stats: slowest installs: 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s inductive PProd (#12); 0.000s def Nat.pred (#24); 0.000s def Nat.sub (#26) con-leche: stats: check pool: 0.001s wall, 4 workers, 13 records, busy 0.002s (51.3%); tail 0.000s after the last start, 4 busy then, 0.001s worker-time in it (55.9%) con-leche: stats: slowest checks: 0.000s definition Nat.mul.match_1 (#20); 0.000s definition Nat.pow.match_1 (#23); 0.000s definition Nat.brecOn.go (#14); 0.000s definition Nat.brecOn (#15); 0.000s definition Nat.sub._f (#25) con-leche: stats: peak RSS 0.02 GiB
Test "other/orphan-ctor"
Expected: ✋ reject · Size: 1.4 KB · Lines: 22 · lean4export: 3.1.0 · Lean: 4.29.1 · 📄 Declaration
Proof of False from a constructor of an inductive type that does not exist.
The export contains False exactly as the prelude has it — an empty
Prop-valued inductive with no constructors, its ctors field is the empty
list — together with its ordinary False.rec. Smuggled into the same
inductive block is a constructor named rogue, of type False, with no
parameters and no fields, whose induct field names Orphan, a name for
which the export has no declaration at all. The theorem inconsistent : False
is then simply rogue.
A checker must derive the constructors of an inductive group from the
inductive declarations and reject any exported constructor that is not one of
them; here that fails because False has no constructors, and the inductive
type rogue claims to come from does not exist. A checker that instead
registers exported constructors as given — or that only checks constructors
whose induct field points at a declaration it knows — ends up with an
inhabitant of the genuine empty type.
This is the constructor-side counterpart of bugs/orphan-rec: in both cases the
bogus declaration escapes by not being attached to any inductive declaration
that the checker verifies, rather than by disagreeing with one.
Test result: ✋ rejected · exit code 1 · wall time: 17 ms · instructions: 19.3 M · max rss memory: 18.0 MB
stderr:
con-leche: invalid: the inductive block lists 0 constructors and carries 1 constructor records (--verified)
Test "other/proj-of-prop"
Expected: ✋ reject · Size: 3.9 KB · Lines: 56 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A proof of False via a projection from a Prop-typed structure whose
constructor was applied to an ill-typed argument. The exported term is
badFalse : False := (Wrapper.mk True.intro).p
where Wrapper : Prop has a single field p : False, so Wrapper.mk
expects a proof of False but is given True.intro : True.
A sound checker must reject this. A checker that types a projection by
inferring (rather than checking) its structure argument — i.e. that
trusts the structure to be well-typed instead of verifying the
constructor's argument types against its binders — will accept it,
because Wrapper.mk True.intro still formally inhabits Wrapper at
the structural level, and the p projection is then read back out at
the declared field type False.
Test result: ✋ rejected · exit code 1 · wall time: 26 ms · instructions: 23.8 M · max rss memory: 21.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 14 records, busy 0.002s (17.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (3.1%) con-leche: stats: slowest installs: 0.001s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Wrapper (#11); 0.000s inductive Eq (#0); 0.000s inductive True (#12) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (41.3%) con-leche: stats: slowest checks: 0.000s theorem badFalse (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: application type mismatch [at theorem badFalse, fold position 13] (--verified) t=0.0s
Test "other/sparse-name-index"
Expected: 👍 accept · Size: 292 B · Lines: 4 · lean4export: 0.1.0 · Lean: 4.29.1 · 📄 Declaration
Lean4export will create internalization-table references contiguously in
order: in references for names, il references for levels, and ie
references for expressions all work this way.
However, the spec merely requires that these are integers. It's reasonable for an implementation to assume these are approximately dense (and to treat them as array indices instead of hashtable entries), but a kernel should handle skipped indices or out-of-order indices.
This test checks that a kernel doesn't require internalization-table
references to be assigned sequentially starting from 1. If the "2" and "4"
were replaced by "1" and "0", respectively, this would be the expected
encoding of axiom foo : Prop. This encoding should be equivalent.
Test result: 🚫 declined · exit code 2 · wall time: 28 ms · instructions: 22.5 M · max rss memory: 20.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (1 still running, not counted): 0.001s wall, 4 workers + the commit thread, 10 records, busy 0.001s (18.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.1%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s axiom foo (#11); 0.000s inductive False (#3) con-leche: stats: peak RSS 0.02 GiB con-leche: not implemented yet: non-standard axiom (foo) [at axiom foo, fold position 11] (--verified) t=0.0s
Test "perf/app-lam"
Expected: 👍 accept · Size: 1.2 MB · Lines: 28.6 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A synthetically generated term with n levels of alternating applications and lambdas, with DAG sharing.
At each level, a constant is applied to two identical lambda arguments. The export format records these as a single shared expression (DAG). Each lambda body grows with the nesting depth, referencing all enclosing binders.
This tests two aspects of checker performance:
Infer cache: Since both arguments at each level are the same expression, a checker without an infer cache re-infers the type of each shared subterm, doubling work at every level — O(2ⁿ) total.
Substitution cost: Even with a cache, type-inferring each lambda requires substituting into its body (size O(n)) at each of the n levels, giving O(n²) total. Whether this cost arises depends on the checker's binder representation.
Test result: 👍 accepted · exit code 0 · wall time: 5.1 s · instructions: 24.4 G · max rss memory: 1.2 GB
stdout:
con-leche: accepted 22 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 5.0s con-leche: stats: install pool: 0.013s wall, 4 workers + the commit thread, 32 records, busy 0.014s (21.7%); tail 0.010s after the last start, 1 busy then, 0.010s worker-time in it (19.8%) con-leche: stats: slowest installs: 0.010s def dag_app_binder (#31); 0.001s inductive HAdd (#12); 0.001s inductive And (#9); 0.000s def Nat.add (#25); 0.000s inductive OfNat (#27) con-leche: stats: check pool: 5.026s wall, 4 workers, 15 records, busy 5.026s (25.0%); tail 5.025s after the last start, 4 busy then, 5.025s worker-time in it (24.9%) con-leche: stats: slowest checks: 5.025s definition dag_app_binder (#31); 0.000s definition Nat.add._f (#24); 0.000s definition Nat.brecOn.go (#20); 0.000s definition instHAdd (#16); 0.000s definition HAdd.hAdd (#13) con-leche: stats: peak RSS 1.22 GiB
Test "perf/args-before-unfold"
Expected: 👍 accept · Size: 44.5 KB · Lines: 1.2 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
count #n and count (N.add #(n-1) #1)
where #k is the numeral with k successors, and count #k evaluates to #k
in Θ(k²) reductions.
N.add #(n-1) #1 reduces to #n in n steps, so the two arguments agree for
Θ(n), and the applications agree with them without count ever being
unfolded. Evaluating both applications costs Θ(n²). The test asks whether
a checker tries the arguments of a shared head constant before unfolding it.
N=1000 in the Lean source. From Courant and Leroy, POPL 2026, §10.
Test result: 👍 accepted · exit code 0 · wall time: 32 ms · instructions: 85.9 M · max rss memory: 24.2 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.001s (33.7%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (37.5%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s theorem kernel_args_before_unfold (#14); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.008s wall, 3 workers, 3 records, busy 0.008s (32.8%); tail 0.008s after the last start, 3 busy then, 0.008s worker-time in it (33.2%) con-leche: stats: slowest checks: 0.008s theorem kernel_args_before_unfold (#14); 0.000s definition N.add (#12); 0.000s definition count (#13) con-leche: stats: peak RSS 0.02 GiB
Test "perf/beta-ladder"
Expected: 👍 accept · Size: 450.6 KB · Lines: 10.4 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check reduces
(fun x₁ => … (fun xₙ => x₁ + (x₂ + (… + (xₙ + 0)))) 0 …) 0
to 0, through n beta redexes over a body that reads every binder.
Reducing the ladder takes n beta steps whatever a checker does, so the test is what one step costs. Substituting into the body on entry to binder k copies the n − k redexes still below it, and those copies sum to Θ(n²). Carrying the substitution in an environment leaves the body untouched, for Θ(n).
N=2000 in the Lean source.
Test result: 👍 accepted · exit code 0 · wall time: 701 ms · instructions: 5.4 G · max rss memory: 393.9 MB
stdout:
con-leche: accepted 12 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.6s con-leche: stats: install pool: 0.004s wall, 4 workers + the commit thread, 21 records, busy 0.005s (24.1%); tail 0.002s after the last start, 1 busy then, 0.002s worker-time in it (19.5%) con-leche: stats: slowest installs: 0.002s theorem beta_ladder (#20); 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s def Nat.add (#19); 0.000s inductive PProd (#12) con-leche: stats: check pool: 0.659s wall, 4 workers, 7 records, busy 0.660s (25.0%); tail 0.659s after the last start, 4 busy then, 0.659s worker-time in it (25.0%) con-leche: stats: slowest checks: 0.658s theorem beta_ladder (#20); 0.000s definition Nat.brecOn.go (#14); 0.000s definition Nat.below (#13); 0.000s definition Nat.brecOn (#15); 0.000s definition Nat.add._f (#18) con-leche: stats: peak RSS 0.38 GiB
Test "perf/church-numerals"
Expected: 👍 accept · Size: 9.6 KB · Lines: 227 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
cmul (cnum n) (cnum (n+1)) and cmul (cnum (n+1)) (cnum n)
where cnum k is the Church numeral fun X s z => s (s (... z)) and
cmul a b iterates b as many times as a counts.
Both sides have the normal form with n(n+1) applications of the bound s.
Unfolding cmul on the left leaves cnum n X (cnum (n+1) X s), where each of
the n occurrences of the bound function copies the redex cnum (n+1) X s, so
the normal form takes n(n+1) beta steps and shares nothing. No other delta
step is available, so the Θ(n²) measured is beta reduction under binders
and little else.
N=120 in the Lean source, giving a reduction depth of 14520. From the
conv_eval benchmark of András Kovács' smalltt.
Test result: 👍 accepted · exit code 0 · wall time: 116 ms · instructions: 319.7 M · max rss memory: 46.1 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 14 records, busy 0.001s (17.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.6%) con-leche: stats: slowest installs: 0.001s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s def CNat (#11) con-leche: stats: check pool: 0.087s wall, 3 workers, 3 records, busy 0.086s (33.1%); tail 0.086s after the last start, 3 busy then, 0.086s worker-time in it (33.2%) con-leche: stats: slowest checks: 0.086s theorem kernel_church_numerals (#13); 0.000s definition cmul (#12); 0.000s definition CNat (#11) con-leche: stats: peak RSS 0.04 GiB
Test "perf/discarded-argument"
Expected: 👍 accept · Size: 15.9 KB · Lines: 367 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
dropArg (count #n) and dropArg (count #(n+1))
where count #k evaluates to the numeral #k in Θ(k²) reductions, and
dropArg maps every numeral to N.O.
Unfolding dropArg leaves N.O against N.O, for Θ(1). Comparing the
arguments first evaluates two numerals of different value, for Θ(n²), and
then throws that answer away. The test asks whether a checker unfolds a
constant before looking at an argument the constant never uses.
N=200 in the Lean source. From Courant and Leroy, POPL 2026, §10.
Test result: 👍 accepted · exit code 0 · wall time: 49 ms · instructions: 79.0 M · max rss memory: 25.1 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 16 records, busy 0.001s (29.2%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (22.8%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s theorem kernel_discarded_argument (#15) con-leche: stats: check pool: 0.008s wall, 4 workers, 4 records, busy 0.008s (24.4%); tail 0.008s after the last start, 3 busy then, 0.008s worker-time in it (25.0%) con-leche: stats: slowest checks: 0.007s theorem kernel_discarded_argument (#15); 0.000s definition count (#14); 0.000s definition N.add (#13); 0.000s definition dropArg (#12) con-leche: stats: peak RSS 0.02 GiB
Test "perf/discarded-argument-match"
Expected: 👍 accept · Size: 29.2 KB · Lines: 606 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
discarded-argument.lean with count and N.add written by structural
recursion, so the declaration to check is the same
dropArg (count #n) and dropArg (count #(n+1))
over definitions that unfold through brecOn rather than through N.rec.
brecOn reduces via the course-of-values table
N.below #k = m #(k-1) ×' (m #(k-2) ×' (… ×' PUnit)), a k-deep tuple holding
the result at every predecessor. The compiled count reads only x.1, so
the rest of the table is built and never read, and typing each projection
forces N.below to the depth of that projection.
N=200 in the Lean source, matching its pair.
Test result: 👍 accepted · exit code 0 · wall time: 64 ms · instructions: 224.9 M · max rss memory: 25.3 MB
stdout:
con-leche: accepted 17 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 27 records, busy 0.002s (29.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (15.7%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive PProd (#14); 0.000s inductive Bool (#10); 0.000s inductive PUnit (#13) con-leche: stats: check pool: 0.037s wall, 4 workers, 13 records, busy 0.037s (25.3%); tail 0.036s after the last start, 4 busy then, 0.036s worker-time in it (24.9%) con-leche: stats: slowest checks: 0.036s theorem kernel_discarded_argument_match (#26); 0.000s definition N.brecOn.go (#16); 0.000s definition N.add.match_1 (#21); 0.000s definition N.add._f (#22); 0.000s definition N.below (#15) con-leche: stats: peak RSS 0.02 GiB
Test "perf/folded-constant-first"
Expected: 👍 accept · Size: 52.0 KB · Lines: 1.3 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
tagged (count #n) and (false, count #n)
where tagged m = (isZero m, m), so unfolding the left side leaves the same
application count #n in both components, forced by isZero in one and
plain in the other.
The plain occurrences are identical, for Θ(1); the forced one evaluates
count #n once. The order matters for a checker that leaves a constant
unfolded once it reduces it: reducing the forced component first replaces
count #n by its value on one side, and the plain comparison then faces a
folded application against an evaluated one. Here the forcing component
comes first; folded-constant-last.lean swaps them, and the ratio between
the two files is what that costs.
N=1000 in the Lean source. From Courant and Leroy, POPL 2026, §10, where the two orders cost Rocq 3 × 10⁻⁵ s and 0.078 s.
Test result: 👍 accepted · exit code 0 · wall time: 46 ms · instructions: 118.1 M · max rss memory: 24.4 MB
stdout:
con-leche: accepted 9 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.003s wall, 4 workers + the commit thread, 18 records, busy 0.003s (21.3%); tail 0.001s after the last start, 1 busy then, 0.001s worker-time in it (19.5%) con-leche: stats: slowest installs: 0.001s theorem kernel_folded_constant_first (#17); 0.001s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive N (#12); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.020s wall, 4 workers, 5 records, busy 0.020s (24.5%); tail 0.019s after the last start, 4 busy then, 0.019s worker-time in it (24.9%) con-leche: stats: slowest checks: 0.019s theorem kernel_folded_constant_first (#17); 0.000s definition isZero (#13); 0.000s definition count (#16); 0.000s definition tagged (#14); 0.000s definition N.add (#15) con-leche: stats: peak RSS 0.02 GiB
Test "perf/folded-constant-last"
Expected: 👍 accept · Size: 51.0 KB · Lines: 1.3 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
tagged (count #n) and (count #n, false)
where tagged m = (m, isZero m): folded-constant-first.lean with the
components swapped, so the plain occurrences of count #n are compared
before anything forces the application.
N=1000 in the Lean source. From Courant and Leroy, POPL 2026, §10.
Test result: 👍 accepted · exit code 0 · wall time: 49 ms · instructions: 117.8 M · max rss memory: 24.6 MB
stdout:
con-leche: accepted 9 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 18 records, busy 0.001s (17.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.4%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s theorem kernel_folded_constant_last (#17); 0.000s inductive Prod (#11); 0.000s inductive Bool (#10); 0.000s inductive N (#12) con-leche: stats: check pool: 0.019s wall, 4 workers, 5 records, busy 0.019s (25.0%); tail 0.018s after the last start, 3 busy then, 0.018s worker-time in it (24.9%) con-leche: stats: slowest checks: 0.018s theorem kernel_folded_constant_last (#17); 0.000s definition tagged (#14); 0.000s definition isZero (#13); 0.000s definition N.add (#15); 0.000s definition count (#16) con-leche: stats: peak RSS 0.02 GiB
Test "perf/fueled-chain"
Expected: 👍 accept · Size: 848.6 KB · Lines: 17.3 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Distilled from con-leche's fuel-bridge (_datF) lemmas, the declarations on
which nanobruijn times out on the con-leche test.
Fueled α packages a fuel-indexed family p : Nat → Except Unit α with a
proof whose type mentions p twice under binders. A _datF lemma states that
running a monadic function in Fueled and extracting at fuel F equals
running it in Except Unit, proved by unfolding and rewriting with the atF
lemmas for bind/pure/throw/ite. What is left for the kernel is a
definitional equality between two monadic programs that differ only in the
monad instance, under one binder per bind and a do-notation join point
per unless … throw guard.
chainN (N = 6, 9, 12) has N binds, each followed by a guard. A checker
that recognises the unfolded and the literal program as equal outright is
fast (nanoda: 2 ms, 18 ms, 32 ms); one that compares them structurally
unfolds bind to Subtype.mk p h and, through proof irrelevance on the
hs, re-compares the rest of the program twice per guard
(nanobruijn: 19 ms, 4.1 s, 256 s). Without the guards it is cheap for both.
Test result: 👍 accepted · exit code 0 · wall time: 77 ms · instructions: 422.6 M · max rss memory: 45.5 MB
stdout:
con-leche: accepted 143 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.006s wall, 4 workers + the commit thread, 145 records, busy 0.012s (36.7%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (6.6%) con-leche: stats: slowest installs: 0.001s def Bool.casesOn (#67); 0.001s inductive Iff (#128); 0.001s inductive Except (#11); 0.000s inductive And (#9); 0.000s inductive MonadExceptOf (#26) con-leche: stats: check pool: 0.022s wall, 4 workers, 109 records, busy 0.056s (61.3%); tail 0.019s after the last start, 4 busy then, 0.043s worker-time in it (56.7%) con-leche: stats: slowest checks: 0.018s theorem chain12_datF (#144); 0.013s theorem chain6_datF (#140); 0.012s theorem chain9_datF (#142); 0.000s definition Except.map.match_1 (#90); 0.000s theorem lift_atF (#124) con-leche: stats: peak RSS 0.04 GiB
Test "perf/grind-ring-5"
Expected: 👍 accept · Size: 9.8 MB · Lines: 200.3 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A grind tactic test from the Lean 4 test suite.
This produces a theorem with a rather large proof term that needs fast reduction.
Test result: 👍 accepted · exit code 0 · wall time: 6.1 s · instructions: 26.0 G · max rss memory: 179.5 MB
stdout:
con-leche: accepted 2273 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.9s, check 5.0s con-leche: stats: install pool: 0.928s wall, 4 workers + the commit thread, 2274 records, busy 1.487s (32.0%); tail 0.002s after the last start, 4 busy then, 0.000s worker-time in it (0.3%) con-leche: stats: slowest installs: 0.766s def Nat.land (#795); 0.155s def Lean.Grind.Semiring.ofNat_succ._autoParam (#309); 0.150s def Lean.Grind.Ring.zsmul_natCast_eq_nsmul._autoParam (#334); 0.104s def Classical.propDecidable.match_1 (#386); 0.089s def Nat.mod (#216) con-leche: stats: check pool: 5.046s wall, 4 workers, 2149 records, busy 5.696s (28.2%); tail 4.830s after the last start, 4 busy then, 4.836s worker-time in it (25.0%) con-leche: stats: slowest checks: 4.830s theorem _private.Test.0.thm._proof_1_1 (#2272); 0.035s theorem _private.Init.Grind.Ring.Basic.0.Lean.Grind.Ring.intCast_nat_sub._proof_1_2 (#1492); 0.024s theorem _private.Init.Data.Nat.Div.Lemmas.0.Nat.div_le_iff_le_mul._proof_1_1 (#1634); 0.018s theorem _private.Init.Data.Nat.Div.Lemmas.0.Nat.lt_of_div_eq_zero._proof_1_1 (#1625); 0.018s theorem _private.Init.Grind.Ring.Basic.0.Lean.Grind.Ring.intCast_nat_sub._proof_1_3 (#1495) con-leche: stats: peak RSS 0.17 GiB
Test "perf/identical-nesting"
Expected: 👍 accept · Size: 8.7 KB · Lines: 172 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
f4 (f4 (... (f4 N.O) ...)) and f4 (f4 (... (f4 N.O) ...))
n applications of f4 on each side, the same term twice, where f0 is the
identity on N and each of f1, f2, f3, f4 applies its predecessor
twice, so the nesting expands into 16n applications of f0.
The test asks whether a checker compares the two sides before it starts unfolding, which answers in Θ(n). Unfolding one side at a time offers 16n applications to choose from per side, and the reachable pairs of partially unfolded sides grow exponentially in n.
N=30 in the Lean source. From Courant and Leroy, POPL 2026, §10.
Test result: 👍 accepted · exit code 0 · wall time: 31 ms · instructions: 24.9 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 8 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 18 records, busy 0.002s (18.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (7.1%) con-leche: stats: slowest installs: 0.001s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive N (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 4 workers, 6 records, busy 0.000s (10.8%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (11.6%) con-leche: stats: slowest checks: 0.000s definition f1 (#13); 0.000s theorem kernel_identical_nesting (#17); 0.000s definition f3 (#15); 0.000s definition f0 (#12); 0.000s definition f2 (#14) con-leche: stats: peak RSS 0.02 GiB
Test "perf/irrelevance-before-evaluation"
Expected: 👍 accept · Size: 17.5 KB · Lines: 388 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check is
slowTriv (count #n) = True.intro
proved by Eq.refl, where slowTriv m : True recurses over m, so forcing
it to a constructor evaluates the numeral in Θ(n²) reductions.
Checking compares the two proofs as arguments of Eq, whose head is rigid:
nothing can be unfolded instead. Proof irrelevance settles the proofs by
their type for Θ(1); evaluating the left one to a constructor costs
Θ(n²) and yields the answer irrelevance already gave. The test asks
whether a checker consults proof irrelevance before it reduces.
N=200 in the Lean source.
Test result: 👍 accepted · exit code 0 · wall time: 31 ms · instructions: 28.1 M · max rss memory: 21.4 MB
stdout:
con-leche: accepted 7 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 17 records, busy 0.001s (24.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.2%) con-leche: stats: slowest installs: 0.000s inductive True (#11); 0.000s inductive And (#9); 0.000s inductive N (#12); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 4 workers, 4 records, busy 0.000s (22.7%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (30.7%) con-leche: stats: slowest checks: 0.000s theorem kernel_irrelevance_before_evaluation (#16); 0.000s definition count (#15); 0.000s definition slowTriv (#13); 0.000s definition N.add (#14) con-leche: stats: peak RSS 0.02 GiB
Test "perf/irrelevance-refutes"
Expected: 👍 accept · Size: 13.1 KB · Lines: 244 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check is
f 100000 (slowRefl 100000) = f 100001 (slowRefl 100001)
proved by rfl, where f ignores its arguments and slowRefl m : m = m
is a Nat.rec over m, so unfolding it to rfl takes Θ(m) steps.
Both sides apply f, so a checker may first compare the arguments, find
them different, and then unfold f. Comparing the literals refutes for
Θ(1). Comparing the proofs, proof irrelevance refutes them by their
types, 100000 = 100000 against 100001 = 100001, also for Θ(1): two
proofs of propositions that are not defeq are not defeq. A checker that
takes only proof irrelevance's positive answer, and otherwise unfolds the
proofs, evaluates both recursions for Θ(m).
Official reaches the proofs first. f is a regular definition at the head
of both sides, so lazy_delta_reduction_step tries the arguments before
unfolding it, and is_def_eq_args compares them last to first. (The
congruence fallback at the end of is_def_eq_core, is_def_eq_app,
compares first to last, but it is not reached here.) For the proofs,
is_def_eq_core stops on is_def_eq_proof_irrel's l_false.
Distilled from decide +kernel on Rat arithmetic, e.g.
(1 : Rat) / 1000000000 * ((1000000 : Int) : Rat) = 1 / 1000, where the
proofs are Nat.gcd_dvd terms by well-founded recursion and the
comparison that reaches them is of Int.divExact's arguments, last to first.
Test result: 👍 accepted · exit code 0 · wall time: 30 ms · instructions: 25.8 M · max rss memory: 20.8 MB
stdout:
con-leche: accepted 9 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 18 records, busy 0.001s (18.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (7.1%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive OfNat (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def OfNat.ofNat (#12) con-leche: stats: check pool: 0.001s wall, 4 workers, 6 records, busy 0.000s (16.5%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (35.2%) con-leche: stats: slowest checks: 0.000s theorem irrelevance_refutes (#17); 0.000s definition f (#14); 0.000s definition slowRefl (#16); 0.000s definition OfNat.ofNat (#12); 0.000s definition instOfNatNat (#13) con-leche: stats: peak RSS 0.02 GiB
Test "perf/let-fold"
Expected: 👍 accept · Size: 316.9 KB · Lines: 6.0 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check is
let d := bits #n 0; (rfl : d + 0 = Nat.add d 0)
where bits #n 0 is a closed Nat whose evaluation makes 2^n recursive
calls, and the rfl is wrapped in id so that its type is compared with
d + 0 = Nat.add d 0 inside the body of the let.
The two sides differ only in how the addition is written. Unfolding
HAdd.hAdd turns the left side into the right, for Θ(1). But both sides
are additions of literals to a closed term, so a checker that folds closed
Nat arithmetic (Nat.add on literals via GMP) will try to evaluate d
first, for Θ(2^n). The official kernel only folds terms without free
variables, and it checks the body of a let with d as a free variable
(bound to its value in the local context), so it never evaluates bits. A
checker that substitutes the value for d before checking the body makes
the comparison closed and pays for the evaluation.
Found by con-leche on openai/math (SquareDifference,
OAI.SquareDifference.source_ordered_contraction), where the bound value is
Fintype.card TupleVertex, whose evaluation enumerates permutations and
takes the checker past 6 GB; the official kernel checks that declaration in
16 ms.
N=16 in the Lean source.
Test result: 👍 accepted · exit code 0 · wall time: 5.5 s · instructions: 15.2 G · max rss memory: 351.4 MB
stdout:
con-leche: accepted 156 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 5.3s con-leche: stats: install pool: 0.087s wall, 4 workers + the commit thread, 162 records, busy 0.093s (21.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (2.4%) con-leche: stats: slowest installs: 0.082s def Nat.mod (#149); 0.000s inductive Mul (#153); 0.000s inductive HMul (#151); 0.000s inductive And (#9); 0.000s inductive LT (#98) con-leche: stats: check pool: 5.398s wall, 4 workers, 126 records, busy 5.408s (25.0%); tail 5.394s after the last start, 4 busy then, 5.394s worker-time in it (24.9%) con-leche: stats: slowest checks: 5.393s theorem kernel_let_fold (#161); 0.000s definition _private.Init.Prelude.0.Nat.le_trans.match_1_10 (#117); 0.000s definition _private.Init.Prelude.0.Nat.succ_le_succ.match_1_7 (#83); 0.000s definition _private.Init.Prelude.0.Nat.ble_eq_true_of_le.match_1_7 (#88); 0.000s theorem Nat.succ_sub_succ_eq_sub (#139) con-leche: stats: peak RSS 0.34 GiB
Test "perf/let-ladder"
Expected: 👍 accept · Size: 457.6 KB · Lines: 10.4 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check has type Nat and value
let x₃ := 0; x₃ + (let x₂ := 0; x₂ + (let x₁ := 0; x₁ + (x₃ + (x₂ + (x₁ + 0)))))
shown at n=3: n let bindings, each separated from the next by an addition,
over an innermost sum that names every binding.
Substituting a binding into the body before checking it traverses O(n) nodes at each of the n bindings, for Θ(n²) in time and in allocated nodes. Recording the binding and reading it where the body names it costs O(1) per binding, for Θ(n).
The additions are what keep the bindings apart: a run of adjacent lets could
be opened by a single substitution; not so here.
Nat.add is the only application head, so no beta reduction is involved.
N=2000 in the Lean source.
Test result: 👍 accepted · exit code 0 · wall time: 485 ms · instructions: 2.9 G · max rss memory: 225.7 MB
stdout:
con-leche: accepted 14 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.4s con-leche: stats: install pool: 0.007s wall, 4 workers + the commit thread, 24 records, busy 0.006s (18.2%); tail 0.003s after the last start, 1 busy then, 0.003s worker-time in it (18.9%) con-leche: stats: slowest installs: 0.003s def kernel_quadratic_let_ladder (#23); 0.001s inductive And (#9); 0.000s def Nat.add (#22); 0.000s inductive Bool (#10); 0.000s inductive OfNat (#11) con-leche: stats: check pool: 0.432s wall, 4 workers, 9 records, busy 0.432s (24.9%); tail 0.431s after the last start, 3 busy then, 0.431s worker-time in it (24.9%) con-leche: stats: slowest checks: 0.431s definition kernel_quadratic_let_ladder (#23); 0.000s definition Nat.add.match_1 (#20); 0.000s definition Nat.brecOn.go (#17); 0.000s definition Nat.add._f (#21); 0.000s definition OfNat.ofNat (#12) con-leche: stats: peak RSS 0.22 GiB
Test "perf/magma-list-deep-n21"
Expected: 👍 accept · Size: 1.1 MB · Lines: 21.8 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Countermodel certificate for an equational-theories implication, closed by
decide. A magma on Fin 21 with an inline List operation table satisfies
x = (x ◇ x) ◇ (x ◇ (y ◇ y)) but not x = x ◇ (x ◇ x). The search space is
only 21^2 tuples, but each equation nests the operation several deep, so
every tuple expands into a chain of linear list lookups.
From a corpus of certificates generated for the SAIR math distillation
challenge (equational theories track). The small end of the deep-nesting
family; magma-list-deep-n36 is the same workload at a larger scale.
Test result: 👍 accepted · exit code 0 · wall time: 10.1 s · instructions: 24.3 G · max rss memory: 596.3 MB
stdout:
con-leche: accepted 514 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 1.1s, check 8.9s con-leche: stats: install pool: 1.133s wall, 4 workers + the commit thread, 520 records, busy 2.355s (41.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (14.7%) con-leche: stats: slowest installs: 1.002s def Nat.land (#345); 0.996s def List.get!Internal._f (#474); 0.134s def String.instInhabited (#461); 0.120s def Nat.mod (#166); 0.056s def Nat.div (#214) con-leche: stats: check pool: 8.946s wall, 4 workers, 451 records, busy 8.985s (25.1%); tail 8.932s after the last start, 4 busy then, 8.932s worker-time in it (24.9%) con-leche: stats: slowest checks: 8.932s definition countermodel (#519); 0.001s definition _private.Init.Data.Nat.Div.Basic.0.Nat.div.go.fuel_congr._f (#260); 0.001s theorem Nat.modCore_lt (#419); 0.001s theorem Nat.div_eq_ite (#262); 0.000s theorem Nat.le_trans (#135) con-leche: stats: peak RSS 0.58 GiB
Test "perf/magma-list-deep-n36"
Expected: 👍 accept · Size: 1.2 MB · Lines: 23.0 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Countermodel certificate for an equational-theories implication, closed by
decide. A magma on Fin 36 with an inline List operation table satisfies
x = y ◇ (y ◇ (x ◇ (y ◇ x))) but not x = x ◇ (x ◇ x). The search space is
only 36^2 tuples, but each side of the equation nests the operation five
deep, so every tuple expands into a long chain of linear list lookups. The
heaviest test of the magma family.
From a corpus of certificates generated for the SAIR math distillation
challenge (equational theories track). magma-list-deep-n21 is the same
workload at a smaller scale.
Test result: 👍 accepted · exit code 0 · wall time: 1.9 m · instructions: 282.0 G · max rss memory: 7.3 GB
stdout:
con-leche: accepted 514 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 1.1s, check 112.3s con-leche: stats: install pool: 1.125s wall, 4 workers + the commit thread, 520 records, busy 2.338s (41.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (19.2%) con-leche: stats: slowest installs: 0.972s def Nat.land (#345); 0.966s def List.get!Internal._f (#474); 0.155s def String.instInhabited (#461); 0.142s def Nat.mod (#166); 0.060s def Nat.div (#214) con-leche: stats: check pool: 112.330s wall, 4 workers, 451 records, busy 112.366s (25.0%); tail 112.317s after the last start, 4 busy then, 112.317s worker-time in it (25.0%) con-leche: stats: slowest checks: 112.317s definition countermodel (#519); 0.001s theorem Nat.modCore_lt (#419); 0.001s definition _private.Init.Data.Nat.Div.Basic.0.Nat.div.go.fuel_congr._f (#260); 0.001s theorem Nat.div_eq_ite (#262); 0.000s definition Nat.decidableBallLT._f (#508) con-leche: stats: peak RSS 7.34 GiB
Test "perf/magma-list-pair-n21"
Expected: 👍 accept · Size: 583.1 KB · Lines: 11.0 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Countermodel certificate for an equational-theories implication, closed by
decide. A magma on Fin 21 with an inline List operation table satisfies
x ◇ y = z ◇ w but not x = x ◇ x. Checking the certificate evaluates the
decidable instance over all 21^4 ≈ 195k four-tuples; every ◇ unfolds to a
linear lookup into the list. The widest search space of the magma family.
From a corpus of certificates generated for the SAIR math distillation
challenge (equational theories track). magma-list-pair-n7 is the same
workload at a smaller scale.
Test result: 👍 accepted · exit code 0 · wall time: 38.7 s · instructions: 186.8 G · max rss memory: 5.1 GB
stdout:
con-leche: accepted 276 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 38.5s con-leche: stats: install pool: 0.036s wall, 4 workers + the commit thread, 282 records, busy 0.042s (23.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (15.1%) con-leche: stats: slowest installs: 0.033s def Nat.mod (#151); 0.000s inductive Exists (#11); 0.000s inductive Nat.le.below (#73); 0.000s inductive Mod (#157); 0.000s inductive And (#9) con-leche: stats: check pool: 38.579s wall, 4 workers, 240 records, busy 38.592s (25.0%); tail 38.575s after the last start, 4 busy then, 38.575s worker-time in it (25.0%) con-leche: stats: slowest checks: 38.575s definition countermodel (#281); 0.000s theorem Nat.modCore_lt (#186); 0.000s theorem Nat.modCoreGo_lt (#185); 0.000s definition _private.Init.Prelude.0.Nat.ble_eq_true_of_le.match_1_7 (#94); 0.000s theorem Nat.succ_sub_succ_eq_sub (#141) con-leche: stats: peak RSS 5.11 GiB
Test "perf/magma-list-pair-n7"
Expected: 👍 accept · Size: 583.6 KB · Lines: 11.0 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Countermodel certificate for an equational-theories implication, closed by
decide. A magma on Fin 7 with an inline List operation table satisfies
x ◇ y = z ◇ (w ◇ u) but not x = x ◇ x. Checking the certificate evaluates
the decidable instance over all 7^5 ≈ 17k five-tuples; every ◇ unfolds to
a linear lookup into the list.
From a corpus of certificates generated for the SAIR math distillation
challenge (equational theories track). The small end of the list-table
family; magma-list-pair-n21 is the same workload at a larger scale.
Test result: 👍 accepted · exit code 0 · wall time: 2.8 s · instructions: 17.0 G · max rss memory: 475.8 MB
stdout:
con-leche: accepted 276 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 2.7s con-leche: stats: install pool: 0.040s wall, 4 workers + the commit thread, 282 records, busy 0.045s (22.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (3.9%) con-leche: stats: slowest installs: 0.036s def Nat.mod (#151); 0.000s inductive Exists (#11); 0.000s inductive Nat.le.below (#73); 0.000s inductive Mod (#157); 0.000s inductive NeZero (#257) con-leche: stats: check pool: 2.724s wall, 4 workers, 240 records, busy 2.738s (25.1%); tail 2.720s after the last start, 4 busy then, 2.720s worker-time in it (25.0%) con-leche: stats: slowest checks: 2.720s definition countermodel (#281); 0.000s theorem Nat.modCore_lt (#186); 0.000s definition _private.Init.Prelude.0.Nat.le_trans.match_1_10 (#119); 0.000s definition _private.Init.Prelude.0.Nat.succ_le_succ.match_1_7 (#79); 0.000s theorem Nat.succ_sub_succ_eq_sub (#141) con-leche: stats: peak RSS 0.46 GiB
Test "perf/magma-string-n4"
Expected: 👍 accept · Size: 16.5 MB · Lines: 344.3 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Countermodel certificate for an equational-theories implication, closed by
decide. A magma on Fin 4 with the operation table encoded as a String
satisfies x ◇ x = y ◇ ((x ◇ (y ◇ z)) ◇ z) but not
x ◇ x = x ◇ (((y ◇ x) ◇ y) ◇ z). The smallest magma of the family (4^3
tuples); the cost is dominated by decoding each table entry out of the
string on every lookup.
From a corpus of certificates generated for the SAIR math distillation
challenge (equational theories track). The small end of the string-table
family; magma-string-pair-n9 is the same workload at a larger scale.
Test result: 👍 accepted · exit code 0 · wall time: 1.2 s · instructions: 31.0 G · max rss memory: 138.0 MB
stdout:
con-leche: accepted 3268 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.4s, check 0.7s con-leche: stats: install pool: 0.467s wall, 4 workers + the commit thread, 3269 records, busy 1.687s (72.2%); tail 0.001s after the last start, 1 busy then, 0.000s worker-time in it (0.3%) con-leche: stats: slowest installs: 0.461s def Nat.lor (#961); 0.320s def Nat.land (#492); 0.311s theorem Nat.exists_testBit_ne_of_ne (#1035); 0.293s def List.get?Internal._sparseCasesOn_1 (#1667); 0.087s def ByteArray.get._auto_1 (#936) con-leche: stats: check pool: 0.727s wall, 4 workers, 3135 records, busy 2.389s (82.1%); tail 0.177s after the last start, 4 busy then, 0.192s worker-time in it (27.1%) con-leche: stats: slowest checks: 0.230s theorem _private.Init.Data.Array.Extract.0.Array.extract_append_extract._proof_1_1 (#2694); 0.181s theorem _private.Init.Data.Array.Extract.0.Array.extract_append_extract._proof_1_3 (#2701); 0.177s definition countermodel (#3268); 0.076s theorem _private.Init.Data.Array.Extract.0.Array.extract_append_extract._proof_1_2 (#2702); 0.058s theorem _private.Init.Data.Nat.Bitwise.Lemmas.0.Nat.two_pow_succ_sub_succ_div_two._proof_1_1 (#2026) con-leche: stats: peak RSS 0.13 GiB
Test "perf/magma-string-pair-n9"
Expected: 👍 accept · Size: 16.6 MB · Lines: 344.3 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Countermodel certificate for an equational-theories implication, closed by
decide. A magma on Fin 9 with the operation table encoded as a String
satisfies x ◇ y = (((z ◇ w) ◇ y) ◇ x) ◇ y but not
x ◇ y = ((z ◇ (z ◇ y)) ◇ x) ◇ y. Checking the certificate evaluates the
decidable instance over all 9^4 ≈ 6.5k four-tuples, decoding each table
entry out of the string on every lookup. The heaviest of the string-table
tests.
From a corpus of certificates generated for the SAIR math distillation
challenge (equational theories track). magma-string-n4 is the same
workload at a smaller scale.
Test result: 👍 accepted · exit code 0 · wall time: 7.8 s · instructions: 72.7 G · max rss memory: 968.2 MB
stdout:
con-leche: accepted 3268 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.4s, check 7.3s con-leche: stats: install pool: 0.443s wall, 4 workers + the commit thread, 3269 records, busy 1.627s (73.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.5%) con-leche: stats: slowest installs: 0.438s def Nat.lor (#961); 0.310s def Nat.land (#492); 0.302s theorem Nat.exists_testBit_ne_of_ne (#1035); 0.285s def List.get?Internal._sparseCasesOn_1 (#1667); 0.082s def ByteArray.get._auto_1 (#936) con-leche: stats: check pool: 7.327s wall, 4 workers, 3135 records, busy 8.912s (30.4%); tail 6.804s after the last start, 4 busy then, 6.820s worker-time in it (25.0%) con-leche: stats: slowest checks: 6.803s definition countermodel (#3268); 0.232s theorem _private.Init.Data.Array.Extract.0.Array.extract_append_extract._proof_1_1 (#2694); 0.175s theorem _private.Init.Data.Array.Extract.0.Array.extract_append_extract._proof_1_3 (#2701); 0.076s theorem _private.Init.Data.Array.Extract.0.Array.extract_append_extract._proof_1_2 (#2702); 0.042s theorem _private.Init.Data.Nat.Bitwise.Lemmas.0.Nat.two_pow_succ_sub_succ_div_two._proof_1_1 (#2026) con-leche: stats: peak RSS 0.94 GiB
Test "perf/proj-cheap-struct"
Expected: 👍 accept · Size: 85.9 KB · Lines: 1.5 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
(S u).re and (S ()).re
where u is a definition that unfolds to (), and reducing S _ to a
constructor takes Θ(N) steps (it is a foldr over List.range N, with
N = 2^17).
.re is a projection function, so both sides unfold to a primitive
projection of S u and S (). Official reduces the structure of a
projection during definitional equality only with whnf_core (no delta),
compares the two stuck projections by their structures, and finds those
equal by comparing the arguments of S. That is five unfoldings in all.
A checker that fully reduces the structure of the projection to find a
constructor evaluates S on both sides: Θ(N) steps, which runs into a
step budget smaller than N.
Distilled from a Palomar submission, where the structure is a
Finset.sum over Finset.range (2^17) under Complex.re.
Test result: 👍 accepted · exit code 0 · wall time: 16 ms · instructions: 57.5 M · max rss memory: 23.1 MB
stdout:
con-leche: accepted 57 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.003s wall, 4 workers + the commit thread, 66 records, busy 0.005s (26.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.3%) con-leche: stats: slowest installs: 0.000s def List.below (#17); 0.000s inductive HPow (#46); 0.000s inductive List (#15); 0.000s inductive PProd (#16); 0.000s inductive HAdd (#26) con-leche: stats: check pool: 0.000s wall, 4 workers, 42 records, busy 0.001s (57.8%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (27.5%) con-leche: stats: slowest checks: 0.000s definition List.brecOn.go (#18); 0.000s definition List.foldr._f (#23); 0.000s definition Nat.brecOn.go (#32); 0.000s definition List.below (#17); 0.000s definition List.casesOn (#20) con-leche: stats: peak RSS 0.02 GiB
Test "perf/proj-lazy-struct"
Expected: 👍 accept · Size: 44.9 KB · Lines: 808 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
(P (slow 100000)).1 and (Q (slow 100001)).1
where P a and Q a both unfold to (0, a), and slow n takes Θ(n)
steps to evaluate.
Official compares two projections of the same structure by lazily
unfolding their structs, and projects as soon as neither side unfolds
any further: after unfolding P and Q, it compares just the first
fields, 0 and 0. That is four unfoldings in all. A checker that
instead compares the two structs completely (here (0, slow 100000)
and (0, slow 100001)) before projecting also compares the second
fields, which differ, and does so by evaluating slow.
This is the counterpart of proj-cheap-struct, where the structs must
not be evaluated because they are equal by their arguments.
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 39.6 M · max rss memory: 23.1 MB
stdout:
con-leche: accepted 31 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.002s wall, 4 workers + the commit thread, 40 records, busy 0.002s (23.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (3.0%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s def Nat.add (#32); 0.000s inductive HAdd (#25); 0.000s inductive Add (#27) con-leche: stats: check pool: 0.000s wall, 4 workers, 22 records, busy 0.001s (51.8%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (31.2%) con-leche: stats: slowest checks: 0.000s definition Nat.brecOn.go (#20); 0.000s definition Prod.fst (#12); 0.000s definition instOfNatNat (#15); 0.000s definition P (#16); 0.000s definition OfNat.ofNat (#14) con-leche: stats: peak RSS 0.02 GiB
Test "perf/proj-stuck-struct"
Expected: 👍 accept · Size: 50.1 KB · Lines: 916 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A definitional equality under a projection whose structure argument is stuck, distilled from a fuel-bridge lemma of con-leche's own proof library, on which con-leche ran out of memory.
step c n x : Nat × Nat recurses structurally on the fuel n; for a
variable x each level is stuck on match x, and each branch reads .1
of two recursive calls. stepN checks (step (id c) N x).1 =
(step c N x).1 by rfl, the sides differing only in id c vs c.
A checker that leaves a stuck projection's structure argument alone (as
the reference kernel's whnf_core does when reduce_proj fails) compares
step (id c) N x =?= step c N x, tries the arguments first, and is done
at once. A checker that replaces it by its weak head normal form has lost
the step head and unrolls the recursion tree on both sides:
exponential in N (con-leche before the fix: 0.2 s, 2 s, 17 s and
73 MB, 0.4 GB, 2.6 GB for N = 12, 16, 20; official, nanoda, lean4lean:
~0.02 s at every N).
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 41.4 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 34 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 43 records, busy 0.001s (25.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.7%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive HAdd (#24); 0.000s def Nat.add (#31); 0.000s inductive Bool (#10) con-leche: stats: check pool: 0.000s wall, 4 workers, 25 records, busy 0.001s (51.8%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (30.3%) con-leche: stats: slowest checks: 0.000s definition step._f (#36); 0.000s definition Nat.brecOn.go (#16); 0.000s definition Nat.casesOn (#21); 0.000s definition step.match_3 (#22); 0.000s definition step.match_1 (#35) con-leche: stats: peak RSS 0.02 GiB
Test "perf/refute-cheap-first"
Expected: ✋ reject · Size: 20.7 KB · Lines: 439 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check claims
(false, count #n) = (true, count #(n+1))
and must be rejected. Both sides are constructor applications, so comparing
components is the only route, and either component refutes on its own:
false against true for Θ(1), the numerals for Θ(n²) (count #k
evaluates to #k in Θ(k²) reductions). The test asks in which order a
checker visits the components. refute-cheap-last.lean swaps them, and the
ratio between the two files is what that order costs.
N=200 in the Lean source. From Courant and Leroy, POPL 2026, §10, where the two orders cost Rocq 4 × 10⁻⁶ s and 0.61 s.
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 29.2 M · max rss memory: 21.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 16 records, busy 0.001s (34.0%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (31.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Prod (#11); 0.000s inductive Bool (#10); 0.000s inductive N (#12); 0.000s theorem kernel_refute_cheap_first (#15) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (29.9%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (46.8%) con-leche: stats: slowest checks: 0.000s theorem kernel_refute_cheap_first (#15); 0.000s definition N.add (#13); 0.000s definition count (#14) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem kernel_refute_cheap_first [at theorem kernel_refute_cheap_first, fold position 15] (--verified) t=0.0s
Test "perf/refute-cheap-last"
Expected: ✋ reject · Size: 20.5 KB · Lines: 439 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check claims
(count #n, false) = (count #(n+1), true)
and must be rejected: refute-cheap-first.lean with the components swapped,
so the cheap refutation sits behind the expensive one for a checker that
visits components left to right.
N=200 in the Lean source. From Courant and Leroy, POPL 2026, §10.
Test result: ✋ rejected · exit code 1 · wall time: 16 ms · instructions: 98.6 M · max rss memory: 23.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 16 records, busy 0.001s (27.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.0%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive N (#12); 0.000s inductive Bool (#10); 0.000s theorem kernel_refute_cheap_last (#15) con-leche: stats: check pool: 0.005s wall, 3 workers, 3 records, busy 0.004s (32.5%); tail 0.004s after the last start, 2 busy then, 0.004s worker-time in it (33.2%) con-leche: stats: slowest checks: 0.004s theorem kernel_refute_cheap_last (#15); 0.000s definition N.add (#13); 0.000s definition count (#14) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem kernel_refute_cheap_last [at theorem kernel_refute_cheap_last, fold position 15] (--verified) t=0.0s
Test "perf/repeated-subproblem"
Expected: 👍 accept · Size: 11.4 KB · Lines: 214 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
perfect #n leaf and perfect #(n-1) (node leaf leaf)
where perfect #k t builds the perfect binary tree of depth k with leaves
t, in k steps that each duplicate the tree so far into both arguments of
Tr.node.
Both sides reduce to the perfect tree of depth n. Descending them meets
Tr.node u u against Tr.node v v at every level, where both argument
positions pose the same subproblem, so the recursion reaches 2^n pairs of
nodes of which n are distinct. The test asks whether a checker records the
pairs it has proved convertible: Θ(n) if it does, Θ(2ⁿ) if not.
N=20 in the Lean source, stepped up by one rather than doubled. From Courant and Leroy, POPL 2026, §10.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 26.9 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.000s (15.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (10.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Tr (#11); 0.000s inductive Bool (#10); 0.000s inductive N (#12); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (49.5%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (62.6%) con-leche: stats: slowest checks: 0.000s theorem kernel_repeated_subproblem (#14); 0.000s definition perfect (#13) con-leche: stats: peak RSS 0.02 GiB
Test "perf/shared-subterm"
Expected: 👍 accept · Size: 50.1 KB · Lines: 1.3 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
ldepth (perfect #n leaf) and ldepth2 (perfect #n leaf)
where perfect #n leaf builds the perfect binary tree of depth n in n steps
that each duplicate the tree so far, and ldepth and ldepth2 both return
the length of the leftmost path.
The head constants differ, so both sides are evaluated, and neither traversal
looks beyond the leftmost path: ldepth walks n nodes for Θ(n), ldepth2
folds n additions over growing numerals for Θ(n²). The test asks whether a
checker consumes the tree through its representation, for Θ(n²), or
expands it into the 2ⁿ nodes of its normal form.
N=1000 in the Lean source. From Courant and Leroy, POPL 2026, §10.
Test result: 👍 accepted · exit code 0 · wall time: 30 ms · instructions: 235.1 M · max rss memory: 28.8 MB
stdout:
con-leche: accepted 8 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 18 records, busy 0.001s (25.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.7%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive Tr (#12); 0.000s theorem kernel_shared_subterm (#17); 0.000s inductive Bool (#10) con-leche: stats: check pool: 0.017s wall, 4 workers, 5 records, busy 0.017s (24.8%); tail 0.017s after the last start, 4 busy then, 0.017s worker-time in it (24.9%) con-leche: stats: slowest checks: 0.017s theorem kernel_shared_subterm (#17); 0.000s definition ldepth (#13); 0.000s definition N.add (#15); 0.000s definition perfect (#14); 0.000s definition ldepth2 (#16) con-leche: stats: peak RSS 0.02 GiB
Test "perf/shift-cascade"
Expected: 👍 accept · Size: 256.3 KB · Lines: 5.1 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Stress test for cascading substitution overhead in kernel let processing.
N nested let bindings inside a lambda, where each value references the
outer lambda parameter and the previous binding:
fun (a : Nat → Nat) => let f₁ := fun x => a x let f₂ := fun x => a (f₁ x) ... let fₙ := fun x => a (fₙ₋₁ x) fₙ 0
The kernel processes each let by substituting the value into the body.
Each value has a free bvar (references a), so substitution under inner
binders creates shifted copies. In a de Bruijn kernel with deferred shifts,
these Shift(val, offset) wrappers accumulate: step k must traverse
through O(k) wrappers from previous steps, giving O(N²) total work.
A locally-nameless kernel substitutes fvars that need no shifting, giving O(N) total.
N=1000 in the Lean source. Increase to stress further.
Test result: 👍 accepted · exit code 0 · wall time: 19 ms · instructions: 76.4 M · max rss memory: 33.2 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.001s (29.4%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (26.2%) con-leche: stats: slowest installs: 0.000s inductive OfNat (#11); 0.000s inductive And (#9); 0.000s def shift_cascade (#14); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.002s wall, 3 workers, 3 records, busy 0.002s (31.9%); tail 0.002s after the last start, 3 busy then, 0.002s worker-time in it (33.7%) con-leche: stats: slowest checks: 0.002s definition shift_cascade (#14); 0.000s definition instOfNatNat (#13); 0.000s definition OfNat.ofNat (#12) con-leche: stats: peak RSS 0.03 GiB
Test "perf/unroll-versus-evaluate"
Expected: 👍 accept · Size: 44.6 KB · Lines: 1.2 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The declaration to check compares
count #(n+1) and N.add (count #n) #1
where #k is the numeral with k successors, and count #k evaluates to #k
in Θ(k²) reductions.
The head constants differ. Unrolling count once turns the left side into the
right side, leaving a traversal of the shared numeral #n, for Θ(n);
evaluating both sides costs Θ(n²). The test asks which of two differing
head constants a checker chooses to unfold.
N=1000 in the Lean source. From Courant and Leroy, POPL 2026, §2.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 44.6 M · max rss memory: 23.7 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.001s (30.9%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (27.6%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s theorem kernel_unroll_versus_evaluate (#14); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.001s (34.7%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (38.3%) con-leche: stats: slowest checks: 0.000s theorem kernel_unroll_versus_evaluate (#14); 0.000s definition N.add (#12); 0.000s definition count (#13) con-leche: stats: peak RSS 0.02 GiB
Test "std"
Expected: 👍 accept · Size: 569.0 MB · Lines: 10.8 M · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The complete Std library export from Lean 4.
This test contains the standard library extensions beyond core Lean 4, including:
- Enhanced data structures (HashMap, RBTree, etc.)
- Additional mathematical operations
- Extended list and array operations
- Utility functions and theorems
This represents a medium-sized test case, larger than core modules but smaller than Mathlib, making it useful for performance testing.
Test result: 👍 accepted · exit code 0 · wall time: 20.8 s · instructions: 674.9 G · max rss memory: 696.8 MB
stdout:
con-leche: accepted 101286 declarations (--verified)
stderr:
con-leche: stats: phases: parse 1.2s, install 1.5s, check 17.9s con-leche: stats: install pool: 1.341s wall, 4 workers + the commit thread, 101286 records, busy 6.139s (91.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (13.4%) con-leche: stats: slowest installs: 0.824s def String.instInhabited (#1254); 0.821s theorem Int.ofNat_mul_negOfNat (#1410); 0.821s theorem List.zipWith.eq_2 (#1280); 0.820s theorem Int.sub_add_cancel (#1344); 0.429s def Nat.xor (#850) con-leche: stats: check pool: 17.930s wall, 4 workers, 100201 records, busy 71.476s (99.6%); tail 0.070s after the last start, 4 busy then, 0.070s worker-time in it (24.9%) con-leche: stats: slowest checks: 0.431s theorem _private.Init.Data.Vector.Extract.0.Vector.extract_append._proof_1 (#89871); 0.410s theorem _private.Init.Data.Array.Extract.0.Array.extract_append._proof_1_1 (#7447); 0.368s theorem Std.Tactic.BVDecide.BVExpr.bitblast.goCache._mutual.eq_def (#21861); 0.298s theorem Std.Tactic.BVDecide.BVExpr.bitblast.goCache_Inv_of_Inv._mutual (#22986); 0.284s theorem _private.Init.Data.Vector.Extract.0.Vector.extract_extract._proof_1 (#68804) con-leche: stats: peak RSS 0.68 GiB
Test "tutorial/001_basicDef"
Expected: 👍 accept · Size: 367 B · Lines: 6 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Basic definition
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.6 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (18.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.1%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive False (#3) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (32.6%) con-leche: stats: slowest checks: 0.000s definition basicDef (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/002_badDef"
Expected: ✋ reject · Size: 365 B · Lines: 6 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Mismatched types
Test result: ✋ rejected · exit code 1 · wall time: 18 ms · instructions: 22.6 M · max rss memory: 21.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 11 records, busy 0.000s (16.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (3.6%) con-leche: stats: slowest checks: 0.000s definition badDef (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in definition badDef [at def badDef, fold position 11] (--verified) t=0.0s
Test "tutorial/003_arrowType"
Expected: 👍 accept · Size: 622 B · Lines: 12 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Arrow type (function type)
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 22.7 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.3%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0); 0.000s def arrowType (#11) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (31.1%) con-leche: stats: slowest checks: 0.000s definition arrowType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/004_dependentType"
Expected: 👍 accept · Size: 460 B · Lines: 7 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Dependent type (forall)
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.7 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (16.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (15.9%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def dependentType (#11); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (14.5%) con-leche: stats: slowest checks: 0.000s definition dependentType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/005_constType"
Expected: 👍 accept · Size: 897 B · Lines: 17 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Lambda expression
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 22.7 M · max rss memory: 20.8 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (19.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.9%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (12.3%) con-leche: stats: slowest checks: 0.000s definition constType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/006_betaReduction"
Expected: 👍 accept · Size: 1.3 KB · Lines: 27 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Lambda reduction
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 22.8 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (17.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (1.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (21.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (36.4%) con-leche: stats: slowest checks: 0.000s definition betaReduction (#12); 0.000s definition constType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/007_betaReduction2"
Expected: 👍 accept · Size: 1.4 KB · Lines: 28 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Lambda reduction under binder
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.8 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (18.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (8.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (26.2%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (43.7%) con-leche: stats: slowest checks: 0.000s definition betaReduction2 (#12); 0.000s definition constType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/008_forallSortWhnf"
Expected: 👍 accept · Size: 1.2 KB · Lines: 25 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The binding domain of a forall may need to be reduce before it is a sort
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.9 M · max rss memory: 20.7 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (18.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.4%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def id (#11); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (27.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (54.5%) con-leche: stats: slowest checks: 0.000s definition forallSortWhnf (#12); 0.000s definition id (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/009_forallSortBad"
Expected: ✋ reject · Size: 1.2 KB · Lines: 26 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The binding domain of a forall has to be a sort
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 22.9 M · max rss memory: 20.6 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 13 records, busy 0.001s (17.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0); 0.000s def id (#11) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (15.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (42.7%) con-leche: stats: slowest checks: 0.000s definition forallSortBad (#12); 0.000s definition id (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: expected a sort [at def forallSortBad, fold position 12] (--verified) t=0.0s
Test "tutorial/010_nonTypeType"
Expected: ✋ reject · Size: 1.1 KB · Lines: 21 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The type of a declaration has to be a type, not some other expression
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 22.8 M · max rss memory: 23.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (17.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s def constType (#11) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (14.7%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (56.9%) con-leche: stats: slowest checks: 0.000s definition constType (#11); 0.000s definition nonTypeType (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: expected a sort [at def nonTypeType, fold position 12] (--verified) t=0.0s
Test "tutorial/011_nonTypeAxiom"
Expected: ✋ reject · Size: 1.0 KB · Lines: 20 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
This applies to axioms as well, which are easy to overlook because they have no value to check the type against. Letting one through is not merely untidy: an axiom whose type is an arbitrary term inhabits whatever that term is later found definitionally equal to, and the eta and proof irrelevance rules are happy to equate a term like this with a great many things.
Test result: ✋ rejected · exit code 1 · wall time: 13 ms · instructions: 22.6 M · max rss memory: 20.7 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 9 records, busy 0.000s (1.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.0%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1); 0.000s inductive Empty (#2); 0.000s axiom Quot.sound (#8) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: expected a sort [at axiom nonTypeAxiom, fold position 12] (--verified) t=0.0s
Test "tutorial/012_nonPropThm"
Expected: ✋ reject · Size: 424 B · Lines: 7 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The type of a theorem has to be a proposition
Test result: ✋ rejected · exit code 1 · wall time: 13 ms · instructions: 22.6 M · max rss memory: 20.8 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (15.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.1%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (15.1%) con-leche: stats: slowest checks: 0.000s theorem nonPropThm (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type of theorem nonPropThm is not a proposition [at theorem nonPropThm, fold position 11] (--verified) t=0.0s
Test "tutorial/013_thmProof"
Expected: 👍 accept · Size: 1.3 KB · Lines: 26 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A theorem can refer to another theorem
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 22.9 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (17.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.6%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s theorem pImpliesP (#11); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (24.7%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (45.6%) con-leche: stats: slowest checks: 0.000s theorem thmProof (#12); 0.000s theorem pImpliesP (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/014_selfProof"
Expected: ✋ reject · Size: 459 B · Lines: 8 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A theorem cannot refer to itself
Test result: ✋ rejected · exit code 1 · wall time: 16 ms · instructions: 22.6 M · max rss memory: 20.7 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.0%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s axiom Quot.sound (#8) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (26.1%) con-leche: stats: slowest checks: 0.000s theorem selfProof (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: unknown constant in value of selfProof [at theorem selfProof, fold position 11] (--verified) t=0.0s
Test "tutorial/015_levelComp1"
Expected: 👍 accept · Size: 391 B · Lines: 7 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Some level computation
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.6 M · max rss memory: 20.7 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (18.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s def levelComp1 (#11) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (31.7%) con-leche: stats: slowest checks: 0.000s definition levelComp1 (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/016_levelComp2"
Expected: 👍 accept · Size: 409 B · Lines: 8 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Some level computation
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 22.6 M · max rss memory: 20.8 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot (#4); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (24.2%) con-leche: stats: slowest checks: 0.000s definition levelComp2 (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/017_levelComp3"
Expected: 👍 accept · Size: 427 B · Lines: 9 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Some level computation
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.7 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 11 records, busy 0.000s (17.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.1%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s def levelComp3 (#11) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (27.7%) con-leche: stats: slowest checks: 0.000s definition levelComp3 (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/018_levelParams"
Expected: 👍 accept · Size: 1.4 KB · Lines: 29 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Level parameters
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.9 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (18.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.0%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def levelParamF (#11); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (20.8%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (43.3%) con-leche: stats: slowest checks: 0.000s definition levelParams (#12); 0.000s definition levelParamF (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/019_tut06_bad01"
Expected: ✋ reject · Size: 427 B · Lines: 8 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Duplicate universe parameters
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 22.5 M · max rss memory: 20.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.001s wall, 4 workers + the commit thread, 10 records, busy 0.000s (8.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (10.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4); 0.000s inductive Empty (#2) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: duplicate universe parameters in tut06_bad01 [at def tut06_bad01, fold position 11] (--verified) t=0.0s
Test "tutorial/020_levelComp4"
Expected: 👍 accept · Size: 424 B · Lines: 8 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Some level computation
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.6 M · max rss memory: 20.8 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (10.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s axiom Quot.sound (#8) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (19.8%) con-leche: stats: slowest checks: 0.000s definition levelComp4 (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/021_levelComp5"
Expected: 👍 accept · Size: 424 B · Lines: 8 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Some level computation
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.6 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (18.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (17.2%) con-leche: stats: slowest checks: 0.000s definition levelComp5 (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/022_imax1"
Expected: 👍 accept · Size: 809 B · Lines: 16 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type inference for forall using imax
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.7 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (18.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.4%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s def imax1 (#11) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (22.6%) con-leche: stats: slowest checks: 0.000s definition imax1 (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/023_imax2"
Expected: 👍 accept · Size: 828 B · Lines: 17 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type inference for forall using imax
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.7 M · max rss memory: 20.6 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (19.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.4%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot (#4); 0.000s inductive Eq (#0); 0.000s def imax2 (#11) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (31.5%) con-leche: stats: slowest checks: 0.000s definition imax2 (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/024_levelMaxComm"
Expected: 👍 accept · Size: 524 B · Lines: 12 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Level equality: max is commutative (max u v ≈ max v u).
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.6 M · max rss memory: 20.7 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (3.9%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (32.3%) con-leche: stats: slowest checks: 0.000s definition levelMaxComm (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/025_levelMaxAssoc"
Expected: 👍 accept · Size: 623 B · Lines: 16 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Level equality: max is associative (max (max u v) w ≈ max u (max v w)).
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.6 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (21.5%) con-leche: stats: slowest checks: 0.000s definition levelMaxAssoc (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/026_levelMaxIdem"
Expected: 👍 accept · Size: 447 B · Lines: 9 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Level equality: max is idempotent (max u u ≈ u).
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.7 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s inductive False (#3) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (24.4%) con-leche: stats: slowest checks: 0.000s definition levelMaxIdem (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/027_levelMaxAbsorb"
Expected: 👍 accept · Size: 526 B · Lines: 12 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Level equality: max absorption (max u (max u v) ≈ max u v).
Test result: 👍 accepted · exit code 0 · wall time: 34 ms · instructions: 22.7 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def levelMaxAbsorb (#11); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (33.0%) con-leche: stats: slowest checks: 0.000s definition levelMaxAbsorb (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/028_inferVar"
Expected: 👍 accept · Size: 713 B · Lines: 12 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type inference of local variables
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.7 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def inferVar (#11); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (22.6%) con-leche: stats: slowest checks: 0.000s definition inferVar (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/029_defEqLambda"
Expected: 👍 accept · Size: 1.4 KB · Lines: 26 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Definitional equality between lambdas
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 22.8 M · max rss memory: 20.8 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (16.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.6%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (27.4%) con-leche: stats: slowest checks: 0.000s definition defEqLambda (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/030_peano1"
Expected: 👍 accept · Size: 3.6 KB · Lines: 73 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Peano arithmetic: 2 = 2
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.7 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 7 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 18 records, busy 0.000s (17.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 4 workers, 7 records, busy 0.000s (23.4%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (22.8%) con-leche: stats: slowest checks: 0.000s definition PN.succ (#12); 0.000s definition PN (#11); 0.000s definition PN.zero (#13); 0.000s theorem peano1 (#17); 0.000s definition PN.lit0 (#14) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/031_peano2"
Expected: 👍 accept · Size: 4.5 KB · Lines: 90 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Peano arithmetic: 1 + 1 = 2
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 24.2 M · max rss memory: 23.1 MB
stdout:
con-leche: accepted 8 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 19 records, busy 0.000s (18.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (7.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot (#4); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 4 workers, 8 records, busy 0.000s (29.7%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (41.6%) con-leche: stats: slowest checks: 0.000s theorem peano2 (#18); 0.000s definition PN.zero (#13); 0.000s definition PN.succ (#12); 0.000s definition PN (#11); 0.000s definition PN.lit2 (#16) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/032_peano3"
Expected: 👍 accept · Size: 4.9 KB · Lines: 98 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Peano arithmetic: 2 * 2 = 4
Test result: 👍 accepted · exit code 0 · wall time: 15 ms · instructions: 24.7 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 10 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 21 records, busy 0.000s (18.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def PN (#11); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 4 workers, 10 records, busy 0.000s (26.4%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (27.9%) con-leche: stats: slowest checks: 0.000s theorem peano3 (#20); 0.000s definition PN.succ (#12); 0.000s definition PN (#11); 0.000s definition PN.zero (#13); 0.000s definition PN.mul (#19) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/033_letType"
Expected: 👍 accept · Size: 489 B · Lines: 9 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type checking a non-dependent let
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.6 M · max rss memory: 20.8 MB
stdout:
con-leche: accepted 1 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 11 records, busy 0.000s (18.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.9%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def letType (#11); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (15.2%) con-leche: stats: slowest checks: 0.000s definition letType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/034_letTypeDep"
Expected: 👍 accept · Size: 1.2 KB · Lines: 26 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type checking a dependent let
Test result: 🚫 declined · exit code 2 · wall time: 12 ms · instructions: 22.7 M · max rss memory: 20.5 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (3 still running, not counted): 0.000s wall, 4 workers + the commit thread, 10 records, busy 0.000s (3.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s axiom aDepProp (#11); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s axiom mkADepProp (#12); 0.000s quot Quot (#4) con-leche: stats: peak RSS 0.02 GiB con-leche: not implemented yet: non-standard axiom (aDepProp) [at axiom aDepProp, fold position 11] (--verified) t=0.0s
Test "tutorial/035_letRed"
Expected: 👍 accept · Size: 627 B · Lines: 12 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reducing a let
Test result: 🚫 declined · exit code 2 · wall time: 11 ms · instructions: 22.6 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 2 records, busy 0.000s (0.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.2%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s quot Quot.lift (#6) con-leche: stats: peak RSS 0.02 GiB con-leche: not implemented yet: non-standard axiom (aProp) [at axiom aProp, fold position 11] (--verified) t=0.0s
Test "tutorial/036_empty"
Expected: 👍 accept · Size: 1.2 KB · Lines: 20 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A simple empty inductive type
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.7 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (20.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.0%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def empty (#11); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (9.3%) con-leche: stats: slowest checks: 0.000s definition empty (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/037_boolType"
Expected: 👍 accept · Size: 2.3 KB · Lines: 37 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A simple enumeration inductive type
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 22.8 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 10 records, busy 0.000s (18.6%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (20.3%) con-leche: stats: slowest installs: 0.000s def boolType (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s quot Quot.ind (#7); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (13.7%) con-leche: stats: slowest checks: 0.000s definition boolType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/038_twoBool"
Expected: 👍 accept · Size: 4.2 KB · Lines: 65 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A simple product type
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.6 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (30.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (7.8%) con-leche: stats: slowest installs: 0.000s inductive TwoBool (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (17.9%) con-leche: stats: slowest checks: 0.000s definition twoBool (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/039_andType"
Expected: 👍 accept · Size: 3.2 KB · Lines: 57 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A parametrized product type (no level parameters)
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 22.9 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.001s (29.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.6%) con-leche: stats: slowest installs: 0.000s def andType (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (21.2%) con-leche: stats: slowest checks: 0.000s definition andType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/040_prodType"
Expected: 👍 accept · Size: 3.8 KB · Lines: 76 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A parametrized product type (with level parameters)
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.2 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 11 records, busy 0.000s (16.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s quot Quot.lift (#6) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (35.1%) con-leche: stats: slowest checks: 0.000s definition prodType (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/041_pprodType"
Expected: 👍 accept · Size: 3.8 KB · Lines: 75 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A parametrized product type (with more general level parameters)
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.1 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (29.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (15.8%) con-leche: stats: slowest installs: 0.000s inductive PProd (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (30.5%) con-leche: stats: slowest checks: 0.000s definition pprodType (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/042_pUnitType"
Expected: 👍 accept · Size: 1.8 KB · Lines: 31 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Level-polymorphic unit type
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.1 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (25.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PUnit (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (21.1%) con-leche: stats: slowest checks: 0.000s definition pUnitType (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/043_eqType"
Expected: 👍 accept · Size: 3.2 KB · Lines: 62 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Equality, as an important indexed non-recursive data type
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 22.9 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (18.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.3%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def eqType (#11); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (26.4%) con-leche: stats: slowest checks: 0.000s definition eqType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/044_natDef"
Expected: 👍 accept · Size: 3.3 KB · Lines: 61 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A recursive inductive data type
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 23.8 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (27.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.7%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (11.7%) con-leche: stats: slowest checks: 0.000s definition natDef (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/045_rbTreeDef"
Expected: 👍 accept · Size: 15.7 KB · Lines: 296 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A recursive indexed data type
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 32.9 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (3 still running, not counted): 0.001s wall, 4 workers + the commit thread, 11 records, busy 0.001s (19.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (9.4%) con-leche: stats: slowest installs: 0.000s inductive RBTree (#13); 0.000s inductive Color (#11); 0.000s inductive N (#12); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (26.0%) con-leche: stats: slowest checks: 0.000s definition rbTreeDef (#14) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/046_inductBadNonSort"
Expected: ✋ reject · Size: 1.2 KB · Lines: 20 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive type with a non-sort type
Test result: ✋ rejected · exit code 1 · wall time: 15 ms · instructions: 22.7 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (2 still running, not counted): 0.000s wall, 4 workers + the commit thread, 10 records, busy 0.000s (6.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (1.8%) con-leche: stats: slowest installs: 0.000s inductive Nat (#1); 0.000s inductive inductBadNonSort (#12); 0.000s quot Quot (#4); 0.000s inductive Eq (#0); 0.000s def constType (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: expected a sort [at inductive inductBadNonSort, fold position 12] (--verified) t=0.0s
Test "tutorial/047_inductBadNonSort2"
Expected: ✋ reject · Size: 598 B · Lines: 8 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Another inductive type with a non-sort type
Test result: 🚫 declined · exit code 2 · wall time: 13 ms · instructions: 22.6 M · max rss memory: 21.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (3 still running, not counted): 0.000s wall, 4 workers + the commit thread, 7 records, busy 0.000s (3.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s axiom aType (#11); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s inductive False (#3); 0.000s inductive inductBadNonSort2 (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: not implemented yet: non-standard axiom (aType) [at axiom aType, fold position 11] (--verified) t=0.0s
Test "tutorial/048_inductLevelParam"
Expected: ✋ reject · Size: 515 B · Lines: 7 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive with duplicate level params
Test result: ✋ rejected · exit code 1 · wall time: 13 ms · instructions: 22.6 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 3 records, busy 0.000s (1.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.0%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s inductive Empty (#2) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: duplicate universe parameters in inductLevelParam [at inductive inductLevelParam, fold position 11] (--verified) t=0.0s
Test "tutorial/049_inductTooFewParams"
Expected: ✋ reject · Size: 548 B · Lines: 6 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive with too few parameters in the type
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 22.6 M · max rss memory: 20.9 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 2 records, busy 0.000s (1.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.2%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive False (#3) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: number of parameters mismatch [at inductive inductTooFewParams, fold position 11] (--verified) t=0.0s
Test "tutorial/050_inductWrongCtorParams"
Expected: ✋ reject · Size: 1.2 KB · Lines: 16 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive with a constructor with wrong parameters
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 19.3 M · max rss memory: 19.8 MB
stderr:
con-leche: invalid: recursor inductWrongCtorParams.rec declares 0 parameters; the block declares 1 (--verified)
Test "tutorial/051_inductWrongCtorResParams"
Expected: ✋ reject · Size: 1.3 KB · Lines: 19 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive with a constructor with wrong parameters in result (they are swapped)
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 19.3 M · max rss memory: 20.1 MB
stderr:
con-leche: invalid: recursor inductWrongCtorResParams.rec declares 0 parameters; the block declares 2 (--verified)
Test "tutorial/052_inductWrongCtorResLevel"
Expected: ✋ reject · Size: 1.4 KB · Lines: 23 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive with a constructor with wrong level parameters in result (they are swapped)
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 19.4 M · max rss memory: 20.1 MB
stderr:
con-leche: invalid: recursor inductWrongCtorResLevel.rec declares 0 parameters; the block declares 2 (--verified)
Test "tutorial/053_inductInIndex"
Expected: ✋ reject · Size: 1.1 KB · Lines: 14 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A constructor with an unexpected occurrence of the type in index position of a return type.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 19.3 M · max rss memory: 18.0 MB
stderr:
con-leche: invalid: recursor inductInIndex.rec declares 0 motives; the block has 1 inductive types (--verified)
Test "tutorial/054_indNeg"
Expected: ✋ reject · Size: 996 B · Lines: 12 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The classic example of an inductive with negative recursive occurrence
Test result: ✋ rejected · exit code 1 · wall time: 8 ms · instructions: 19.3 M · max rss memory: 18.1 MB
stderr:
con-leche: invalid: recursor indNeg.rec declares 0 motives; the block has 1 inductive types (--verified)
Test "tutorial/055_reduceCtorParam.mk"
Expected: 👍 accept · Size: 4.1 KB · Lines: 80 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
When checking inductives, we expect the kernel to reduce the types of constructor arguments.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.2 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 14 records, busy 0.001s (18.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (19.3%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive reduceCtorParam (#13); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def id (#11) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (13.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (13.8%) con-leche: stats: slowest checks: 0.000s definition id (#11); 0.000s definition constType (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/056_reduceCtorType.mk"
Expected: ✋ reject · Size: 1.5 KB · Lines: 26 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
When checking inductives, we expect the kernel to not reduce the type of the constructor itself;
that should be all manifest foralls
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 19.4 M · max rss memory: 17.9 MB
stderr:
con-leche: invalid: recursor reduceCtorType.rec declares 0 motives; the block has 1 inductive types (--verified)
Test "tutorial/057_indNegReducible"
Expected: ✋ reject · Size: 1.9 KB · Lines: 31 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
When checking inductives, we expect the kernel to not reduce the type of the constructor parameters further than head normal form. Recursive occurrences nested inside the head normal form are considered negative occurrences, even if they could be reduced to disappear.
Test result: ✋ rejected · exit code 1 · wall time: 9 ms · instructions: 19.3 M · max rss memory: 18.2 MB
stderr:
con-leche: invalid: recursor indNegReducible.rec declares 0 motives; the block has 1 inductive types (--verified)
Test "tutorial/058_predWithTypeField"
Expected: 👍 accept · Size: 2.0 KB · Lines: 32 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive proposition can have constructors with fields of arbitrary level.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 23.2 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (25.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PredWithTypeField (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (13.9%) con-leche: stats: slowest checks: 0.000s definition predWithTypeField (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/059_typeWithTypeField"
Expected: 👍 accept · Size: 2.1 KB · Lines: 36 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive type can have fields of level up to that of the inductive.
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 23.3 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (29.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.1%) con-leche: stats: slowest installs: 0.000s inductive TypeWithTypeField (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive False (#3) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (23.8%) con-leche: stats: slowest checks: 0.000s definition typeWithTypeField (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/060_typeWithTypeFieldPoly"
Expected: 👍 accept · Size: 2.1 KB · Lines: 38 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive type can have fields of level up to that of the inductive (polymorphic variant).
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 23.3 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.001s wall, 4 workers + the commit thread, 13 records, busy 0.000s (17.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (11.6%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive TypeWithTypeFieldPoly (#11); 0.000s inductive Eq (#0); 0.000s inductive False (#3) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (14.8%) con-leche: stats: slowest checks: 0.000s definition typeWithTypeFieldPoly (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/061_typeWithTooHighTypeField.mk"
Expected: ✋ reject · Size: 943 B · Lines: 11 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive type can have fields of from higher universes.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 19.3 M · max rss memory: 20.0 MB
stderr:
con-leche: invalid: recursor typeWithTooHighTypeField.rec declares 0 motives; the block has 1 inductive types (--verified)
Test "tutorial/062_emptyRec"
Expected: 👍 accept · Size: 1.2 KB · Lines: 21 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 22.7 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (19.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.6%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def emptyRec (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (17.0%) con-leche: stats: slowest checks: 0.000s definition emptyRec (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/063_boolRec"
Expected: 👍 accept · Size: 3.0 KB · Lines: 53 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 22.9 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.001s (35.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (35.6%) con-leche: stats: slowest installs: 0.000s def boolRec (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s axiom Quot.sound (#8) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (41.0%) con-leche: stats: slowest checks: 0.000s definition boolRec (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/064_twoBoolRec"
Expected: 👍 accept · Size: 4.8 KB · Lines: 78 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 23.8 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 13 records, busy 0.001s (27.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (14.3%) con-leche: stats: slowest installs: 0.000s inductive TwoBool (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (49.8%) con-leche: stats: slowest checks: 0.000s definition twoBoolRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/065_andRec"
Expected: 👍 accept · Size: 3.2 KB · Lines: 58 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 23.0 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.001s (33.0%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (19.2%) con-leche: stats: slowest installs: 0.000s def andRec (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s axiom Quot.sound (#8) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (39.5%) con-leche: stats: slowest checks: 0.000s definition andRec (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/066_prodRec"
Expected: 👍 accept · Size: 4.0 KB · Lines: 79 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.3 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (26.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.1%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (41.4%) con-leche: stats: slowest checks: 0.000s definition prodRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/067_pprodRec"
Expected: 👍 accept · Size: 4.0 KB · Lines: 78 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.3 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (30.2%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (21.0%) con-leche: stats: slowest installs: 0.000s inductive PProd (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def pprodRec (#12) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (40.7%) con-leche: stats: slowest checks: 0.000s definition pprodRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/068_punitRec"
Expected: 👍 accept · Size: 2.2 KB · Lines: 39 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.3 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (24.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PUnit (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (47.9%) con-leche: stats: slowest checks: 0.000s definition punitRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/069_eqRec"
Expected: 👍 accept · Size: 3.3 KB · Lines: 63 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 10 ms · instructions: 23.1 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (16.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def eqRec (#11); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (55.2%) con-leche: stats: slowest checks: 0.000s definition eqRec (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/070_nRec"
Expected: 👍 accept · Size: 3.3 KB · Lines: 61 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 23.9 M · max rss memory: 20.8 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (26.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (13.1%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def nRec (#12) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (4.5%) con-leche: stats: slowest checks: 0.000s definition nRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/071_rbTreeRef"
Expected: 👍 accept · Size: 16.2 KB · Lines: 303 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 33.7 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 15 records, busy 0.001s (25.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (14.7%) con-leche: stats: slowest installs: 0.000s inductive RBTree (#13); 0.000s inductive Color (#11); 0.000s inductive And (#9); 0.000s inductive N (#12); 0.000s inductive Bool (#10) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (61.6%) con-leche: stats: slowest checks: 0.000s definition rbTreeRef (#14) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/072_boolPropRec"
Expected: 👍 accept · Size: 2.3 KB · Lines: 34 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Inductive predicates eliminate into Prop if they have more than one constructor.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.4 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (27.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.9%) con-leche: stats: slowest installs: 0.000s inductive BoolProp (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (13.9%) con-leche: stats: slowest checks: 0.000s definition boolPropRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/073_BogusRecursor"
Expected: ✋ reject · Size: 1.8 KB · Lines: 27 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A kernel must not blindly trust the recursors it is handed. If we write
inductive BogusRecursor : Type where
| mk : BogusRecursor
then the recursor BogusRecursor.rec will be correctly derived with type
{motive : BogusRecursor → Sort u} → motive .mk → (t : BogusRecursor) → motive t.
This test instead claims that the recursor is a constant of type False, and
then uses it to prove bogusRecursorFalse : False. A kernel that validates
the recursors it is handed rejects the bogus recursor itself; a kernel that
ignores them and derives the recursors anew rejects the proof of False
(the derived recursor neither has type False nor zero universe parameters).
Either way, this test must be rejected.
Test result: ✋ rejected · exit code 1 · wall time: 9 ms · instructions: 19.4 M · max rss memory: 17.9 MB
stderr:
con-leche: invalid: recursor BogusRecursor.rec declares 0 motives; the block has 1 inductive types (--verified)
Test "tutorial/074_existsRec"
Expected: 👍 accept · Size: 3.6 KB · Lines: 66 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Inductive predicates eliminate into Prop if they have one constructors and it carries data.
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 24.4 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (32.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (18.0%) con-leche: stats: slowest installs: 0.000s inductive Exists (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (38.0%) con-leche: stats: slowest checks: 0.000s definition existsRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/075_typeSingletonRecReduction"
Expected: 👍 accept · Size: 7.9 KB · Lines: 138 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Because NewSingleton is a singleton, NewSingleton.rec true x reduces to
true even though x is a variable.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.0 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (26.8%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (34.2%) con-leche: stats: slowest installs: 0.000s inductive NewSingleton (#11); 0.000s inductive And (#9); 0.000s def typeSingletonRecReduction (#13); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (35.2%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (53.4%) con-leche: stats: slowest checks: 0.000s definition typeSingletonRecReduction (#13); 0.000s definition rfl (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/076_sortElimPropRec"
Expected: 👍 accept · Size: 5.6 KB · Lines: 97 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Inductive predicates eliminate into Sort if they have one constructors and it carries data, but the data is known from the type, e.g. a parameter or an index
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.5 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (30.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (13.9%) con-leche: stats: slowest installs: 0.000s inductive SortElimProp (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive False (#3); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (39.2%) con-leche: stats: slowest checks: 0.000s definition sortElimPropRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/077_sortElimProp2Rec"
Expected: 👍 accept · Size: 6.6 KB · Lines: 114 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Inductive predicates eliminate into Sort if they have one constructors and it carries data, but the data is known from the type, e.g. a parameter or an index. However, it must occur directly in the result type, with no intervening reduction.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.9 M · max rss memory: 20.7 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (28.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (9.3%) con-leche: stats: slowest installs: 0.000s inductive SortElimProp2 (#12); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def id (#11) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (30.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (42.3%) con-leche: stats: slowest checks: 0.000s definition sortElimProp2Rec (#13); 0.000s definition id (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/078_boolRecEqns"
Expected: 👍 accept · Size: 10.8 KB · Lines: 199 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reduction behavior of Bool.rec
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.1 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.001s (33.8%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (37.5%) con-leche: stats: slowest installs: 0.000s theorem boolRecEqns (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (74.1%) con-leche: stats: slowest checks: 0.000s theorem boolRecEqns (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/079_prodRecEqns"
Expected: 👍 accept · Size: 10.1 KB · Lines: 205 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reduction behavior of Prod.rec
Test result: 👍 accepted · exit code 0 · wall time: 10 ms · instructions: 25.3 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (29.8%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (22.2%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (66.3%) con-leche: stats: slowest checks: 0.000s theorem prodRecEqns (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/080_nRecReduction"
Expected: 👍 accept · Size: 12.7 KB · Lines: 238 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A proof relying on the reduction behavior of N.rec
Test result: 👍 accepted · exit code 0 · wall time: 10 ms · instructions: 25.7 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.000s (29.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.9%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (27.4%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (39.7%) con-leche: stats: slowest checks: 0.000s theorem nRecReduction (#14); 0.000s definition N.add (#12); 0.000s definition id (#13) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/081_listRecReduction"
Expected: 👍 accept · Size: 17.5 KB · Lines: 335 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reduction behavior of List.rec
Test result: 👍 accepted · exit code 0 · wall time: 10 ms · instructions: 27.8 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 7 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 16 records, busy 0.001s (34.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (14.8%) con-leche: stats: slowest installs: 0.000s def List.recOn (#12); 0.000s inductive And (#9); 0.000s inductive List (#11); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 4 workers, 4 records, busy 0.000s (25.7%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (30.0%) con-leche: stats: slowest checks: 0.000s theorem listRecReduction (#15); 0.000s definition myListApped (#13); 0.000s definition List.recOn (#12); 0.000s definition id (#14) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/082_RBTree.id_spec"
Expected: 👍 accept · Size: 47.9 KB · Lines: 1.0 k · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reduction behavior of RBTree.rec
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 43.2 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 7 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 17 records, busy 0.001s (25.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (10.5%) con-leche: stats: slowest installs: 0.000s inductive RBTree (#13); 0.000s inductive Color (#11); 0.000s inductive And (#9); 0.000s inductive N (#12); 0.000s inductive Bool (#10) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (34.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (39.0%) con-leche: stats: slowest checks: 0.000s theorem RBTree.id_spec (#16); 0.000s definition RBTree.id (#14); 0.000s definition id (#15) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/083_And.right"
Expected: 👍 accept · Size: 4.3 KB · Lines: 74 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type-checking simple projection functions
Test result: 👍 accepted · exit code 0 · wall time: 36 ms · instructions: 23.1 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (32.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (18.3%) con-leche: stats: slowest installs: 0.000s theorem And.left (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (38.2%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (57.8%) con-leche: stats: slowest checks: 0.000s theorem And.left (#11); 0.000s theorem And.right (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/084_Prod.snd"
Expected: 👍 accept · Size: 4.5 KB · Lines: 83 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type-checking projection functions with parameters
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.4 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (28.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (18.6%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (34.3%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (59.3%) con-leche: stats: slowest checks: 0.000s definition Prod.snd (#13); 0.000s definition Prod.fst (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/085_PProd.snd"
Expected: 👍 accept · Size: 4.5 KB · Lines: 83 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type-checking projection functions
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.4 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (29.6%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (17.7%) con-leche: stats: slowest installs: 0.000s inductive PProd (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot.ind (#7) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (24.9%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (39.8%) con-leche: stats: slowest checks: 0.000s definition PProd.snd (#13); 0.000s definition PProd.fst (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/086_PSigma.snd"
Expected: 👍 accept · Size: 5.1 KB · Lines: 96 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type-checking dependent projection functions
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.9 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (30.4%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (16.8%) con-leche: stats: slowest installs: 0.000s inductive PSigma (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def PSigma.fst (#12) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (33.2%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (55.8%) con-leche: stats: slowest checks: 0.000s definition PSigma.snd (#13); 0.000s definition PSigma.fst (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/087_projOutOfRange"
Expected: ✋ reject · Size: 3.8 KB · Lines: 67 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Out of range projection
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 22.9 M · max rss memory: 21.4 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.001s (31.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.9%) con-leche: stats: slowest installs: 0.000s def projOutOfRange (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (52.6%) con-leche: stats: slowest checks: 0.000s definition projOutOfRange (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: projection index out of range [at def projOutOfRange, fold position 11] (--verified) t=0.0s
Test "tutorial/088_projNotStruct"
Expected: ✋ reject · Size: 3.5 KB · Lines: 64 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projection out something that is not a structure
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 23.8 M · max rss memory: 23.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (30.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (18.7%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (32.0%) con-leche: stats: slowest checks: 0.000s definition projNotStruct (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: invalid projection: not a structure-like type, or no such field [at def projNotStruct, fold position 12] (--verified) t=0.0s
Test "tutorial/089_projProp1"
Expected: 👍 accept · Size: 8.2 KB · Lines: 143 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out of a proposition
The lean kernel allows projections out of propositions if they precede all dependent data fields.
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 25.2 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 14 records, busy 0.001s (17.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (8.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PropStructure (#12); 0.000s inductive Bool (#10); 0.000s inductive PUnit (#11); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (39.7%) con-leche: stats: slowest checks: 0.000s definition projProp1 (#13) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/090_projProp2"
Expected: ✋ reject · Size: 8.2 KB · Lines: 143 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out of a proposition
The lean kernel disallows data projections out of propositional structures.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 25.2 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (28.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.8%) con-leche: stats: slowest installs: 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s inductive PropStructure (#12); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (16.9%) con-leche: stats: slowest checks: 0.000s definition projProp2 (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: projection from a propositional structure must be a proposition [at def projProp2, fold position 13] (--verified) t=0.0s
Test "tutorial/091_projProp3"
Expected: 👍 accept · Size: 8.2 KB · Lines: 143 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out of a proposition
The lean kernel allows projections out of propositions if they precede all dependent data fields. Non-dependent data fields are not relevant.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 25.3 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (28.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (10.0%) con-leche: stats: slowest installs: 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s inductive PropStructure (#12); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (30.3%) con-leche: stats: slowest checks: 0.000s definition projProp3 (#13) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/092_projProp4"
Expected: ✋ reject · Size: 8.2 KB · Lines: 143 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out of a proposition
The lean kernel disallows data projections out of propositional structures.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 25.3 M · max rss memory: 20.8 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (30.3%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (17.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PUnit (#11); 0.000s inductive PropStructure (#12); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (30.3%) con-leche: stats: slowest checks: 0.000s definition projProp4 (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: projection from a propositional structure must be a proposition [at def projProp4, fold position 13] (--verified) t=0.0s
Test "tutorial/093_projProp5"
Expected: ✋ reject · Size: 8.4 KB · Lines: 148 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out of a proposition
The lean kernel disallows proof projections out of propositional structures that depend on data.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 25.3 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (32.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (11.2%) con-leche: stats: slowest installs: 0.000s inductive PUnit (#11); 0.000s inductive And (#9); 0.000s inductive PropStructure (#12); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (37.9%) con-leche: stats: slowest checks: 0.000s definition projProp5 (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: projection from a propositional structure must be a proposition [at def projProp5, fold position 13] (--verified) t=0.0s
Test "tutorial/094_projProp6"
Expected: ✋ reject · Size: 8.2 KB · Lines: 143 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out of a proposition.
The lean kernel rejects any projections out of a proposition that come after a dependent data field, even if that is not used by the present projection.
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 25.3 M · max rss memory: 21.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (32.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (13.6%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PUnit (#11); 0.000s inductive PropStructure (#12); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (24.6%) con-leche: stats: slowest checks: 0.000s definition projProp6 (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: projection from a propositional structure must be a proposition [at def projProp6, fold position 13] (--verified) t=0.0s
Test "tutorial/095_projDataIndexRec"
Expected: 👍 accept · Size: 6.8 KB · Lines: 111 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The recursor for ProjDataIndex allows elimination into sort.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 25.3 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.001s (31.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (13.3%) con-leche: stats: slowest installs: 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive ProjDataIndex (#13); 0.000s inductive Bool (#10); 0.000s axiom Quot.sound (#8) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (43.7%) con-leche: stats: slowest checks: 0.000s definition projDataIndexRec (#14) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/096_projIndexData"
Expected: ✋ reject · Size: 14.1 KB · Lines: 226 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out data is not allowed, even if this data appears as an index and the recursor would allow it.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 27.8 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (1 still running, not counted): 0.000s wall, 4 workers + the commit thread, 11 records, busy 0.000s (9.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (3.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (26.7%) con-leche: stats: slowest checks: 0.000s definition projIndexData (#16) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: invalid projection: the node names another structure [at def projIndexData, fold position 16] (--verified) t=0.0s
Test "tutorial/097_projIndexData2"
Expected: ✋ reject · Size: 14.1 KB · Lines: 226 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projecting out data is not allowed, even if this data appears as an index and the recursor would allow it.
This also forbids projecting out proofs that follow such fields.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 27.7 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 17 records, busy 0.001s (25.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.9%) con-leche: stats: slowest installs: 0.000s inductive PropStructure (#15); 0.000s inductive N (#11); 0.000s inductive And (#9); 0.000s inductive PUnit (#14); 0.000s inductive ProjDataIndex (#13) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (29.6%) con-leche: stats: slowest checks: 0.000s definition projIndexData2 (#16) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: projection index out of range [at def projIndexData2, fold position 16] (--verified) t=0.0s
Test "tutorial/098_projRed"
Expected: 👍 accept · Size: 9.9 KB · Lines: 177 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Projection reductions
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 25.1 M · max rss memory: 23.3 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 15 records, busy 0.001s (33.6%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (37.9%) con-leche: stats: slowest installs: 0.000s inductive Prod (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def projRed (#14); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (25.1%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (31.5%) con-leche: stats: slowest checks: 0.000s definition projRed (#14); 0.000s definition Prod.snd (#12); 0.000s definition rfl (#13) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/099_ruleK"
Expected: 👍 accept · Size: 6.5 KB · Lines: 121 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Rule k for Eq:
The recursor reduces even if the major argument is not a constructor,
as long replacing the major argument with a constructor is type correct.
Test result: 👍 accepted · exit code 0 · wall time: 10 ms · instructions: 23.4 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.001s (34.6%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (33.9%) con-leche: stats: slowest installs: 0.000s theorem ruleK (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (70.7%) con-leche: stats: slowest checks: 0.000s theorem ruleK (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/100_ruleKbad"
Expected: ✋ reject · Size: 6.5 KB · Lines: 121 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Rule k for Eq should not fire if the types of the major argument
do not match that of the constructor.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 23.4 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (14.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (12.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Nat (#1); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (59.4%) con-leche: stats: slowest checks: 0.000s theorem ruleKbad (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem ruleKbad [at theorem ruleKbad, fold position 11] (--verified) t=0.0s
Test "tutorial/101_ruleKAcc"
Expected: ✋ reject · Size: 12.5 KB · Lines: 229 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Rule k should not fire for Acc.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 26.9 M · max rss memory: 21.3 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (32.0%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (17.4%) con-leche: stats: slowest installs: 0.000s inductive Acc (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (70.8%) con-leche: stats: slowest checks: 0.000s theorem ruleKAcc (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem ruleKAcc [at theorem ruleKAcc, fold position 12] (--verified) t=0.0s
Test "tutorial/102_aNatLit"
Expected: 👍 accept · Size: 3.0 KB · Lines: 54 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Type checking Nat literals
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 22.9 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool (2 still running, not counted): 0.000s wall, 4 workers + the commit thread, 10 records, busy 0.000s (4.4%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (0.2%) con-leche: stats: slowest installs: 0.000s def aNatLit (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1); 0.000s axiom Quot.sound (#8) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (21.3%) con-leche: stats: slowest checks: 0.000s definition aNatLit (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/103_natLitEq"
Expected: 👍 accept · Size: 6.1 KB · Lines: 114 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reducing Nat literals
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 23.2 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (20.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.1%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s theorem natLitEq (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (36.9%) con-leche: stats: slowest checks: 0.000s theorem natLitEq (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/104_proofIrrelevance"
Expected: 👍 accept · Size: 5.0 KB · Lines: 100 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof irrelevance: every Prop is a subsingleton, if p : Prop then all elements of p
are definitionally equal.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 23.3 M · max rss memory: 21.3 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (18.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.0%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def rfl (#11); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (44.9%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (63.1%) con-leche: stats: slowest checks: 0.000s definition proofIrrelevance (#12); 0.000s definition rfl (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/105_proofIrrelevanceBad"
Expected: ✋ reject · Size: 4.7 KB · Lines: 93 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof irrelevance is limited to Prop: if p : Type, then all elements of p are not
definitionally equal.
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 23.3 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 13 records, busy 0.001s (20.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.4%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def rfl (#11); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (32.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (56.3%) con-leche: stats: slowest checks: 0.000s definition proofIrrelevanceBad (#12); 0.000s definition rfl (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in definition proofIrrelevanceBad [at def proofIrrelevanceBad, fold position 12] (--verified) t=0.0s
Test "tutorial/106_proofIrrelevanceWhnf"
Expected: 👍 accept · Size: 5.6 KB · Lines: 112 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof irrelevance: if p : A and A is definitionally equal to Prop, then all elements of p
are still definitionally equal. Just applying proof irrelevance at Sort 0 isn't sufficient.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.5 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (17.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s def id (#11) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (26.9%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (41.6%) con-leche: stats: slowest checks: 0.000s definition proofIrrelevanceWhnf (#13); 0.000s definition rfl (#12); 0.000s definition id (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/107_proofIrrelevanceUnderBinder"
Expected: 👍 accept · Size: 1.9 KB · Lines: 39 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Proof irrelevance applies to any two terms of a proposition, not just to variables.
Checking this definition needs aPropFamily (h anElem) ≡ aPropFamily (h anotherElem),
i.e. h anElem ≡ h anotherElem. Both are proofs of aProp, since h : aType → aProp,
so they are definitionally equal even though their arguments are not. A checker that
compares the two applications structurally, without first noticing that they are
proofs, wrongly rejects this.
Test result: 🚫 declined · exit code 2 · wall time: 10 ms · instructions: 22.8 M · max rss memory: 20.8 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (2 still running, not counted): 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (19.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (26.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s axiom aPropFamily (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: not implemented yet: non-standard axiom (aType) [at axiom aType, fold position 11] (--verified) t=0.0s
Test "tutorial/108_unitEta1"
Expected: 👍 accept · Size: 6.2 KB · Lines: 116 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Unit eta
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.8 M · max rss memory: 20.9 MB
stdout:
con-leche: accepted 5 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 15 records, busy 0.000s (18.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.2%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive PUnit (#11); 0.000s def rfl (#13) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (24.1%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (43.2%) con-leche: stats: slowest checks: 0.000s definition unitEta1 (#14); 0.000s definition rfl (#13); 0.000s definition Unit (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/109_unitEta2"
Expected: 👍 accept · Size: 5.9 KB · Lines: 109 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Unit eta
Test result: 👍 accepted · exit code 0 · wall time: 10 ms · instructions: 23.8 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (27.0%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PUnit (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def rfl (#12) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (23.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (40.1%) con-leche: stats: slowest checks: 0.000s definition unitEta2 (#13); 0.000s definition rfl (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/110_unitEta3"
Expected: 👍 accept · Size: 6.0 KB · Lines: 111 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Unit eta
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.7 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.000s (23.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.8%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive PUnit (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def rfl (#12) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (29.4%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (41.3%) con-leche: stats: slowest checks: 0.000s definition unitEta3 (#13); 0.000s definition rfl (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/111_indexedUnitEta"
Expected: ✋ reject · Size: 7.2 KB · Lines: 121 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The unit-like rule, which makes any two elements of a single-constructor type with
no fields definitionally equal, is also restricted to non-recursive structures
without indices (is_def_eq_unit_like goes through is_non_rec_structure), so it
does not fire for IndexedUnit.
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 23.9 M · max rss memory: 21.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 13 records, busy 0.001s (31.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (9.4%) con-leche: stats: slowest installs: 0.000s inductive IndexedUnit (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (58.4%) con-leche: stats: slowest checks: 0.000s definition indexedUnitEta (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in definition indexedUnitEta [at def indexedUnitEta, fold position 12] (--verified) t=0.0s
Test "tutorial/112_structEta"
Expected: 👍 accept · Size: 12.5 KB · Lines: 230 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Structure eta
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 25.8 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 7 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 16 records, busy 0.000s (17.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (13.9%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Prod (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def Prod.fst (#12) con-leche: stats: check pool: 0.000s wall, 4 workers, 4 records, busy 0.000s (25.2%); tail 0.000s after the last start, 4 busy then, 0.000s worker-time in it (36.2%) con-leche: stats: slowest checks: 0.000s definition structEta (#15); 0.000s definition Prod.snd (#13); 0.000s definition Prod.fst (#12); 0.000s definition rfl (#14) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/113_indexedStructEta"
Expected: ✋ reject · Size: 8.5 KB · Lines: 138 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Structure eta applies only to non-recursive structures without indices: the
official kernel's is_non_rec_structure requires nindices == 0, so it does not
fire for IndexedSingleton even though that has a single constructor.
Every field of IndexedSingleton.mk is a proof, so a kernel that checks only
"has a single constructor" and then compares the fields against projections
would have proof irrelevance discharge the remaining goals, and would wrongly
accept this.
Test result: ✋ rejected · exit code 1 · wall time: 33 ms · instructions: 24.6 M · max rss memory: 20.8 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (28.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (9.3%) con-leche: stats: slowest installs: 0.000s inductive IndexedSingleton (#12); 0.000s inductive And (#9); 0.000s inductive True (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (50.8%) con-leche: stats: slowest checks: 0.000s definition indexedStructEta (#13) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in definition indexedStructEta [at def indexedStructEta, fold position 13] (--verified) t=0.0s
Test "tutorial/114_funEta"
Expected: 👍 accept · Size: 5.2 KB · Lines: 104 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Function eta for non-dependent functions.
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 23.4 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 13 records, busy 0.000s (18.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (15.7%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def rfl (#11); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (26.7%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (61.8%) con-leche: stats: slowest checks: 0.000s theorem funEta (#12); 0.000s definition rfl (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/115_funEtaDep"
Expected: 👍 accept · Size: 5.3 KB · Lines: 106 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Function eta for dependent functions (pi types).
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 23.4 M · max rss memory: 23.2 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.000s (16.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (6.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s def rfl (#11) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (35.4%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (44.3%) con-leche: stats: slowest checks: 0.000s theorem funEtaDep (#12); 0.000s definition rfl (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/116_funEtaBad"
Expected: ✋ reject · Size: 4.9 KB · Lines: 97 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Eta should not identify functions with different bodies.
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 23.3 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (17.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.0%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s theorem funEtaBad (#11); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (67.5%) con-leche: stats: slowest checks: 0.000s theorem funEtaBad (#11) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem funEtaBad [at theorem funEtaBad, fold position 11] (--verified) t=0.0s
Test "tutorial/117_reflOccLeft"
Expected: ✋ reject · Size: 3.7 KB · Lines: 61 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Rejection: recursive occurrence on the left of an arrow, behind further arrows inside a constructor argument.
The constructor argument is a function type Nat → (I → Nat).
Test result: ✋ rejected · exit code 1 · wall time: 9 ms · instructions: 19.7 M · max rss memory: 20.1 MB
stderr:
con-leche: invalid: recursor reflOccLeft.rec declares 0 motives; the block has 1 inductive types (--verified)
Test "tutorial/118_reflOccInIndex"
Expected: ✋ reject · Size: 3.9 KB · Lines: 66 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Rejection: recursive occurrence in index position, behind a further arrow.
We build an indexed inductive I : Type → Type with a constructor argument
Nat → I (I α), so the recursive occurrence appears as an index argument.
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 19.7 M · max rss memory: 19.9 MB
stderr:
con-leche: invalid: constructor reflOccInIndex.mk declares 1 fields at 0 parameters; its type has 2 binders (--verified)
Test "tutorial/119_reduceCtorParamRefl.mk"
Expected: 👍 accept · Size: 4.5 KB · Lines: 88 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
When checking inductives, we expect the kernel to reduce the types of constructor arguments in all positive positions.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 24.6 M · max rss memory: 23.3 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (30.8%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (29.9%) con-leche: stats: slowest installs: 0.000s inductive reduceCtorParamRefl (#13); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (12.8%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (10.7%) con-leche: stats: slowest checks: 0.000s definition id (#11); 0.000s definition constType (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/120_reduceCtorParamRefl2.mk"
Expected: 👍 accept · Size: 4.5 KB · Lines: 88 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
When checking inductives, we expect the kernel to reduce the types of constructor arguments in all positive positions.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 24.5 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 14 records, busy 0.001s (30.3%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (20.0%) con-leche: stats: slowest installs: 0.000s inductive reduceCtorParamRefl2 (#13); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 2 workers, 2 records, busy 0.000s (6.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.0%) con-leche: stats: slowest checks: 0.000s definition id (#11); 0.000s definition constType (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/121_rTreeRec"
Expected: 👍 accept · Size: 5.5 KB · Lines: 91 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of the generated recursor.
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 24.4 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 3 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (29.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (10.5%) con-leche: stats: slowest installs: 0.000s inductive RTree (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (37.9%) con-leche: stats: slowest checks: 0.000s definition rTreeRec (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/122_rtreeRecReduction"
Expected: 👍 accept · Size: 10.7 KB · Lines: 191 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reduction behavior of RTree.rec on RTree.mk.
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 25.3 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 15 records, busy 0.001s (29.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (4.4%) con-leche: stats: slowest installs: 0.000s inductive RTree (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s inductive False (#3) con-leche: stats: check pool: 0.000s wall, 3 workers, 3 records, busy 0.000s (30.8%); tail 0.000s after the last start, 3 busy then, 0.000s worker-time in it (46.1%) con-leche: stats: slowest checks: 0.000s theorem rtreeRecReduction (#14); 0.000s definition RTree.left (#12); 0.000s definition rfl (#13) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/123_accRecType"
Expected: 👍 accept · Size: 7.5 KB · Lines: 151 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of Acc.rec.
Test result: 👍 accepted · exit code 0 · wall time: 14 ms · instructions: 26.2 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 2 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.001s wall, 4 workers + the commit thread, 13 records, busy 0.001s (17.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (12.9%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Acc (#11); 0.000s inductive Bool (#10); 0.000s inductive Eq (#0); 0.000s def accRecType (#12) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (54.7%) con-leche: stats: slowest checks: 0.000s definition accRecType (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/124_accRecReduction"
Expected: 👍 accept · Size: 13.0 KB · Lines: 243 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Acc.rec reduces on Acc.intro.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 27.2 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 4 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (34.6%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (33.5%) con-leche: stats: slowest installs: 0.000s inductive Acc (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s theorem accRecReduction (#12); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (60.3%) con-leche: stats: slowest checks: 0.000s theorem accRecReduction (#12) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/125_accRecNoEta"
Expected: ✋ reject · Size: 12.7 KB · Lines: 235 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Acc.rec does not have structure eta.
Test result: ✋ rejected · exit code 1 · wall time: 13 ms · instructions: 26.9 M · max rss memory: 21.3 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 13 records, busy 0.001s (31.4%); tail 0.000s after the last start, 2 busy then, 0.000s worker-time in it (27.9%) con-leche: stats: slowest installs: 0.000s inductive Acc (#11); 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s theorem accRecNoEta (#12); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (60.9%) con-leche: stats: slowest checks: 0.000s theorem accRecNoEta (#12) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: type mismatch in theorem accRecNoEta [at theorem accRecNoEta, fold position 12] (--verified) t=0.0s
Test "tutorial/126_quotMkType"
Expected: 👍 accept · Size: 6.3 KB · Lines: 123 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of Quot.mk.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.2 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (21.4%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.0%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def quotMkType (#11); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (27.0%) con-leche: stats: slowest checks: 0.000s definition quotMkType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/127_quotIndType"
Expected: 👍 accept · Size: 6.3 KB · Lines: 124 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of Quot.ind.
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 23.2 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (19.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (16.6%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def quotIndType (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (40.3%) con-leche: stats: slowest checks: 0.000s definition quotIndType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/128_quotLiftType"
Expected: 👍 accept · Size: 6.3 KB · Lines: 124 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of Quot.lift.
Test result: 👍 accepted · exit code 0 · wall time: 11 ms · instructions: 23.3 M · max rss memory: 21.2 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (20.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.1%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def quotLiftType (#11); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (57.3%) con-leche: stats: slowest checks: 0.000s definition quotLiftType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/129_quotSoundType"
Expected: 👍 accept · Size: 7.2 KB · Lines: 141 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Asserting the type of Quot.sound.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 23.3 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 7 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (19.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.0%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s def quotSoundType (#11); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (54.6%) con-leche: stats: slowest checks: 0.000s definition quotSoundType (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/130_quotLiftReduction"
Expected: 👍 accept · Size: 7.8 KB · Lines: 153 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reduction behavior of Quot.lift on Quot.mk.
Test result: 👍 accepted · exit code 0 · wall time: 13 ms · instructions: 23.9 M · max rss memory: 21.0 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (20.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (17.5%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s theorem quotLiftReduction (#11); 0.000s inductive Eq (#0); 0.000s quot Quot (#4) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (67.7%) con-leche: stats: slowest checks: 0.000s theorem quotLiftReduction (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/131_quotIndReduction"
Expected: 👍 accept · Size: 7.6 KB · Lines: 151 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Reduction behavior of Quot.ind on Quot.mk.
Test result: 👍 accepted · exit code 0 · wall time: 12 ms · instructions: 23.8 M · max rss memory: 21.1 MB
stdout:
con-leche: accepted 6 declarations (--verified)
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check 0.0s con-leche: stats: install pool: 0.000s wall, 4 workers + the commit thread, 12 records, busy 0.000s (21.6%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (18.6%) con-leche: stats: slowest installs: 0.000s inductive And (#9); 0.000s inductive Bool (#10); 0.000s theorem quotIndReduction (#11); 0.000s quot Quot (#4); 0.000s inductive Eq (#0) con-leche: stats: check pool: 0.000s wall, 1 worker, 1 records, busy 0.000s (67.0%) con-leche: stats: slowest checks: 0.000s theorem quotIndReduction (#11) con-leche: stats: peak RSS 0.02 GiB
Test "tutorial/132_dup_defs"
Expected: ✋ reject · Size: 475 B · Lines: 7 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Two definitions with the same name
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 22.6 M · max rss memory: 20.8 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 3 records, busy 0.000s (1.3%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s inductive Empty (#2) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: duplicate declaration dup_defs [at def dup_defs, fold position 12] (--verified) t=0.0s
Test "tutorial/133_dup_ind_def"
Expected: ✋ reject · Size: 1.7 KB · Lines: 27 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A definition and a constructor with the same name
Test result: ✋ rejected · exit code 1 · wall time: 11 ms · instructions: 22.7 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (3 still running, not counted): 0.000s wall, 4 workers + the commit thread, 7 records, busy 0.000s (3.1%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.0%) con-leche: stats: slowest installs: 0.000s quot Quot (#4); 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot.lift (#6); 0.000s inductive Empty (#2) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: duplicate declaration dup_ind_def [at inductive dup_ind_def, fold position 12] (--verified) t=0.0s
Test "tutorial/134_dup_ctor_def"
Expected: ✋ reject · Size: 1.7 KB · Lines: 27 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A definition and a constructor with the same name
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 22.7 M · max rss memory: 21.2 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 7 records, busy 0.000s (1.9%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4); 0.000s inductive Empty (#2); 0.000s inductive False (#3) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: duplicate declaration dup_ctor_def.mk [at inductive dup_ctor_def, fold position 12] (--verified) t=0.0s
Test "tutorial/135_dup_rec_def"
Expected: ✋ reject · Size: 1.7 KB · Lines: 27 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A definition and a recursor with the same name
Test result: ✋ rejected · exit code 1 · wall time: 13 ms · instructions: 22.8 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 7 records, busy 0.000s (1.7%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s quot Quot (#4); 0.000s inductive Empty (#2); 0.000s axiom Quot.sound (#8) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: duplicate declaration dup_rec_def.rec [at inductive dup_rec_def, fold position 12] (--verified) t=0.0s
Test "tutorial/136_misnamed_rec_user"
Expected: ✋ reject · Size: 2.0 KB · Lines: 33 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
The name of the recursor for misnamed_rec must be misnamed_rec.rec:
another name (like misnamed_rec.not_rec) should be rejected.
dupRecUser is included so that checkers that recreate the recursor (as misnamed_rec.rec)
rather than validating it still fail, because misnamed_rec_user references misnamed_rec.not_rec.
Test result: ✋ rejected · exit code 1 · wall time: 10 ms · instructions: 22.9 M · max rss memory: 21.0 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 7 records, busy 0.000s (2.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s quot Quot (#4); 0.000s inductive Nat (#1); 0.000s inductive Empty (#2); 0.000s axiom Quot.sound (#8) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: target rec: the block's recursor names are not the generated ones (one T.rec per member) [at inductive misnamed_rec, fold position 11] (--verified) t=0.0s
Test "tutorial/137_dup_rec_def2"
Expected: ✋ reject · Size: 1.7 KB · Lines: 28 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Even if a kernel doesn't catch a recursor for dup_rec_def2 that is misnamed
as dup_rec_def2.not_rec, it should catch some other constant being given
the name dup_rec_def2.rec that is reserved for the recursor.
Test result: ✋ rejected · exit code 1 · wall time: 13 ms · instructions: 22.8 M · max rss memory: 20.8 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (4 still running, not counted): 0.000s wall, 4 workers + the commit thread, 4 records, busy 0.000s (1.5%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.0%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive Nat (#1); 0.000s inductive Empty (#2); 0.000s quot Quot.mk (#5) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: target rec: the block's recursor names are not the generated ones (one T.rec per member) [at inductive dup_rec_def2, fold position 12] (--verified) t=0.0s
Test "tutorial/138_dup_ctor_rec"
Expected: ✋ reject · Size: 1.5 KB · Lines: 24 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
A constructor and a recursor with the same name
Test result: ✋ rejected · exit code 1 · wall time: 12 ms · instructions: 22.8 M · max rss memory: 21.1 MB
stderr:
con-leche: stats: phases: parse 0.0s, install 0.0s, check not reached con-leche: stats: install pool (3 still running, not counted): 0.000s wall, 4 workers + the commit thread, 3 records, busy 0.000s (1.2%); tail 0.000s after the last start, 1 busy then, 0.000s worker-time in it (0.1%) con-leche: stats: slowest installs: 0.000s inductive Eq (#0); 0.000s inductive False (#3); 0.000s quot Quot.ind (#7) con-leche: stats: peak RSS 0.02 GiB con-leche: invalid: duplicate declaration dup_ctor_rec.rec [at inductive dup_ctor_rec, fold position 11] (--verified) t=0.0s
Test "tutorial/139_DupConCon"
Expected: ✋ reject · Size: 2.2 KB · Lines: 34 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
An inductive with two constructors with the same name
Test result: ✋ rejected · exit code 1 · wall time: 9 ms · instructions: 19.4 M · max rss memory: 18.1 MB
stderr:
con-leche: invalid: duplicate constructor name in an inductive type's ctors (--verified)
Test "tutorial/140_falseFromUnsafe"
Expected: ✋ reject · Size: 1.3 KB · Lines: 22 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Unsafe definitions cannot be used in theorems
Test result: 🚫 declined · exit code 2 · wall time: 9 ms · instructions: 19.3 M · max rss memory: 20.2 MB
stderr:
con-leche: declined: definition with safety 'unsafe' (--verified)
Test "tutorial/141_falseFromPartial"
Expected: ✋ reject · Size: 1.3 KB · Lines: 22 · lean4export: 3.1.0 · Lean: 4.34.1 · 📄 Declaration · 🔗 Source
Partial definitions cannot be used in theorems
Test result: 🚫 declined · exit code 2 · wall time: 31 ms · instructions: 19.3 M · max rss memory: 18.2 MB
stderr:
con-leche: declined: definition with safety 'partial' (--verified)