diff --git a/apps/shared/storage_expression_model.cpp b/apps/shared/storage_expression_model.cpp index 982a1309f..59f9a8a32 100644 --- a/apps/shared/storage_expression_model.cpp +++ b/apps/shared/storage_expression_model.cpp @@ -31,7 +31,7 @@ Expression StorageExpressionModel::expression(Poincare::Context * context) const if (m_expression.isUninitialized()) { assert(!isNull()); Ion::Storage::Record::Data recordData = value(); - m_expression = Expression::ExpressionFromAddress(expressionAddressForValue(recordData), expressionSizeForValue(recordData)).deepReduce(*context, Preferences::AngleUnit::Degree, true); + m_expression = Expression::ExpressionFromAddress(expressionAddressForValue(recordData), expressionSizeForValue(recordData)).reduce(*context, Preferences::AngleUnit::Degree, true); } return m_expression; } diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 6bd0e22ee..de67877cc 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -145,9 +145,9 @@ public: * order) and 'constant' with the constant of the expression. */ bool getLinearCoefficients(char * variables, int maxVariableLength, Expression coefficients[], Expression constant[], Context & context, Preferences::AngleUnit angleUnit) const; /* getPolynomialCoefficients fills the table coefficients with the expressions - * of the first 3 polynomial coefficients and return polynomialDegree. - * coefficients has up to 3 entries. It supposed to be called on Reduced - * expression. */ + * of the first 3 polynomial coefficients and returns the polynomial degree. + * It is supposed to be called on a reduced expression. + * coefficients has up to 3 entries. */ static constexpr int k_maxPolynomialDegree = 2; static constexpr int k_maxNumberOfPolynomialCoefficients = k_maxPolynomialDegree+1; int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context & context, Preferences::AngleUnit angleUnit) const; @@ -167,7 +167,7 @@ public: /* Simplification */ static Expression ParseAndSimplify(const char * text, Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); Expression simplify(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); - Expression deepReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); + Expression reduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); void reduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return node()->reduceChildren(context, angleUnit, replaceSymbols); } @@ -253,7 +253,12 @@ protected: private: /* Simplification */ + Expression deepReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); + void deepReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { + return node()->deepReduceChildren(context, angleUnit, replaceSymbols); + } void defaultReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols); + void defaultDeepReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols); Expression defaultShallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); Expression defaultShallowBeautify(Context & context, Preferences::AngleUnit angleUnit) { return *this; } diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index 39559d000..93ae1be7a 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -144,6 +144,7 @@ public: /* Simplification */ /*!*/ virtual void reduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols); + /*!*/ virtual void deepReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols); /*!*/ virtual Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); /*!*/ virtual Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit); /* Return a clone of the denominator part of the expression */ diff --git a/poincare/include/poincare/store.h b/poincare/include/poincare/store.h index ee87fa4e0..aabeb6603 100644 --- a/poincare/include/poincare/store.h +++ b/poincare/include/poincare/store.h @@ -26,6 +26,7 @@ public: private: // Simplification void reduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) override; + void deepReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) override; Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true) override; // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 28844a674..e0611efa0 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -334,7 +334,7 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences numerator.shallowReduce(context, angleUnit); // Step 5: Simplify the denominator (in case it's a rational number) - inverseDenominator.deepReduce(context, angleUnit); + inverseDenominator.reduce(context, angleUnit); /* Step 6: We simplify the resulting multiplication forbidding any * distribution of multiplication on additions (to avoid an infinite loop). */ diff --git a/poincare/src/confidence_interval.cpp b/poincare/src/confidence_interval.cpp index dc875567e..f095211fb 100644 --- a/poincare/src/confidence_interval.cpp +++ b/poincare/src/confidence_interval.cpp @@ -94,7 +94,7 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Ang matrix.addChildAtIndexInPlace(Addition(r0, sqr), 1, 1); matrix.setDimensions(1, 2); replaceWithInPlace(matrix); - matrix.reduceChildren(context, angleUnit, replaceSymbols); + matrix.deepReduceChildren(context, angleUnit, replaceSymbols); return matrix; } diff --git a/poincare/src/equal.cpp b/poincare/src/equal.cpp index b5e20a540..3bcb7469f 100644 --- a/poincare/src/equal.cpp +++ b/poincare/src/equal.cpp @@ -43,7 +43,7 @@ Evaluation EqualNode::templatedApproximate(Context& context, Preferences::Ang Expression Equal::standardEquation(Context & context, Preferences::AngleUnit angleUnit) const { Expression sub = Subtraction(childAtIndex(0).clone(), childAtIndex(1).clone()); - return sub.deepReduce(context, angleUnit); + return sub.reduce(context, angleUnit); } Expression Equal::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index c2089d717..97bd74c31 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -172,6 +172,13 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex void Expression::defaultReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { for (int i = 0; i < numberOfChildren(); i++) { + childAtIndex(i).reduce(context, angleUnit, replaceSymbols); + } +} + +void Expression::defaultDeepReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { + for (int i = 0; i < numberOfChildren(); i++) { + assert(!childAtIndex(i).recursivelyMatches(IsMatrix, context)); childAtIndex(i).deepReduce(context, angleUnit, replaceSymbols); } } @@ -289,9 +296,19 @@ Expression Expression::simplify(Context & context, Preferences::AngleUnit angleU return e; } +Expression Expression::reduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { +#if MATRIX_EXACT_REDUCING +#else + if (recursivelyMatches(IsMatrix, context)) { + return *this; + } +#endif + return deepReduce(context, angleUnit, replaceSymbols); +} + Expression Expression::deepReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { - assert(!IsMatrix(*this, context)); - reduceChildren(context, angleUnit, replaceSymbols); + assert(!recursivelyMatches(IsMatrix, context)); + deepReduceChildren(context, angleUnit, replaceSymbols); return shallowReduce(context, angleUnit, replaceSymbols); } diff --git a/poincare/src/expression_node.cpp b/poincare/src/expression_node.cpp index ab016ce1c..d5d06a8c0 100644 --- a/poincare/src/expression_node.cpp +++ b/poincare/src/expression_node.cpp @@ -95,6 +95,10 @@ void ExpressionNode::reduceChildren(Context & context, Preferences::AngleUnit an Expression(this).defaultReduceChildren(context, angleUnit, replaceSymbols); } +void ExpressionNode::deepReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { + Expression(this).defaultDeepReduceChildren(context, angleUnit, replaceSymbols); +} + Expression ExpressionNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return Expression(this).defaultShallowReduce(context, angleUnit, replaceSymbols); } diff --git a/poincare/src/function.cpp b/poincare/src/function.cpp index 2f61b5496..efa8c9063 100644 --- a/poincare/src/function.cpp +++ b/poincare/src/function.cpp @@ -123,7 +123,7 @@ Expression Function::shallowReduce(Context & context, Preferences::AngleUnit ang Symbol x = Symbol(Symbol::SpecialSymbols::UnknownX); result = result.replaceSymbolWithExpression(x, childAtIndex(0)); replaceWithInPlace(result); - return result.deepReduce(context, angleUnit, replaceSymbols); + return result.reduce(context, angleUnit, replaceSymbols); } return *this; } diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 79dcdca70..00aa34ac2 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -574,7 +574,7 @@ void Multiplication::addMissingFactors(Expression factor, Context & context, Pre * base if any. Otherwise, we add it as an new child. */ for (int i = 0; i < numberOfChildren(); i++) { if (TermsHaveIdenticalBase(childAtIndex(i), factor)) { - Expression sub = Subtraction(CreateExponent(childAtIndex(i)), CreateExponent(factor)).deepReduce(context, angleUnit); + Expression sub = Subtraction(CreateExponent(childAtIndex(i)), CreateExponent(factor)).reduce(context, angleUnit); if (sub.sign() == ExpressionNode::Sign::Negative) { // index[0] < index[1] sub = Opposite(sub); if (factor.type() == ExpressionNode::Type::Power) { diff --git a/poincare/src/prediction_interval.cpp b/poincare/src/prediction_interval.cpp index a5d725ed9..b512d2126 100644 --- a/poincare/src/prediction_interval.cpp +++ b/poincare/src/prediction_interval.cpp @@ -102,7 +102,7 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Ang matrix.addChildAtIndexInPlace(Addition(r0.clone(), m), 1, 1); matrix.setDimensions(1, 2); replaceWithInPlace(matrix); - matrix.reduceChildren(context, angleUnit, replaceSymbols); + matrix.deepReduceChildren(context, angleUnit, replaceSymbols); return matrix; } diff --git a/poincare/src/store.cpp b/poincare/src/store.cpp index 3985badd2..c83913ba0 100644 --- a/poincare/src/store.cpp +++ b/poincare/src/store.cpp @@ -18,6 +18,10 @@ void StoreNode::reduceChildren(Context & context, Preferences::AngleUnit angleUn Expression(this).defaultReduceChildren(context, angleUnit, false); } +void StoreNode::deepReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { + Expression(this).defaultDeepReduceChildren(context, angleUnit, false); +} + Expression StoreNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return Store(this).shallowReduce(context, angleUnit, replaceSymbols); } diff --git a/poincare/src/symbol.cpp b/poincare/src/symbol.cpp index 88831edd2..2930d67c4 100644 --- a/poincare/src/symbol.cpp +++ b/poincare/src/symbol.cpp @@ -162,10 +162,10 @@ Expression Symbol::shallowReduce(Context & context, Preferences::AngleUnit angle } const Expression e = context.expressionForSymbol(*this); if (!e.isUninitialized()) { - // The stored expression had been beautified, so we need to call deepReduce + // The stored expression is beautified, so we need to call reduce Expression result = e.clone(); replaceWithInPlace(result); - return result.deepReduce(context, angleUnit); + return result.reduce(context, angleUnit); } return *this; } diff --git a/poincare/test/properties.cpp b/poincare/test/properties.cpp index aa042d46e..6583d8b83 100644 --- a/poincare/test/properties.cpp +++ b/poincare/test/properties.cpp @@ -118,14 +118,14 @@ void assert_parsed_expression_has_polynomial_coefficient(const char * expression Shared::GlobalContext globalContext; Expression e = parse_expression(expression); quiz_assert(!e.isUninitialized()); - e = e.deepReduce(globalContext, angleUnit); + e = e.reduce(globalContext, angleUnit); Expression coefficientBuffer[Poincare::Expression::k_maxNumberOfPolynomialCoefficients]; int d = e.getPolynomialReducedCoefficients(symbolName, coefficientBuffer, globalContext, Radian); for (int i = 0; i <= d; i++) { Expression f = parse_expression(coefficients[i]); quiz_assert(!f.isUninitialized()); - coefficientBuffer[i] = coefficientBuffer[i].deepReduce(globalContext, angleUnit); - f = f.deepReduce(globalContext, angleUnit); + coefficientBuffer[i] = coefficientBuffer[i].reduce(globalContext, angleUnit); + f = f.reduce(globalContext, angleUnit); quiz_assert(coefficientBuffer[i].isIdenticalTo(f)); } quiz_assert(coefficients[d+1] == 0);