From 6a0d958c4e218f7e4183e60d2c55ffa9341f9ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 10 Oct 2017 12:08:57 +0200 Subject: [PATCH] [poincare] Factorize simplify code in dynamic hierarchy Change-Id: I0ae0ab5e08e4661e6eab1344baf35a535d31cd04 --- poincare/include/poincare/addition.h | 1 + poincare/include/poincare/dynamic_hierarchy.h | 5 ++++ poincare/include/poincare/multiplication.h | 2 +- poincare/src/addition.cpp | 24 +++++++++---------- poincare/src/dynamic_hierarchy.cpp | 16 +++++++++++++ poincare/src/multiplication.cpp | 15 ++++-------- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 00d996c0d..968a86ef7 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -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; }; } diff --git a/poincare/include/poincare/dynamic_hierarchy.h b/poincare/include/poincare/dynamic_hierarchy.h index ca8be932f..f0dcbe229 100644 --- a/poincare/include/poincare/dynamic_hierarchy.h +++ b/poincare/include/poincare/dynamic_hierarchy.h @@ -2,6 +2,7 @@ #define POINCARE_DYNAMIC_HIERARCHY_H #include +#include 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; }; diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index e838e3470..82079817f 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -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; }; } diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 4190fa339..ea006719d 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -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(operand(i))), *(static_cast(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(operand(i)), const_cast(operand(i+1))); - if (numberOfOperands() > 1 && operand(i)->type() == Type::Rational && static_cast(operand(i))->isZero()) { - removeOperand(operand(i), true); - if (i > 0) { - i--; - } - } } else { i++; } } - if (numberOfOperands() > 1 && operand(0)->type() == Type::Rational && static_cast(operand(0))->isZero()) { - removeOperand(operand(0), true); - } - if (numberOfOperands() == 1) { - replaceWith(const_cast(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 Poincare::Addition::compute(Poincare::Complex, Poincare::Complex); template Poincare::Complex Poincare::Addition::compute(Poincare::Complex, Poincare::Complex); diff --git a/poincare/src/dynamic_hierarchy.cpp b/poincare/src/dynamic_hierarchy.cpp index ab4525103..5e97b5f38 100644 --- a/poincare/src/dynamic_hierarchy.cpp +++ b/poincare/src/dynamic_hierarchy.cpp @@ -151,4 +151,20 @@ void DynamicHierarchy::sortChildren() { } } +void DynamicHierarchy::squashUnaryHierarchy() { + assert(parent() != nullptr); + if (numberOfOperands() == 1) { + replaceWith(const_cast(operand(0)), true); + } +} + +bool DynamicHierarchy::deleteUselessOperand(int index) { + assert(index < numberOfOperands() && numberOfOperands() > 1); + if (operand(index)->type() == Type::Rational && isUselessOperand(static_cast(operand(index)))) { + removeOperand(operand(index), true); + return true; + } + return false; +} + } diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index a82f94cf8..04b1ad875 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -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(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(operand(index))->isOne()) { - removeOperand(operand(index), true); - return true; - } - return false; +bool Multiplication::isUselessOperand(const Rational * r) { + return r->isOne(); } template Poincare::Evaluation* Poincare::Multiplication::computeOnComplexAndMatrix(Poincare::Complex const*, Poincare::Evaluation*);