Skip to content

Simplify does not gather a^p / b^p into (a/b)^p when a base is itself a power #740

Description

@Rafael-SOWNet

Simplify gathers a quotient of two powers with the same exponent into a single power — a^p / b^p becomes (a/b)^p — but it stops doing so as soon as one of the bases is itself a power.

"(y + 1) ^ x / y ^ x".Simplify()            // (1 + 1/y) ^ x          ✅ gathered
"(x ^ 2 + 1) ^ x / (x ^ 2 + 2) ^ x".Simplify()  // (1 + (-1)/(x^2 + 2)) ^ x  ✅ gathered
"a ^ x / b ^ x".Simplify()                  // (a / b) ^ x           ✅ gathered

"(a ^ 2 + 1) ^ x / (a ^ 2) ^ x".Simplify()  // unchanged             ❌
"(x ^ 2 + 1) ^ x / (x ^ 2) ^ x".Simplify()  // unchanged             ❌
"(x ^ 3 + 1) ^ x / (x ^ 3) ^ x".Simplify()  // unchanged             ❌

It is the shape of the base, not the variable: a^2 fails exactly as x^2 does, while a plain variable or a sum gathers fine.

A second way in, with the same outcome by a different route — here the denominator is flattened first, so the two exponents stop matching and there is nothing left to gather on:

"(sqrt(x) + 1) ^ x / sqrt(x) ^ x".Simplify()   // (sqrt(x) + 1) ^ x / x ^ (x/2)

Why it is worth fixing

Gathering is what makes these tractable downstream. The limit machinery reads a 1^oo off the single power and cannot see one in the quotient, so the same limit is answered or not depending only on how it was written:

"((x ^ 2 + 1) / x ^ 2) ^ x".Limit("x", "+oo")   // 1              ✅  (20 ms)
"(x ^ 2 + 1) ^ x / (x ^ 2) ^ x".Limit("x", "+oo")  // unevaluated ❌  (5.5 s)

Both are the same function, and the second spends five seconds not answering it.

This is not a wrong answer — the quotient form declines rather than returning something false — so it is a gap rather than a defect.

Context

Found while fixing #738, where the sibling quotients were gathered and so were being answered wrongly rather than not at all. That fix re-reads the second remarkable limit after simplification, which covers everything the gathering reaches; this issue is exactly the remainder it cannot reach, because for these no single power is ever produced.

Measured on master at 318ac9f.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions