[poincare] shallowBeautify can modify the reduction context

UnitConvert must set UnitConversion to None, otherwise the unit asked
for in the conversion might get changed after being properly set in
UnitConvert::shallowBeautify.
This commit is contained in:
Léa Saviot
2020-11-09 11:46:16 +01:00
committed by EmilieNumworks
parent 3a0796d3c5
commit 5df60e946a
28 changed files with 128 additions and 89 deletions

View File

@@ -55,7 +55,7 @@ private:
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
// Derivation
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
@@ -83,7 +83,7 @@ public:
static Addition Builder(Expression e1, Expression e2) { return Addition::Builder({e1, e2}); }
// Expression
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) {

View File

@@ -30,7 +30,7 @@ private:
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(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. */
@@ -54,7 +54,7 @@ public:
// Simplification
Expression shallowReduce();
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
// Common operations (done in-place)
Expression squareNorm(ExpressionNode::ReductionContext reductionContext);

View File

@@ -61,7 +61,7 @@ public:
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
LayoutShape leftLayoutShape() const override { assert(!m_negative); return LayoutShape::Decimal; };
LayoutShape rightLayoutShape() const override { return LayoutShape::Decimal; }

View File

@@ -390,7 +390,7 @@ protected:
Expression makePositiveAnyNegativeNumeralFactor(ExpressionNode::ReductionContext reductionContext);
Expression denominator(ExpressionNode::ReductionContext reductionContext) const { return node()->denominator(reductionContext); }
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext) { return node()->shallowReduce(reductionContext); }
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext) { return node()->shallowBeautify(reductionContext); }
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { return node()->shallowBeautify(reductionContext); }
Expression deepBeautify(ExpressionNode::ReductionContext reductionContext);
// WARNING: this must be called on reduced expressions
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
@@ -429,6 +429,10 @@ private:
Expression defaultHandleUnitsInChildren(); // Children must be reduced
Expression shallowReduceUsingApproximation(ExpressionNode::ReductionContext reductionContext);
Expression defaultShallowBeautify() { return *this; }
void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
node()->deepBeautifyChildren(reductionContext);
}
void defaultDeepBeautifyChildren(ExpressionNode::ReductionContext reductionContext);
bool defaultDidDerivate() { return false; }
Expression defaultUnaryFunctionDifferential() { return *this; }

View File

@@ -284,8 +284,9 @@ public:
/* Simplification */
/*!*/ virtual void deepReduceChildren(ReductionContext reductionContext);
/*!*/ virtual void deepBeautifyChildren(ReductionContext reductionContext);
/*!*/ virtual Expression shallowReduce(ReductionContext reductionContext);
/*!*/ virtual Expression shallowBeautify(ReductionContext reductionContext);
/*!*/ virtual Expression shallowBeautify(ReductionContext * reductionContext);
/*!*/ virtual bool derivate(ReductionContext, Expression symbol, Expression symbolValue);
virtual Expression unaryFunctionDifferential();
/* Return a clone of the denominator part of the expression */

View File

@@ -27,7 +27,7 @@ private:
/* Serialization */
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
/* Simplification */
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
Expression shallowReduce(ReductionContext reductionContext) override;
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
@@ -49,7 +49,7 @@ public:
// Expression
Expression shallowReduce(Context * context);
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
};
}

View File

@@ -26,7 +26,7 @@ private:
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
// Evaluation

View File

@@ -26,7 +26,7 @@ private:
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
// Evaluation

View File

@@ -29,7 +29,7 @@ public:
// Simplification
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override;
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
// Derivation

View File

@@ -47,7 +47,7 @@ private:
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
Expression denominator(ExpressionNode::ReductionContext reductionContext) const override;
// Derivation
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
@@ -85,7 +85,7 @@ public:
// Simplification
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
Expression denominator(ExpressionNode::ReductionContext reductionContext) const;
void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) {
NAryExpression::sortChildrenInPlace(order, context, false, canBeInterrupted);

View File

@@ -53,7 +53,7 @@ private:
// Simplify
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); }
LayoutShape rightLayoutShape() const override { return LayoutShape::RightOfPower; }
int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
@@ -83,7 +83,7 @@ public:
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const;
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
private:

View File

