[poincare] In power: (a^b)^c = a^(b+c) if a > 0 or c is integer

Change-Id: Iad7b559de5e15972a54e322bca832d78596abf53
This commit is contained in:
Émilie Feral
2017-10-06 17:06:46 +02:00
parent d855ee8364
commit 082e6468f7
2 changed files with 18 additions and 9 deletions

View File

@@ -34,7 +34,7 @@ private:
int compareToSameTypeExpression(const Expression * e) const override;
/* Simplification */
void immediateSimplify() override;
void simplifyPowerPower(Power * p, Rational * r);
void simplifyPowerPower(Power * p, Expression * r);
void simplifyPowerMultiplication(Multiplication * m, Rational * r);
void simplifyRationalRationalPower(Rational * a, Rational * b);
static Expression * CreateSimplifiedIntegerRationalPower(Integer i, Rational * r);

View File

@@ -160,10 +160,6 @@ void Power::immediateSimplify() {
Rational r = Rational::Power(*(e), b->numerator());
replaceWith(new Rational(r),true);
return;
} else if (operand(0)->type() == Type::Power) {
Power * e = static_cast<Power *>((Expression *)operand(0));
simplifyPowerPower(e, b);
return;
} else if (operand(0)->type() == Type::Multiplication) {
Multiplication * e = static_cast<Multiplication *>((Expression *)operand(0));
simplifyPowerMultiplication(e, b);
@@ -176,14 +172,27 @@ void Power::immediateSimplify() {
return;
}
}
// TODO: (a^b)^c -> a^(b+c) if a > 0
// (a^b)^c -> a^(b+c) if a > 0 or c is integer
if (operand(0)->type() == Type::Power) {
Power * p = static_cast<Power *>((Expression *)operand(0));
// Check is a > 0 or c is Integer
if (p->operand(0)->isPositive() ||
(operand(1)->type() == Type::Rational && static_cast<Rational *>((Expression *)operand(1))->denominator().isOne())) {
simplifyPowerPower(p, const_cast<Expression *>(operand(1)));
return;
}
}
// TODO: (a*b)^c -> |a|^c*(sign(a)*b)^c
}
void Power::simplifyPowerPower(Power * p, Rational * r) {
const Expression * multOperands[2] = {const_cast<Expression *>(p->operand(1)), r};
void Power::simplifyPowerPower(Power * p, Expression * e) {
Expression * p0 = const_cast<Expression *>(p->operand(0));
Expression * p1 = const_cast<Expression *>(p->operand(1));
p->detachOperands();
const Expression * multOperands[2] = {p1, e};
Multiplication * m = new Multiplication(multOperands, 2, false);
replaceOperand(r, m, false);
replaceOperand(e, m, false);
replaceOperand(p, p0, true);
m->immediateSimplify();
immediateSimplify();
}