Test "perf/folded-constant-first"
Expected: 👍 accept · Size: 52.0 KB · Lines: 1.3 k · lean4export: 3.1.0 · Lean: 4.29.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.
| Checker | Result | ⏱️ | 🧠 | |||
|---|---|---|---|---|---|---|
| mathgraph | 👍 | 3 ms | (÷15) | 50.6 MB | (-26%) | |
| ind-models | 👍 | 79 ms | (+93%) | 109.4 MB | (+59%) | |
| official-nightly | 👍 | 41 ms | (0%) | 66.9 MB | (-3%) | |
| evmlean | 🚫 | 2.3 s | 139.1 MB | |||
| nanoda | 👍 | 7 ms | (÷5.8) | 4.5 MB | (÷15) | |
| mini | 💥 | 51.1 s | 91.0 MB | |||
| lean4lean | 👍 | 47 ms | (+14%) | 101.4 MB | (+48%) | |
| sokonanoda | 👍 | 3 ms | (÷14) | 50.5 MB | (-27%) | |
| zignodamus | 👍 | 3 ms | (÷12) | 9.5 MB | (÷7.2) | |
| nanoclo | 👍 | 4 ms | (÷10) | 54.4 MB | (-21%) | |
| nanobruijn | 👍 | 7 ms | (÷5.8) | 17.4 MB | (÷3.9) | |
| kiota | 👍 | 7 ms | (÷6.2) | 13.5 MB | (÷5.1) | |
| official | 👍 | 41 ms | (0%) | 68.7 MB | (0%) | |
| vow-lean-kernel | 👍 | 217 ms | (×5.3) | 22.1 MB | (÷3.1) | |
| rpylean | 👍 | 8 ms | (÷5.0) | 19.6 MB | (÷3.5) | |
| official-v4.28.0 | 👍 | 48 ms | (+19%) | 76.9 MB | (+12%) | |
| still-nanoda | 👍 | 7 ms | (÷5.9) | 4.3 MB | (÷16) | |
| nyaya | ✋ | 17 ms | 13.6 MB | |||
| parse-only | 👍 | 30 ms | (-26%) | 64.0 MB | (-7%) |