#include #include #include #include #include #include #include #include #include #include #include namespace Poincare { SequenceNode::SequenceNode(const char * newName, int length) : SymbolAbstractNode() { strlcpy(const_cast(name()), newName, length+1); } Expression SequenceNode::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { return Sequence(this).replaceSymbolWithExpression(symbol, expression); } int SequenceNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { /* This function ensures that terms like u(n) and u(n+1), u(n) and v(n), * u(a) and u(b) do not factorize. * We never want to factorize. The only cases where it could be useful are * like the following : u(n)+u(n). But thanks to the cache system, no * computation is needed for the second term.*/ assert(type() == e->type()); assert(numberOfChildren() == 1); assert(e->numberOfChildren() == 1); ExpressionNode * seq = const_cast(e); int delta = strcmp(name(), reinterpret_cast(seq)->name()); if (delta == 0) { return SimplificationOrder(childAtIndex(0), e->childAtIndex(0), ascending, canBeInterrupted, ignoreParentheses); } return delta; } Layout SequenceNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { assert(name()[0] >= 'u' && name()[0] <= 'w'); Layout rank = childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits); return HorizontalLayout::Builder( CodePointLayout::Builder(name()[0]), VerticalOffsetLayout::Builder(rank, VerticalOffsetLayoutNode::Position::Subscript)); } int SequenceNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name()); } Expression SequenceNode::shallowReduce(ReductionContext reductionContext) { return Sequence(this).shallowReduce(reductionContext); } Evaluation SequenceNode::approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation SequenceNode::approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return templatedApproximate(context, complexFormat, angleUnit); } template Evaluation SequenceNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { if (childAtIndex(0)->approximate((T)1, context, complexFormat, angleUnit).isUndefined()) { return Complex::Undefined(); } Expression e = context->expressionForSymbolAbstract(this, false); if (e.isUninitialized()) { return Complex::Undefined(); } return e.node()->approximate(T(), context, complexFormat, angleUnit); } Sequence Sequence::Builder(const char * name, size_t length, Expression child) { Sequence seq = SymbolAbstract::Builder(name, length); if (!child.isUninitialized()) { seq.replaceChildAtIndexInPlace(0, child); } return seq; } Expression Sequence::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { // Replace the symbol in the child childAtIndex(0).replaceSymbolWithExpression(symbol, expression); if (symbol.type() == ExpressionNode::Type::Sequence && hasSameNameAs(symbol)) { Expression value = expression.clone(); Expression p = parent(); if (!p.isUninitialized() && p.node()->childAtIndexNeedsUserParentheses(value, p.indexOfChild(*this))) { value = Parenthesis::Builder(value); } replaceWithInPlace(value); return value; } return *this; } Expression Sequence::shallowReduce(ExpressionNode::ReductionContext reductionContext) { if (reductionContext.symbolicComputation() == ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined || childAtIndex(0).isUndefined()) { return replaceWithUndefinedInPlace(); } return *this; } Expression Sequence::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) { return *this; } }