Skip to content

Add up the like terms Expand produces (#164) - #676

Merged
Happypig375 merged 1 commit into
ASC-Community:masterfrom
Rafael-SOWNet:fix/expand-collects-terms
Aug 4, 2026
Merged

Happypig375 merged 1 commit into
ASC-Community:masterfrom
Rafael-SOWNet:fix/expand-collects-terms

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Closes #164 properly. My
earlier PR #666 added a test for it that asserted Simplify, and the issue is about
Expand — that was the wrong test, and the issue rightly stayed open.

(x+1)^2 * (x+2-1)^2

  -3 + 4 + 2*x*(-1) + 2*x*2 + x^2 + 2*x + 2*x*(-4) + 2*x*4 + 2*x*2*x*(-1)
  + 2*x*2*x*2 + 2*x*x^2 + x^2 + x^2*(-4) + x^2*4 + x^2*2*x*(-1)
  + x^2*2*x*2 + x^2^2

Sixteen terms, of which five are distinct. "Cannot be expanded" is exactly right.

What it does

You had both already worked out what this needs, on the issue itself: each term of the
result wants simplifying, but Simplify is far too expensive to call from inside
Expand — "some kind of fast Simplify that unites terms by their common multiplier".

That is what this is, and no more. Each term is reduced to a coefficient and a product of
powers; PowerRules folds (x^2)^2 into x^4 so the two are not counted as different
monomials; terms whose products agree are added together.

(x+1)^2 * (x+2-1)^2   →  1 + 4x + 6x² + 4x³ + x⁴
((x-1)*(x-2))^3       →  8 − 36x + 66x² − 63x³ + 33x⁴ − 9x⁵ + x⁶

The second is the case @Happypig375 asked for in the same thread.

The part that looks wasteful and is not

A term whose coefficients cancel is written out rather than dropped. That is the whole
of the correctness here. The monomial may carry a domain condition:

(4a - 2)/(2x) + (1 - 2a)/x

is zero only where x is not. Both terms are c · x⁻¹, the coefficients cancel, and
dropping the term collected the whole thing to a plain 0 — throwing the condition away.
Written out, InnerSimplified turns 0 · x⁻¹ back into 0 provided not x = 0. An
existing test caught this, and there is now one of my own pinning it.

Four existing expectations change

All to the collected form, which is the point of the change:

Test was now
ExpandCollapseTest.Factorial x^2 + x*3 + 2*x + 6 x^2 + 5*x + 6
PolyParser.TestLinear3 a + 3 + 1 a + 4
IntegrationTest.TestIndefinite same terms, C first
IntegrationTest.TestLnAbsSquared `((ln x

The last two are the same expression written differently; the first two are the
collection working.

Testing

UnitTests 3892 passed / 0 failed, FSharpWrapperUnitTests 127 passed / 0 failed, both
netstandard2.0 and net7.0 build.

12 new tests: both cases from the issue, ordinary products, unlike terms across different
variables being left apart, value preservation at points, and the cancelling-terms case
above.

🤖 Generated with Claude Code

`(x+1)^2 * (x+2-1)^2` expanded to sixteen terms, of which five are distinct. The
issue is titled "cannot be expanded" and that is what it means.

The two of you had already worked out what it needs, on the issue: each term of the
result wants simplifying, but Simplify is far too expensive to call from inside
Expand -- "some kind of fast Simplify that unites terms by their common multiplier".
That is what this is. Each term is reduced to a coefficient and a product of powers,
PowerRules folds (x^2)^2 into x^4 so the two are not counted as different monomials,
and terms whose products agree are added together. Nothing else.

    (x+1)^2 * (x+2-1)^2   1 + 4x + 6x^2 + 4x^3 + x^4
    ((x-1)*(x-2))^3       8 - 36x + 66x^2 - 63x^3 + 33x^4 - 9x^5 + x^6

The second is the case asked for in the same thread.

A term whose coefficients cancel is written out rather than dropped. That looks
wasteful, and it is the whole of the correctness here: the monomial may carry a
domain condition, and (4a - 2)/(2x) + (1 - 2a)/x is zero only where x is not.
Dropping the term collected it to a plain 0 and threw that away. Written out,
InnerSimplified turns 0 * x^-1 back into `0 provided not x = 0`. There is a test.

Four existing expectations change, all to the collected form: 3x + 2x arriving as
5x in ExpandCollapseTest, `a + 3 + 1` as `a + 4` in PolyParser, and two orderings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 96.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.99%. Comparing base (90c00a8) to head (91f976d).
⚠️ Report is 51 commits behind head on master.

Files with missing lines Patch % Lines
...Math/Functions/Evaluation/Evaluation.Definition.cs 96.00% 1 Missing and 1 partial ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #676      +/-   ##
==========================================
- Coverage   80.99%   79.99%   -1.01%     
==========================================
  Files         155      156       +1     
  Lines       13687    12687    -1000     
  Branches     1957     2075     +118     
==========================================
- Hits        11086    10149     -937     
+ Misses       1990     1928      -62     
+ Partials      611      610       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Happypig375
Happypig375 merged commit 9b50cd9 into ASC-Community:master Aug 4, 2026
24 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the fix/expand-collects-terms branch August 4, 2026 20:49
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.

(x+1)^2(x+2-1)^2 cannot be expanded

3 participants