Skip to content

perf(ACMax): simplify arithmetic certificates and reduce compile time - #729

Queued
Vilin97 wants to merge 2 commits into
mainfrom
researcher/optimize-acmax-20261102
Queued

Vilin97 wants to merge 2 commits into
mainfrom
researcher/optimize-acmax-20261102

Conversation

@Vilin97

@Vilin97 Vilin97 commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

ACMax's arithmetic tactics repeatedly inspect large graph proof contexts. This change limits those tactics to the scalar facts they need and replaces several searches with explicit order and polynomial certificates. It also removes 154 transitively redundant public import statements using lake shake --keep-public. Only the existing ACMax project and its generated module index change.

Base: edbe5bd56f476cc2965564676b66199f281ab714.
Head: 9928dba2860d790af0eb42962244c89cac397ce8.
The repository's pins remain Lean 4.35.0-rc3 and Mathlib c55e6e786f49471c72fbddbec5415808896aec1e.

The project was selected from the existing source profile: approximately 33,000 lines across 66 files, with 121.3 seconds of instrumented source time. The cubic certificate and girth transport proof accounted for 7.88 s and 7.69 s of that historical source profile. Those historical numbers guided selection; the measurements below use clean project builds.

Concrete changes:

  • Keep positivity in shifted coordinates in the uniform power certificates, and reuse a scalar census inequality in both range proofs.
  • Factor the two Sigma transfer estimates into small scalar lemmas and restrict the overflow argument to its linear inequalities.
  • Supply the girth transport step with its nonnegative products so linear arithmetic replaces nonlinear cross-product generation.
  • Use explicit edge-charge facts in double-star case proofs, named algebraic identities for pointwise simplification, and only the needed inequalities in finite-case injectivity proofs.
  • Use order and power monotonicity directly in the Rayleigh, quotient and sharp Moore bounds.
  • Compile three scalar Moore certificates in an independent Counting.Arithmetic module. The original theorem names and signatures remain as wrappers.

Declaration audit: before editing, import LeanPool.ACMax.Imports with private visibility, extensions disabled and trust level zero. Serialize every project declaration's owner, name, kind, universes, safety, raw type expression, and complete non-theorem value and metadata. Retain and compare those raw records after the change. All 2,831 original declarations remain: 2,823 records are byte-identical, and eight private generated proof types differ only in bound variable labels. A second Lean traversal renames bound labels only and verifies those eight types are identical in every other expression node and metadata field. Its base raw records are also checked against the original pre-edit manifest. There are zero missing declarations or semantic differences; all 85 original definition values remain byte-identical. Nine declarations are added: six supporting theorems and three generated proofs. No original statement, definition, universe parameter, safety level or public name changes.

Observed clean-build results (chronological order):

Revision/run Wall seconds User CPU seconds System CPU seconds Peak process RSS (KiB)
base-1 283.49 396.88 35.54 2,096,556
head-1 276.49 361.69 36.58 2,103,032
head-2 265.68 363.46 36.17 2,101,148
base-2 322.05 399.80 35.87 2,094,512

Mean wall time falls from 302.77 s to 271.085 s (10.47%). Mean user CPU falls from 398.34 s to 362.575 s (8.98%). Peak process RSS does not improve. These are observations from four runs on a shared VM; the remaining wall-time variability limits any claim about other runs or hardware.

A follow-up profile of StarMoatSharp found its previously expensive nonlinear arithmetic call at 3.64 s on the base and below the 100 ms reporting threshold on the head. This check did not show the suspected per-module regression.

Measurement method: remove every ACMax root/subtree Lean and IR build artifact before each run; retain the same warm, private external dependency cache. Run committed, clean source trees in base/head/head/base order with LEAN_NUM_THREADS=4 /usr/bin/time -v taskset -c 4-7 lake --wfail build LeanPool.ACMax.Imports. Record each source fingerprint, wall time, user/system CPU and maximum process RSS. CPU affinity is identical on both revisions; the VM remains shared.

Validation passed:

  • Warning-free selected-project build.
  • lake exe mk_all --module --check.
  • lake exe runLinter --no-build LeanPool.ACMax.Imports (all imported LeanPool declarations).
  • lake exe lint-style LeanPool.ACMax.Imports (selected source import closure).
  • python -m lean_pool.quality --repo .. --static-only.
  • The unchanged repository axiom, option-backdoor, project-card and declaration checks restricted to all 67 ACMax modules: zero errors.
  • Independent private-import axiom traversal: 2,840 project declarations and 43,131 transitive constants, with only Quot.sound, Classical.choice and propext.
  • lake shake --force --keep-public LeanPool.ACMax.Imports: zero remaining suggestions.
  • git diff --check.

