Power constructor: merges (B^k)^e → B^(k·e) when sound (k = ±1 or * e an integer), drops exponent 1. Also emulates Mathematica's input * auto-evaluation, which the Rubi corpus assumes: compound numeric-linear * exponents collapse (1+2n−2(1+n) → −1) and u^0 → 1 unconditionally (CE * soundly refus
(ce: ComputeEngine, base: Expression, exp: Expression)
| 197 | * exponents collapse (1+2n−2(1+n) → −1) and u^0 → 1 unconditionally (CE |
| 198 | * soundly refuses this for unknown u; WL applies it on input). */ |
| 199 | function pow(ce: ComputeEngine, base: Expression, exp: Expression): Expression { |
| 200 | if (exp.operator === 'Add' && leafCountOf(exp) <= 24) { |
| 201 | try { |
| 202 | const collapsed: Expression = exp.simplify(); |
| 203 | if (collapsed.isNumberLiteral) exp = collapsed; |
| 204 | } catch { |
| 205 | // deadline during exponent simplify: keep the original exponent |
| 206 | } |
| 207 | } |
| 208 | if (exp.isSame(0)) return ce.One; |
| 209 | if (exp.isSame(1)) return base; |
| 210 | if (base.operator === 'Power' && base.ops) { |
| 211 | const inner = base.ops[1]; |
| 212 | const mergeable = |
| 213 | inner.isSame(-1) || |
| 214 | inner.isSame(1) || |
| 215 | (isNumber(exp) && exp.isInteger === true); |
| 216 | if (mergeable) { |
| 217 | const merged = inner.mul(exp).evaluate(); |
| 218 | return pow(ce, base.ops[0], merged); |
| 219 | } |
| 220 | } |
| 221 | return ce._fn('Power', [base, exp]); |
| 222 | } |
| 223 | |
| 224 | /** |
| 225 | * Rebuild an expression through the canonical constructors. Pattern |
no test coverage detected