Drop the absolute value from an antiderivative unless the codomain is real (#946) - #952
Merged
Merged
Conversation
… real (#946) ln(abs(f)) is an antiderivative of f'/f on the real line and nowhere else: abs is not holomorphic, so differentiating it off the line does not return the integrand. The integral table produced it unconditionally, including under the default codomain, which is the complex plane -- so the default answer to the simplest integral in the library was not an antiderivative. #946, answered there with "might need to separate by codomain", which is what this does. Eleven rules introduced the absolute value themselves and all eleven now ask AntiderivativeLog. The rule for the integral of ln(abs(ax + b)) is deliberately not among them: there the absolute value is the integrand the caller wrote rather than something the rule added, so it stays. Under Domain.Real every one of them returns exactly what it returned before, so the change is a no-op for a caller who has said where they are working. The existing integration tests asserted the real-line forms, so they are now scoped to Domain.Real and keep binding; two new theories cover the default and the real setting explicitly. The two InnerSimplify tests pinned the default and record the new value. Suite 7234 passed, 0 failed. casbench 116/119 with 0 wrong, 0 error, 0 timeout -- unchanged, and it verifies an antiderivative by differentiating it back.
16 tasks
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 #946.
ln(abs(f))is an antiderivative off'/fon the real line and nowhere else —absis not holomorphic, so differentiating it off the line does not return the integrand. The integral table produced it unconditionally, including under the default codomain, which isDomain.Complex. So the default answer to the simplest integral in the library was not an antiderivative of anything.@Happypig375 answered the issue with "Might need to separate by codomain", which is what this does.
The old answer is still available, and is now a statement about where you are working rather than the only thing on offer:
The setting already had precedent —
Patterns.Power.csasks the same question the same way, and this uses the same form.Blast radius, measured rather than assumed
The issue reads as one rule. It is twelve sites, of which eleven change. All eleven introduce the absolute value themselves, and all now route through one helper:
∫ 1/x(the issue's own case)IndefiniteIntegralSolver∫ csc,∫ tan,∫ cotIntegralPatterns∫ arctan,∫ arccotanIntegralPatternsIntegralPatternsIntegralPatternsThe twelfth is deliberately left alone.
∫ ln(abs(ax + b)) dx = ((ax+b)/a)(ln(abs(ax+b)) − 1)keeps its absolute value, because there it comes from the integrand the caller wrote rather than from the rule. Changing it would alter an answer that is already correct on both domains. The applying script asserts that rule is still present, so the distinction cannot rot silently.Behaviour
Under
Domain.Realevery one of the eleven returns exactly what it returned before, so this is a no-op for a caller who has said where they are working. Only the default changes, and it changes from a non-antiderivative to an antiderivative.Recorded in
BREAKING-CHANGES.md, marked Silent — the call still succeeds and quietly returns a different expression, which is the class of change worth reading first.Evidence
casbench116/119, 0 wrong / 0 error / 0 timeout — identical to its baseline. This is the harness that matters most here, because it verifies an antiderivative by differentiating it back rather than by comparing to stored text.1/x → ln(x) + C,tan(x) → -ln(cos(x)) + C,1/(2x+5) → ln(2x+5)/2 + C,arctan(x) → x·arctan(x) − ln(1+x²)/2 + CNineteen existing tests failed before the test changes, all from this one cause. They asserted the real-line forms, so they are now scoped to
Domain.Realand keep binding rather than being edited to agree with the new output — the twoInnerSimplifyTestcases are the exception, because they pinned the default and so their expected value is what changed. Two new theories cover the default and the real setting explicitly, so both branches of the separation are tested.What it does not do
Simplifyor evaluation — only the integral table.Domain.Realbehaviour at all.🤖 Generated with Claude Code