diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 7a17468eb..738600510 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -55,7 +55,7 @@ private: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; // Derivation bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override; @@ -83,7 +83,7 @@ public: static Addition Builder(Expression e1, Expression e2) { return Addition::Builder({e1, e2}); } // Expression Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); - Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext); bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue); int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const; void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) { diff --git a/poincare/include/poincare/complex_cartesian.h b/poincare/include/poincare/complex_cartesian.h index 5f6734dce..c19de35fa 100644 --- a/poincare/include/poincare/complex_cartesian.h +++ b/poincare/include/poincare/complex_cartesian.h @@ -30,7 +30,7 @@ private: Evaluation approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate(approximationContext); } // Simplification Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; LayoutShape leftLayoutShape() const override { /* leftLayoutShape is called after beautifying expression. ComplexCartesian * is transformed in another expression at beautifying. */ @@ -54,7 +54,7 @@ public: // Simplification Expression shallowReduce(); - Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext); // Common operations (done in-place) Expression squareNorm(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/decimal.h b/poincare/include/poincare/decimal.h index 60a217438..f1c0db848 100644 --- a/poincare/include/poincare/decimal.h +++ b/poincare/include/poincare/decimal.h @@ -61,7 +61,7 @@ public: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; LayoutShape leftLayoutShape() const override { assert(!m_negative); return LayoutShape::Decimal; }; LayoutShape rightLayoutShape() const override { return LayoutShape::Decimal; } diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 9c3307846..84a763257 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -390,7 +390,7 @@ protected: Expression makePositiveAnyNegativeNumeralFactor(ExpressionNode::ReductionContext reductionContext); Expression denominator(ExpressionNode::ReductionContext reductionContext) const { return node()->denominator(reductionContext); } Expression shallowReduce(ExpressionNode::ReductionContext reductionContext) { return node()->shallowReduce(reductionContext); } - Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext) { return node()->shallowBeautify(reductionContext); } + Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { return node()->shallowBeautify(reductionContext); } Expression deepBeautify(ExpressionNode::ReductionContext reductionContext); // WARNING: this must be called on reduced expressions Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext); @@ -429,6 +429,10 @@ private: Expression defaultHandleUnitsInChildren(); // Children must be reduced Expression shallowReduceUsingApproximation(ExpressionNode::ReductionContext reductionContext); Expression defaultShallowBeautify() { return *this; } + void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) { + node()->deepBeautifyChildren(reductionContext); + } + void defaultDeepBeautifyChildren(ExpressionNode::ReductionContext reductionContext); bool defaultDidDerivate() { return false; } Expression defaultUnaryFunctionDifferential() { return *this; } diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index e3000d8f7..aee2cd79f 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -284,8 +284,9 @@ public: /* Simplification */ /*!*/ virtual void deepReduceChildren(ReductionContext reductionContext); + /*!*/ virtual void deepBeautifyChildren(ReductionContext reductionContext); /*!*/ virtual Expression shallowReduce(ReductionContext reductionContext); - /*!*/ virtual Expression shallowBeautify(ReductionContext reductionContext); + /*!*/ virtual Expression shallowBeautify(ReductionContext * reductionContext); /*!*/ virtual bool derivate(ReductionContext, Expression symbol, Expression symbolValue); virtual Expression unaryFunctionDifferential(); /* Return a clone of the denominator part of the expression */ diff --git a/poincare/include/poincare/factor.h b/poincare/include/poincare/factor.h index 3e16af3ab..c9203bdf2 100644 --- a/poincare/include/poincare/factor.h +++ b/poincare/include/poincare/factor.h @@ -27,7 +27,7 @@ private: /* Serialization */ int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Simplification */ - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; Expression shallowReduce(ReductionContext reductionContext) override; LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } @@ -49,7 +49,7 @@ public: // Expression Expression shallowReduce(Context * context); - Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext); }; } diff --git a/poincare/include/poincare/great_common_divisor.h b/poincare/include/poincare/great_common_divisor.h index 28a4665a7..739b5db3a 100644 --- a/poincare/include/poincare/great_common_divisor.h +++ b/poincare/include/poincare/great_common_divisor.h @@ -26,7 +26,7 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation diff --git a/poincare/include/poincare/least_common_multiple.h b/poincare/include/poincare/least_common_multiple.h index 10545e171..169f14e4a 100644 --- a/poincare/include/poincare/least_common_multiple.h +++ b/poincare/include/poincare/least_common_multiple.h @@ -26,7 +26,7 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation diff --git a/poincare/include/poincare/logarithm.h b/poincare/include/poincare/logarithm.h index f56f740d0..1c9465c14 100644 --- a/poincare/include/poincare/logarithm.h +++ b/poincare/include/poincare/logarithm.h @@ -29,7 +29,7 @@ public: // Simplification void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override; Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Derivation diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index 452cfcb61..d8b80bf0b 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -47,7 +47,7 @@ private: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; Expression denominator(ExpressionNode::ReductionContext reductionContext) const override; // Derivation bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override; @@ -85,7 +85,7 @@ public: // Simplification Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); - Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext); Expression denominator(ExpressionNode::ReductionContext reductionContext) const; void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) { NAryExpression::sortChildrenInPlace(order, context, false, canBeInterrupted); diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index c9a25279d..74e21ea8e 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -53,7 +53,7 @@ private: // Simplify Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); } LayoutShape rightLayoutShape() const override { return LayoutShape::RightOfPower; } int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; @@ -83,7 +83,7 @@ public: Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext); int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const; Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); - Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext); bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue); private: diff --git a/poincare/include/poincare/rational.h b/poincare/include/poincare/rational.h index 9215e2e2a..2b7bf6271 100644 --- a/poincare/include/poincare/rational.h +++ b/poincare/include/poincare/rational.h @@ -58,7 +58,7 @@ public: private: int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; LayoutShape leftLayoutShape() const override { assert(!m_negative); return isInteger() ? LayoutShape::Integer : LayoutShape::Fraction; }; Expression setSign(Sign s, ReductionContext reductionContext) override; Expression denominator(ReductionContext reductionContext) const override; diff --git a/poincare/include/poincare/unit.h b/poincare/include/poincare/unit.h index ded37f0b8..4d4eee249 100644 --- a/poincare/include/poincare/unit.h +++ b/poincare/include/poincare/unit.h @@ -473,7 +473,7 @@ public: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; LayoutShape leftLayoutShape() const override { return LayoutShape::OneLetter; } // TODO const Representative * representative() const { return m_representative; } @@ -686,7 +686,7 @@ public: // Simplification Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); - Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(); bool isBaseUnit() const { return node()->representative()->isBaseUnit() && node()->prefix() == node()->representative()->basePrefix(); } void chooseBestRepresentativeAndPrefix(double * value, double exponent, ExpressionNode::ReductionContext reductionContext, bool optimizePrefix); diff --git a/poincare/include/poincare/unit_convert.h b/poincare/include/poincare/unit_convert.h index c4cccf592..c97eb3cdf 100644 --- a/poincare/include/poincare/unit_convert.h +++ b/poincare/include/poincare/unit_convert.h @@ -23,7 +23,8 @@ private: Expression removeUnit(Expression * unit) override; // Simplification void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override; - Expression shallowBeautify(ReductionContext reductionContext) override; + void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext * reductionContext) override; // Evalutation Evaluation approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate(approximationContext); } Evaluation approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate(approximationContext); } @@ -38,7 +39,8 @@ public: // Expression void deepReduceChildren(ExpressionNode::ReductionContext reductionContext); - Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext); private: UnitConvertNode * node() const { return static_cast(Expression::node()); } }; diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 070168b28..a6d4da2ca 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -46,7 +46,7 @@ Expression AdditionNode::shallowReduce(ReductionContext reductionContext) { return Addition(this).shallowReduce(reductionContext); } -Expression AdditionNode::shallowBeautify(ReductionContext reductionContext) { +Expression AdditionNode::shallowBeautify(ReductionContext * reductionContext) { return Addition(this).shallowBeautify(reductionContext); } @@ -84,7 +84,7 @@ int Addition::getPolynomialCoefficients(Context * context, const char * symbolNa return deg; } -Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { +Expression Addition::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { /* Beautifying AdditionNode essentially consists in adding Subtractions if * needed. * In practice, we want to turn "a+(-1)*b" into "a-b". Or, more precisely, any @@ -98,12 +98,12 @@ Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionC /* Sort children in decreasing order: * 1+x+x^2 --> x^2+x+1 * 1+R(2) --> R(2)+1 */ - sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, false, canBeInterrupted); }, reductionContext.context(), true); + sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, false, canBeInterrupted); }, reductionContext->context(), true); int nbChildren = numberOfChildren(); for (int i = 0; i < nbChildren; i++) { // Try to make the child i positive if any negative numeral factor is found - Expression subtractant = childAtIndex(i).makePositiveAnyNegativeNumeralFactor(reductionContext); + Expression subtractant = childAtIndex(i).makePositiveAnyNegativeNumeralFactor(*reductionContext); if (subtractant.isUninitialized()) { // if subtractant is not initialized, it means the child i had no negative numeral factor @@ -130,7 +130,6 @@ Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionC } Expression result = squashUnaryHierarchyInPlace(); - return result; } diff --git a/poincare/src/complex_cartesian.cpp b/poincare/src/complex_cartesian.cpp index c0dbf3e57..ad4470cf4 100644 --- a/poincare/src/complex_cartesian.cpp +++ b/poincare/src/complex_cartesian.cpp @@ -32,7 +32,7 @@ Expression ComplexCartesianNode::shallowReduce(ReductionContext reductionContext return ComplexCartesian(this).shallowReduce(); } -Expression ComplexCartesianNode::shallowBeautify(ReductionContext reductionContext) { +Expression ComplexCartesianNode::shallowBeautify(ReductionContext * reductionContext) { return ComplexCartesian(this).shallowBeautify(reductionContext); } @@ -77,11 +77,11 @@ Expression ComplexCartesian::shallowReduce() { return *this; } -Expression ComplexCartesian::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { +Expression ComplexCartesian::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { Expression a = real(); Expression b = imag(); - Expression oppositeA = a.makePositiveAnyNegativeNumeralFactor(reductionContext); - Expression oppositeB = b.makePositiveAnyNegativeNumeralFactor(reductionContext); + Expression oppositeA = a.makePositiveAnyNegativeNumeralFactor(*reductionContext); + Expression oppositeB = b.makePositiveAnyNegativeNumeralFactor(*reductionContext); a = oppositeA.isUninitialized() ? a : oppositeA; b = oppositeB.isUninitialized() ? b : oppositeB; Expression e = Expression::CreateComplexExpression(a, b, Preferences::ComplexFormat::Cartesian, diff --git a/poincare/src/decimal.cpp b/poincare/src/decimal.cpp index 82330919d..30ee799eb 100644 --- a/poincare/src/decimal.cpp +++ b/poincare/src/decimal.cpp @@ -115,7 +115,7 @@ Expression DecimalNode::shallowReduce(ReductionContext reductionContext) { return Decimal(this).shallowReduce(); } -Expression DecimalNode::shallowBeautify(ReductionContext reductionContext) { +Expression DecimalNode::shallowBeautify(ReductionContext * reductionContext) { return Decimal(this).shallowBeautify(); } diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 6154d7635..685242180 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -388,6 +388,18 @@ Expression Expression::shallowReduceUsingApproximation(ExpressionNode::Reduction return *this; } +void Expression::defaultDeepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) { + const int nbChildren = numberOfChildren(); + for (int i = 0; i < nbChildren; i++) { + Expression child = childAtIndex(i); + child = child.deepBeautify(reductionContext); + // We add missing Parentheses after beautifying the parent and child + if (node()->childAtIndexNeedsUserParentheses(child, i)) { + replaceChildAtIndexInPlace(i, Parenthesis::Builder(child)); + } + } +} + bool Expression::SimplificationHasBeenInterrupted() { return sSimplificationHasBeenInterrupted; } @@ -656,7 +668,7 @@ void Expression::beautifyAndApproximateScalar(Expression * simplifiedExpression, ecomplexClone.imag().deepBeautify(userReductionContext); *approximateExpression = ecomplexClone.approximate(context, complexFormat, angleUnit); } - // Step 2: create the simplied expression with the required complex format + // Step 2: create the simplified expression with the required complex format Expression ra = complexFormat == Preferences::ComplexFormat::Polar ? ecomplex.clone().convert().norm(userReductionContext).shallowReduce(userReductionContext) : ecomplex.real(); @@ -833,16 +845,8 @@ Expression Expression::deepReduce(ExpressionNode::ReductionContext reductionCont } Expression Expression::deepBeautify(ExpressionNode::ReductionContext reductionContext) { - Expression e = shallowBeautify(reductionContext); - const int nbChildren = e.numberOfChildren(); - for (int i = 0; i < nbChildren; i++) { - Expression child = e.childAtIndex(i); - child = child.deepBeautify(reductionContext); - // We add missing Parentheses after beautifying the parent and child - if (e.node()->childAtIndexNeedsUserParentheses(child, i)) { - e.replaceChildAtIndexInPlace(i, Parenthesis::Builder(child)); - } - } + Expression e = shallowBeautify(&reductionContext); + e.deepBeautifyChildren(reductionContext); return e; } diff --git a/poincare/src/expression_node.cpp b/poincare/src/expression_node.cpp index 4bd4b9823..a58a12775 100644 --- a/poincare/src/expression_node.cpp +++ b/poincare/src/expression_node.cpp @@ -103,11 +103,15 @@ void ExpressionNode::deepReduceChildren(ExpressionNode::ReductionContext reducti Expression(this).defaultDeepReduceChildren(reductionContext); } +void ExpressionNode::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) { + Expression(this).defaultDeepBeautifyChildren(reductionContext); +} + Expression ExpressionNode::shallowReduce(ReductionContext reductionContext) { return Expression(this).defaultShallowReduce(); } -Expression ExpressionNode::shallowBeautify(ReductionContext reductionContext) { +Expression ExpressionNode::shallowBeautify(ReductionContext * reductionContext) { return Expression(this).defaultShallowBeautify(); } diff --git a/poincare/src/factor.cpp b/poincare/src/factor.cpp index bff8a70f6..549e62297 100644 --- a/poincare/src/factor.cpp +++ b/poincare/src/factor.cpp @@ -31,7 +31,7 @@ Expression FactorNode::shallowReduce(ReductionContext reductionContext) { return Factor(this).shallowReduce(reductionContext.context()); } -Expression FactorNode::shallowBeautify(ReductionContext reductionContext) { +Expression FactorNode::shallowBeautify(ReductionContext * reductionContext) { return Factor(this).shallowBeautify(reductionContext); } @@ -85,7 +85,7 @@ Expression Factor::shallowReduce(Context * context) { return *this; } -Expression Factor::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { +Expression Factor::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { Expression c = childAtIndex(0); if (c.type() != ExpressionNode::Type::Rational) { return replaceWithUndefinedInPlace(); diff --git a/poincare/src/great_common_divisor.cpp b/poincare/src/great_common_divisor.cpp index 5641df6c1..88637076f 100644 --- a/poincare/src/great_common_divisor.cpp +++ b/poincare/src/great_common_divisor.cpp @@ -19,8 +19,8 @@ Expression GreatCommonDivisorNode::shallowReduce(ReductionContext reductionConte return GreatCommonDivisor(this).shallowReduce(reductionContext); } -Expression GreatCommonDivisorNode::shallowBeautify(ReductionContext reductionContext) { - return GreatCommonDivisor(this).shallowBeautify(reductionContext.context()); +Expression GreatCommonDivisorNode::shallowBeautify(ReductionContext * reductionContext) { + return GreatCommonDivisor(this).shallowBeautify(reductionContext->context()); } template diff --git a/poincare/src/least_common_multiple.cpp b/poincare/src/least_common_multiple.cpp index 6702aaac8..03437d58f 100644 --- a/poincare/src/least_common_multiple.cpp +++ b/poincare/src/least_common_multiple.cpp @@ -19,8 +19,8 @@ Expression LeastCommonMultipleNode::shallowReduce(ReductionContext reductionCont return LeastCommonMultiple(this).shallowReduce(reductionContext); } -Expression LeastCommonMultipleNode::shallowBeautify(ReductionContext reductionContext) { - return LeastCommonMultiple(this).shallowBeautify(reductionContext.context()); +Expression LeastCommonMultipleNode::shallowBeautify(ReductionContext * reductionContext) { + return LeastCommonMultiple(this).shallowBeautify(reductionContext->context()); } template diff --git a/poincare/src/logarithm.cpp b/poincare/src/logarithm.cpp index bc9d96ad1..182747767 100644 --- a/poincare/src/logarithm.cpp +++ b/poincare/src/logarithm.cpp @@ -95,12 +95,12 @@ Expression LogarithmNode<1>::unaryFunctionDifferential() { /**/ template<> -Expression LogarithmNode<1>::shallowBeautify(ReductionContext reductionContext) { +Expression LogarithmNode<1>::shallowBeautify(ReductionContext * reductionContext) { return CommonLogarithm(this); } template<> -Expression LogarithmNode<2>::shallowBeautify(ReductionContext reductionContext) { +Expression LogarithmNode<2>::shallowBeautify(ReductionContext * reductionContext) { return Logarithm(this).shallowBeautify(); } diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 8bcb13ad2..a0ba391ea 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -211,7 +211,7 @@ Expression MultiplicationNode::shallowReduce(ReductionContext reductionContext) return Multiplication(this).shallowReduce(reductionContext); } -Expression MultiplicationNode::shallowBeautify(ReductionContext reductionContext) { +Expression MultiplicationNode::shallowBeautify(ReductionContext * reductionContext) { return Multiplication(this).shallowBeautify(reductionContext); } @@ -400,7 +400,7 @@ static bool CanSimplifyUnitProduct( return isSimpler; } -Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { +Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { /* Beautifying a Multiplication consists in several possible operations: * - Add Opposite ((-3)*x -> -(3*x), useful when printing fractions) * - Recognize derived units in the product of units @@ -408,7 +408,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu */ // Step 1: Turn -n*A into -(n*A) - Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(reductionContext); + Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(*reductionContext); // If one negative numeral factor was made positive, we turn the expression in an Opposite if (!noNegativeNumeral.isUninitialized()) { Opposite o = Opposite::Builder(); @@ -425,7 +425,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu Expression units; /* removeUnit has to be called on reduced expression but we want to modify * the least the expression so we use the uninvasive reduction context. */ - self = deepReduce(ExpressionNode::ReductionContext::NonInvasiveReductionContext(reductionContext)); + self = deepReduce(ExpressionNode::ReductionContext::NonInvasiveReductionContext(*reductionContext)); self = removeUnit(&units); if (self.isUndefined() || units.isUninitialized()) { @@ -434,7 +434,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu goto replace_by_result; } - ExpressionNode::UnitConversion unitConversionMode = reductionContext.unitConversion(); + ExpressionNode::UnitConversion unitConversionMode = reductionContext->unitConversion(); if (unitConversionMode == ExpressionNode::UnitConversion::Default) { /* Step 2a: Recognize derived units * - Look up in the table of derived units, the one which itself or its inverse simplifies 'units' the most. @@ -501,7 +501,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu // Apply simplifications if (unitsAccu.numberOfChildren() > 0) { // Divide by derived units - units = Division::Builder(units, unitsAccu.clone()).deepReduce(reductionContext); + units = Division::Builder(units, unitsAccu.clone()).deepReduce(*reductionContext); Expression newUnits; // Separate units and generated values units = units.removeUnit(&newUnits); @@ -528,7 +528,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu * most relevant. */ - double value = self.approximateToScalar(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); + double value = self.approximateToScalar(reductionContext->context(), reductionContext->complexFormat(), reductionContext->angleUnit()); if (std::isnan(value)) { // If the value is undefined, return "undef" without any unit result = Undefined::Builder(); @@ -538,7 +538,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu /* In most cases, unit composition works the same for imperial and * metric units. However, in imperial, we want volumes to be displayed * using volume units instead of cubic length. */ - const bool forceVolumeRepresentative = reductionContext.unitFormat() == Preferences::UnitFormat::Imperial && UnitNode::Vector::FromBaseUnits(units) == UnitNode::VolumeRepresentative::Default().dimensionVector(); + const bool forceVolumeRepresentative = reductionContext->unitFormat() == Preferences::UnitFormat::Imperial && UnitNode::Vector::FromBaseUnits(units) == UnitNode::VolumeRepresentative::Default().dimensionVector(); const UnitNode::Representative * repr; if (forceVolumeRepresentative) { /* The choice of representative doesn't matter, as it will be tuned to a @@ -546,9 +546,9 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu repr = UnitNode::VolumeRepresentative::Default().representativesOfSameDimension(); units = Unit::Builder(repr, UnitNode::Prefix::EmptyPrefix()); value /= repr->ratio(); - Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, reductionContext); + Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, *reductionContext); } else { - Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, reductionContext); + Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, *reductionContext); } } // Build final Expression @@ -558,7 +558,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu } else { // Step 3: Create a Division if relevant Expression numer, denom; - splitIntoNormalForm(numer, denom, reductionContext); + splitIntoNormalForm(numer, denom, *reductionContext); if (!numer.isUninitialized()) { result = numer; } diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 6738c1d24..dc8a93e3e 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -225,7 +225,7 @@ Expression PowerNode::shallowReduce(ReductionContext reductionContext) { return Power(this).shallowReduce(reductionContext); } -Expression PowerNode::shallowBeautify(ReductionContext reductionContext) { +Expression PowerNode::shallowBeautify(ReductionContext * reductionContext) { return Power(this).shallowBeautify(reductionContext); } @@ -985,14 +985,14 @@ Expression Power::shallowReduce(ExpressionNode::ReductionContext reductionContex return *this; } -Expression Power::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { +Expression Power::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { // Step 1: X^-y -> 1/(X->shallowBeautify)^y - Expression p = denominator(reductionContext); + Expression p = denominator(*reductionContext); // If the denominator is initialized, the index of the power is of form -y if (!p.isUninitialized()) { Division d = Division::Builder(Rational::Builder(1), p); replaceWithInPlace(d); - p.shallowReduce(reductionContext); + p.shallowReduce(*reductionContext); return d.shallowBeautify(reductionContext); } // Step 2: Turn a^(1/n) into root(a, n), unless base is a unit diff --git a/poincare/src/rational.cpp b/poincare/src/rational.cpp index 58f07cc3e..6757bee85 100644 --- a/poincare/src/rational.cpp +++ b/poincare/src/rational.cpp @@ -141,7 +141,7 @@ Expression RationalNode::shallowReduce(ReductionContext reductionContext) { return Rational(this).shallowReduce(); } -Expression RationalNode::shallowBeautify(ReductionContext reductionContext) { +Expression RationalNode::shallowBeautify(ReductionContext * reductionContext) { return Rational(this).shallowBeautify(); } diff --git a/poincare/src/unit.cpp b/poincare/src/unit.cpp index 8ba9a1d9c..8b5df0904 100644 --- a/poincare/src/unit.cpp +++ b/poincare/src/unit.cpp @@ -701,8 +701,8 @@ Expression UnitNode::shallowReduce(ReductionContext reductionContext) { return Unit(this).shallowReduce(reductionContext); } -Expression UnitNode::shallowBeautify(ReductionContext reductionContext) { - return Unit(this).shallowBeautify(reductionContext); +Expression UnitNode::shallowBeautify(ReductionContext * reductionContext) { + return Unit(this).shallowBeautify(); } template @@ -824,7 +824,7 @@ Expression Unit::BuildSplit(double value, const Unit * units, int length, Expres ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion::None); - return res.squashUnaryHierarchyInPlace().shallowBeautify(keepUnitsContext); + return res.squashUnaryHierarchyInPlace().shallowBeautify(&keepUnitsContext); } Expression Unit::ConvertTemperatureUnits(Expression e, Unit unit, ExpressionNode::ReductionContext reductionContext) { @@ -904,7 +904,7 @@ Expression Unit::shallowReduce(ExpressionNode::ReductionContext reductionContext return result; } -Expression Unit::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { +Expression Unit::shallowBeautify() { // Force Float(1) in front of an orphan Unit if (parent().isUninitialized() || parent().type() == ExpressionNode::Type::Opposite) { Multiplication m = Multiplication::Builder(Float::Builder(1.)); diff --git a/poincare/src/unit_convert.cpp b/poincare/src/unit_convert.cpp index 9d5ea9309..86252bda4 100644 --- a/poincare/src/unit_convert.cpp +++ b/poincare/src/unit_convert.cpp @@ -20,7 +20,7 @@ Expression UnitConvertNode::removeUnit(Expression * unit) { childAtIndex(1)->removeUnit(unit); return UnitConvert(this).replaceWithUndefinedInPlace(); } -Expression UnitConvertNode::shallowBeautify(ReductionContext reductionContext) { +Expression UnitConvertNode::shallowBeautify(ReductionContext * reductionContext) { return UnitConvert(this).shallowBeautify(reductionContext); } @@ -28,6 +28,10 @@ void UnitConvertNode::deepReduceChildren(ExpressionNode::ReductionContext reduct UnitConvert(this).deepReduceChildren(reductionContext); } +void UnitConvertNode::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) { + UnitConvert(this).deepBeautifyChildren(reductionContext); +} + template Evaluation UnitConvertNode::templatedApproximate(ApproximationContext approximationContext) const { /* If we are here, it means that the unit convert node was not shallowReduced. @@ -50,15 +54,27 @@ void UnitConvert::deepReduceChildren(ExpressionNode::ReductionContext reductionC childAtIndex(1).deepReduce(reductionContextKeepUnitAsIs); } -Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { +void UnitConvert::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) { + ExpressionNode::ReductionContext reductionContextKeepUnitAsIs = ExpressionNode::ReductionContext( + reductionContext.context(), + reductionContext.complexFormat(), + reductionContext.angleUnit(), + reductionContext.unitFormat(), + reductionContext.target(), + reductionContext.symbolicComputation(), + ExpressionNode::UnitConversion::None); + defaultDeepBeautifyChildren(reductionContextKeepUnitAsIs); +} + +Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { // Discard cases like 4 -> _m/_km { ExpressionNode::ReductionContext reductionContextWithUnits = ExpressionNode::ReductionContext( - reductionContext.context(), - reductionContext.complexFormat(), - reductionContext.angleUnit(), - reductionContext.unitFormat(), - reductionContext.target(), + reductionContext->context(), + reductionContext->complexFormat(), + reductionContext->angleUnit(), + reductionContext->unitFormat(), + reductionContext->target(), ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined); Expression unit; Expression childWithoutUnit = childAtIndex(1).clone().deepReduce(reductionContextWithUnits).removeUnit(&unit); @@ -68,14 +84,6 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti } } // Find the unit - ExpressionNode::ReductionContext reductionContextWithoutUnits = ExpressionNode::ReductionContext( - reductionContext.context(), - reductionContext.complexFormat(), - reductionContext.angleUnit(), - reductionContext.unitFormat(), - reductionContext.target(), - ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined, - ExpressionNode::UnitConversion::None); Expression unit; childAtIndex(1).removeUnit(&unit); if (unit.isUninitialized()) { @@ -88,7 +96,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti if (unit.type() == ExpressionNode::Type::Unit) { Unit unitRef = static_cast(unit); if (unitRef.representative()->dimensionVector() == Unit::TemperatureRepresentative::Default().dimensionVector()) { - Expression result = Unit::ConvertTemperatureUnits(childAtIndex(0), unitRef, reductionContext); + Expression result = Unit::ConvertTemperatureUnits(childAtIndex(0), unitRef, *reductionContext); replaceWithInPlace(result); return result; } @@ -96,7 +104,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti // Divide the left member by the new unit Expression division = Division::Builder(childAtIndex(0), unit.clone()); - division = division.deepReduce(reductionContext); + division = division.deepReduce(*reductionContext); Expression divisionUnit; division = division.removeUnit(&divisionUnit); if (!divisionUnit.isUninitialized()) { @@ -105,8 +113,25 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti } Expression result = Multiplication::Builder(division, unit); replaceWithInPlace(result); + ExpressionNode::ReductionContext reductionContextWithoutUnits = ExpressionNode::ReductionContext( + reductionContext->context(), + reductionContext->complexFormat(), + reductionContext->angleUnit(), + reductionContext->unitFormat(), + reductionContext->target(), + ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined, + ExpressionNode::UnitConversion::None); result = result.shallowReduce(reductionContextWithoutUnits); - return result.shallowBeautify(reductionContextWithoutUnits); + result = result.shallowBeautify(&reductionContextWithoutUnits); + *reductionContext = ExpressionNode::ReductionContext( + reductionContext->context(), + reductionContext->complexFormat(), + reductionContext->angleUnit(), + reductionContext->unitFormat(), + reductionContext->target(), + reductionContext->symbolicComputation(), + ExpressionNode::UnitConversion::None); + return result; } template Evaluation UnitConvertNode::templatedApproximate(ApproximationContext approximationContext) const;