[poincare] Fixed two serious bugs in sequences simplification

This commit is contained in:
Laury
2022-04-30 19:12:54 +02:00
parent 39f33347f9
commit 745099842a
2 changed files with 23 additions and 5 deletions

View File

@@ -128,6 +128,7 @@ const Expression GlobalContext::ExpressionForSequence(const SymbolAbstract & sym
if (!rank.isUninitialized()) {
bool rankIsInteger = false;
double rankValue = rank.approximateToScalar<double>(ctx, Poincare::Preferences::sharedPreferences()->complexFormat(), Poincare::Preferences::sharedPreferences()->angleUnit());
int rankValueFloor = std::floor(rankValue);
if (rank.type() == ExpressionNode::Type::Rational) {
Rational n = static_cast<Rational &>(rank);
rankIsInteger = n.isInteger();
@@ -137,11 +138,17 @@ const Expression GlobalContext::ExpressionForSequence(const SymbolAbstract & sym
* approximate the rank and check if it is an integer. Unfortunately this
* leads to some edge cases were, because of quantification, we have
* floor(x) = x while x is not integer.*/
rankIsInteger = std::floor(rankValue) == rankValue;
rankIsInteger = rankValueFloor == rankValue;
}
if (rankIsInteger && !seq.badlyReferencesItself(ctx)) {
SequenceContext sqctx(ctx, sequenceStore());
return Float<double>::Builder(seq.evaluateXYAtParameter(rankValue, &sqctx).x2());
if (rankIsInteger) {
if (rankValueFloor - seq.initialRank() < (int) seq.type()) { // Seq can reference itself but be defined explicitly for first values
assert(rankValueFloor - seq.initialRank() == 0 || rankValueFloor - seq.initialRank() == 1);
return rankValueFloor - seq.initialRank() == 0 ? seq.firstInitialConditionExpressionClone() : seq.secondInitialConditionExpressionClone();
}
if (!seq.badlyReferencesItself(ctx)) {
SequenceContext sqctx(ctx, sequenceStore());
return Float<double>::Builder(seq.evaluateXYAtParameter(rankValue, &sqctx).x2());
}
}
}
return Float<double>::Builder(NAN);