Skip to content

Reduce GapCVP proof elaboration cost - #808

Merged
Vilin97 merged 4 commits into
mainfrom
codex/daily-optimize-20261112-evening
Nov 13, 2026
Merged

Vilin97 merged 4 commits into
mainfrom
codex/daily-optimize-20261112-evening

Conversation

@Vilin97

@Vilin97 Vilin97 commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator

GapCVP repeatedly elaborates concrete machine transitions and field/parity-matrix expressions. This reduces that work while retaining every existing declaration and the project's public API. GapCVP was selected for its 71 modules, approximately 137,000 source lines, broad initial imports, and repeated transition-proof infrastructure.

The changes:

  • Prove integer-grid closedness directly using integer coordinate separation, removing Part01A's private lattice-theory import. The existing public lattice import remains in the entry module.
  • Remove redundant Boolean case splits and simplification around direct theorem applications; use direct reflexivity at 136 transition call sites.
  • Use an explicit rewrite set, derived from Lean's simplifier diagnostics, at 266 further transition call sites. Existing step-tactic definitions are preserved.
  • Supply rational-function injectivity and a local scalar-action witness directly, and isolate the valuation exponent rewrite.
  • Use generic basis-projection and paired-index lemmas, with explicit wrapper reduction, to avoid large Gaussian/parity-matrix definitional comparisons.

Invariant audit. Before editing, save the private-level compiled project environment and a declaration manifest from base d1019ceec2f68c6ff2eaa59a413bc20b3fceac0b. Import base and optimized environments separately and structurally compare every original project-owned declaration, including private and compiler-generated declarations. For theorems, compare the complete ConstantVal (name, universes and elaborated type) and mutual-declaration metadata, excluding only the proof body. For every other declaration, compare the complete ConstantInfo, including values, safety and constructor/recursor data. Hash manifests are supplemental; this audit compares the actual expressions.

Result: 15,835 original declarations, zero forbidden differences. There are 298 changed existing theorem bodies and 272 new Lean constants: 266 generated simplification auxiliaries, two tactic parsers with their implementations, and two supporting lemmas. No existing statement, definition, instance, notation, public import/export path, or namespace API is changed.

Measurements. Paired measurements are at commit 0fa993866eb7146554183f1a92542bf1defa94d8. Each run deletes only GapCVP's compiled and IR artifacts and executes:

taskset -c 0,1,2,3 lake build +LeanPool.GapCVP.Imports:olean

External dependency and compiler-plugin caches stay warm. Base and optimized sources alternate in the same isolated Azure VM worktree. GNU time records elapsed/user/system seconds and peak process RSS; no profiler or other validation runs alongside a timed build.

Pair Base wall (s) Optimized wall (s) Base user CPU (s) Optimized user CPU (s) Base peak RSS (KiB) Optimized peak RSS (KiB)
1 439.23 371.87 506.75 448.90 1,959,136 1,945,772
2 393.27 382.94 474.99 464.13 1,959,364 1,956,620

Mean wall time: 416.25 → 377.405 seconds (9.33% lower). Mean user CPU time is 7.00% lower; peak process RSS is essentially unchanged. The 10% target was not reached within the six-hour optimization budget. These are shared-VM observations, not a prediction for hosted CI. Representative first-pair Lake module times were Part09 34→25 s and Part13 24→16 s.

Final head 537eaeece59b02c29ad950435012f2b5005fc23f adds one unused-private-import removal and reflows the transition argument lists. A second structural comparison against the measured commit found zero differences across all 16,107 constants, including theorem proof values. The final head also passed an unpaired clean verification build: 444.03 s wall, 490.82 s user CPU, 46.74 s system CPU, peak process RSS 1,942,948 KiB. This unpaired validation run is not included in the paired performance estimate above.

Validation. Final-head validation covers a clean warning-free build of all 71 project modules, Mathlib/Batteries slow declaration linters, style, project-scoped repository quality/card/size checks, axiom and option/backdoor audits, the generated project aggregate, lake shake --force --keep-public LeanPool.GapCVP.Imports, changed-file build-time limits, and git diff --check. No sources were added or moved, so the generated indexes and fixed LeanPool.lean remain unchanged. Toolchain pins remain Lean 4.35.0 and Mathlib v4.35.0.