The full compiled pool and protected review remain for CI. No gates, linter configuration, waivers or toolchain pins change. This PR does not request queue entry or auto-merge.

@greptile-apps

greptile-apps Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

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 concrete blocker was found in the reviewed changes.

Summary

This refactor narrows arithmetic tactics to the facts they need and moves three Moore certificates into a graph-independent module.

  • Sharp Moore bounds use standalone arithmetic certificates.
  • Arithmetic proofs use focused facts instead of broad searches.
  • ACMax modules rely on fewer repeated public imports.

Performance conclusions rely on the supplied measurements. No build or timing run was performed during this review. The removed Mathlib imports and external source/license evidence were not independently rechecked.

Reviews (1) · Last reviewed commit: "perf(ACMax): isolate scalar proofs and t..." · Reviewed by Greptile

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Proof profile (new / modified Lean files)

lake build wall time (changed modules): 16.54 s (= 0.28 min) — user 6.08 s, sys 3.81 s.

This build covers the added modules and their dependency cones on top of the measurement environment; modified files are measured without rebuilding the pool.

Statement changes

✅ No statements changed — all 669 tracked declarations across 49 modified files kept their type; only proofs / definition bodies changed.

Also: 3 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 (3)
  • ACMax.uniform_count_bound — LeanPool/ACMax/Band/CertUniform.lean
  • ACMax.sigma_nonusable_transfer_arithmetic — LeanPool/ACMax/Counting/SigmaCloud.lean
  • ACMax.sigma_usable_transfer_arithmetic — LeanPool/ACMax/Counting/SigmaCloud.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: 6,414,755 → 5,668,482 (-746,273, -11.6%). Commands: 3,808 → 3,810.

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

