From 0d9629e226b855ea88b8032a92e461e51807feec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 29 Jul 2019 16:06:57 +0200 Subject: [PATCH] [poincare] Omit multiplication when possible at beautifying --- poincare/include/poincare/absolute_value.h | 1 + poincare/include/poincare/addition.h | 13 ++++++++++ poincare/include/poincare/arc_cosine.h | 4 +++ poincare/include/poincare/arc_sine.h | 3 +++ poincare/include/poincare/arc_tangent.h | 3 +++ .../include/poincare/binomial_coefficient.h | 2 ++ poincare/include/poincare/ceiling.h | 2 ++ poincare/include/poincare/complex_argument.h | 3 +++ poincare/include/poincare/complex_cartesian.h | 7 ++++- .../include/poincare/confidence_interval.h | 3 +++ poincare/include/poincare/conjugate.h | 3 +++ poincare/include/poincare/constant.h | 2 ++ poincare/include/poincare/cosine.h | 3 +++ poincare/include/poincare/decimal.h | 2 ++ poincare/include/poincare/derivative.h | 2 ++ poincare/include/poincare/determinant.h | 2 ++ poincare/include/poincare/division.h | 1 + poincare/include/poincare/division_quotient.h | 4 +++ .../include/poincare/division_remainder.h | 4 +++ poincare/include/poincare/empty_expression.h | 6 +++++ poincare/include/poincare/equal.h | 1 + poincare/include/poincare/expression_node.h | 9 +++++++ poincare/include/poincare/factor.h | 3 +++ poincare/include/poincare/factorial.h | 3 +++ poincare/include/poincare/float.h | 4 +++ poincare/include/poincare/floor.h | 2 ++ poincare/include/poincare/frac_part.h | 3 +++ poincare/include/poincare/function.h | 3 +++ .../include/poincare/great_common_divisor.h | 2 ++ .../hyperbolic_trigonometric_function.h | 2 ++ poincare/include/poincare/imaginary_part.h | 2 ++ poincare/include/poincare/infinity.h | 3 +++ poincare/include/poincare/integral.h | 2 ++ .../include/poincare/least_common_multiple.h | 2 ++ poincare/include/poincare/logarithm.h | 2 ++ poincare/include/poincare/matrix.h | 3 +++ poincare/include/poincare/matrix_dimension.h | 2 ++ poincare/include/poincare/matrix_identity.h | 2 ++ poincare/include/poincare/matrix_inverse.h | 2 ++ poincare/include/poincare/matrix_trace.h | 2 ++ poincare/include/poincare/matrix_transpose.h | 2 ++ .../poincare/multiplication_explicite.h | 1 + poincare/include/poincare/n_ary_expression.h | 3 +++ .../include/poincare/naperian_logarithm.h | 2 ++ poincare/include/poincare/nth_root.h | 2 ++ poincare/include/poincare/opposite.h | 2 ++ poincare/include/poincare/parenthesis.h | 1 + .../include/poincare/permute_coefficient.h | 2 ++ poincare/include/poincare/power.h | 2 ++ .../include/poincare/prediction_interval.h | 2 ++ poincare/include/poincare/randint.h | 2 ++ poincare/include/poincare/random.h | 3 +++ poincare/include/poincare/rational.h | 2 ++ poincare/include/poincare/real_part.h | 2 ++ poincare/include/poincare/round.h | 2 ++ poincare/include/poincare/sequence.h | 1 + poincare/include/poincare/sign_function.h | 2 ++ poincare/include/poincare/sine.h | 2 ++ poincare/include/poincare/square_root.h | 2 ++ poincare/include/poincare/store.h | 1 + poincare/include/poincare/subtraction.h | 3 +++ poincare/include/poincare/symbol.h | 1 + poincare/include/poincare/tangent.h | 2 ++ poincare/include/poincare/undefined.h | 2 ++ poincare/src/expression.cpp | 4 +++ poincare/src/multiplication_explicite.cpp | 26 +++++++++++++++++++ 66 files changed, 199 insertions(+), 1 deletion(-) diff --git a/poincare/include/poincare/absolute_value.h b/poincare/include/poincare/absolute_value.h index b0bc1a963..356f4dae8 100644 --- a/poincare/include/poincare/absolute_value.h +++ b/poincare/include/poincare/absolute_value.h @@ -43,6 +43,7 @@ public: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } }; class AbsoluteValue final : public Expression { diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 2d66228f6..5761d67e2 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -36,6 +36,19 @@ public: template static MatrixComplex computeOnComplexAndMatrix(const std::complex c, const MatrixComplex m, Preferences::ComplexFormat complexFormat) { return ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(m, c, complexFormat, compute); } + + // Simplification + LayoutShape leftLayoutShape() const override { + /* When beautifying an Multiplication of Addition, Parentheses will be added + * around Addition. leftLayoutShape being called after beautifying, we + * should not call it on an Addition. */ + assert(false); + return NAryExpressionNode::leftLayoutShape(); + } + LayoutShape rightLayoutShape() const override { + assert(false); + return NAryExpressionNode::rightLayoutShape(); + } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/include/poincare/arc_cosine.h b/poincare/include/poincare/arc_cosine.h index 4a50d65d4..04af1d903 100644 --- a/poincare/include/poincare/arc_cosine.h +++ b/poincare/include/poincare/arc_cosine.h @@ -21,6 +21,7 @@ public: // Properties Type type() const override { return Type::ArcCosine; } + private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; @@ -28,6 +29,9 @@ private: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/arc_sine.h b/poincare/include/poincare/arc_sine.h index 201590ae1..8d6706d71 100644 --- a/poincare/include/poincare/arc_sine.h +++ b/poincare/include/poincare/arc_sine.h @@ -27,6 +27,9 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/arc_tangent.h b/poincare/include/poincare/arc_tangent.h index b4648ae20..9b2b14ac8 100644 --- a/poincare/include/poincare/arc_tangent.h +++ b/poincare/include/poincare/arc_tangent.h @@ -31,6 +31,9 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/binomial_coefficient.h b/poincare/include/poincare/binomial_coefficient.h index eb691aeb5..f6dae2503 100644 --- a/poincare/include/poincare/binomial_coefficient.h +++ b/poincare/include/poincare/binomial_coefficient.h @@ -30,6 +30,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }; + // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/ceiling.h b/poincare/include/poincare/ceiling.h index 2924ed60b..93e31f8af 100644 --- a/poincare/include/poincare/ceiling.h +++ b/poincare/include/poincare/ceiling.h @@ -29,6 +29,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }; + // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/complex_argument.h b/poincare/include/poincare/complex_argument.h index c8a39399e..ed477d043 100644 --- a/poincare/include/poincare/complex_argument.h +++ b/poincare/include/poincare/complex_argument.h @@ -28,6 +28,9 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/complex_cartesian.h b/poincare/include/poincare/complex_cartesian.h index 99b3a6f88..8edfffbb4 100644 --- a/poincare/include/poincare/complex_cartesian.h +++ b/poincare/include/poincare/complex_cartesian.h @@ -29,8 +29,13 @@ private: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowBeautify(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { + /* leftLayoutShape is called after beautifying expression. ComplexCartesian + * is transformed in another expression at beautifying. */ + assert(false); + return LayoutShape::BoundaryPunctuation; + }; -private: template Complex templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; diff --git a/poincare/include/poincare/confidence_interval.h b/poincare/include/poincare/confidence_interval.h index 7dec9769f..b36cb2d09 100644 --- a/poincare/include/poincare/confidence_interval.h +++ b/poincare/include/poincare/confidence_interval.h @@ -28,6 +28,9 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/conjugate.h b/poincare/include/poincare/conjugate.h index a1cf92fec..bf52fa928 100644 --- a/poincare/include/poincare/conjugate.h +++ b/poincare/include/poincare/conjugate.h @@ -28,6 +28,9 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); }; + LayoutShape rightLayoutShape() const override { return childAtIndex(0)->rightLayoutShape(); } + // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/constant.h b/poincare/include/poincare/constant.h index a09f763b9..9d9fcf425 100644 --- a/poincare/include/poincare/constant.h +++ b/poincare/include/poincare/constant.h @@ -48,6 +48,8 @@ public: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::SpecialLetter; }; + private: char m_name[0]; // MUST be the last member variable diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index dde0aa524..f78e3cdb4 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -34,6 +34,9 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplication Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); diff --git a/poincare/include/poincare/decimal.h b/poincare/include/poincare/decimal.h index 488098993..b3258c241 100644 --- a/poincare/include/poincare/decimal.h +++ b/poincare/include/poincare/decimal.h @@ -58,6 +58,8 @@ public: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowBeautify(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { assert(!m_negative); return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::DigitOrLetter; } // Serialization int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override; diff --git a/poincare/include/poincare/derivative.h b/poincare/include/poincare/derivative.h index 9b5f6f3e5..29c85490c 100644 --- a/poincare/include/poincare/derivative.h +++ b/poincare/include/poincare/derivative.h @@ -33,6 +33,8 @@ private: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/determinant.h b/poincare/include/poincare/determinant.h index 0abe92881..5b6560a00 100644 --- a/poincare/include/poincare/determinant.h +++ b/poincare/include/poincare/determinant.h @@ -25,6 +25,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Simplification */ Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } /* Approximation */ Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/division.h b/poincare/include/poincare/division.h index b4aa9f3c4..702a571e1 100644 --- a/poincare/include/poincare/division.h +++ b/poincare/include/poincare/division.h @@ -47,6 +47,7 @@ public: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::ShiftedBaseline; }; private: // Approximation diff --git a/poincare/include/poincare/division_quotient.h b/poincare/include/poincare/division_quotient.h index 87c0ca5c9..0aaaf0aea 100644 --- a/poincare/include/poincare/division_quotient.h +++ b/poincare/include/poincare/division_quotient.h @@ -23,6 +23,10 @@ public: // Complex bool isReal(Context * context) const override { return true; } + // Simplification + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/include/poincare/division_remainder.h b/poincare/include/poincare/division_remainder.h index e1f178d47..f3e4203da 100644 --- a/poincare/include/poincare/division_remainder.h +++ b/poincare/include/poincare/division_remainder.h @@ -24,6 +24,10 @@ public: // Complex bool isReal(Context * context) const override { return true; } + // Simplification + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/include/poincare/empty_expression.h b/poincare/include/poincare/empty_expression.h index a0332b9bf..d4374f02e 100644 --- a/poincare/include/poincare/empty_expression.h +++ b/poincare/include/poincare/empty_expression.h @@ -22,6 +22,12 @@ public: // Properties Type type() const override { return Type::EmptyExpression; } int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; + + // Simplification + LayoutShape leftLayoutShape() const override { + assert(false); + return LayoutShape::DigitOrLetter; + }; private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/include/poincare/equal.h b/poincare/include/poincare/equal.h index b32f84e59..f3d18e8b2 100644 --- a/poincare/include/poincare/equal.h +++ b/poincare/include/poincare/equal.h @@ -23,6 +23,7 @@ public: private: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { assert(false); return LayoutShape::DigitOrLetter; }; // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index 0c34f0f0a..1c28f882e 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -197,6 +197,15 @@ public: /*!*/ virtual Expression shallowBeautify(ReductionContext reductionContext); /* Return a clone of the denominator part of the expression */ /*!*/ virtual Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + /* LayoutShape is used to check if the multiplication sign can be omitted between two expressions. It depends on the "layout syle" of the on the right of the left expression */ + enum class LayoutShape { + DigitOrLetter, + SpecialLetter, + BoundaryPunctuation, + ShiftedBaseline + }; + virtual LayoutShape leftLayoutShape() const = 0; + virtual LayoutShape rightLayoutShape() const { return leftLayoutShape(); } /* Hierarchy */ ExpressionNode * childAtIndex(int i) const override { return static_cast(TreeNode::childAtIndex(i)); } diff --git a/poincare/include/poincare/factor.h b/poincare/include/poincare/factor.h index e2be32f03..07b7881d4 100644 --- a/poincare/include/poincare/factor.h +++ b/poincare/include/poincare/factor.h @@ -27,6 +27,9 @@ private: /* Simplification */ Expression shallowBeautify(ReductionContext reductionContext) override; Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + /* Evaluation */ Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/factorial.h b/poincare/include/poincare/factorial.h index f69eeb867..8f33f3e5e 100644 --- a/poincare/include/poincare/factorial.h +++ b/poincare/include/poincare/factorial.h @@ -34,6 +34,9 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplication Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/float.h b/poincare/include/poincare/float.h index 8d308455f..96531299b 100644 --- a/poincare/include/poincare/float.h +++ b/poincare/include/poincare/float.h @@ -49,6 +49,10 @@ public: Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } private: + // Simplification + LayoutShape leftLayoutShape() const override { assert(m_value >= 0); return LayoutShape::DigitOrLetter; } + LayoutShape rightLayoutShape() const override { return LayoutShape::DigitOrLetter; } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return Complex::Builder((U)m_value); } diff --git a/poincare/include/poincare/floor.h b/poincare/include/poincare/floor.h index ae1fc48af..f3f232e2b 100644 --- a/poincare/include/poincare/floor.h +++ b/poincare/include/poincare/floor.h @@ -31,6 +31,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }; + // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/frac_part.h b/poincare/include/poincare/frac_part.h index d532fd5f3..afc7bca35 100644 --- a/poincare/include/poincare/frac_part.h +++ b/poincare/include/poincare/frac_part.h @@ -31,6 +31,9 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/function.h b/poincare/include/poincare/function.h index aad9921ab..dac53428e 100644 --- a/poincare/include/poincare/function.h +++ b/poincare/include/poincare/function.h @@ -42,6 +42,9 @@ private: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowReplaceReplaceableSymbols(Context * context) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } + // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; diff --git a/poincare/include/poincare/great_common_divisor.h b/poincare/include/poincare/great_common_divisor.h index 839b677a2..11882a523 100644 --- a/poincare/include/poincare/great_common_divisor.h +++ b/poincare/include/poincare/great_common_divisor.h @@ -28,6 +28,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/hyperbolic_trigonometric_function.h b/poincare/include/poincare/hyperbolic_trigonometric_function.h index fa504a0d6..e30d2c882 100644 --- a/poincare/include/poincare/hyperbolic_trigonometric_function.h +++ b/poincare/include/poincare/hyperbolic_trigonometric_function.h @@ -12,6 +12,8 @@ public: int numberOfChildren() const override { return 1; } private: // Simplification + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } Expression shallowReduce(ReductionContext reductionContext) override; }; diff --git a/poincare/include/poincare/imaginary_part.h b/poincare/include/poincare/imaginary_part.h index 5515f7010..ab37623ed 100644 --- a/poincare/include/poincare/imaginary_part.h +++ b/poincare/include/poincare/imaginary_part.h @@ -30,6 +30,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { return Complex::Builder(std::imag(c)); diff --git a/poincare/include/poincare/infinity.h b/poincare/include/poincare/infinity.h index abd565856..1e98ee0a6 100644 --- a/poincare/include/poincare/infinity.h +++ b/poincare/include/poincare/infinity.h @@ -37,6 +37,9 @@ public: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override; private: + // Simplification + LayoutShape leftLayoutShape() const override { assert(!m_negative); return LayoutShape::DigitOrLetter; } + LayoutShape rightLayoutShape() const override { return LayoutShape::DigitOrLetter; } template Evaluation templatedApproximate() const; bool m_negative; }; diff --git a/poincare/include/poincare/integral.h b/poincare/include/poincare/integral.h index 05fc1c72e..6608cff9b 100644 --- a/poincare/include/poincare/integral.h +++ b/poincare/include/poincare/integral.h @@ -31,6 +31,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::DigitOrLetter; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/least_common_multiple.h b/poincare/include/poincare/least_common_multiple.h index 933d047f3..37f02b819 100644 --- a/poincare/include/poincare/least_common_multiple.h +++ b/poincare/include/poincare/least_common_multiple.h @@ -28,6 +28,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Simplification */ Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } /* Evaluation */ Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/logarithm.h b/poincare/include/poincare/logarithm.h index 6bb32e06c..a9f99732a 100644 --- a/poincare/include/poincare/logarithm.h +++ b/poincare/include/poincare/logarithm.h @@ -29,6 +29,8 @@ public: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowBeautify(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { /* log has a branch cut on ]-inf, 0]: it is then multivalued on this cut. We diff --git a/poincare/include/poincare/matrix.h b/poincare/include/poincare/matrix.h index 87b87fb28..beb661f87 100644 --- a/poincare/include/poincare/matrix.h +++ b/poincare/include/poincare/matrix.h @@ -35,6 +35,9 @@ public: Type type() const override { return Type::Matrix; } int polynomialDegree(Context * context, const char * symbolName) const override; + // Simplification + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }; + // Approximation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); diff --git a/poincare/include/poincare/matrix_dimension.h b/poincare/include/poincare/matrix_dimension.h index 1bf5fd4c0..7fab86226 100644 --- a/poincare/include/poincare/matrix_dimension.h +++ b/poincare/include/poincare/matrix_dimension.h @@ -26,6 +26,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/matrix_identity.h b/poincare/include/poincare/matrix_identity.h index 9dc9f9bd2..3c7ffe497 100644 --- a/poincare/include/poincare/matrix_identity.h +++ b/poincare/include/poincare/matrix_identity.h @@ -24,6 +24,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/matrix_inverse.h b/poincare/include/poincare/matrix_inverse.h index b7149dfea..4b88f9305 100644 --- a/poincare/include/poincare/matrix_inverse.h +++ b/poincare/include/poincare/matrix_inverse.h @@ -25,6 +25,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/matrix_trace.h b/poincare/include/poincare/matrix_trace.h index 29e7609d3..a1574ecee 100644 --- a/poincare/include/poincare/matrix_trace.h +++ b/poincare/include/poincare/matrix_trace.h @@ -25,6 +25,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/matrix_transpose.h b/poincare/include/poincare/matrix_transpose.h index 97f8d1515..35cdafab4 100644 --- a/poincare/include/poincare/matrix_transpose.h +++ b/poincare/include/poincare/matrix_transpose.h @@ -25,6 +25,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/multiplication_explicite.h b/poincare/include/poincare/multiplication_explicite.h index e248db8ef..b8d5d3a2e 100644 --- a/poincare/include/poincare/multiplication_explicite.h +++ b/poincare/include/poincare/multiplication_explicite.h @@ -54,6 +54,7 @@ public: Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + Expression omitMultiplicationWhenPossible(); Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; void sortChildrenInPlace(ExpressionOrder order, Context * context, bool canBeInterrupted) { NAryExpression::sortChildrenInPlace(order, context, false, canBeInterrupted); diff --git a/poincare/include/poincare/n_ary_expression.h b/poincare/include/poincare/n_ary_expression.h index 5234ac225..47fc5dd74 100644 --- a/poincare/include/poincare/n_ary_expression.h +++ b/poincare/include/poincare/n_ary_expression.h @@ -31,6 +31,9 @@ public: Expression squashUnaryHierarchyInPlace(); protected: + LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); }; + LayoutShape rightLayoutShape() const override { return childAtIndex(0)->rightLayoutShape(); } + /* With a pool of size < 120k and TreeNode of size 20, a node can't have more * than 6144 children which fit in uint16_t. */ uint16_t m_numberOfChildren; diff --git a/poincare/include/poincare/naperian_logarithm.h b/poincare/include/poincare/naperian_logarithm.h index 0c82860ff..ceefe9f87 100644 --- a/poincare/include/poincare/naperian_logarithm.h +++ b/poincare/include/poincare/naperian_logarithm.h @@ -26,6 +26,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } /* Evaluation */ template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { /* ln has a branch cut on ]-inf, 0]: it is then multivalued on this cut. We diff --git a/poincare/include/poincare/nth_root.h b/poincare/include/poincare/nth_root.h index d6d9728f5..94905cea1 100644 --- a/poincare/include/poincare/nth_root.h +++ b/poincare/include/poincare/nth_root.h @@ -25,6 +25,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::ShiftedBaseline; }; + LayoutShape rightLayoutShape() const override { return childAtIndex(0)->rightLayoutShape(); } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/opposite.h b/poincare/include/poincare/opposite.h index 5d8c2050f..205388cbd 100644 --- a/poincare/include/poincare/opposite.h +++ b/poincare/include/poincare/opposite.h @@ -42,6 +42,8 @@ public: // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { assert(false); return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return childAtIndex(0)->rightLayoutShape(); } }; class Opposite final : public Expression { diff --git a/poincare/include/poincare/parenthesis.h b/poincare/include/poincare/parenthesis.h index b89db7c18..177776860 100644 --- a/poincare/include/poincare/parenthesis.h +++ b/poincare/include/poincare/parenthesis.h @@ -27,6 +27,7 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }; // Approximation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/permute_coefficient.h b/poincare/include/poincare/permute_coefficient.h index 3786c377b..d39ccce7a 100644 --- a/poincare/include/poincare/permute_coefficient.h +++ b/poincare/include/poincare/permute_coefficient.h @@ -32,6 +32,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index 3766e810d..537c7e266 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -48,6 +48,8 @@ private: // Simplify Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowBeautify(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); }; + LayoutShape rightLayoutShape() const override { return LayoutShape::ShiftedBaseline; }; int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; diff --git a/poincare/include/poincare/prediction_interval.h b/poincare/include/poincare/prediction_interval.h index ff750b610..e1133ae3b 100644 --- a/poincare/include/poincare/prediction_interval.h +++ b/poincare/include/poincare/prediction_interval.h @@ -28,6 +28,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/randint.h b/poincare/include/poincare/randint.h index 0eab1e67f..514747aa8 100644 --- a/poincare/include/poincare/randint.h +++ b/poincare/include/poincare/randint.h @@ -38,6 +38,8 @@ private: template Evaluation templateApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } }; class Randint final : public Expression { diff --git a/poincare/include/poincare/random.h b/poincare/include/poincare/random.h index 9746f3c78..1677dc7b7 100644 --- a/poincare/include/poincare/random.h +++ b/poincare/include/poincare/random.h @@ -27,6 +27,9 @@ public: Sign sign(Context * context) const override { return Sign::Positive; } Expression setSign(Sign s, ReductionContext reductionContext) override; private: + // Simplification + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/include/poincare/rational.h b/poincare/include/poincare/rational.h index 119d6b44b..1dab7d779 100644 --- a/poincare/include/poincare/rational.h +++ b/poincare/include/poincare/rational.h @@ -55,6 +55,8 @@ private: int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowBeautify(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { assert(!m_negative); return isInteger() ? LayoutShape::DigitOrLetter : LayoutShape::ShiftedBaseline; }; + LayoutShape rightLayoutShape() const override { return isInteger() ? LayoutShape::DigitOrLetter : LayoutShape::ShiftedBaseline; } Expression setSign(Sign s, ReductionContext reductionContext) override; Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; bool m_negative; diff --git a/poincare/include/poincare/real_part.h b/poincare/include/poincare/real_part.h index ec61002d8..c68e28921 100644 --- a/poincare/include/poincare/real_part.h +++ b/poincare/include/poincare/real_part.h @@ -30,6 +30,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { return Complex::Builder(std::real(c)); diff --git a/poincare/include/poincare/round.h b/poincare/include/poincare/round.h index e5ec2f702..6d070ef26 100644 --- a/poincare/include/poincare/round.h +++ b/poincare/include/poincare/round.h @@ -29,6 +29,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/sequence.h b/poincare/include/poincare/sequence.h index 69cc8656e..0067f3790 100644 --- a/poincare/include/poincare/sequence.h +++ b/poincare/include/poincare/sequence.h @@ -17,6 +17,7 @@ private: virtual Layout createSequenceLayout(Layout argumentLayout, Layout symbolLayout, Layout subscriptLayout, Layout superscriptLayout) const = 0; // Simplication Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }; /* Approximation */ Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/sign_function.h b/poincare/include/poincare/sign_function.h index 376a36459..99259f7c8 100644 --- a/poincare/include/poincare/sign_function.h +++ b/poincare/include/poincare/sign_function.h @@ -32,6 +32,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index 6a2517d87..5424fb117 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -35,6 +35,8 @@ private: // Simplication Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/square_root.h b/poincare/include/poincare/square_root.h index 96b19309e..6617f4422 100644 --- a/poincare/include/poincare/square_root.h +++ b/poincare/include/poincare/square_root.h @@ -27,6 +27,8 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }; + LayoutShape rightLayoutShape() const override { return childAtIndex(0)->rightLayoutShape(); } // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { diff --git a/poincare/include/poincare/store.h b/poincare/include/poincare/store.h index 012d02306..771b5b613 100644 --- a/poincare/include/poincare/store.h +++ b/poincare/include/poincare/store.h @@ -27,6 +27,7 @@ private: // Simplification void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override {} Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { assert(false); return LayoutShape::DigitOrLetter; }; // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/include/poincare/subtraction.h b/poincare/include/poincare/subtraction.h index 7fb341314..e83120752 100644 --- a/poincare/include/poincare/subtraction.h +++ b/poincare/include/poincare/subtraction.h @@ -42,6 +42,9 @@ public: Expression shallowReduce(ReductionContext reductionContext) override; private: + /* Simplification */ + LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); }; + LayoutShape rightLayoutShape() const override { return childAtIndex(1)->rightLayoutShape(); } /* Evaluation */ template static MatrixComplex computeOnMatrixAndComplex(const MatrixComplex m, const std::complex c, Preferences::ComplexFormat complexFormat) { return ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(m, c, complexFormat, compute); diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index cc14c040a..4033a8b38 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -38,6 +38,7 @@ public: /* Simplification */ Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowReplaceReplaceableSymbols(Context * context) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; /* Approximation */ Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index 2769ce19b..ae1741a8a 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -32,6 +32,8 @@ private: // Simplication Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian); diff --git a/poincare/include/poincare/undefined.h b/poincare/include/poincare/undefined.h index 3ab003952..43c03441b 100644 --- a/poincare/include/poincare/undefined.h +++ b/poincare/include/poincare/undefined.h @@ -37,6 +37,8 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override; protected: template Evaluation templatedApproximate() const; + // Simplification + LayoutShape leftLayoutShape() const override { return LayoutShape::DigitOrLetter; }; }; class Undefined final : public Number { diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index a4d019dc8..e86619265 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -616,6 +616,10 @@ Expression Expression::deepBeautify(ExpressionNode::ReductionContext reductionCo e.replaceChildAtIndexInPlace(i, Parenthesis::Builder(child)); } } + // We choose whether or not to omit multiplication sign after beautifying parent and child + if (e.type() == ExpressionNode::Type::MultiplicationExplicite) { + e = static_cast(e).omitMultiplicationWhenPossible(); + } return e; } diff --git a/poincare/src/multiplication_explicite.cpp b/poincare/src/multiplication_explicite.cpp index 83516eb25..4bbaaf821 100644 --- a/poincare/src/multiplication_explicite.cpp +++ b/poincare/src/multiplication_explicite.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -65,6 +66,31 @@ Expression MultiplicationExplicite::shallowReduce(ExpressionNode::ReductionConte return privateShallowReduce(reductionContext, true, true); } +static bool canOmitSignBefore(ExpressionNode::LayoutShape right) { + // 2π, 2(1+2), ππ, π(1+2) + return right == ExpressionNode::LayoutShape::SpecialLetter || right == ExpressionNode::LayoutShape::BoundaryPunctuation; +} + +Expression MultiplicationExplicite::omitMultiplicationWhenPossible() { + int i = 0; + while (i < numberOfChildren() - 1) { + Expression childI = childAtIndex(i); + Expression childI1 = childAtIndex(i+1); + if (canOmitSignBefore(childI1.node()->leftLayoutShape())) { + if (childI.type() == ExpressionNode::Type::MultiplicationImplicite) { + static_cast(childI).addChildAtIndexInPlace(childI1, childI.numberOfChildren(), childI.numberOfChildren()); + } else { + Expression impliciteMultiplication = MultiplicationImplicite::Builder(childI, childI1); + replaceChildAtIndexInPlace(i, impliciteMultiplication); + } + removeChildAtIndexInPlace(i+1); + continue; + } + i++; + } + return squashUnaryHierarchyInPlace(); +} + Expression MultiplicationExplicite::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { /* Beautifying a Multiplication consists in several possible operations: * - Add Opposite ((-3)*x -> -(3*x), useful when printing fractions)