Only GapCVP Lean source changes. Some definition lists are repeated at restricted-tactic call sites to retain the original tactic definitions unchanged. Full-pool and hosted validation remain the PR's responsibility; no merge or auto-merge is enabled.

@greptile-apps

greptile-apps Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Advisory cross-file review against Lean Pool's supervisory rubric. This is not by itself a significance, source-verification, or merge verdict.

RetriggerView in Greptile

[Medium impact] No blocking issue was identified in the latest changes or the full-PR rules check.

Summary

The PR reduces proof elaboration work in GapCVP while keeping existing declarations and tactic definitions.

  • GapCVP proofs reach the same results with less repeated elaboration work.

Reviews (3) · Last reviewed commit: "Document restricted GapCVP step tactics" · Reviewed by Greptile

@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Proof profile (new / modified Lean files)

Statement changes

✅ No statements changed — all 7,077 tracked declarations across 39 modified files kept their type; only proofs / definition bodies changed.

Also: 2 declarations added, 0 removed. A reorganization moves declarations between files, which shows up here as an add in one file and a remove in another.

➕ Declarations added (2)
  • GapCVP.Factor400BinaryInstanceBridge.effectiveGapCVPInstance_basis — LeanPool/GapCVP/Part10A.lean
  • GapCVP.MatrixEntrySemantics.binaryFieldParityMatrix_apply_index — LeanPool/GapCVP/Part13.lean

Statements are compared textually against the merge base (comments and whitespace ignored; by proof terms embedded in a type are treated as proof-irrelevant), the same method as physlib's /check-golf. Anonymous instances and examples are not tracked.

Compile cost of modified files — base → head

Heartbeats: 3,421,470 → 3,429,159 (+7,689, +0.2%). Commands: 7,143 → 7,160.

Per-file wall sum: 389.8 s → 690.8 s (+77.2%). Wall clock is measured under parallel load and is noisy; heartbeats are deterministic and are the regression signal.

Files: 21 compared — 3 cheaper, 2 costlier, 16 within noise (threshold: |Δ heartbeats| ≥ 1,000 and ≥ 1%).

Both sides are elaborated against the merge-base build of the pool — sound when only proofs and definition bodies change; a file whose statements changed may fail there and is flagged ⚠. Heartbeats come from disjoint root command traces with trace.profiler.useHeartbeats and synchronous elaboration, converted to maxHeartbeats units. Failed measurements are not classified as cheaper or costlier. Δ lines counts added/deleted lines from this PR diff.

