Repository navigation
Simplify the intersection #415 asks for, and correct two tests from #666 (#415, #424, #263) - #677
Merged
Happypig375 merged 1 commit intoAug 4, 2026
Conversation
|
Codecov Report❌ Patch coverage is
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. 🚀 New features to boost your workflow:
|
…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
force-pushed
the
fix/pinned-issue-followups
branch
from
August 4, 2026 11:08
eac626b to
de0d8ee
Compare
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>
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.
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
and it came back exactly as written. Two things were missing, and both are here:
right-hand side however simple each piece was.
IntersectIntervalAndIntervalgave up unless every endpoint was a bareRealnode.(sqrt(33) - 3) / 6is aDivf, so it never was one, and the whole intersection wasabandoned. 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.
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 aProvidedf. The issue is about thePiecewisenode, which is a different one — so the test was not testing the issue atall. Rewritten with
piecewise(...), including a three-branch case that checks thebranches 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
here:
SolveSystemreturnsnullwhen it finds nothing, and what it should returninstead — an empty matrix, an empty set, something else — is an API decision I would
rather you made than guess at. Try another equation when elimination stalls, fixing dense linear systems (#608) #667 fixed one reason it was reaching that line
needlessly, but the line itself is untouched. Happy to do it once you say which.
Expandrather than a test problem.Testing
UnitTests3886 passed / 0 failed,FSharpWrapperUnitTests127 passed / 0 failed, bothnetstandard2.0andnet7.0build.🤖 Generated with Claude Code