diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index 256c1d479..cf16e64ba 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -63,10 +63,8 @@ private: }; class Multiplication : public NAryExpression { - friend class AdditionNode; friend class Addition; friend class Power; - friend class UnitConvert; public: Multiplication(const MultiplicationNode * n) : NAryExpression(n) {} static Multiplication Builder(const Tuple & children = {}) { return TreeHandle::NAryBuilder(convert(children)); } @@ -92,7 +90,6 @@ public: private: // Simplification Expression privateShallowReduce(ExpressionNode::ReductionContext reductionContext, bool expand, bool canBeInterrupted); - void mergeMultiplicationChildrenInPlace(); void factorizeBase(int i, int j, ExpressionNode::ReductionContext reductionContext); void mergeInChildByFactorizingBase(int i, Expression e, ExpressionNode::ReductionContext reductionContext); void factorizeExponent(int i, int j, ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/n_ary_expression.h b/poincare/include/poincare/n_ary_expression.h index 6db14d2ed..97455f3af 100644 --- a/poincare/include/poincare/n_ary_expression.h +++ b/poincare/include/poincare/n_ary_expression.h @@ -52,6 +52,7 @@ public: Expression squashUnaryHierarchyInPlace() { return node()->squashUnaryHierarchyInPlace(); } + void mergeSameTypeChildrenInPlace(); /* allChildrenAreReal returns: * - 1 if all children are real * - 0 if all non real children are ComplexCartesian diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 02167bf56..9db97c40d 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -144,14 +144,7 @@ Expression Addition::shallowReduce(ExpressionNode::ReductionContext reductionCon /* Step 1: Addition is associative, so let's start by merging children which * are additions. */ - int i = 0; - while (i < numberOfChildren()) { - if (childAtIndex(i).type() == ExpressionNode::Type::Addition) { - mergeChildrenAtIndexInPlace(childAtIndex(i), i); - continue; - } - i++; - } + mergeSameTypeChildrenInPlace(); const int childrenCount = numberOfChildren(); assert(childrenCount > 1); @@ -230,7 +223,7 @@ Expression Addition::shallowReduce(ExpressionNode::ReductionContext reductionCon /* Step 5: Factorize like terms. Thanks to the simplification order, those are * next to each other at this point. */ - i = 0; + int i = 0; while (i < numberOfChildren()-1) { Expression e1 = childAtIndex(i); Expression e2 = childAtIndex(i+1); diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 38b9fd4e3..9a7fff846 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -481,7 +481,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu } // Build final Expression result = Multiplication::Builder(resultWithoutUnit, units); - static_cast(result).mergeMultiplicationChildrenInPlace(); + static_cast(result).mergeSameTypeChildrenInPlace(); } } @@ -505,7 +505,7 @@ Expression Multiplication::privateShallowReduce(ExpressionNode::ReductionContext /* Step 1: MultiplicationNode is associative, so let's start by merging children * which also are multiplications themselves. */ - mergeMultiplicationChildrenInPlace(); + mergeSameTypeChildrenInPlace(); Context * context = reductionContext.context(); @@ -790,19 +790,6 @@ Expression Multiplication::privateShallowReduce(ExpressionNode::ReductionContext return result; } -void Multiplication::mergeMultiplicationChildrenInPlace() { - // Multiplication is associative: a*(b*c)->a*b*c - int i = 0; - while (i < numberOfChildren()) { - Expression c = childAtIndex(i); - if (c.type() == ExpressionNode::Type::Multiplication) { - mergeChildrenAtIndexInPlace(c, i); - continue; - } - i++; - } -} - void Multiplication::factorizeBase(int i, int j, ExpressionNode::ReductionContext reductionContext) { /* This function factorizes two children which have a common base. For example * if this is Multiplication::Builder(pi^2, pi^3), then pi^2 and pi^3 could be merged diff --git a/poincare/src/n_ary_expression.cpp b/poincare/src/n_ary_expression.cpp index 917877808..314f4b8cb 100644 --- a/poincare/src/n_ary_expression.cpp +++ b/poincare/src/n_ary_expression.cpp @@ -97,6 +97,21 @@ int NAryExpressionNode::simplificationOrderGreaterType(const ExpressionNode * e, return 0; } +void NAryExpression::mergeSameTypeChildrenInPlace() { + // Multiplication is associative: a*(b*c)->a*b*c + // The same goes for Addition + ExpressionNode::Type parentType = type(); + int i = 0; + while (i < numberOfChildren()) { + Expression c = childAtIndex(i); + if (c.type() != parentType) { + i++; + } else { + mergeChildrenAtIndexInPlace(c, i); + } + } +} + int NAryExpression::allChildrenAreReal(Context * context) const { int i = 0; int result = 1; diff --git a/poincare/src/unit_convert.cpp b/poincare/src/unit_convert.cpp index 0002bb500..a4d4fedd5 100644 --- a/poincare/src/unit_convert.cpp +++ b/poincare/src/unit_convert.cpp @@ -71,7 +71,7 @@ Expression UnitConvert::shallowReduce(ExpressionNode::ReductionContext reduction return Undefined::Builder(); } division = Multiplication::Builder(Float::Builder(floatValue), finalUnit); - static_cast(division).mergeMultiplicationChildrenInPlace(); + static_cast(division).mergeSameTypeChildrenInPlace(); replaceWithInPlace(division); return division; }