diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index 095dfe5cb..04152da80 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -3,6 +3,8 @@ #include #include +#include +#include namespace Poincare { @@ -29,6 +31,12 @@ private: int compareToGreaterTypeExpression(const Expression * e) const override; int compareToSameTypeExpression(const Expression * e) const override; + /* Simplification */ + void immediateSimplify() override; + void simplifyRationalPower(Expression * e, Rational * b); + void simplifyPowerPower(Power * p, Rational * r); + void simplifyPowerMultiplication(Multiplication * m, Rational * r); + void simplifyRationalRationalPower(Rational * a, Rational * b); }; } diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 9ad16bfa9..c94aa6279 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -6,9 +6,8 @@ extern "C" { #include #include #include -#include -#include #include +#include #include "layout/baseline_relative_layout.h" namespace Poincare { @@ -103,4 +102,96 @@ int Power::compareToGreaterTypeExpression(const Expression * e) const { return operand(1)->compareTo(&one); } +void Power::immediateSimplify() { + if (operand(0)->type() == Type::Undefined || operand(1)->type() == Type::Undefined) { + replaceWith(new Undefined(), true); + return; + } + if (operand(0)->type() == Type::Rational) { + const Rational * a = static_cast(operand(0)); + if (a->isZero()) { + if (operand(1)->type() == Type::Rational) { + const Rational * b = static_cast(operand(1)); + if (!b->isNegative()) { + replaceWith(new Rational(Integer(0)), true); + return; + } else { + replaceWith(new Undefined(), true); + return; + } + } + } + if (a->isOne()) { + replaceWith(new Rational(Integer(1)), true); + } + } + if (operand(1)->type() == Type::Rational) { + const Rational * b = static_cast(operand(1)); + simplifyRationalPower(const_cast(operand(0)), const_cast(b)); + } +} + +void Power::simplifyRationalPower(Expression * e, Rational * b) { + if (b->isZero()) { + replaceWith(new Rational(Integer(0)), true); + return; + } + if (b->isOne()) { + replaceWith(new Rational(Integer(1), true)); + return; + } + /* a^n with n Integer */ + if (b->denominator().isOne()) { + if (e->type() == Type::Rational) { + Rational r = Rational::Power(*(static_cast(e)), b->numerator()); + replaceWith(new Rational(r),true); + return; + } else if (e->type() == Type::Power) { + return simplifyPowerPower(static_cast(e), b); + } else if (e->type() == Type::Multiplication) { + return simplifyPowerMultiplication(static_cast(e), b); + } + } + if (e->type() == Type::Rational) { + return simplifyRationalRationalPower(static_cast((Expression *)operand(0)), b); + } +} + +void Power::simplifyPowerPower(Power * p, Rational * r) { + const Expression * multOperands[2] = {const_cast(p->operand(1)), r}; + Multiplication * m = new Multiplication(multOperands, 2, false); + replaceOperand(r, m, false); + m->immediateSimplify(); + if (operand(1)->type() == Type::Rational) { + simplifyRationalPower(const_cast(operand(0)), static_cast((Expression *)operand(1))); + } +} + +void Power::simplifyPowerMultiplication(Multiplication * m, Rational * r) { + for (int index = 0; index < m->numberOfOperands(); index++) { + Expression * rCopy = r->clone(); + Expression * factor = const_cast(m->operand(index)); + const Expression * powOperands[2] = {factor, rCopy}; + Power * p = new Power(powOperands, false); + m->replaceOperand(factor, p, false); + p->simplifyRationalPower(const_cast(p->operand(0)), static_cast(rCopy)); + } + detachOperand(m); + replaceWith(m, true); // delete r + m->immediateSimplify(); +} + +void Power::simplifyRationalRationalPower(Rational * a, Rational * b) { + /*const Expression * n = SimplifyIntegerRationalPower(a->numerator(), b); + const Expression * d = SimplifyIntegerRationalPower(a->denominator(), b); + const Expression * multOp[2] = {n, d}; + Multiplication * m = new Multiplication(multOp, 2, false); + replaceWith(m, true); + m->immediateSimplify();*/ +} + +/*Expression * Power::SimplifyIntegerRationalPower(Integer i, Rational * r) { +// TODO +}*/ + }