mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] Fixed two serious bugs in sequences simplification
This commit is contained in:
@@ -128,6 +128,7 @@ const Expression GlobalContext::ExpressionForSequence(const SymbolAbstract & sym
|
|||||||
if (!rank.isUninitialized()) {
|
if (!rank.isUninitialized()) {
|
||||||
bool rankIsInteger = false;
|
bool rankIsInteger = false;
|
||||||
double rankValue = rank.approximateToScalar<double>(ctx, Poincare::Preferences::sharedPreferences()->complexFormat(), Poincare::Preferences::sharedPreferences()->angleUnit());
|
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) {
|
if (rank.type() == ExpressionNode::Type::Rational) {
|
||||||
Rational n = static_cast<Rational &>(rank);
|
Rational n = static_cast<Rational &>(rank);
|
||||||
rankIsInteger = n.isInteger();
|
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
|
* approximate the rank and check if it is an integer. Unfortunately this
|
||||||
* leads to some edge cases were, because of quantification, we have
|
* leads to some edge cases were, because of quantification, we have
|
||||||
* floor(x) = x while x is not integer.*/
|
* floor(x) = x while x is not integer.*/
|
||||||
rankIsInteger = std::floor(rankValue) == rankValue;
|
rankIsInteger = rankValueFloor == rankValue;
|
||||||
}
|
}
|
||||||
if (rankIsInteger && !seq.badlyReferencesItself(ctx)) {
|
if (rankIsInteger) {
|
||||||
SequenceContext sqctx(ctx, sequenceStore());
|
if (rankValueFloor - seq.initialRank() < (int) seq.type()) { // Seq can reference itself but be defined explicitly for first values
|
||||||
return Float<double>::Builder(seq.evaluateXYAtParameter(rankValue, &sqctx).x2());
|
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);
|
return Float<double>::Builder(NAN);
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ Expression Sequence::shallowReduce(ExpressionNode::ReductionContext reductionCon
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression result = replacedByDefinitionIfPossible(reductionContext.context());
|
Expression result = replacedByDefinitionIfPossible(reductionContext.context()); // We don't need to check if the result is uninitialized
|
||||||
result = Expression::ExpressionWithoutSymbols(result, reductionContext.context());
|
result = Expression::ExpressionWithoutSymbols(result, reductionContext.context());
|
||||||
|
|
||||||
if (result.isUninitialized()) {
|
if (result.isUninitialized()) {
|
||||||
@@ -184,6 +184,17 @@ Expression Sequence::replacedByDefinitionIfPossible(Context * context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Expression result = seq.expressionClone();
|
Expression result = seq.expressionClone();
|
||||||
|
|
||||||
|
if (result.hasExpression([](Expression e, const void * context) {
|
||||||
|
if (e.type() != ExpressionNode::Type::Sequence) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return strcmp(static_cast<Sequence&>(e).name(), reinterpret_cast<const char *>(context)) == 0;
|
||||||
|
}, reinterpret_cast<const void *>(name())))
|
||||||
|
{
|
||||||
|
return Expression();
|
||||||
|
}
|
||||||
|
|
||||||
return result.replaceSymbolWithExpression(Symbol::Builder(UCodePointUnknown), childAtIndex(0));
|
return result.replaceSymbolWithExpression(Symbol::Builder(UCodePointUnknown), childAtIndex(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user