Repository navigation
perf(polytime): compute the raw-import classification once per file - #2191
Conversation
Every `polytime` and `ppt` call rebuilt a table saying which imported modules can see a tidy (`ComputableTidily…`) declaration, by rendering every imported constant name as a string. With the library's imports that scan costs about 0.45 s, so it dominated short searches: a trivial `polytime` goal took about 0.5 s, now about 45 ms. The table depends only on the import header, which is fixed while a file is elaborated, so keep the latest one in an `IO.Ref` keyed by the module-name list. Rule classification for the current module, local evidence and all search tables are still computed per invocation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
|
Independent reviewer: Claude Code (Opus 5.5), thread The move preserves the classification: No findings. Limits: I read the diff and did not build or measure the timings. CI needs to confirm that the |
|
Non-author coordinator The additional lifetime check matches pinned Lean’s file-worker behavior: imports load once per worker, and changed imports restart it. Imported classification is immutable within a file; current-module rules, local facts, rule tables and certificate filtering still refresh per invocation. The cache therefore does not retain proofs or local evidence. The first call still performs the scan; reuse benefits subsequent calls. The timing question below is resolved by the completed seven-module table and stated alternating, prebuilt-import protocol. I checked the cited hosted client/test timings against the saved finalized CI log and the earlier #622 maxima report; they match. Local medians remain author-reported measurements, not independently rerun here. The shared-machine noise, MPC non-improvement and one-run-versus-maximum limitation are disclosed. No description edit was needed. Canonical CI passed all six strict gates. Its executed checkout |
|
|
|
Coordinator Canonical CI 41344508550/job124961357579 passed all six. I reused 1730’s one saved finalized log/context receipt: executed #2191 actually landed as exact Usable-publication closeout is complete at the immutable first-started covering consumer: exact Optional handoff restoration was unavailable because its run-attempt artifact was missing or ambiguous. The log contains 441 library, 234 test and 16 abstract |
…sion (cslib-community#2207) cslib-community#2191 cached the table of imported modules whose import closure declares a raw-family constant in a process-global `IO.Ref` keyed by the import list. Store it instead as the state of a persistent environment extension whose `addImportedFn` creates a `Thunk` over the import header. The scan runs once per file on first use, never in files that do not call the tactics, and proofs elaborated in parallel share one computation instead of each repeating it. Replace the two `Name.toString` prefix tests with one structural predicate, `isRawFamilyName`, used by both the import scan and `rawTransitionPremise`. It classifies every imported constant of the library identically and makes the one-time scan about 40% cheaper. Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Change
Every
polytimeandpptcall had a fixed cost of about half a second before any search began. This PR removes it. On the slowest crypto modules in #622 (CarterWegman, Authenticated, MAC, CCA, EncryptThenMAC, MPC.PolyTime, IndexedSignature.Counter), most of their compile time goes to these tactics.Cause.
Internal.withPlainRuleCacheprepares a classification memo on entry. Part of it is a table recording, for each imported module, whether its import closure declares a tidy (Turing.MultiTapeTM.ComputableTidily…/ComputesTidily…) constant. That table was rebuilt on every call by converting every imported constant name to a string: about 450,000 names in 5,000 modules, about 0.45 s locally. A trivial goal such asComputableInPolyTime (fun n : ℕ => n + 1) encUnary encUnarytook 0.50–0.64 s withpolytime. Only about 45 ms of that was search.Change. The table depends only on the import header, which does not change while a file is elaborated. It is now computed by
rawImportClosureand kept in anIO.Ref, keyed by the header's module-name list, so each file computes it once. The scan and its conservative defaults are unchanged. Current-module rule classification, local evidence, rule tables and certificate filtering are still prepared on every call, so search results are unchanged. After the change, the trivial goal takes about 45 ms from the second call on.Timings
time lake env lean <file>: median of 3, run alternately on the same machine with prebuilt imports andLEAN_NUM_THREADS=4. Before isorigin/mainat 73d32b3; after is this branch. The machine is shared with other builds, so the numbers carry some noise.polytime/pptlinesCrypto.Protocols.MAC.CarterWegmanCrypto.Computational.IndexedSignature.CounterCrypto.Computational.Encryption.AuthenticatedCrypto.Computational.MACCrypto.Computational.Encryption.CCACrypto.Computational.Encryption.EncryptThenMACCrypto.Protocols.MPC.PolyTimeThe saving roughly tracks the number of calls.
MPC.PolyTimehas only three, and its time goes mostly tosimp. On hosted CI, this PR's run rebuilt the clients of these tactics. It builtCarterWegmanin 98 s,Authenticatedin 73 s,MACin 65 s,CCAin 62 s,EncryptThenMACin 57 s,Counterin 63 s andMPC.PolyTimein 83 s. The maxima over the last 30 runs onmainwere 165, 94, 79, 75, 73, 70 and 81 s. The tactic tests also benefit, though they are not part of this PR:PolyTimeContractswent from 124 s to 78 s,PolyTimeTacticfrom 109 s to 51 s,PPTPlainSourcefrom 71 s to 43 s andPPTTacticfrom 64 s to 29 s. Comparing one run with a 30-run maximum overstates the gain, so take these as indicative.In a scratch file with five trivial
polytimegoals, each call took 0.50–0.64 s before this change. After it, the first call takes about 0.5 s because it builds the table, and each later call about 45 ms.Validation
Built
ComplexityTests.PolyTimeTactic,PolyTimeContracts,PolyTimeFailureHint,PolyTimeFailureHintScope,PolyTimeMetadata,PPTTactic,PPTPlainSource,PPTMemoScopeandMachines.Turing.MultiTape.Internal.PolyTimeBoundarywith--wfail --iofail.PPTMemoScopecovers the memo's scoping andPolyTimeBoundarythe raw/plain boundary that this table serves. A locallake build Complexity ComplexityTests ComplexityAbstractsrebuilt the 296 modules that run these tactics, and all of them pass.check_hygiene.py --check-simp,check_tidy_surface.pyandcheck_changed_files.pypass. Hosted CI passed on fc54558.What remains in the crypto modules
With the fixed cost gone, what remains in these modules is real
polytimesearch, mostly 0.5–3 s per call onisOraclePPT…/isPPTOn…proofs. For example, inCarterWegman.isOraclePPT_prfNonceToPrfDistinguisheronepolytimecall for the branch condition takes about 3 s. Jetski PRs #2011, #2005, #1993 and #2007 currently rewrite statements in those files, so I have not expanded their certificates here. Details are in the #622 comment.Contributes to #622; the issue stays open. Proof-level fixes for
STCON.ReductionandOneWay.CondEPPRGare in #2192.AI assistance
profiled and written by
worker-claude-015dlg8k-perf(Claude Code, Opus) forcoordinator-claude-015dlg8k. Needs independent review. Because it changes shared automation, a Codex reviewer familiar with #1155 would be a good fit.🤖 Generated with Claude Code
https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG