mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] remove max recursion limit
This commit is contained in:
@@ -90,9 +90,6 @@ class Expression : public TreeHandle {
|
||||
friend class SymbolNode;
|
||||
|
||||
public:
|
||||
static void TidyAfterException() {
|
||||
UnlockRecursionCountReset();
|
||||
}
|
||||
static bool isExpression() { return true; }
|
||||
|
||||
/* Constructor & Destructor */
|
||||
@@ -252,9 +249,6 @@ protected:
|
||||
Expression defaultReplaceSymbols(Context & context);
|
||||
|
||||
/* Simplification */
|
||||
static void IncrementRecursionCount();
|
||||
static bool RecursionMaximalDepthExceeded();
|
||||
static bool RecursionCountResetisLocked();
|
||||
Expression denominator(Context & context, Preferences::AngleUnit angleUnit) const { return node()->denominator(context, angleUnit); }
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true) { return node()->shallowReduce(context, angleUnit, replaceSymbols); }
|
||||
Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) { return node()->shallowBeautify(context, angleUnit); }
|
||||
@@ -263,9 +257,6 @@ protected:
|
||||
|
||||
private:
|
||||
/* Simplification */
|
||||
static constexpr int sRecursionLimit = 2000; //TODO value?
|
||||
static bool ResetRecursionCountAndLockReset();
|
||||
static void UnlockRecursionCountReset();
|
||||
Expression deepReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true);
|
||||
void deepReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) {
|
||||
return node()->deepReduceChildren(context, angleUnit, replaceSymbols);
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
static int sRecursionCount = 0;
|
||||
static bool sRecursionCountResetIsLocked = false;
|
||||
|
||||
/* Constructor & Destructor */
|
||||
|
||||
Expression Expression::clone() const { TreeHandle c = TreeHandle::clone(); return static_cast<Expression&>(c); }
|
||||
@@ -78,32 +75,15 @@ bool Expression::isRationalOne() const {
|
||||
}
|
||||
|
||||
bool Expression::recursivelyMatches(ExpressionTest test, Context & context) const {
|
||||
// Reset recursion count if needed
|
||||
bool willHaveToUnlock = ResetRecursionCountAndLockReset();
|
||||
|
||||
bool result = false;
|
||||
|
||||
IncrementRecursionCount();
|
||||
if (RecursionMaximalDepthExceeded()) {
|
||||
//TODO propagate recursion error?
|
||||
} else {
|
||||
if (test(*this, context)) {
|
||||
result = true;
|
||||
} else {
|
||||
for (int i = 0; i < this->numberOfChildren(); i++) {
|
||||
if (childAtIndex(i).recursivelyMatches(test, context)) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (test(*this, context)) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < this->numberOfChildren(); i++) {
|
||||
if (childAtIndex(i).recursivelyMatches(test, context)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock recursion count reset if needed
|
||||
if (willHaveToUnlock) {
|
||||
UnlockRecursionCountReset();
|
||||
}
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Expression::isApproximate(Context & context) const {
|
||||
@@ -120,11 +100,6 @@ bool Expression::isApproximate(Context & context) const {
|
||||
}
|
||||
|
||||
bool Expression::IsMatrix(const Expression e, Context & context) {
|
||||
assert(RecursionCountResetisLocked());
|
||||
IncrementRecursionCount();
|
||||
if (RecursionMaximalDepthExceeded()) {
|
||||
return false;
|
||||
}
|
||||
return e.type() == ExpressionNode::Type::Matrix
|
||||
|| e.type() == ExpressionNode::Type::ConfidenceInterval
|
||||
|| e.type() == ExpressionNode::Type::MatrixDimension
|
||||
@@ -262,20 +237,7 @@ Expression Expression::defaultReplaceSymbols(Context & context) {
|
||||
|
||||
template<typename U>
|
||||
Evaluation<U> Expression::approximateToEvaluation(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
bool willHaveToUnlock = ResetRecursionCountAndLockReset();
|
||||
|
||||
IncrementRecursionCount();
|
||||
Evaluation<U> result;
|
||||
if (RecursionMaximalDepthExceeded()) {
|
||||
result = Complex<U>::Undefined(); // TODO Propagate error "Recursion too deep"
|
||||
} else {
|
||||
result = node()->approximate(U(), context, angleUnit);
|
||||
}
|
||||
|
||||
if (willHaveToUnlock) {
|
||||
UnlockRecursionCountReset();
|
||||
}
|
||||
return result;
|
||||
return node()->approximate(U(), context, angleUnit);
|
||||
}
|
||||
|
||||
Expression Expression::defaultReplaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression expression) {
|
||||
@@ -295,18 +257,10 @@ int Expression::defaultGetPolynomialCoefficients(Context & context, const char *
|
||||
}
|
||||
|
||||
int Expression::getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
// Reset recursion count if needed
|
||||
bool willHaveToUnlock = ResetRecursionCountAndLockReset();
|
||||
|
||||
int degree = getPolynomialCoefficients(context, symbolName, coefficients);
|
||||
for (int i = 0; i <= degree; i++) {
|
||||
coefficients[i] = coefficients[i].deepReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
// Unlock recursion count reinitialization if needed
|
||||
if (willHaveToUnlock) {
|
||||
UnlockRecursionCountReset();
|
||||
}
|
||||
return degree;
|
||||
}
|
||||
|
||||
@@ -369,39 +323,10 @@ Expression Expression::simplify(Context & context, Preferences::AngleUnit angleU
|
||||
}
|
||||
|
||||
Expression Expression::reduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) {
|
||||
// Reset recursion count if needed
|
||||
bool willHaveToUnlock = ResetRecursionCountAndLockReset();
|
||||
|
||||
Expression result = deepReduce(context, angleUnit, replaceSymbols);
|
||||
|
||||
// Unlock recursion count reinitialization if needed
|
||||
if (willHaveToUnlock) {
|
||||
UnlockRecursionCountReset();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Expression::ResetRecursionCountAndLockReset() {
|
||||
if (!sRecursionCountResetIsLocked) {
|
||||
sRecursionCount = 0;
|
||||
sRecursionCountResetIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Expression::UnlockRecursionCountReset() {
|
||||
sRecursionCountResetIsLocked = false;
|
||||
return deepReduce(context, angleUnit, replaceSymbols);
|
||||
}
|
||||
|
||||
Expression Expression::deepReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) {
|
||||
IncrementRecursionCount();
|
||||
if (RecursionMaximalDepthExceeded()) {
|
||||
sSimplificationHasBeenInterrupted = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
#else
|
||||
if (IsMatrix(*this, context)) {
|
||||
@@ -423,18 +348,6 @@ Expression Expression::deepBeautify(Context & context, Preferences::AngleUnit an
|
||||
return e;
|
||||
}
|
||||
|
||||
void Expression::IncrementRecursionCount() {
|
||||
sRecursionCount++;
|
||||
}
|
||||
|
||||
bool Expression::RecursionMaximalDepthExceeded() {
|
||||
return sRecursionCount >= Expression::sRecursionLimit;
|
||||
}
|
||||
|
||||
bool Expression::RecursionCountResetisLocked() {
|
||||
return sRecursionCountResetIsLocked;
|
||||
}
|
||||
|
||||
Expression Expression::setSign(ExpressionNode::Sign s, Context & context, Preferences::AngleUnit angleUnit) {
|
||||
return node()->setSign(s, context, angleUnit);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@ void Init() {
|
||||
void Tidy() {
|
||||
// Clean Integer
|
||||
Integer::TidyIntegerBuffer();
|
||||
|
||||
// Unlock recursion count
|
||||
Expression::TidyAfterException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -134,11 +134,6 @@ Evaluation<T> SymbolNode::templatedApproximate(Context& context, Preferences::An
|
||||
/* First, replace all the symbols iteratively. This prevents a memory
|
||||
* failure symbols are defined circularly. */
|
||||
while (e.hasSymbols(context)) {
|
||||
assert(Expression::RecursionCountResetisLocked());
|
||||
Expression::IncrementRecursionCount();
|
||||
if (Expression::RecursionMaximalDepthExceeded()) {
|
||||
return Complex<T>::Undefined();
|
||||
}
|
||||
e = e.replaceSymbols(context);
|
||||
}
|
||||
return e.approximateToEvaluation<T>(context, angleUnit);
|
||||
@@ -183,12 +178,6 @@ Expression Symbol::shallowReduce(Context & context, Preferences::AngleUnit angle
|
||||
/* First, replace all the symbols iteratively. This prevents a memory
|
||||
* failure symbols are defined circularly. */
|
||||
while (result.hasSymbols(context)) {
|
||||
assert(RecursionCountResetisLocked());
|
||||
IncrementRecursionCount();
|
||||
if (RecursionMaximalDepthExceeded()) {
|
||||
replaceWithInPlace(e);
|
||||
return e;
|
||||
}
|
||||
result = result.replaceSymbols(context);
|
||||
}
|
||||
replaceWithInPlace(result);
|
||||
|
||||
Reference in New Issue
Block a user