Repository navigation
Show the rewrites worth reading, not all 270 of them (#28) - #978
Merged
Merged
Conversation
RewriteRecording collects every rewrite that fires. On the expression #28 was filed about, `x^(-1)/(y/z)`, that is 270 of them, cycling, almost all the canonical-order sort. The mechanism was there and the answer was not readable. Derivation is the same list with two things taken out: - rewrites from sets that only put an expression into a canonical shape, which is 251 of the 270 here; - rewrites already shown, since the simplifier explores several candidate forms and rewrites the same subexpression the same way in each. 270 becomes 6, and the six are what the reporter asked for. Their Output[0] was `any1 / (any2 / any3) -> any1 * any3 / any2` written out by hand; that rule is in the derivation, named, with the subexpression it fired on. `x + x` and `sin(x)^2 + cos(x)^2` come back as one step each. Normalisation is *declared* by the rule set rather than detected. Reordering `y + x` to `x + y` and collapsing `x + x` to `2 * x` are both equivalences that change the tree; which one was meant as tidying is a fact about intent that no amount of looking at the rewrite settles. Hence RewriteRuleSet.IsNormalization, true for the three sorts and nothing else. **What this is not, and the docs say so.** It is a set of rewrites, not a path. Simplify searches candidates and keeps the best, so some entries belong to branches that lost -- visible on `(x + 1) * (x - 1)`, whose derivation contains a difference-of-squares step to `(x - sqrt(1)) * (x + sqrt(1))` that is not on the route to `x ^ 2 - 1`. And a step's Before is a subexpression, not the whole expression at that moment. A single path with whole-expression stages needs Simplificator.Alternate to record which candidate each rewrite belonged to, which it does not do. Recording whole-expression transitions instead was tried first and measured worse: 509 rule-set applications, 214 of them changing, against 270 node rewrites. Volume is not what stands between the recording and an explanation; selection is. Public API: two additive members. Suite 7317 passed, 0 failed, 14 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 17, 2026
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.
Closes #28.
RewriteRecordingcollects every rewrite that fires. On the expression #28 was filed about, that is 270 of them, cycling, almost all the canonical-order sort:The mechanism was there; the answer was not readable.
Derivationis the same list with two things taken out — rewrites from sets that only put an expression into a canonical shape (251 of the 270 here), and rewrites already shown, since the simplifier explores several candidate forms and rewrites the same subexpression the same way in each.270 becomes 5, and they are what the reporter asked for:
Output[1]is the rule the reporter wrote out by hand —any1 / (any2 / any3) -> any1 * any3 / any2— named, with the subexpression it fired on.x + xandsin(x)^2 + cos(x)^2come back as one step each.Normalisation is declared, not detected
RewriteRuleSet.IsNormalization, true for the three sorts and nothing else. Reorderingy + xtox + yand collapsingx + xto2 * xare both equivalences that change the tree; which one was meant as tidying is a fact about intent that no amount of looking at the rewrite settles. So the set says.What this is not, and the docs say so
It is a set of rewrites, not a path.
Simplifysearches candidates and keeps the best, so some entries belong to branches that lost — visible on(x + 1) * (x - 1), whose derivation contains a difference-of-squares step to(x - sqrt(1)) * (x + sqrt(1))that is not on the route tox ^ 2 - 1. And a step'sBeforeis a subexpression, not the whole expression at that moment.A single path with whole-expression stages needs
Simplificator.Alternateto record which candidate each rewrite belonged to. That is not here.The design I tried first, and why it is not this
I assumed the fix was recording whole-expression transitions rather than node-level ones, and measured before building it: 509 rule-set applications, 214 of them changing the expression, against 270 node-level steps. Recording more faithfully is worse. The problem is not granularity, it is that most of what happens is not worth reading — so the answer had to be selection.
Tests and checks
Four tests added, including one asserting the raw recording does contain normalisation, so the filter test cannot pass vacuously.
Public API is exactly two additive members:
Suite 7317 passed, 0 failed, 14 skipped.
One thing worth stating rather than hiding: an earlier run of this suite had
OneSidedLimitTest.ADifferenceOfReciprocalLogarithms(Left)fail, taking 1 m against 11 s in isolation. It passes in isolation, it passed on the re-run, andmasterran clean — and this change is data-only, so nothing in the library reads either new member. I believe it is a flake in a test this repo has recorded as timing-sensitive before, but I would rather say so than report a first-time-green suite.