File Δ lines HB base HB head Δ HB Δ HB % Wall base (s) Wall head (s)
LeanPool/GapCVP/Part01A.lean +78/-45 211,945 238,385 +26,439 +12.5% 31.84 54.78
LeanPool/GapCVP/Part14B.lean +8/-15 583,464 566,753 -16,711 -2.9% 51.42 101.40
LeanPool/GapCVP/Part15.lean +4/-6 165,783 168,045 +2,261 +1.4% 23.68 43.28
LeanPool/GapCVP/Part04A.lean +1/-1 85,537 83,404 -2,134 -2.5% 9.34 16.97
LeanPool/GapCVP/Part04D.lean +1/-2 28,189 26,838 -1,351 -4.8% 4.47 7.86
LeanPool/GapCVP/Part08D.lean +7/-20 239,632 238,584 -1,048 -0.4% 32.23 46.75
LeanPool/GapCVP/Part16A.lean +3/-3 317,688 318,497 +809 +0.3% 31.32 68.21
LeanPool/GapCVP/Part16B.lean +6/-6 300,750 300,576 -174 -0.1% 21.84 43.08
LeanPool/GapCVP/Part02.lean +9/-9 155,508 155,596 +88 +0.1% 21.40 37.70
LeanPool/GapCVP/Part11C.lean +5/-8 93,268 93,181 -87 -0.1% 16.25 23.62
LeanPool/GapCVP/Part12C.lean +3/-3 240,878 240,812 -65 -0.0% 26.31 44.91
LeanPool/GapCVP/Part14A.lean +2/-2 13,911 13,847 -64 -0.5% 3.95 5.62
LeanPool/GapCVP/Part17.lean +2/-2 123,887 123,824 -63 -0.1% 13.86 21.93
LeanPool/GapCVP/Part03F.lean +4/-8 51,919 51,859 -60 -0.1% 5.36 8.62
LeanPool/GapCVP/Part06D.lean +2/-2 236,598 236,557 -41 -0.0% 30.26 40.61
LeanPool/GapCVP/Part07D.lean +2/-4 198,914 198,875 -38 -0.0% 17.74 41.68
LeanPool/GapCVP/Part07A.lean +2/-2 35,403 35,368 -35 -0.1% 7.27 10.56
LeanPool/GapCVP/Part08A.lean +2/-2 20,098 20,067 -31 -0.2% 5.06 8.31
LeanPool/GapCVP/Part07C.lean +2/-2 68,977 68,951 -26 -0.0% 7.85 15.55
LeanPool/GapCVP/Part10A.lean +12/-3 229,018 229,043 +25 +0.0% 24.03 42.50
LeanPool/GapCVP/Part05F.lean +3/-3 20,102 20,096 -6 -0.0% 4.33 6.82
Total +158/-148 3,421,470 3,429,159 +7,689 +0.2% 389.8 690.8

New files — absolute profile

Total heartbeats: — maxHeartbeats units across 0 valid files (846 added LOC).

Sum of lean --profile: — across 0 valid files. Import-excluded time: —.

Count-heartbeats wall-clock total: 0.00 s. Repeated import cost inside lean --profile: —.

Heartbeat values sum disjoint root command traces with trace.profiler.useHeartbeats and synchronous elaboration, converted from raw allocations to maxHeartbeats units by dividing by 1000. They include command elaboration and kernel checking, exclude imports, and include profiler overhead; they are not comparable to the deprecated linter's totals. Per-file wall clocks are measured under parallel load and are noisier than heartbeats.

LOC counts added lines in the profiled Lean files from this PR diff.

File LOC Heartbeats (maxHB) Count wall (s) lean --profile (s) Without import (s) Import (s) Commands Errors
LeanPool/GapCVP/Part03A.lean 43 — — — — — 173 1
LeanPool/GapCVP/Part03B.lean 27 — — — — — 60 1
LeanPool/GapCVP/Part03C.lean 177 — — — — — 166 1
LeanPool/GapCVP/Part03D.lean 23 — — — — — 162 1
LeanPool/GapCVP/Part03E.lean 51 — — — — — 86 1
LeanPool/GapCVP/Part04B.lean 32 — — — — — 93 1
LeanPool/GapCVP/Part04E.lean 37 — — — — — 94 1
LeanPool/GapCVP/Part04F.lean 48 — — — — — 166 1
LeanPool/GapCVP/Part05A.lean 27 — — — — — 78 1
LeanPool/GapCVP/Part05B.lean 63 — — — — — 196 1
LeanPool/GapCVP/Part05C.lean 55 — — — — — 172 1
LeanPool/GapCVP/Part05D.lean 38 — — — — — 153 1
LeanPool/GapCVP/Part05E.lean 23 — — — — — 94 1
LeanPool/GapCVP/Part06A.lean 45 — — — — — 273 1
LeanPool/GapCVP/Part06B.lean 44 — — — — — 126 1
LeanPool/GapCVP/Part09.lean 65 — — — — — 798 1
LeanPool/GapCVP/Part10B.lean 18 — — — — — 508 1
LeanPool/GapCVP/Part13.lean 30 — — — — — 793 1
Total 846 — 0.00 — — — 4191 18

Aggregate phase totals

Phase Time
Unavailable —

Advisory only — never blocks merge. Full log uploaded as the proof-profile artifact.

@Vilin97

Vilin97 commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator Author

🤖 LLM review — refactor (gpt-6.1-sol)

Reviewed head: 537eaeece59b02c29ad950435012f2b5005fc23f

