[poincare] Factorize simplify code in dynamic hierarchy

Change-Id: I0ae0ab5e08e4661e6eab1344baf35a535d31cd04
This commit is contained in:
Émilie Feral
2017-10-10 12:08:57 +02:00
parent 6be0cb8b94
commit 6a0d958c4e
6 changed files with 39 additions and 24 deletions

View File

@@ -41,6 +41,7 @@ private:
void factorizeChildren(Expression * e1, Expression * e2);
static const Rational RationalFactor(Expression * e);
static bool TermsHaveIdenticalNonRationalFactors(const Expression * e1, const Expression * e2);
bool isUselessOperand(const Rational * r) override;
};
}

View File

@@ -2,6 +2,7 @@
#define POINCARE_DYNAMIC_HIERARCHY_H
#include <poincare/hierarchy.h>
#include <poincare/rational.h>
namespace Poincare {
@@ -23,10 +24,14 @@ public:
void addOperandAtIndex(Expression * operand, int index);
void mergeOperands(DynamicHierarchy * d);
void sortChildren();
void squashUnaryHierarchy();
protected:
bool deleteUselessOperand(int index);
private:
void removeOperandAtIndex(int i, bool deleteAfterRemoval);
int compareToSameTypeExpression(const Expression * e) const override;
int compareToGreaterTypeExpression(const Expression * e) const override;
virtual bool isUselessOperand(const Rational * r) = 0;
const Expression ** m_operands;
int m_numberOfOperands;
};

View File

@@ -43,7 +43,7 @@ private:
static bool TermHasRationalBase(const Expression * e);
static bool TermHasRationalExponent(const Expression * e);
static const Expression * CreateExponent(Expression * e);
bool deleteUselessFactor(int index);
bool isUselessOperand(const Rational * r) override;
};
}

View File

@@ -40,28 +40,23 @@ void Addition::immediateSimplify() {
sortChildren();
int i = 0;
while (i < numberOfOperands()-1) {
if (deleteUselessOperand(i) && i > 0) {
i--;
}
if (i == numberOfOperands()-1) {
break;
}
if (operand(i)->type() == Type::Rational && operand(i+1)->type() == Type::Rational) {
Rational a = Rational::Addition(*(static_cast<const Rational *>(operand(i))), *(static_cast<const Rational *>(operand(i+1))));
replaceOperand(operand(i), new Rational(a), true);
removeOperand(operand(i+1), true);
} else if (TermsHaveIdenticalNonRationalFactors(operand(i), operand(i+1))) {
factorizeChildren(const_cast<Expression *>(operand(i)), const_cast<Expression *>(operand(i+1)));
if (numberOfOperands() > 1 && operand(i)->type() == Type::Rational && static_cast<const Rational *>(operand(i))->isZero()) {
removeOperand(operand(i), true);
if (i > 0) {
i--;
}
}
} else {
i++;
}
}
if (numberOfOperands() > 1 && operand(0)->type() == Type::Rational && static_cast<const Rational *>(operand(0))->isZero()) {
removeOperand(operand(0), true);
}
if (numberOfOperands() == 1) {
replaceWith(const_cast<Expression *>(operand(0)), true);
}
squashUnaryHierarchy();
}
void Addition::factorizeChildren(Expression * e1, Expression * e2) {
@@ -125,6 +120,11 @@ void Addition::immediateBeautify() {
}
}
bool Addition::isUselessOperand(const Rational * r) {
return r->isZero();
}
template Poincare::Complex<float> Poincare::Addition::compute<float>(Poincare::Complex<float>, Poincare::Complex<float>);
template Poincare::Complex<double> Poincare::Addition::compute<double>(Poincare::Complex<double>, Poincare::Complex<double>);

View File

@@ -151,4 +151,20 @@ void DynamicHierarchy::sortChildren() {
}
}
void DynamicHierarchy::squashUnaryHierarchy() {
assert(parent() != nullptr);
if (numberOfOperands() == 1) {
replaceWith(const_cast<Expression *>(operand(0)), true);
}
}
bool DynamicHierarchy::deleteUselessOperand(int index) {
assert(index < numberOfOperands() && numberOfOperands() > 1);
if (operand(index)->type() == Type::Rational && isUselessOperand(static_cast<const Rational *>(operand(index)))) {
removeOperand(operand(index), true);
return true;
}
return false;
}
}

View File

@@ -97,7 +97,7 @@ void Multiplication::immediateSimplify() {
/* Now, no more node can be an addition or a multiplication */
int i = 0;
while (i < numberOfOperands()-1) {
if (deleteUselessFactor(i) && i > 0) {
if (deleteUselessOperand(i) && i > 0) {
i--;
}
if (i == numberOfOperands()-1) {
@@ -115,9 +115,7 @@ void Multiplication::immediateSimplify() {
i++;
}
}
if (numberOfOperands() == 1) {
replaceWith(const_cast<Expression *>(operand(0)), true);
}
squashUnaryHierarchy();
}
void Multiplication::factorizeBase(Expression * e1, Expression * e2) {
@@ -187,13 +185,8 @@ bool Multiplication::TermHasRationalExponent(const Expression * e) {
return hasRationalExponent;
}
bool Multiplication::deleteUselessFactor(int index) {
assert(index < numberOfOperands() && numberOfOperands() > 1);
if (operand(index)->type() == Type::Rational && static_cast<const Rational *>(operand(index))->isOne()) {
removeOperand(operand(index), true);
return true;
}
return false;
bool Multiplication::isUselessOperand(const Rational * r) {
return r->isOne();
}
template Poincare::Evaluation<float>* Poincare::Multiplication::computeOnComplexAndMatrix<float>(Poincare::Complex<float> const*, Poincare::Evaluation<float>*);