From fe3fa9bf7ce107c026b2b1150ee216103ce272cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 17 Nov 2017 18:07:05 +0100 Subject: [PATCH] [poincare] Do not simplify power when it is the children of a logarithm that can simplify Change-Id: Ibec5a97b4eda0cf25efcbe5ee4f9a99673c0eb8a --- poincare/include/poincare/power.h | 1 + poincare/src/power.cpp | 30 ++++++++++++++++++++++++++---- poincare/test/simplify_easy.cpp | 4 ++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index b0d0918e9..cc7faacc1 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -40,6 +40,7 @@ private: Expression * simplifyPowerMultiplication(Multiplication * m, Expression * r, Context & context, AngleUnit angleUnit); Expression * simplifyRationalRationalPower(Expression * result, Rational * a, Rational * b, Context & context, AngleUnit angleUnit); Expression * removeSquareRootsFromDenominator(Context & context, AngleUnit angleUnit); + bool parentIsALogarithmOfSameBase() const; bool isNthRootOfUnity() const; static Expression * CreateSimplifiedIntegerRationalPower(Integer i, Rational * r, bool isDenominator, Context & context, AngleUnit angleUnit); static Expression * CreateNthRootOfUnity(const Rational r); diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 28421dc0c..4a697952f 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -201,6 +201,7 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) { return replaceWith(CreateNthRootOfUnity(r))->shallowReduce(context, angleUnit); } } + bool letPowerAtRoot = parentIsALogarithmOfSameBase(); if (operand(0)->type() == Type::Rational) { Rational * a = static_cast(editableOperand(0)); // 0^x @@ -217,12 +218,12 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) { return replaceWith(new Rational(1), true); } // p^q with p, q rationals - if (operand(1)->type() == Type::Rational) { + if (!letPowerAtRoot && operand(1)->type() == Type::Rational) { return simplifyRationalRationalPower(this, a, static_cast(editableOperand(1)), context, angleUnit); } } // e^(i*Pi*r) with r rational - if (isNthRootOfUnity()) { + if (!letPowerAtRoot && isNthRootOfUnity()) { Expression * m = editableOperand(1); detachOperand(m); Expression * i = m->editableOperand(m->numberOfOperands()-1); @@ -264,7 +265,7 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) { } } // (a*b*c*...)^r ? - if (operand(0)->type() == Type::Multiplication) { + if (!letPowerAtRoot && operand(0)->type() == Type::Multiplication) { Multiplication * m = static_cast(editableOperand(0)); // (a*b*c*...)^n = a^n*b^n*c^n*... if n integer if (operand(1)->type() == Type::Rational && static_cast(editableOperand(1))->denominator().isOne()) { @@ -295,7 +296,7 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) { } } // a^(b+c) -> Rational(a^b)*a^c with a and b rational - if (operand(0)->type() == Type::Rational && operand(1)->type() == Type::Addition) { + if (!letPowerAtRoot && operand(0)->type() == Type::Rational && operand(1)->type() == Type::Addition) { Addition * a = static_cast(editableOperand(1)); // Check is b is rational if (a->operand(0)->type() == Type::Rational) { @@ -311,6 +312,27 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) { return this; } +bool Power::parentIsALogarithmOfSameBase() const { + if (parent()->type() == Type::Logarithm && parent()->operand(0) == this) { + // parent = log(10^x) + if (parent()->numberOfOperands() == 1) { + if (operand(0)->type() == Type::Rational && static_cast(operand(0))->isTen()) { + return true; + } + return false; + } + // parent = log(x^y,x) + if (operand(0)->isIdenticalTo(parent()->operand(1))) { + return true; + } + } + // parent = ln(e^x) + if (parent()->type() == Type::NaperianLogarithm && parent()->operand(0) == this && operand(0)->type() == Type::Symbol && static_cast(operand(0))->name() == Ion::Charset::Exponential) { + return true; + } + return false; +} + Expression * Power::simplifyPowerPower(Power * p, Expression * e, Context& context, AngleUnit angleUnit) { Expression * p0 = p->editableOperand(0); Expression * p1 = p->editableOperand(1); diff --git a/poincare/test/simplify_easy.cpp b/poincare/test/simplify_easy.cpp index 659c35f09..0989d2e88 100644 --- a/poincare/test/simplify_easy.cpp +++ b/poincare/test/simplify_easy.cpp @@ -483,6 +483,10 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("X^ln(PX)", "PX"); assert_parsed_expression_simplify_to("X^log(PX)", "X^(log(P)+log(X))"); assert_parsed_expression_simplify_to("R(X^2)", "X"); + assert_parsed_expression_simplify_to("ln(X^(IP/7))", "IP/7"); + assert_parsed_expression_simplify_to("log(10^24)", "24"); + assert_parsed_expression_simplify_to("log((23P)^4,23P)", "4"); + assert_parsed_expression_simplify_to("log(10^(2+P))", "2+P"); /* This does not work but should not as it is above k_primorial32 = 1*3*5*7*11*... (product of first 32 primes. */ //assert_parsed_expression_simplify_to("1881676377434183981909562699940347954480361860897069^(1/3)", "123456789123456789");