From f95f9ebb2da25090c22493e602c87a5bc1d6f6d7 Mon Sep 17 00:00:00 2001 From: Laury Date: Thu, 24 Feb 2022 18:48:10 +0100 Subject: [PATCH] [poincare] Better simplification of sequences --- poincare/include/poincare/addition.h | 1 + poincare/include/poincare/expression.h | 1 + poincare/include/poincare/expression_node.h | 6 +++++- poincare/include/poincare/multiplication.h | 1 + poincare/include/poincare/rational.h | 1 + poincare/include/poincare/symbol.h | 1 + poincare/src/addition.cpp | 10 ++++++++++ poincare/src/multiplication.cpp | 10 ++++++++++ poincare/src/sequence.cpp | 15 +-------------- poincare/src/sum_and_product.cpp | 6 ------ 10 files changed, 31 insertions(+), 21 deletions(-) diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 738600510..759facf23 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -24,6 +24,7 @@ public: // Properties Type type() const override { return Type::Addition; } + virtual ExpressionNode::IntegerStatus integerStatus(Context * context) const override; int polynomialDegree(Context * context, const char * symbolName) const override; int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override; diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 452c078d1..4ac1ba707 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -152,6 +152,7 @@ public: bool isOfType(ExpressionNode::Type * types, int length) const { return node()->isOfType(types, length); } ExpressionNode::Sign sign(Context * context) const { return node()->sign(context); } ExpressionNode::NullStatus nullStatus(Context * context) const { return node()->nullStatus(context); } + ExpressionNode::IntegerStatus integerStatus(Context * context) const { return node()->integerStatus(context); } bool isStrictly(ExpressionNode::Sign s, Context * context) const { return s == node()->sign(context) && node()->nullStatus(context) == ExpressionNode::NullStatus::NonNull; } bool isUndefined() const { return node()->type() == ExpressionNode::Type::Undefined || node()->type() == ExpressionNode::Type::Unreal; } bool isNumber() const { return node()->isNumber(); } diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index ce0a702cf..862e10e73 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -162,7 +162,10 @@ public: NonNull = 0, Null = 1, }; - + enum class IntegerStatus { + Unknown = -1, + Integer = 1, + }; class ComputationContext { public: ComputationContext( @@ -233,6 +236,7 @@ public: virtual Sign sign(Context * context) const { return Sign::Unknown; } virtual NullStatus nullStatus(Context * context) const { return NullStatus::Unknown; } + virtual IntegerStatus integerStatus(Context * context) const { return IntegerStatus::Unknown; } virtual bool isNumber() const { return false; } virtual bool isRandom() const { return false; } virtual bool isParameteredExpression() const { return false; } diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index d8b80bf0b..744471134 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -21,6 +21,7 @@ public: // Properties Type type() const override { return Type::Multiplication; } + virtual IntegerStatus integerStatus(Context * context) const override; Sign sign(Context * context) const override; int polynomialDegree(Context * context, const char * symbolName) const override; int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override; diff --git a/poincare/include/poincare/rational.h b/poincare/include/poincare/rational.h index 0e1b38374..34615a6ca 100644 --- a/poincare/include/poincare/rational.h +++ b/poincare/include/poincare/rational.h @@ -18,6 +18,7 @@ public: void setNegative(bool negative) { m_negative = negative; } bool isInteger() const { return denominator().isOne(); } NullStatus nullStatus(Context * context) const override { return isZero() ? NullStatus::Null : NullStatus::NonNull; } + virtual IntegerStatus integerStatus(Context * context) const { return isInteger() ? IntegerStatus::Integer : IntegerStatus::Unknown; } // TreeNode size_t size() const override; diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index 4f18e6176..43c4dd3fb 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -21,6 +21,7 @@ public: // Expression Properties Type type() const override { return Type::Symbol; } + virtual IntegerStatus integerStatus(Context * context) const { return context->expressionTypeForIdentifier(m_name, strlen(m_name)) == Context::SymbolAbstractType::Integer ? IntegerStatus::Integer : IntegerStatus::Unknown; } Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) override; int polynomialDegree(Context * context, const char * symbolName) const override; int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override; diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 5352cd851..2032b7bab 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -57,6 +57,16 @@ bool AdditionNode::derivate(ReductionContext reductionContext, Expression symbol // Addition +ExpressionNode::IntegerStatus AdditionNode::integerStatus(Context * context) const { + int nbOfChildren = numberOfChildren(); + for (int i = 0; i < nbOfChildren; i++) { + if (childAtIndex(i)->integerStatus(context) != IntegerStatus::Integer) { + return IntegerStatus::Unknown; + } + } + return IntegerStatus::Integer; +} + const Number Addition::NumeralFactor(const Expression & e) { if (e.type() == ExpressionNode::Type::Multiplication && e.childAtIndex(0).isNumber()) { Number result = e.childAtIndex(0).convert(); diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index a5ba391fc..2f93440ce 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -42,6 +42,16 @@ ExpressionNode::Sign MultiplicationNode::sign(Context * context) const { return (Sign)sign; } +ExpressionNode::IntegerStatus MultiplicationNode::integerStatus(Context * context) const { + int nbOfChildren = numberOfChildren(); + for (int i = 0; i < nbOfChildren; i++) { + if (childAtIndex(i)->integerStatus(context) != IntegerStatus::Integer) { + return IntegerStatus::Unknown; + } + } + return IntegerStatus::Integer; +} + int MultiplicationNode::polynomialDegree(Context * context, const char * symbolName) const { int degree = 0; for (ExpressionNode * c : children()) { diff --git a/poincare/src/sequence.cpp b/poincare/src/sequence.cpp index 666b418c7..5c24602d7 100644 --- a/poincare/src/sequence.cpp +++ b/poincare/src/sequence.cpp @@ -166,21 +166,8 @@ Expression Sequence::deepReplaceReplaceableSymbols(Context * context, bool * did Expression Sequence::replacedByDefinitionIfPossible(Context * context) { // We try to replace the sequence by his definition ONLY if the index is an integer - bool canBeReplacedByExpression = false; - if (childAtIndex(0).type() == ExpressionNode::Type::Symbol) { - const char * symbolName = (childAtIndex(0).convert()).name(); - if (context->expressionTypeForIdentifier(symbolName, strlen(symbolName)) == Context::SymbolAbstractType::Integer) { - canBeReplacedByExpression = true; - } - } else if (childAtIndex(0).type() == ExpressionNode::Type::Rational) { - Rational r = childAtIndex(0).convert(); - if (r.isInteger()) { - canBeReplacedByExpression = true; - } - } - - if (!canBeReplacedByExpression) { + if (childAtIndex(0).integerStatus(context) != ExpressionNode::IntegerStatus::Integer) { return Expression(); } diff --git a/poincare/src/sum_and_product.cpp b/poincare/src/sum_and_product.cpp index a05e3e955..b5e7c6873 100644 --- a/poincare/src/sum_and_product.cpp +++ b/poincare/src/sum_and_product.cpp @@ -45,12 +45,6 @@ Evaluation SumAndProductNode::templatedApproximate(ApproximationContext appro } nContext.setApproximationForVariable((T)i); Expression child = Expression(childAtIndex(0)).clone(); - if (child.type() == ExpressionNode::Type::Sequence) { - /* Since we cannot get the expression of a sequence term like we would for - * a function, we replace its potential abstract rank by the value it should - * have. We can then evaluate its value */ - child.childAtIndex(0).replaceSymbolWithExpression(symbol, Float::Builder(i)); - } approximationContext.setContext(&nContext); result = evaluateWithNextTerm(T(), result, child.node()->approximate(T(), approximationContext), approximationContext.complexFormat()); if (result.isUndefined()) {