diff --git a/apps/sequence/test/sequence.cpp b/apps/sequence/test/sequence.cpp index c09412eb4..337f060ad 100644 --- a/apps/sequence/test/sequence.cpp +++ b/apps/sequence/test/sequence.cpp @@ -399,6 +399,19 @@ QUIZ_CASE(sequence_evaluation) { conditions1[2] = "6"; conditions2[2] = nullptr; check_sequences_defined_by(results32, types, definitions, conditions1, conditions2); + + // u independent, v depends on u(n+6) + // u(n) = 9n; v(n+1) = u(n+6)+v(0); v(0) = 9 + double results33[MaxNumberOfSequences][10] = {{0.0, 9.0, 18.0, 27.0, 36.0, 45.0, 54.0, 63.0, 72.0, 81.0}, + {9.0, 63.0, 72.0, 81.0, 90.0, 99.0, 108.0, 117.0, 126.0, 135.0}, + {}}; + types[0] = Sequence::Type::Explicit; + types[1] = Sequence::Type::SingleRecurrence; + definitions[0] = "9n"; + definitions[1] = "u(n+6)+v(0)"; + definitions[2] = nullptr; + conditions1[1] = "9"; + check_sequences_defined_by(results33, types, definitions, conditions1, conditions2); } QUIZ_CASE(sequence_sum_evaluation) { diff --git a/apps/shared/sequence.cpp b/apps/shared/sequence.cpp index 20f0f47d9..c72c131a6 100644 --- a/apps/shared/sequence.cpp +++ b/apps/shared/sequence.cpp @@ -243,7 +243,6 @@ T Sequence::approximateToNextRank(int n, SequenceContext * sqctx, int sequenceIn symbols[i][j] = Symbol::Builder(name[j], strlen(name[j])); } } - ctx.setNValue(n); switch (type()) { case Type::Explicit: { diff --git a/apps/shared/sequence_cache_context.cpp b/apps/shared/sequence_cache_context.cpp index 518029f04..92842203a 100644 --- a/apps/shared/sequence_cache_context.cpp +++ b/apps/shared/sequence_cache_context.cpp @@ -33,7 +33,7 @@ const Expression SequenceCacheContext::expressionForSymbolAbstract(const Poin Ion::Storage::Record record = m_sequenceContext->sequenceStore()->recordAtIndex(index); if (!record.isNull()) { Sequence * seq = m_sequenceContext->sequenceStore()->modelForRecord(record); - rank.replaceSymbolWithExpression(Symbol::Builder(UCodePointUnknown), Float::Builder(m_nValue)); + rank.replaceSymbolWithExpression(Symbol::Builder(UCodePointUnknown), Float::Builder(unknownSymbolValue)); T n = PoincareHelpers::ApproximateToScalar(rank, this); // In case the sequence referenced is not defined or if the rank is not an int, return NAN if (seq->fullName() != nullptr) { diff --git a/apps/shared/sequence_cache_context.h b/apps/shared/sequence_cache_context.h index 9fa79b22e..a3495f512 100644 --- a/apps/shared/sequence_cache_context.h +++ b/apps/shared/sequence_cache_context.h @@ -14,12 +14,10 @@ public: SequenceCacheContext(SequenceContext * sequenceContext); const Poincare::Expression expressionForSymbolAbstract(const Poincare::SymbolAbstract & symbol, bool clone, float unknownSymbolValue = NAN) override; void setValueForSymbol(T value, const Poincare::Symbol & symbol); - void setNValue(int n) { m_nValue = n; } private: int nameIndexForSymbol(const Poincare::Symbol & symbol); int rankIndexForSymbol(const Poincare::Symbol & symbol); T m_values[MaxNumberOfSequences][MaxRecurrenceDepth]; - int m_nValue; SequenceContext * m_sequenceContext; }; diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp index eb206b1f6..32a72fbcc 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -407,7 +407,7 @@ void Parser::parseReservedFunction(Expression & leftHandSide, const Expression:: } } -void Parser::parseSequence(Expression & leftHandSide, const char name, Token::Type leftDelimiter1, Token::Type rightDelimiter1, Token::Type leftDelimiter2, Token::Type rightDelimiter2) { +void Parser::parseSequence(Expression & leftHandSide, const char * name, Token::Type leftDelimiter1, Token::Type rightDelimiter1, Token::Type leftDelimiter2, Token::Type rightDelimiter2) { bool delimiterTypeIsOne = popTokenIfType(leftDelimiter1); if (!delimiterTypeIsOne && !popTokenIfType(leftDelimiter2)) { m_status = Status::Error; // Left delimiter missing. @@ -418,7 +418,7 @@ void Parser::parseSequence(Expression & leftHandSide, const char name, Token::Ty } else if (!popTokenIfType(rightDelimiter)) { m_status = Status::Error; // Right delimiter missing } else { - leftHandSide = Sequence::Builder(&name, 1, rank); + leftHandSide = Sequence::Builder(name, 1, rank); } } } @@ -439,7 +439,7 @@ void Parser::parseSpecialIdentifier(Expression & leftHandSide) { /* Special case for sequences (e.g. "u(n)", "u{n}", ...) * We know that m_currentToken.text()[0] is either 'u', 'v' or 'w', so we do * not need to pass a code point to parseSequence. */ - parseSequence(leftHandSide, m_currentToken.text()[0], Token::LeftParenthesis, Token::RightParenthesis, Token::LeftBrace, Token::RightBrace); + parseSequence(leftHandSide, m_currentToken.text(), Token::LeftParenthesis, Token::RightParenthesis, Token::LeftBrace, Token::RightBrace); } } diff --git a/poincare/src/parsing/parser.h b/poincare/src/parsing/parser.h index 8770d6220..e6fe72f58 100644 --- a/poincare/src/parsing/parser.h +++ b/poincare/src/parsing/parser.h @@ -75,7 +75,7 @@ private: Expression parseCommaSeparatedList(); void parseReservedFunction(Expression & leftHandSide, const Expression::FunctionHelper * const * functionHelper); void parseSpecialIdentifier(Expression & leftHandSide); - void parseSequence(Expression & leftHandSide, const char name, Token::Type leftDelimiter1, Token::Type rightDelimiter1, Token::Type leftDelimiter2, Token::Type rightDelimiter2); + void parseSequence(Expression & leftHandSide, const char * name, Token::Type leftDelimiter1, Token::Type rightDelimiter1, Token::Type leftDelimiter2, Token::Type rightDelimiter2); void parseCustomIdentifier(Expression & leftHandSide, const char * name, size_t length); void defaultParseLeftParenthesis(bool isSystemParenthesis, Expression & leftHandSide, Token::Type stoppingType);