@@ -58,7 +58,7 @@ public:
private:
int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
LayoutShape leftLayoutShape() const override { assert(!m_negative); return isInteger() ? LayoutShape::Integer : LayoutShape::Fraction; };
Expression setSign(Sign s, ReductionContext reductionContext) override;
Expression denominator(ReductionContext reductionContext) const override;

View File

@@ -473,7 +473,7 @@ public:
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
LayoutShape leftLayoutShape() const override { return LayoutShape::OneLetter; } // TODO
const Representative * representative() const { return m_representative; }
@@ -686,7 +686,7 @@ public:
// Simplification
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify();
bool isBaseUnit() const { return node()->representative()->isBaseUnit() && node()->prefix() == node()->representative()->basePrefix(); }
void chooseBestRepresentativeAndPrefix(double * value, double exponent, ExpressionNode::ReductionContext reductionContext, bool optimizePrefix);

View File

@@ -23,7 +23,8 @@ private:
Expression removeUnit(Expression * unit) override;
// Simplification
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext reductionContext) override;
void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) override;
Expression shallowBeautify(ReductionContext * reductionContext) override;
// Evalutation
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
@@ -38,7 +39,8 @@ public:
// Expression
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
private:
UnitConvertNode * node() const { return static_cast<UnitConvertNode *>(Expression::node()); }
};

View File

@@ -46,7 +46,7 @@ Expression AdditionNode::shallowReduce(ReductionContext reductionContext) {
return Addition(this).shallowReduce(reductionContext);
}
Expression AdditionNode::shallowBeautify(ReductionContext reductionContext) {
Expression AdditionNode::shallowBeautify(ReductionContext * reductionContext) {
return Addition(this).shallowBeautify(reductionContext);
}
@@ -84,7 +84,7 @@ int Addition::getPolynomialCoefficients(Context * context, const char * symbolNa
return deg;
}
Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
Expression Addition::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
/* Beautifying AdditionNode essentially consists in adding Subtractions if
* needed.
* In practice, we want to turn "a+(-1)*b" into "a-b". Or, more precisely, any
@@ -98,12 +98,12 @@ Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionC
/* Sort children in decreasing order:
* 1+x+x^2 --> x^2+x+1
* 1+R(2) --> R(2)+1 */
sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, false, canBeInterrupted); }, reductionContext.context(), true);
sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, false, canBeInterrupted); }, reductionContext->context(), true);
int nbChildren = numberOfChildren();
for (int i = 0; i < nbChildren; i++) {
// Try to make the child i positive if any negative numeral factor is found
Expression subtractant = childAtIndex(i).makePositiveAnyNegativeNumeralFactor(reductionContext);
Expression subtractant = childAtIndex(i).makePositiveAnyNegativeNumeralFactor(*reductionContext);
if (subtractant.isUninitialized())
{
// if subtractant is not initialized, it means the child i had no negative numeral factor
@@ -130,7 +130,6 @@ Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionC
}
Expression result = squashUnaryHierarchyInPlace();
return result;
}

View File

