From 7c79c70890e059acfb95d334ca9ae0fcfb314aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 24 Mar 2020 12:16:05 +0100 Subject: [PATCH] [poincare] When simplification has been interrupted, escape the end of simplification. Otherwise we can be stuck in infinite loop. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the following bug: when simplifying an expression as 'bigRational1^x*bigRational2^x', we use the rule a^x*b^x --> (a¨b)^x. However, in this case, a*b can't be reduce (resulting rational would be too big) and we're stuck in the loop a^x*b^x --> (a¨b)^x --> a^x*b^x --> (a¨b)^x... --- poincare/src/expression.cpp | 28 ++++++++++++++++------------ poincare/test/simplification.cpp | 2 ++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 602bd3663..7f9c761d8 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -321,18 +321,22 @@ void Expression::defaultDeepReduceChildren(ExpressionNode::ReductionContext redu Expression Expression::defaultShallowReduce() { Expression result; - const int childrenCount = numberOfChildren(); - for (int i = 0; i < childrenCount; i++) { - /* The reduction is shortcut if one child is unreal or undefined: - * - the result is unreal if at least one child is unreal - * - the result is undefined if at least one child is undefined but no child - * is unreal */ - ExpressionNode::Type childIType = childAtIndex(i).type(); - if (childIType == ExpressionNode::Type::Unreal) { - result = Unreal::Builder(); - break; - } else if (childIType == ExpressionNode::Type::Undefined) { - result = Undefined::Builder(); + if (sSimplificationHasBeenInterrupted) { + result = Undefined::Builder(); + } else { + const int childrenCount = numberOfChildren(); + for (int i = 0; i < childrenCount; i++) { + /* The reduction is shortcut if one child is unreal or undefined: + * - the result is unreal if at least one child is unreal + * - the result is undefined if at least one child is undefined but no child + * is unreal */ + ExpressionNode::Type childIType = childAtIndex(i).type(); + if (childIType == ExpressionNode::Type::Unreal) { + result = Unreal::Builder(); + break; + } else if (childIType == ExpressionNode::Type::Undefined) { + result = Undefined::Builder(); + } } } if (!result.isUninitialized()) { diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index cd5bd1c04..89eb2c287 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -1317,6 +1317,8 @@ QUIZ_CASE(poincare_simplification_mix) { //assert_parsed_expression_simplify_to("log(cos(9)^ln(6), 9)", "ln(6)×log(cos(9), 9)"); // TODO: for this to work, we must know the sign of cos(9) assert_parsed_expression_simplify_to("(((√(6)-√(2))/4)/((√(6)+√(2))/4))+1", "-√(3)+3"); assert_parsed_expression_simplify_to("1/√(𝐢) × (√(2)-𝐢×√(2))", "-2×𝐢"); // TODO: get rid of complex at denominator? + + assert_expression_simplifies_approximates_to("abs(√(300000.0003^23))", "9.7027409010183ᴇ62"); } QUIZ_CASE(poincare_hyperbolic_trigonometry) {