Skip to content

Simplify the intersection #415 asks for, and correct two tests from #666 (#415, #424, #263) - #677

Merged
Happypig375 merged 1 commit into
ASC-Community:masterfrom
Rafael-SOWNet:fix/pinned-issue-followups
Aug 4, 2026
Merged

Happypig375 merged 1 commit into
ASC-Community:masterfrom
Rafael-SOWNet:fix/pinned-issue-followups

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Following up on your review of #666, where three of the tests I added were pinning
something other than what the issue was about. Thank you for catching them — you were
right in each case.

#415 — the screenshotted example

The screenshot is

(-1; 1) /\ ((-(sqrt(33) + 3) / 6; (sqrt(33) - 3) / 6) \/ (1; +oo))

and it came back exactly as written. Two things were missing, and both are here:

  • An intersection did not distribute over a union. Nothing could be done with the
    right-hand side however simple each piece was.
  • IntersectIntervalAndInterval gave up unless every endpoint was a bare Real node.
    (sqrt(33) - 3) / 6 is a Divf, so it never was one, and the whole intersection was
    abandoned. Endpoints are now compared by what they evaluate to, while the bounds of
    the answer are taken from the original expressions — so the result stays exact
    rather than becoming a hundred decimal places.
→ (-1; (sqrt(33) - 3) / 6)

The test is now that example, rather than an intersection I chose myself.

#424 — it was an incorrect test, as you said

I had tested "5 provided x = 3", which is a Providedf. The issue is about the
Piecewise node, which is a different one — so the test was not testing the issue at
all. Rewritten with piecewise(...), including a three-branch case that checks the
branches are taken in order.

It passes. The feature does work; my test simply never exercised it.

#263 — the limit is now asserted, not just its termination

It only checked that the limit came back. The limit is what that expression was written
for, so its value is asserted: 167403915.

Still outstanding from that review

Testing

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

🤖 Generated with Claude Code

@codecov-commenter

codecov-commenter commented Aug 3, 2026 •

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 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.45%. Comparing base (90c00a8) to head (de0d8ee).
⚠️ Report is 57 commits behind head on master.

Files with missing lines Patch % Lines
...Core/Entity/Omni/Sets/SetOperators.Intersection.cs 90.00% 0 Missing and 1 partial ⚠️
...Functions/Simplification/Patterns/Patterns.Sets.cs 87.50% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #677      +/-   ##
==========================================
- Coverage   80.99%   80.45%   -0.55%     
==========================================
  Files         155      156       +1     
  Lines       13687    12925     -762     
  Branches     1957     2122     +165     
==========================================
- Hits        11086    10399     -687     
+ Misses       1990     1919      -71     
+ Partials      611      607       -4     

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

…ests

Following up on the review of #666, where three of the tests I added were pinning
something other than what the issue was about.

#415. The screenshot in the issue is

    (-1; 1) /\ ((-(sqrt(33) + 3) / 6; (sqrt(33) - 3) / 6) \/ (1; +oo))

and it came back exactly as written. Two things were missing, and both are here:

  - An intersection did not distribute over a union, so nothing could be done with
    the right-hand side however simple each piece was.
  - IntersectIntervalAndInterval gave up unless every endpoint was a bare Real node.
    (sqrt(33) - 3) / 6 is a division, so it never was one. Endpoints are compared by
    what they evaluate to now, while the bounds of the answer are taken from the
    original expressions, so the result stays exact rather than becoming a hundred
    decimal places.

It gives (-1; (sqrt(33) - 3) / 6).

#424 was tested with `provided`, which is a Providedf. The issue is about the
Piecewise node, which is a different one, so the test was not testing the issue.
Rewritten with piecewise(), including a three-branch case to check the branches are
taken in order. It passes -- the feature does work, my test simply did not exercise
it.

#263 asserted only that the limit came back. The limit is what the expression was
written for, so its value is asserted: 167403915.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Rafael-SOWNet
Rafael-SOWNet force-pushed the fix/pinned-issue-followups branch from eac626b to de0d8ee Compare August 4, 2026 11:08
@Happypig375
Happypig375 merged commit 004e3a4 into ASC-Community:master Aug 4, 2026
24 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the fix/pinned-issue-followups branch August 4, 2026 20:49
Rafael-SOWNet added a commit that referenced this pull request Aug 7, 2026
#415's behaviour was fixed by PR #677, but the example the issue reports is a
screenshot, and what was tested at the time was an intersection of my own
choosing rather than the reporter's. The maintainer said so on the issue. This
is the recorded lesson from that round -- reading an issue is not reproducing
it, and neither is reproducing something nearby -- so here is the expression,
character for character:

    (-1; 1) /\ (((-(sqrt(33) + 3)) / 6; (sqrt(33) - 3) / 6) \/ (1; +oo))
      ->  (-1; (sqrt(33) - 3) / 6)