@@ -32,7 +32,7 @@ Expression ComplexCartesianNode::shallowReduce(ReductionContext reductionContext
return ComplexCartesian(this).shallowReduce();
}
Expression ComplexCartesianNode::shallowBeautify(ReductionContext reductionContext) {
Expression ComplexCartesianNode::shallowBeautify(ReductionContext * reductionContext) {
return ComplexCartesian(this).shallowBeautify(reductionContext);
}
@@ -77,11 +77,11 @@ Expression ComplexCartesian::shallowReduce() {
return *this;
}
Expression ComplexCartesian::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
Expression ComplexCartesian::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
Expression a = real();
Expression b = imag();
Expression oppositeA = a.makePositiveAnyNegativeNumeralFactor(reductionContext);
Expression oppositeB = b.makePositiveAnyNegativeNumeralFactor(reductionContext);
Expression oppositeA = a.makePositiveAnyNegativeNumeralFactor(*reductionContext);
Expression oppositeB = b.makePositiveAnyNegativeNumeralFactor(*reductionContext);
a = oppositeA.isUninitialized() ? a : oppositeA;
b = oppositeB.isUninitialized() ? b : oppositeB;
Expression e = Expression::CreateComplexExpression(a, b, Preferences::ComplexFormat::Cartesian,

View File

@@ -115,7 +115,7 @@ Expression DecimalNode::shallowReduce(ReductionContext reductionContext) {
return Decimal(this).shallowReduce();
}
Expression DecimalNode::shallowBeautify(ReductionContext reductionContext) {
Expression DecimalNode::shallowBeautify(ReductionContext * reductionContext) {
return Decimal(this).shallowBeautify();
}

View File

@@ -388,6 +388,18 @@ Expression Expression::shallowReduceUsingApproximation(ExpressionNode::Reduction
return *this;
}
void Expression::defaultDeepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
const int nbChildren = numberOfChildren();
for (int i = 0; i < nbChildren; i++) {
Expression child = childAtIndex(i);
child = child.deepBeautify(reductionContext);
// We add missing Parentheses after beautifying the parent and child
if (node()->childAtIndexNeedsUserParentheses(child, i)) {
replaceChildAtIndexInPlace(i, Parenthesis::Builder(child));
}
}
}
bool Expression::SimplificationHasBeenInterrupted() {
return sSimplificationHasBeenInterrupted;
}
@@ -656,7 +668,7 @@ void Expression::beautifyAndApproximateScalar(Expression * simplifiedExpression,
ecomplexClone.imag().deepBeautify(userReductionContext);
*approximateExpression = ecomplexClone.approximate<double>(context, complexFormat, angleUnit);
}
// Step 2: create the simplied expression with the required complex format
// Step 2: create the simplified expression with the required complex format
Expression ra = complexFormat == Preferences::ComplexFormat::Polar ?
ecomplex.clone().convert<ComplexCartesian>().norm(userReductionContext).shallowReduce(userReductionContext) :
ecomplex.real();
@@ -833,16 +845,8 @@ Expression Expression::deepReduce(ExpressionNode::ReductionContext reductionCont
}
Expression Expression::deepBeautify(ExpressionNode::ReductionContext reductionContext) {
Expression e = shallowBeautify(reductionContext);
const int nbChildren = e.numberOfChildren();
for (int i = 0; i < nbChildren; i++) {
Expression child = e.childAtIndex(i);
child = child.deepBeautify(reductionContext);
// We add missing Parentheses after beautifying the parent and child
if (e.node()->childAtIndexNeedsUserParentheses(child, i)) {
e.replaceChildAtIndexInPlace(i, Parenthesis::Builder(child));
}
}
Expression e = shallowBeautify(&reductionContext);
e.deepBeautifyChildren(reductionContext);
return e;
}

View File

@@ -103,11 +103,15 @@ void ExpressionNode::deepReduceChildren(ExpressionNode::ReductionContext reducti
Expression(this).defaultDeepReduceChildren(reductionContext);
}
void ExpressionNode::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
Expression(this).defaultDeepBeautifyChildren(reductionContext);
}
Expression ExpressionNode::shallowReduce(ReductionContext reductionContext) {
return Expression(this).defaultShallowReduce();
}
Expression ExpressionNode::shallowBeautify(ReductionContext reductionContext) {
Expression ExpressionNode::shallowBeautify(ReductionContext * reductionContext) {
return Expression(this).defaultShallowBeautify();
}

View File

@@ -31,7 +31,7 @@ Expression FactorNode::shallowReduce(ReductionContext reductionContext) {
return Factor(this).shallowReduce(reductionContext.context());
}
Expression FactorNode::shallowBeautify(ReductionContext reductionContext) {
Expression FactorNode::shallowBeautify(ReductionContext * reductionContext) {
return Factor(this).shallowBeautify(reductionContext);
}
@@ -85,7 +85,7 @@ Expression Factor::shallowReduce(Context * context) {
return *this;
}
Expression Factor::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
Expression Factor::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
Expression c = childAtIndex(0);
if (c.type() != ExpressionNode::Type::Rational) {
return replaceWithUndefinedInPlace();

View File

@@ -19,8 +19,8 @@ Expression GreatCommonDivisorNode::shallowReduce(ReductionContext reductionConte
return GreatCommonDivisor(this).shallowReduce(reductionContext);
}
Expression GreatCommonDivisorNode::shallowBeautify(ReductionContext reductionContext) {
return GreatCommonDivisor(this).shallowBeautify(reductionContext.context());
Expression GreatCommonDivisorNode::shallowBeautify(ReductionContext * reductionContext) {
return GreatCommonDivisor(this).shallowBeautify(reductionContext->context());
}
template<typename T>

View File

@@ -19,8 +19,8 @@ Expression LeastCommonMultipleNode::shallowReduce(ReductionContext reductionCont
return LeastCommonMultiple(this).shallowReduce(reductionContext);
}
Expression LeastCommonMultipleNode::shallowBeautify(ReductionContext reductionContext) {
return LeastCommonMultiple(this).shallowBeautify(reductionContext.context());
Expression LeastCommonMultipleNode::shallowBeautify(ReductionContext * reductionContext) {
return LeastCommonMultiple(this).shallowBeautify(reductionContext->context());
}
template<typename T>

View File

@@ -95,12 +95,12 @@ Expression LogarithmNode<1>::unaryFunctionDifferential() {
/**/
template<>
Expression LogarithmNode<1>::shallowBeautify(ReductionContext reductionContext) {
Expression LogarithmNode<1>::shallowBeautify(ReductionContext * reductionContext) {
return CommonLogarithm(this);
}
template<>
Expression LogarithmNode<2>::shallowBeautify(ReductionContext reductionContext) {
Expression LogarithmNode<2>::shallowBeautify(ReductionContext * reductionContext) {
return Logarithm(this).shallowBeautify();
}

View File

@@ -211,7 +211,7 @@ Expression MultiplicationNode::shallowReduce(ReductionContext reductionContext)
return Multiplication(this).shallowReduce(reductionContext);
}
Expression MultiplicationNode::shallowBeautify(ReductionContext reductionContext) {
Expression MultiplicationNode::shallowBeautify(ReductionContext * reductionContext) {
return Multiplication(this).shallowBeautify(reductionContext);
}
@@ -400,7 +400,7 @@ static bool CanSimplifyUnitProduct(
return isSimpler;
}
Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
/* Beautifying a Multiplication consists in several possible operations:
* - Add Opposite ((-3)*x -> -(3*x), useful when printing fractions)
* - Recognize derived units in the product of units
@@ -408,7 +408,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
*/
// Step 1: Turn -n*A into -(n*A)
Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(reductionContext);
Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(*reductionContext);
// If one negative numeral factor was made positive, we turn the expression in an Opposite
if (!noNegativeNumeral.isUninitialized()) {
Opposite o = Opposite::Builder();
@@ -425,7 +425,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
Expression units;
/* removeUnit has to be called on reduced expression but we want to modify
* the least the expression so we use the uninvasive reduction context. */
self = deepReduce(ExpressionNode::ReductionContext::NonInvasiveReductionContext(reductionContext));
self = deepReduce(ExpressionNode::ReductionContext::NonInvasiveReductionContext(*reductionContext));
self = removeUnit(&units);
if (self.isUndefined() || units.isUninitialized()) {
@@ -434,7 +434,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
goto replace_by_result;
}
ExpressionNode::UnitConversion unitConversionMode = reductionContext.unitConversion();
ExpressionNode::UnitConversion unitConversionMode = reductionContext->unitConversion();
if (unitConversionMode == ExpressionNode::UnitConversion::Default) {
/* Step 2a: Recognize derived units
* - Look up in the table of derived units, the one which itself or its inverse simplifies 'units' the most.
@@ -501,7 +501,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
// Apply simplifications
if (unitsAccu.numberOfChildren() > 0) {
// Divide by derived units
units = Division::Builder(units, unitsAccu.clone()).deepReduce(reductionContext);
units = Division::Builder(units, unitsAccu.clone()).deepReduce(*reductionContext);
Expression newUnits;
// Separate units and generated values
units = units.removeUnit(&newUnits);
@@ -528,7 +528,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
* most relevant.
*/
double value = self.approximateToScalar<double>(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit());
double value = self.approximateToScalar<double>(reductionContext->context(), reductionContext->complexFormat(), reductionContext->angleUnit());
if (std::isnan(value)) {
// If the value is undefined, return "undef" without any unit
result = Undefined::Builder();
@@ -538,7 +538,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
/* In most cases, unit composition works the same for imperial and
* metric units. However, in imperial, we want volumes to be displayed
* using volume units instead of cubic length. */
const bool forceVolumeRepresentative = reductionContext.unitFormat() == Preferences::UnitFormat::Imperial && UnitNode::Vector<int>::FromBaseUnits(units) == UnitNode::VolumeRepresentative::Default().dimensionVector();
const bool forceVolumeRepresentative = reductionContext->unitFormat() == Preferences::UnitFormat::Imperial && UnitNode::Vector<int>::FromBaseUnits(units) == UnitNode::VolumeRepresentative::Default().dimensionVector();
const UnitNode::Representative * repr;
if (forceVolumeRepresentative) {
/* The choice of representative doesn't matter, as it will be tuned to a
@@ -546,9 +546,9 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
repr = UnitNode::VolumeRepresentative::Default().representativesOfSameDimension();
units = Unit::Builder(repr, UnitNode::Prefix::EmptyPrefix());
value /= repr->ratio();
Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, reductionContext);
Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, *reductionContext);
} else {
Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, reductionContext);
Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, *reductionContext);
}
}
// Build final Expression
@@ -558,7 +558,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
} else {
// Step 3: Create a Division if relevant
Expression numer, denom;
splitIntoNormalForm(numer, denom, reductionContext);
splitIntoNormalForm(numer, denom, *reductionContext);
if (!numer.isUninitialized()) {
result = numer;
}

View File

@@ -225,7 +225,7 @@ Expression PowerNode::shallowReduce(ReductionContext reductionContext) {
return Power(this).shallowReduce(reductionContext);
}
Expression PowerNode::shallowBeautify(ReductionContext reductionContext) {
Expression PowerNode::shallowBeautify(ReductionContext * reductionContext) {
return Power(this).shallowBeautify(reductionContext);
}
@@ -985,14 +985,14 @@ Expression Power::shallowReduce(ExpressionNode::ReductionContext reductionContex
return *this;
}
Expression Power::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
Expression Power::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
// Step 1: X^-y -> 1/(X->shallowBeautify)^y
Expression p = denominator(reductionContext);
Expression p = denominator(*reductionContext);
// If the denominator is initialized, the index of the power is of form -y
if (!p.isUninitialized()) {
Division d = Division::Builder(Rational::Builder(1), p);
replaceWithInPlace(d);
p.shallowReduce(reductionContext);
p.shallowReduce(*reductionContext);
return d.shallowBeautify(reductionContext);
}
// Step 2: Turn a^(1/n) into root(a, n), unless base is a unit

View File

@@ -141,7 +141,7 @@ Expression RationalNode::shallowReduce(ReductionContext reductionContext) {
return Rational(this).shallowReduce();
}
Expression RationalNode::shallowBeautify(ReductionContext reductionContext) {
Expression RationalNode::shallowBeautify(ReductionContext * reductionContext) {
return Rational(this).shallowBeautify();
}

View File

@@ -701,8 +701,8 @@ Expression UnitNode::shallowReduce(ReductionContext reductionContext) {
return Unit(this).shallowReduce(reductionContext);
}
Expression UnitNode::shallowBeautify(ReductionContext reductionContext) {
return Unit(this).shallowBeautify(reductionContext);
Expression UnitNode::shallowBeautify(ReductionContext * reductionContext) {
return Unit(this).shallowBeautify();
}
template<typename T>
@@ -824,7 +824,7 @@ Expression Unit::BuildSplit(double value, const Unit * units, int length, Expres
ExpressionNode::ReductionTarget::User,
ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition,
ExpressionNode::UnitConversion::None);
return res.squashUnaryHierarchyInPlace().shallowBeautify(keepUnitsContext);
return res.squashUnaryHierarchyInPlace().shallowBeautify(&keepUnitsContext);
}
Expression Unit::ConvertTemperatureUnits(Expression e, Unit unit, ExpressionNode::ReductionContext reductionContext) {
@@ -904,7 +904,7 @@ Expression Unit::shallowReduce(ExpressionNode::ReductionContext reductionContext
return result;
}
Expression Unit::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
Expression Unit::shallowBeautify() {
// Force Float(1) in front of an orphan Unit
if (parent().isUninitialized() || parent().type() == ExpressionNode::Type::Opposite) {
Multiplication m = Multiplication::Builder(Float<double>::Builder(1.));

View File

@@ -20,7 +20,7 @@ Expression UnitConvertNode::removeUnit(Expression * unit) {
childAtIndex(1)->removeUnit(unit);
return UnitConvert(this).replaceWithUndefinedInPlace();
}
Expression UnitConvertNode::shallowBeautify(ReductionContext reductionContext) {
Expression UnitConvertNode::shallowBeautify(ReductionContext * reductionContext) {
return UnitConvert(this).shallowBeautify(reductionContext);
}
@@ -28,6 +28,10 @@ void UnitConvertNode::deepReduceChildren(ExpressionNode::ReductionContext reduct
UnitConvert(this).deepReduceChildren(reductionContext);
}
void UnitConvertNode::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
UnitConvert(this).deepBeautifyChildren(reductionContext);
}
template<typename T>
Evaluation<T> UnitConvertNode::templatedApproximate(ApproximationContext approximationContext) const {
/* If we are here, it means that the unit convert node was not shallowReduced.
@@ -50,15 +54,27 @@ void UnitConvert::deepReduceChildren(ExpressionNode::ReductionContext reductionC
childAtIndex(1).deepReduce(reductionContextKeepUnitAsIs);
}
Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
void UnitConvert::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
ExpressionNode::ReductionContext reductionContextKeepUnitAsIs = ExpressionNode::ReductionContext(
reductionContext.context(),
reductionContext.complexFormat(),
reductionContext.angleUnit(),
reductionContext.unitFormat(),
reductionContext.target(),
reductionContext.symbolicComputation(),
ExpressionNode::UnitConversion::None);
defaultDeepBeautifyChildren(reductionContextKeepUnitAsIs);
}
Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
// Discard cases like 4 -> _m/_km
{
ExpressionNode::ReductionContext reductionContextWithUnits = ExpressionNode::ReductionContext(
reductionContext.context(),
reductionContext.complexFormat(),
reductionContext.angleUnit(),
reductionContext.unitFormat(),
reductionContext.target(),
reductionContext->context(),
reductionContext->complexFormat(),
reductionContext->angleUnit(),
reductionContext->unitFormat(),
reductionContext->target(),
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined);
Expression unit;
Expression childWithoutUnit = childAtIndex(1).clone().deepReduce(reductionContextWithUnits).removeUnit(&unit);
@@ -68,14 +84,6 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
}
}
// Find the unit
ExpressionNode::ReductionContext reductionContextWithoutUnits = ExpressionNode::ReductionContext(
reductionContext.context(),
reductionContext.complexFormat(),
reductionContext.angleUnit(),
reductionContext.unitFormat(),
reductionContext.target(),
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined,
ExpressionNode::UnitConversion::None);
Expression unit;
childAtIndex(1).removeUnit(&unit);
if (unit.isUninitialized()) {
@@ -88,7 +96,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
if (unit.type() == ExpressionNode::Type::Unit) {
Unit unitRef = static_cast<Unit &>(unit);
if (unitRef.representative()->dimensionVector() == Unit::TemperatureRepresentative::Default().dimensionVector()) {
Expression result = Unit::ConvertTemperatureUnits(childAtIndex(0), unitRef, reductionContext);
Expression result = Unit::ConvertTemperatureUnits(childAtIndex(0), unitRef, *reductionContext);
replaceWithInPlace(result);
return result;
}
@@ -96,7 +104,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
// Divide the left member by the new unit
Expression division = Division::Builder(childAtIndex(0), unit.clone());
division = division.deepReduce(reductionContext);
division = division.deepReduce(*reductionContext);
Expression divisionUnit;
division = division.removeUnit(&divisionUnit);
if (!divisionUnit.isUninitialized()) {
@@ -105,8 +113,25 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
}
Expression result = Multiplication::Builder(division, unit);
replaceWithInPlace(result);
ExpressionNode::ReductionContext reductionContextWithoutUnits = ExpressionNode::ReductionContext(
reductionContext->context(),
reductionContext->complexFormat(),
reductionContext->angleUnit(),
reductionContext->unitFormat(),
reductionContext->target(),
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined,
ExpressionNode::UnitConversion::None);
result = result.shallowReduce(reductionContextWithoutUnits);
return result.shallowBeautify(reductionContextWithoutUnits);
result = result.shallowBeautify(&reductionContextWithoutUnits);
*reductionContext = ExpressionNode::ReductionContext(
reductionContext->context(),
reductionContext->complexFormat(),
reductionContext->angleUnit(),
reductionContext->unitFormat(),
reductionContext->target(),
reductionContext->symbolicComputation(),
ExpressionNode::UnitConversion::None);
return result;
}
template Evaluation<float> UnitConvertNode::templatedApproximate<float>(ApproximationContext approximationContext) const;