[poincare] Add NullStatus and sign for more complex expressions

Change-Id: Ic593517bf7a983985fe3c521e10c19ab0bca4191
This commit is contained in:
Hugo Saint-Vignes
2020-10-23 16:14:54 +02:00
committed by Émilie Feral
parent 61d33be2a7
commit 42f20fb58d
7 changed files with 35 additions and 0 deletions

View File

@@ -23,6 +23,11 @@ public:
#endif
// Properties
Sign sign(Context * context) const override;
NullStatus nullStatus(Context * context) const override {
// NonNull Status can't be returned because denominator could be infinite.
return childAtIndex(0)->nullStatus(context) == NullStatus::Null ? NullStatus::Null : NullStatus::Unknown;
}
Type type() const override { return Type::Division; }
int polynomialDegree(Context * context, const char * symbolName) const override;
Expression removeUnit(Expression * unit) override { assert(false); return ExpressionNode::removeUnit(unit); }

View File

@@ -19,6 +19,7 @@ public:
#endif
// ExpressionNode
Sign sign(Context * context) const override;
Type type() const override { return Type::DivisionQuotient; }
// Simplification

View File

@@ -27,6 +27,10 @@ public:
// Properties
Type type() const override { return Type::Power; }
Sign sign(Context * context) const override;
NullStatus nullStatus(Context * context) const override {
// NonNull Status can't be returned because base could be infinite.
return childAtIndex(0)->nullStatus(context) == NullStatus::Null ? NullStatus::Null : NullStatus::Unknown;
}
Expression setSign(Sign s, ReductionContext reductionContext) override;
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
Expression removeUnit(Expression * unit) override;

View File

@@ -10,6 +10,8 @@ namespace Poincare {
class SquareRootNode /*final*/ : public ExpressionNode {
public:
// ExpressionNode
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context) == Sign::Positive ? Sign::Positive : Sign::Unknown ; }
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->nullStatus(context); }
Type type() const override { return Type::SquareRoot; }
// TreeNode

View File

@@ -14,6 +14,15 @@
namespace Poincare {
ExpressionNode::Sign DivisionNode::sign(Context * context) const {
ExpressionNode::Sign numeratorSign = childAtIndex(0)->sign(context);
ExpressionNode::Sign denominatorSign = childAtIndex(1)->sign(context);
if (numeratorSign == ExpressionNode::Sign::Unknown || denominatorSign == ExpressionNode::Sign::Unknown) {
return ExpressionNode::Sign::Unknown;
}
return numeratorSign == denominatorSign ? ExpressionNode::Sign::Positive : ExpressionNode::Sign::Negative;
}
int DivisionNode::polynomialDegree(Context * context, const char * symbolName) const {
if (childAtIndex(1)->polynomialDegree(context, symbolName) != 0) {
return -1;

View File

@@ -12,6 +12,15 @@ constexpr Expression::FunctionHelper DivisionQuotient::s_functionHelper;
int DivisionQuotientNode::numberOfChildren() const { return DivisionQuotient::s_functionHelper.numberOfChildren(); }
ExpressionNode::Sign DivisionQuotientNode::sign(Context * context) const {
ExpressionNode::Sign numeratorSign = childAtIndex(0)->sign(context);
ExpressionNode::Sign denominatorSign = childAtIndex(1)->sign(context);
if (numeratorSign == ExpressionNode::Sign::Unknown || denominatorSign == ExpressionNode::Sign::Unknown) {
return ExpressionNode::Sign::Unknown;
}
return numeratorSign == denominatorSign ? ExpressionNode::Sign::Positive : ExpressionNode::Sign::Negative;
}
Expression DivisionQuotientNode::shallowReduce(ReductionContext reductionContext) {
return DivisionQuotient(this).shallowReduce(reductionContext.context());
}

View File

@@ -49,6 +49,9 @@ QUIZ_CASE(poincare_properties_is_number_zero) {
quiz_assert(Parenthesis::Builder(Rational::Builder(-7)).nullStatus(&context) == ExpressionNode::NullStatus::NonNull);
quiz_assert(SignFunction::Builder(Rational::Builder(0)).nullStatus(&context) == ExpressionNode::NullStatus::Null);
quiz_assert(Unit::Builder(Unit::k_powerRepresentatives, Unit::Prefix::EmptyPrefix()).nullStatus(&context) == ExpressionNode::NullStatus::NonNull);
quiz_assert(Division::Builder(Rational::Builder(0), Rational::Builder(3,7)).nullStatus(&context) == ExpressionNode::NullStatus::Null);
quiz_assert(Power::Builder(Rational::Builder(0), Rational::Builder(3,7)).nullStatus(&context) == ExpressionNode::NullStatus::Null);
quiz_assert(SquareRoot::Builder(Rational::Builder(2,5)).nullStatus(&context) == ExpressionNode::NullStatus::NonNull);
}
QUIZ_CASE(poincare_properties_is_random) {
@@ -189,6 +192,8 @@ QUIZ_CASE(poincare_properties_expression_sign) {
quiz_assert(SignFunction::Builder(Rational::Builder(-7)).sign(&context) == ExpressionNode::Sign::Negative);
quiz_assert(Unit::Builder(Unit::k_powerRepresentatives, Unit::Prefix::EmptyPrefix()).sign(&context) == ExpressionNode::Sign::Positive);
quiz_assert(VectorNorm::Builder(BasedInteger::Builder(1)).sign(&context) == ExpressionNode::Sign::Positive);
quiz_assert(Division::Builder(Rational::Builder(7,3), Rational::Builder(-1)).sign(&context) == ExpressionNode::Sign::Negative);
quiz_assert(DivisionQuotient::Builder(Rational::Builder(-7), Rational::Builder(-1)).sign(&context) == ExpressionNode::Sign::Positive);
quiz_assert(ArcSine::Builder(Floor::Builder(ArcTangent::Builder(Opposite::Builder(RealPart::Builder(ArcCosine::Builder(Constant::Builder(UCodePointGreekSmallLetterPi))))))).sign(&context) == ExpressionNode::Sign::Negative);
}