Files: 43 compared — 6 cheaper, 0 costlier, 37 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/ACMax/Counting/StarvedCensus.lean +2/-5 460,402 238,511 -221,890 -48.2% 30.30 12.72
LeanPool/ACMax/Spectral/RayleighLower.lean +6/-6 203,637 25,867 -177,770 -87.3% 11.12 2.88
LeanPool/ACMax/Counting/SigmaCloud.lean +21/-13 1,164,976 1,006,097 -158,879 -13.6% 54.57 51.53
LeanPool/ACMax/Counting/StarMoatSharp.lean +2/-4 825,247 736,059 -89,188 -10.8% 46.99 37.25
LeanPool/ACMax/Counting/Quotient.lean +2/-1 249,427 181,949 -67,478 -27.1% 18.15 10.97
LeanPool/ACMax/Counting/FarPair.lean +52/-56 938,957 907,886 -31,071 -3.3% 47.95 38.00
LeanPool/ACMax/Counting/HubCross.lean +0/-8 224,789 224,794 +5 +0.0% 17.75 13.96
LeanPool/ACMax/Counting/SparseCore.lean +0/-1 39,747 39,746 -1 -0.0% 5.22 4.69
LeanPool/ACMax/Cuts/TriangleFree2K2.lean +0/-5 56,639 56,638 -1 -0.0% 4.40 4.91
LeanPool/ACMax/Counting/DoubleStar.lean +0/-2 80,990 80,989 -0 -0.0% 8.17 6.85
LeanPool/ACMax/Reduction/Reduction.lean +0/-4 58,924 58,924 +0 +0.0% 5.23 4.57
LeanPool/ACMax/Spectral/AlgConnK2.lean +0/-4 60,988 60,988 -0 -0.0% 5.36 5.15
LeanPool/ACMax/Counting/XBoundAssembly.lean +0/-3 108,880 108,881 +0 +0.0% 10.12 8.29
LeanPool/ACMax/Cuts/SignedCut.lean +0/-6 74,285 74,284 -0 -0.0% 7.44 5.24
LeanPool/ACMax/Cuts/LowDegreeVertex.lean +0/-5 43,851 43,850 -0 -0.0% 4.30 3.53
LeanPool/ACMax/Cuts/Disconnected.lean +0/-1 3,191 3,191 +0 +0.0% 2.14 2.02
LeanPool/ACMax/Spectral/TestVector.lean +0/-2 2,922 2,922 +0 +0.0% 2.31 2.20
LeanPool/ACMax/Cuts/WeightedCut.lean +0/-6 77,346 77,346 +0 +0.0% 6.79 6.02
LeanPool/ACMax/AHL/AHLAmGm.lean +0/-1 61,658 61,658 +0 +0.0% 10.46 8.98
LeanPool/ACMax/AHL/NBWalk.lean +0/-1 2,858 2,858 +0 +0.0% 4.23 3.55
LeanPool/ACMax/AHL/NBWalkCount.lean +0/-1 5,386 5,386 +0 +0.0% 4.60 3.74
LeanPool/ACMax/AHL/NBWeighted.lean +0/-1 236 236 +0 +0.0% 1.89 1.57
LeanPool/ACMax/Band/AssemblyAllRange.lean +0/-1 15,454 15,454 +0 +0.0% 4.14 3.48
LeanPool/ACMax/Counting/Cherry.lean +0/-3 148,060 148,060 +0 +0.0% 13.16 9.97
LeanPool/ACMax/Counting/CherryMShape.lean +0/-4 161,151 161,151 +0 +0.0% 10.64 12.37
LeanPool/ACMax/Counting/CompactCell.lean +0/-1 155,869 155,869 +0 +0.0% 13.64 10.82
LeanPool/ACMax/Counting/CompactLedgers.lean +0/-7 247,204 247,204 +0 +0.0% 16.41 12.67
LeanPool/ACMax/Counting/DecoratedC4.lean +0/-1 30,933 30,933 +0 +0.0% 4.97 3.97
LeanPool/ACMax/Counting/LargeN.lean +0/-10 195,263 195,263 +0 +0.0% 11.36 13.35
LeanPool/ACMax/Counting/MEdgeSparse.lean +0/-1 29,834 29,834 +0 +0.0% 4.57 3.76
LeanPool/ACMax/Counting/Moats.lean +0/-2 160,514 160,514 +0 +0.0% 10.04 11.83
LeanPool/ACMax/Counting/ResidualInterface.lean +0/-6 6,588 6,588 +0 +0.0% 3.15 2.64
LeanPool/ACMax/Counting/SqrtGirth.lean +0/-7 45,173 45,173 +0 +0.0% 8.19 7.39
LeanPool/ACMax/Counting/TripleCensus.lean +0/-1 68,865 68,865 +0 +0.0% 6.25 4.25
LeanPool/ACMax/Counting/Windows.lean +0/-3 52,014 52,014 +0 +0.0% 4.30 5.31
LeanPool/ACMax/Cuts/GoodC4.lean +0/-2 16,543 16,543 +0 +0.0% 3.38 2.59
LeanPool/ACMax/Cuts/GoodK23.lean +0/-2 22,828 22,828 +0 +0.0% 3.33 2.84
LeanPool/ACMax/Cuts/Ind2K2.lean +0/-4 148,997 148,997 +0 +0.0% 11.80 9.49
LeanPool/ACMax/Cuts/TwoCut.lean +0/-5 101,858 101,858 +0 +0.0% 7.47 7.48
LeanPool/ACMax/Reduction/GapReduction.lean +0/-1 195 195 +0 +0.0% 2.40 1.69
LeanPool/ACMax/Reduction/Residual.lean +0/-2 22,311 22,311 +0 +0.0% 3.96 3.34
LeanPool/ACMax/Spectral/AlgConn.lean +0/-1 634 634 +0 +0.0% 2.48 2.03
LeanPool/ACMax/Spectral/RayleighUpper.lean +0/-4 39,133 39,133 +0 +0.0% 5.04 3.92
Total +85/-204 6,414,755 5,668,482 -746,273 -11.6% 460.2 373.8

New files — absolute profile

Total heartbeats: 979,595 maxHeartbeats units across 4 valid files (164 added LOC).

Sum of lean --profile: 2727.4 ms (= 2.73 s) across 1 valid file. Import-excluded time: 1537.4 ms (= 1.54 s).

Count-heartbeats wall-clock total: 62.93 s. Repeated import cost inside lean --profile: 1190.0 ms (= 1.19 s).

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/ACMax/Counting/PoorCorner.lean 4 713,298 36.53 — — — 279 0
LeanPool/ACMax/Band/CertUniform.lean 31 115,589 13.09 — — — 14 0
LeanPool/ACMax/Counting/V9Discharge.lean 1 114,911 9.08 — — — 93 0
LeanPool/ACMax/Counting/Arithmetic.lean 109 35,797 4.23 2.73 1.54 1.19 23 0
LeanPool/ACMax/Band/CertAllRange.lean 2 — — — — — 14 1
LeanPool/ACMax/Counting/V9DischargeSharp.lean 16 — — — — — 0 1
LeanPool/ACMax/Imports.lean 1 — — — — — 0 1
Total 164 979,595 62.93 2.73 1.54 1.19 423 3

Aggregate phase totals