Measured against master: it answers correctly. The inner interval runs from
about -1.457 to about 0.457, so intersecting with (-1; 1) keeps the left part
and the (1; +oo) branch contributes nothing.

Checked by membership as well as by shape -- seven points either side of the
open ends and of the surd endpoint -- so that an equal answer spelled
differently still passes while a wrong one still fails. The surd endpoints are
the point of the issue: the comparison deciding the intersection has to evaluate
them rather than compare them as written.

Test-only; 11 pass.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rafael-SOWNet added a commit that referenced this pull request Aug 7, 2026
)

* Pin the interval example #415 actually reports

#415's behaviour was fixed by PR #677, but the example the issue reports is a
screenshot, and what was tested at the time was an intersection of my own
choosing rather than the reporter's. The maintainer said so on the issue. This
is the recorded lesson from that round -- reading an issue is not reproducing
it, and neither is reproducing something nearby -- so here is the expression,
character for character:

    (-1; 1) /\ (((-(sqrt(33) + 3)) / 6; (sqrt(33) - 3) / 6) \/ (1; +oo))
      ->  (-1; (sqrt(33) - 3) / 6)

Measured against master: it answers correctly. The inner interval runs from
about -1.457 to about 0.457, so intersecting with (-1; 1) keeps the left part
and the (1; +oo) branch contributes nothing.

Checked by membership as well as by shape -- seven points either side of the
open ends and of the surd endpoint -- so that an equal answer spelled
differently still passes while a wrong one still fails. The surd endpoints are
the point of the issue: the comparison deciding the intersection has to evaluate
them rather than compare them as written.

Test-only; 11 pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Answer the condition when the equation has no unknown in it (#278)

`a = b` solved for x answered `{ }`, which asserts that no x satisfies it --
and every x does, whenever a happens to equal b. #278's second bullet asks for
`{ x : a = b }` and that is now what comes back.

An equation that does not mention the unknown has either no solutions or every
solution, and which of the two is decided by whether what is left is zero. The
first bullet of #278 was already right and stays so: `3 = 5` is `{ }` and
`3 = 3` is the whole codomain. What was missing is the third case, where the
question is not decidable at all.

Evaluation alone does not settle it. `a - a` is zero and does not look it until
the simplifier has been asked, and answering the condition there would be as
wrong as answering the empty set -- it would say "provided a = a" where the
answer is every x. So the residual is simplified before the question is called
undecidable, and `a = a` and `a + b = b + a` both give the codomain. Only an
equation with no unknown in it at all reaches this, so that simplification is
paid for once and never inside a loop.

    3 = 5          { }                    unchanged
    3 = 3          CC                     unchanged
    a = a          { }  ->  CC
    a + b = b + a  { }  ->  CC
    a = b          { }  ->  { x : a - b = 0 }
    sin(a) = 0     { }  ->  { x : sin(a) = 0 }

One case moved rather than changed. `limit(x, x, y)2 - 2` sat in
SolveOneEquation.TestInvertNodes expecting zero roots; the limit binds x, so the
equation reduces to y^2 - 2 and mentions no unknown, and it now answers
`{ x : y^2 - 2 = 0 }` -- every x when y is a square root of 2. That helper
verifies a *count* of roots through an assertion that the answer is a FiniteSet,
which this answer is not, so the case is now in the new file with the assertion
that fits it.

The condition each answer carries is checked against the equation by truth value
at concrete assignments, not by shape -- it is what the answer is claiming, and
a wrong one there is a wrong answer that looks careful. Asserting that Simplify
can prove two booleans equal would have been testing the simplifier instead, and
the helper counts the assignments that actually decided so that a vacuous pass
cannot read as agreement.

Unit 5429 pass 0 fail; F# 130/130; rootcheck 596/596 clean; casbench 113/117
0 wrong; simpsweep 10463/10463; propcheck 0 failures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

3 participants