Repository navigation
The perfect-square collapse asks the rewrite graph before it asks Simplify - #1201
Merged
Merged
Conversation
…plify #746 tier 2's last open item is a production caller for the rewrite graph, with the standing performance condition measured. The one place the library decides an equality by subtracting and simplifying is the perfect-square collapse, which the remark on it calls "the whole cost of this rule": after the numeric pre-filter passes, it ran Simplify three times over radicals to find whether the cross term matches. It now asks Saturation.ProvesEqual first, at the ceiling of rules that never enlarge, under a budget of two thousand steps and fifty milliseconds, and falls through to the symbolic test where the graph does not prove -- a false from the graph is "not proved", never "unequal", so nothing the site reached before is lost, and the numeric check at the end disposes of both routes the same way. Measured per stage on the inputs the rule fires on. Where the graph proves it is faster than what it replaces -- 0.55 ms against 1.7 to 5.1 ms for 2 * sqrt(2) * sqrt(3) against 2 * sqrt(6), and nothing where the two are already one tree, which #1198's constant fold is what made reachable. Where it does not prove it spends 0.24 ms, and it is right not to: 2 * sqrt(x) * sqrt(y) against 2 * sqrt(x * y) is the branch-cut identity the site's own remarks call false, and the guarded rule declines it. At the level of a whole Simplify the change is inside the noise, because the collapse's cost is elsewhere -- 3 to 163 ms per call, in the candidate's own Simplify and the numeric checks. So this is a caller that meets the condition, running only after the numeric pre-filter and bounded, and not a speed-up to advertise. Saturation.SafeRules is the rule list built once and lazily, so a caller inside the simplifier does not rebuild it per call and the registry is not read at type initialisation; the catalogue's private copy now reads it. PerfectSquareProofTest holds the two facts the caller rests on -- the graph proves the surd product, and it refuses the branch-cut identity -- and that the collapse answers what it answered. Part of #746. Full suite 9610 passed, 0 failed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
Every CI leg failed one test: TheSafeCeilingProvesTheCrossTerm, three seconds into a cold process, where the caller's fifty-millisecond wall went on JIT time and the surd product came back unproved. The production budget stays as it is -- a cold first call falls through to Simplify, which is the right answer and merely the slower one, once -- but a test must not carry a wall clock: steps are what bound a proof, and a wall in a test measures the runner. The test's budget keeps the caller's two thousand steps and a thirty-second wall that cannot fire. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
This was referenced Sep 7, 2026
Merged
Rafael-SOWNet
added a commit
that referenced
this pull request
Sep 7, 2026
…s measured (#1203) EMatching.md deferred whether Expands rules ever join SafeRules to "a separate document's question, once one exists", and Transformations.md's list of what is left said the graph had no production caller. Both were true when written and are not now: #1193 and #1194 measured that the growth ceiling is the scheduling policy and that Expands rules do not join the safe set; #1198 and #1202 found what the graph did need -- a rational folded on insertion and an extraction that is a fixed point from the leaves up -- by running the safe ceiling over the corpus; and #1201 gave the graph its first production caller. The documents point at those rather than at a question nobody is going to open. Part of #746. Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#746 tier 2's last open item is a production caller for the rewrite graph, with the standing
performance condition measured. #1198 measured the graph on the corpus and found it cheap and never
ahead of
Simplifyon extraction — so the caller worth having is one that needs the graph'sproof, not its form. The library has exactly one place that decides an equality by subtracting
and simplifying: the perfect-square collapse, whose remark calls that test "the whole cost of this
rule".
What changes
After the numeric pre-filter passes, the collapse asks
Saturation.ProvesEqual(crossTerm, w)first, at the safe ceiling, under 2,000 steps / 50 ms, and falls through to the three
Simplifycalls only where the graph does not prove. A
falsefrom the graph is "not proved", never"unequal", so nothing the site reached before is lost, and the numeric disposer at the end treats
both routes the same.
Saturation.SafeRulesis the rule list built once, lazily; the catalogue'sprivate copy reads it.
Measured, per stage
Simplify2·√2·√3vs2·√62·√a·√bvs itself2·√x·√yvs2·√(xy)2·√1·√(x/2)vs√(2x)So: where the graph proves it is 3–6× faster than what it replaces; where it doesn't it costs
0.24 ms; and at the level of a whole
Simplifythe change is inside the noise (before/aftermedians over 15 runs: 52.4 → 50.5 ms, 60.4 → 60.2, 46.9 → 46.3), because the collapse's cost is
in the candidate's own
Simplifyand the numeric checks, not in the equality test. This is acaller that meets the condition — it runs only after the numeric pre-filter, bounded — and not a
speed-up to advertise. What made the proved case reachable at all is #1198's constant fold
(
2·3 → 6inside the graph).PerfectSquareProofTestpins the two facts the caller rests on — the graph proves the surdproduct; it refuses
√x·√y = √(xy), so a loosened guard fails there before it reaches the rule— and that the collapse answers exactly what it answered.
Part of #746. With this, tier 2's list from the session stands at: items 1–4 done, item 5 has its
first caller; what remains is the e-matcher over the 35 two-sided rules (
EMatching.md), whichchanges speed rather than reach.
Checks
Full suite 9610 passed, 0 failed, 14 skipped — 9 of them new.
🤖 Generated with Claude Code
https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura