Skip to content

A power of the variable is a substitution even where it is written nowhere (#233) - #1135

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
a-power-of-the-variable-is-a-substitution
Sep 1, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
a-power-of-the-variable-is-a-substitution

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Part of #233.

The gap, which was about syntax rather than about integration

int x / (x^4 + 1) came back unevaluated. It wants u = x^2, and two separate things stopped it:

  1. Candidates were taken from the subexpressions that occur, and x^2 occurs nowhere in x / (x^4 + 1). So it was never offered.
  2. Had it been offered, substituting it would have replaced nothing — x^4 is not written as (x^2)^2, and a substitution matches what is written. The integrand would have kept its x and the candidate would have been rejected anyway.

int x^3 / (x^4 + 1) worked throughout, because its substitution u = x^4 does occur. One of the pair working and the other not, for a reason with nothing to do with integration, is what made this hard to see from the outside.

The fix

A power of the variable now offers its divisors as candidates, and substituting a power rewrites the other powers of the variable into powers of itself — which it can do exactly when its exponent divides theirs.

Neither half assumes anything. The caller still checks that no x survives, so a candidate that does not clear the variable is rejected exactly as before.

Newly integrable

x/(x^4 + 1) arctan(x^2)/2 + C
x/(x^4 - 1)
x/(x^4 + 4)
x^2/(x^6 + 1) arctan(x^3)/3 + C
x/(x^6 + 1) arctan and log
x^3/(x^8 + 1) arctan(x^4)/4 + C
x^3/(x^12 + 1)

Each verified by differentiating the answer and comparing with the integrand at nine sampled points, not by reading the printed form. These come out with arctangents and radicals whose shape says nothing about whether they are right, and a wrong constant factor still differentiates back to something proportional — so arctan(x^2)/2 is additionally asserted as a form.

What it still declines, deliberately

x^2 / (x^4 + 1) under u = x^2 leaves a bare x, so it is still rejected — that integral needs the denominator factored over the reals (x^4 + 1 is irreducible over the rationals; it is (x^2 - sqrt(2)x + 1)(x^2 + sqrt(2)x + 1)), which this does not do. It stays open on the issue, and there is a test asserting it is declined so that a future change has to be deliberate about it.

sqrt(tan(x)) likewise remains — the issue calls it "very painful, requires different solvers", and it does.

Measured

Eleven integrals taking the other paths — a substitution that does occur, partial fractions, by parts, a logarithm — are checked the same way and are unchanged. Failed: 0, Passed: 9264 on net10.0, in 6m38s against ~6m50s before, so the extra candidates cost nothing measurable.

Three of the five cases #233 lists were already answered before this: cos(x^2)*x, sin(x)*e^x and 1/(a^2 + x^2), the last as a piecewise on the sign of a^2. Measured, not assumed — the issue's boxes were all still unticked.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

…where

`int x / (x^4 + 1)` came back unevaluated. It wants `u = x^2`, and two separate things stopped it.

Candidates were taken from the subexpressions that occur, and `x^2` occurs nowhere in
`x / (x^4 + 1)`. So it was never offered. And had it been offered, substituting it would have
replaced nothing: `x^4` is not written as `(x^2)^2`, and a substitution matches what is written, so
the integrand would have kept its `x` and the candidate would have been rejected anyway.

`int x^3 / (x^4 + 1)` worked throughout, because its substitution `u = x^4` does occur. That is what
made the gap hard to see from the outside -- one of the pair works and the other does not, for a
reason that is about syntax rather than about integration.

So a power of the variable now offers its divisors as candidates, and substituting a power rewrites
the other powers of the variable into powers of itself, which it can do exactly when its exponent
divides theirs. Nothing is assumed by either: the caller still checks that no `x` survives, so a
candidate that does not clear the variable is rejected as before. `x^2 / (x^4 + 1)` is exactly that
case -- a bare `x` remains, it is still declined, and it stays open on the issue, since it needs the
denominator factored over the reals rather than a substitution.

Newly integrable, each verified by differentiating the answer and comparing with the integrand at
nine sampled points rather than by reading the printed form:

    x/(x^4 + 1)     arctan(x^2)/2 + C
    x/(x^4 - 1)     x/(x^4 + 4)      x^2/(x^6 + 1)
    x/(x^6 + 1)     x^3/(x^8 + 1)    x^3/(x^12 + 1)

Eleven integrals taking the other paths -- a substitution that does occur, partial fractions, by
parts, a logarithm -- are checked the same way and are unchanged. The full suite is green and takes
the same time it did, so the extra candidates cost nothing measurable.

Part of #233. Three of the five it lists were already answered; `sqrt(tan(x))` and
`x^2 / (x^4 + 1)` remain.
@Rafael-SOWNet
Rafael-SOWNet merged commit a720972 into master Sep 1, 2026
31 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the a-power-of-the-variable-is-a-substitution branch October 29, 2026 00:43
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.

1 participant