Verdict: 🛑 request_changes

The refactor replaces redundant simplification and case splits with direct proofs or explicit rewrites, and adds focused projection lemmas. These reduce dependence on broad automation, but repeating machine-specific definition lists across hundreds of proofs introduces maintenance debt. Local elaboration failed because Mathlib dependencies are absent, so I could not independently verify the build or speedup.

Aspect Value
Scope proof elaboration optimization and tactic rewrite
Introduces tech debt 🛑 yes
Maintainability 🛑 regressed
Brittleness ✅ more_robust
Risk 🟡 medium

Keep the targeted proof rewrites, but restore a single maintenance point for each machine's tactic configuration before merging.

Findings (1)

  • duplicated-tactic-configuration — LeanPool/GapCVP/Part03E.lean:356
    The same 28-entry definition list is now repeated at 22 call sites, replacing the shared delimitedCompareStepTac invocation. This pattern extends across 266 calls; Part06B.lean:866 repeats another 23-entry list 20 times. Helper changes and dependency repairs can now require editing many copies instead of one machine tactic. Factor each machine's list into a wrapper around machineStackEquality; add new wrappers alongside the existing exported tactics if their definitions must remain unchanged.

Tokens: 2,210,241 in / 10,335 out · Tier: codex-subscription · Effort: xhigh · Billing: Codex subscription quota (no API credits) · Estimated cost: $8.9960 (Standard API equivalent; uncached input) (long-context rate)
Automated review against .github/REFACTOR_REVIEW_RULES.md. Disagree? Reply on the PR; rules can be updated in a PR of their own.
request_changes is an ask, not a close: of the reviewer's past request_changes verdicts, 39% were merged after a human looked. Read the findings before acting on the verdict.

Keep existing tactics intact and centralize the identical ordered simplification inputs used by 227 machine proof calls.

@Vilin97 Vilin97 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
"summary": "Reviewed 08da721 against main d1019ce. The explicit lattice, algebra and matrix proof rewrites are sound on the inspected provider/caller readset. Nineteen shared restricted wrappers now replace 227 repeated lists, preserving their ordered inputs, all existing declaration headers/data definitions and legacy tactics. This addresses the configured review's maintenance finding. Fresh Lean compilation and protected CI at this repaired head remain pending. The public profile covers only 21 of 39 changed files, so I do not infer an overall speedup from it or adopt the author's separate benchmark as independent evidence.",
"assessment": {
"scope": "Existing GapCVP proof implementations and two supporting lemmas",
"introduces_tech_debt": false,
"maintainability": "improved",
"brittleness": "more_robust",
"risk": "medium",
"assessment_one_sentence": "Shared restricted wrappers preserve the explicit proof strategy and remove the repeated configuration identified by the configured review."
},
"verdict": "approve",
"findings": []
}

Add the tactic docstrings required by docBlame and tacticDocs for the nineteen new restricted wrappers. No proof or gate changes.

@Vilin97 Vilin97 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
"summary": "Reviewed dc52824 against main d1019ce. This revision adds the documentation required for the nineteen restricted step tactics. Removing exactly those comments restores the preceding 08da source byte for byte. The shared-wrapper repair still removes 227 repeated lists while retaining their ordered inputs and the existing declarations, data programs and legacy tactics. The preceding head compiled all 39 changed files within 20 seconds, then failed docBlame/tacticDocs for these nineteen undocumented tactics; style and quality did not run. This repaired head requires its own complete protected validation, and receives no prior-head CI credit. No overall speedup is claimed.",
"assessment": {
"scope": "Existing GapCVP proof implementations and two supporting lemmas",
"introduces_tech_debt": false,
"maintainability": "improved",
"brittleness": "more_robust",
"risk": "low",
"assessment_one_sentence": "The shared restricted wrappers address the repeated configuration, and the documentation-only follow-up directly addresses the observed lint diagnostics."
},
"verdict": "approve",
"findings": []
}

@Vilin97
Vilin97 added this pull request to the merge queue Nov 13, 2026
Merged via the queue into main with commit 701389c Nov 13, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant