[poincare] First version of Power::simplify

Change-Id: Ief654c8f57bacd84a3ee5e386548b131c1ed65d3
This commit is contained in:
Émilie Feral
2017-10-06 13:07:33 +02:00
parent 5fa0d8e089
commit 22be8032e1
2 changed files with 101 additions and 2 deletions

View File

@@ -3,6 +3,8 @@
#include <poincare/static_hierarchy.h>
#include <poincare/evaluation_engine.h>
#include <poincare/rational.h>
#include <poincare/multiplication.h>
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);
};
}

View File

@@ -6,9 +6,8 @@ extern "C" {
#include <math.h>
#include <poincare/complex_matrix.h>
#include <poincare/power.h>
#include <poincare/multiplication.h>
#include <poincare/integer.h>
#include <poincare/opposite.h>
#include <poincare/undefined.h>
#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<const Rational *>(operand(0));
if (a->isZero()) {
if (operand(1)->type() == Type::Rational) {
const Rational * b = static_cast<const Rational *>(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<const Rational *>(operand(1));
simplifyRationalPower(const_cast<Expression *>(operand(0)), const_cast<Rational *>(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<Rational *>(e)), b->numerator());
replaceWith(new Rational(r),true);
return;
} else if (e->type() == Type::Power) {
return simplifyPowerPower(static_cast<Power *>(e), b);
} else if (e->type() == Type::Multiplication) {
return simplifyPowerMultiplication(static_cast<Multiplication *>(e), b);
}
}
if (e->type() == Type::Rational) {
return simplifyRationalRationalPower(static_cast<Rational *>((Expression *)operand(0)), b);
}
}
void Power::simplifyPowerPower(Power * p, Rational * r) {
const Expression * multOperands[2] = {const_cast<Expression *>(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<Expression *>(operand(0)), static_cast<Rational *>((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<Expression *>(m->operand(index));
const Expression * powOperands[2] = {factor, rCopy};
Power * p = new Power(powOperands, false);
m->replaceOperand(factor, p, false);
p->simplifyRationalPower(const_cast<Expression *>(p->operand(0)), static_cast<Rational *>(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
}*/
}