Phase Time
import 1190.0 ms (= 1.19 s)
interpretation 586.0 ms (= 0.59 s)
typeclass inference 251.0 ms (= 0.25 s)
ring 168.0 ms (= 0.17 s)
type checking 136.0 ms (= 0.14 s)
tactic execution 125.0 ms (= 0.12 s)
share common exprs 53.8 ms (= 0.05 s)
linting 47.6 ms (= 0.05 s)
elaboration 45.8 ms (= 0.05 s)
initialization 32.5 ms (= 0.03 s)
process pre-definitions 30.8 ms (= 0.03 s)
norm_num 23.8 ms (= 0.02 s)

Slowest changed modules (from lake build)

Changed module Lake time
LeanPool.ACMax.Counting.Arithmetic 3.40 s
Per-file `lean --profile` output

LeanPool/ACMax/Counting/Arithmetic.lean

import took 1.19s
cumulative profiling times:
	attribute application 0.0415ms
	elaboration 45.8ms
	fix level params 2.95ms
	import 1.19s
	initialization 32.5ms
	instantiate metavars 6.29ms
	interpretation 586ms
	let-to-have transformation 0.0865ms
	linting 47.6ms
	module linting 0.00145ms
	norm_num 23.8ms
	overlappingInstancesLinter 2.07ms
	parsing 6.29ms
	process pre-definitions 30.8ms
	ring 168ms
	share common exprs 53.8ms
	tactic execution 125ms
	tacticAnalysis 19.4ms
	type checking 136ms
	typeclass inference 251ms
real 2.79
user 2.23
sys 0.93

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

@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.

Independent Source APPROVE at 9928dba2860d790af0eb42962244c89cac397ce8; no findings.

The complete 50-file delta and all 26 changed/new proof commands were reviewed, including the full new 109-line arithmetic module. The explicit polynomial identities, sign bounds, product monotonicity and focused tactic inputs discharge the original graph/counting/spectral obligations. Existing theorem contracts and the three public V9 wrappers remain intact; the new scalar helpers remove large graph contexts from arithmetic proofs.

All 154 removed public imports have actual current public runtime re-export paths to the same modules, checked against the complete project and pinned Mathlib sources. The complete native patches round-trip in both directions; existing written declaration prefixes and all 71 non-theorem commands are preserved. The facade, card, other projects and noncontent inputs remain unchanged. These are source and module-exposure checks, without a claim of compiled environment equality.

Author-reported benchmarks are attributed rather than treated as independently reproduced measurements. Current own authored CI is still pending. Configured review, the current-main infrastructure hold and normal protected native-queue checks remain separate.

{
  "summary": "This refactor removes redundant public imports, extracts the graph-free integer inequalities into a shared Arithmetic module while retaining the old public wrappers, and replaces broad arithmetic automation with explicit products, sign bounds and focused tactic inputs. The changed counting and spectral arguments retain their mathematical witnesses and case structure. Actual public reexport paths preserve every removed import at its original module path; no actionable maintainability regression was found.",
  "assessment": {
    "scope": "import pruning, shared arithmetic extraction and targeted proof elaboration",
    "introduces_tech_debt": false,
    "maintainability": "improved",
    "brittleness": "more_robust",
    "risk": "medium",
    "assessment_one_sentence": "The explicit arithmetic interfaces and focused proof steps improve maintainability while preserving the old written contracts and public module exposure."
  },
  "verdict": "approve",
  "findings": []
}

@Vilin97

Vilin97 commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator Author

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

Reviewed head: 9928dba2860d790af0eb42962244c89cac397ce8

Verdict: ✅ approve

This refactor replaces broad arithmetic searches with explicit order arguments and focused certificates, extracts graph-independent Moore lemmas behind compatibility wrappers, and preserves the existing proof structure. All 154 removed public imports remain transitively reachable. The supplied profile supports lower compile cost for the compared files; local compilation stopped at the missing Mathlib dependency, so I did not independently reproduce build timings.

Aspect Value
Scope arithmetic tactic rewrite and module extraction
Introduces tech debt ✅ no
Maintainability ✅ improved
Brittleness ✅ more_robust
Risk ✅ low

Explicit arithmetic dependencies and isolated scalar lemmas make these proofs easier to debug and maintain without losing reusable entry points.


Tokens: 1,215,347 in / 7,361 out · Tier: codex-subscription · Effort: xhigh · Billing: Codex subscription quota (no API credits) · Estimated cost: $4.9718 (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.

@Vilin97
Vilin97 added this pull request to the merge queue Nov 2, 2026
Any commits made after this event will not be merged.
@Vilin97
Vilin97 removed this pull request from the merge queue due to a manual request Nov 3, 2026
@Vilin97
Vilin97 added this pull request to the merge queue Nov 3, 2026
Any commits made after this event will not be merged.

This branch has not been deployed

No deployments
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