From 6135fced52f5c2e0d86333f1216d15fbe8a10a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Wed, 13 Nov 2019 14:49:44 +0100 Subject: [PATCH] [poincare] Power: always reduce (a^b)^(-1) --- poincare/src/power.cpp | 14 +++++++++----- poincare/test/simplification.cpp | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index e5ffc985a..77bba4c05 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -625,18 +625,22 @@ Expression Power::shallowReduce(ExpressionNode::ReductionContext reductionContex * --> tan(2)+tan(2)*[tan(2)^1/2]^(-1)/tan(2) * --> tan(2)^(3/2)+tan(2)^(3/2)*[tan(2)^1/2]^(-1)/tan(2)^3/2 * --> ... - * Indeed, we have to apply the rule (a^b)^c -> a^(b*c) as soon as c is an - * integer. + * Indeed, we have to apply the rule (a^b)^c -> a^(b*c) as soon as c is -1. */ if (baseType == ExpressionNode::Type::Power) { Power powerBase = static_cast(base); + bool cInteger = indexType == ExpressionNode::Type::Rational && static_cast(index).isInteger(); bool applyRule = powerBase.childAtIndex(0).sign(reductionContext.context()) == ExpressionNode::Sign::Positive // a > 0 - || (indexType == ExpressionNode::Type::Rational && static_cast(index).isInteger()); // c integer + || cInteger; // c integer + bool cMinusOne = cInteger && static_cast(index).isMinusOne(); /* If the complexFormat is real, we check that the inner power is defined * before applying the rule (a^b)^c -> a^(b*c). Otherwise, we return - * 'unreal' or we do nothing. */ - if (reductionContext.complexFormat() == Preferences::ComplexFormat::Real) { + * 'unreal' or we do nothing. + * We escape this additional check if c = -1 for two reasons: + * - (a^b)^(-1) has to be reduced to avoid infinite loop discussed above; + * - if a^b is unreal, a^(-b) also. */ + if (!cMinusOne && reductionContext.complexFormat() == Preferences::ComplexFormat::Real) { Expression approximation = powerBase.approximate(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); if (approximation.type() == ExpressionNode::Type::Unreal) { // The inner power is unreal, return "unreal" diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index 23e1820aa..2699ddc57 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -107,6 +107,7 @@ QUIZ_CASE(poincare_simplification_infinity) { } QUIZ_CASE(poincare_simplification_addition) { + assert_parsed_expression_simplify_to("1/x^2+3", "\u00123×x^2+1\u0013/x^2", User, Radian, Real); assert_parsed_expression_simplify_to("1+x", "x+1"); assert_parsed_expression_simplify_to("1/2+1/3+1/4+1/5+1/6+1/7", "223/140"); assert_parsed_expression_simplify_to("1+x+4-i-2x", "-i-x+5");