Repository navigation
A condition the answer states on its own is no longer repeated beside it - #1396
Merged
Merged
Conversation
(1 - ln(x))/x^2 provided not x = 0 excludes a point the expression never reaches: the quotient by x^2 and the ln(x) are each undefined at zero already. A provided whose condition the expression proves on its own -- a quotient by d, a negative power of d, a logarithm of d or to the base d, or d^f with f vanishing too, for d the condition's e, a positive power of it, a product holding it, a polynomial in the variable e is with no constant term, or a polynomial that is zero at the root of a linear e -- comes back without that conjunct. Proven structurally and never guessed: a false negative is a redundant clause, a false positive would claim a value at a point. Only the answer is read this way, and only its top. Inside a piecewise a predicate decides which case is taken and falls through to the next where it fails, so it is not redundant even where the case's expression is undefined without it. And inside the simplifier's own search a provided is what several rules read as "this candidate needs a condition": taken off there, in Providedf's InnerSimplify, the substitution search accepted candidates it had declined and ran x/sin(x) for a minute where it declines in half a second, with the candidates growing to ninth powers on the way. At Simplify's boundary the answer is the same and the search is untouched. The derivatives of ln(x)/x, x^x and x^n lose the condition they repeated (#1394, from the comparison page). One limit is answered by it: (x + sin(x))/x at infinity was 1 + sin(x)/x provided not x = 0 after the division, and the condition stood between the descent and the sum; it is 1 now, by the squeeze theorem, and the two tests that pinned the decline pin the answer. Recorded in BREAKING-CHANGES.md as an improvement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
…ed an entry, both kept
This was referenced Sep 17, 2026
Rafael-SOWNet
added a commit
that referenced
this pull request
Sep 17, 2026
…read in the codomain #1396 decided by the shape of the node -- a quotient by d, a negative power of d, a logarithm of d, d^f with f vanishing -- what the library already says per node: DomainConditionIn(codomain) is what an expression accepts under the reading it is asked in, a nonzero divisor, a nonzero base or a positive exponent, a nonzero antilogarithm over the complex plane and a positive one over the reals, a cosine that is not zero for a tangent. A provided not e = 0 is redundant where that domain condition already excludes the zeros of e: a conjunct not d = 0 or d > 0 with d vanishing there -- e itself, a positive power of it, a product holding it, a sine, tangent, arcsine or arctangent of such a thing, or a polynomial in the variable e is with no constant term -- or a disjunction every side of which does, as x^x's not x = 0 or x > 0. Nothing in the rule decides what a node accepts, so it follows the codomain: when #217 gives 1/0 a value under the codomains that admit a complex infinity, the quotient's domain condition changes there and the condition beside 1/x stops being redundant by itself. The answers are #1396's, and the shapes the list missed: tan(x) provided not cos(x) = 0 and sin(x)/x provided not x = 0 drop their conditions too. Recorded in the Providedf section of SimplificationContract.md, in the comparison page's provided paragraph and in the #1396 entry of BREAKING-CHANGES. Four suites green; the performance gate passed. Part of #1394. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
Rafael-SOWNet
added a commit
that referenced
this pull request
Sep 17, 2026
…read in the codomain (#1402) * A pole is a value, so only an indeterminate form lets Simplify drop the condition beside it #1394's reading: a provided says where the expression has a value, and 1/x at zero has one, the point at infinity, so 1/x provided not x = 0 is a different expression from 1/x and keeps its condition. #1396 dropped it, reading a quotient by d, a negative power of d and a logarithm of d as undefined at the zeros of d; those arms go, and only 0^0 and 0/0 -- d^f or n/d with both vanishing at the zeros of the condition's expression -- are read, a sine, tangent, arcsine or arctangent of something vanishing counting as vanishing. x^x's derivative stays bare, ln(x)/x's derivative keeps its condition as before #1396, and (x + sin(x))/x still has limit 1 at infinity since sin(x)/x is 0/0 at zero. The reading is recorded in the Providedf section of SimplificationContract.md, with the codomain caveat, in the comparison page's provided paragraph, and in the #1396 entry of BREAKING-CHANGES, rewritten to the net behaviour with the day the wider rule stood on master noted. Four suites green; the performance gate passed. Part of #1394. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura * Simplify drops a condition the answer's own domain condition states, read in the codomain #1396 decided by the shape of the node -- a quotient by d, a negative power of d, a logarithm of d, d^f with f vanishing -- what the library already says per node: DomainConditionIn(codomain) is what an expression accepts under the reading it is asked in, a nonzero divisor, a nonzero base or a positive exponent, a nonzero antilogarithm over the complex plane and a positive one over the reals, a cosine that is not zero for a tangent. A provided not e = 0 is redundant where that domain condition already excludes the zeros of e: a conjunct not d = 0 or d > 0 with d vanishing there -- e itself, a positive power of it, a product holding it, a sine, tangent, arcsine or arctangent of such a thing, or a polynomial in the variable e is with no constant term -- or a disjunction every side of which does, as x^x's not x = 0 or x > 0. Nothing in the rule decides what a node accepts, so it follows the codomain: when #217 gives 1/0 a value under the codomains that admit a complex infinity, the quotient's domain condition changes there and the condition beside 1/x stops being redundant by itself. The answers are #1396's, and the shapes the list missed: tan(x) provided not cos(x) = 0 and sin(x)/x provided not x = 0 drop their conditions too. Recorded in the Providedf section of SimplificationContract.md, in the comparison page's provided paragraph and in the #1396 entry of BREAKING-CHANGES. Four suites green; the performance gate passed. Part of #1394. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --------- 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.
#1394:
(1 − ln(x))/x^2 provided not x = 0excludes a point the expression never reaches — the quotient byx^2and theln(x)are each undefined at zero already — and says twice what the expression says once. Aprovidedwhose condition the expression proves on its own comes back without that conjunct.What is proven, and how. A condition
not e = 0is implied where the expression has a node undefined at every zero ofe: a quotient byd, a negative power ofd, a logarithm ofdor to the based, ord^fwithfvanishing too — fordequal toe, a positive power of it, a product holding it, a polynomial in the variableeis with no constant term, or a polynomial that is zero at the root of a lineare. Structural and never guessed: a false negative is a redundant clause, a false positive would claim a value at a point. A condition the expression does not state is kept —x/xstill simplifies to1 provided not x = 0, since1no longer says it;1/(x^2 + 1) provided not x = 0keeps its condition,y/x provided not a x = 0keeps its.Where — and where not. Only the answer of
Simplify, and only its top. Inside a piecewise a predicate decides which case is taken and falls through where it fails, so it is not redundant even when the case's expression is undefined without it. And inside the simplifier's own search aprovidedis what several rules read as "this candidate needs a condition": the first version dropped it inProvidedf.InnerSimplify, and the substitution search then accepted candidates it had declined and ranx/sin(x)for a minute (candidates growing to ninth powers) where it declines in half a second. AtSimplify's boundary the answer is the same and the search is untouched; the gate reads SimplifyEasy +0.6%, SimplifyHard +0.9%, all rows within threshold."ln(x)/x".Differentiate("x").Simplify()(1 − ln(x))/x^2 provided not x = 0(1 − ln(x))/x^2"x^x".Differentiate("x").Simplify()(1 + ln(x)) x^x provided not x = 0(1 + ln(x)) x^x"x^n".Differentiate("x").Simplify()x^n n/x provided not x = 0x^n n/x"1/(x^2 + x) provided not x = 0 and not x + 1 = 0".Simplify()1/(x^2 + x)"(x + sin(x))/x".Limit("x", "+oo")1The last row is a consequence worth naming: after the division the limit's integrand was
1 + sin(x)/x provided not x = 0, and the condition stood between the descent and the sum; without it the squeeze theorem answerssin(x)/xand the limit is 1. Two tests pinned the decline (GruntzTest,LimitAtInfinityTest, "no rule anywhere has a reading of it"); they now pin the answer inBoundedTimesVanishingTest, andx cos(x),x sin(x)stay declined.On the two questions in the issue. Dropping is sound whichever way "undefined" is read —
NaNtoday, a complex infinity under #217 — since aprovidedsays the expression has no value where the condition fails, and nothing changes where it has none anyway; the two notions would differ only in what the value at the point is called, which a condition never gave. And it is a question of the domain (where the expression is defined), not the codomain: the codomain setting decides which branch or which real form is written (ln|x|againstln x), and a condition dropped or kept is the same statement under either.Recorded in
BREAKING-CHANGES.mdas an improvement. Four suites green; the newProvidedImpliedByTheExpressionTestpins eight drops, two derivatives, and three conditions that must stay.Part of #1394.
🤖 Generated with Claude Code
https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura