mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare] Factorize reduce and removeUnit methods
This commit is contained in:
committed by
EmilieNumworks
parent
7146eff7ee
commit
e09bd0a18c
@@ -28,8 +28,7 @@ void UnitListController::setExpression(Poincare::Expression e) {
|
||||
Expression copy = m_expression.clone();
|
||||
Expression units;
|
||||
// Reduce to be able to recognize units
|
||||
PoincareHelpers::Reduce(©, App::app()->localContext(), ExpressionNode::ReductionTarget::User);
|
||||
copy = copy.removeUnit(&units);
|
||||
PoincareHelpers::ReduceAndRemoveUnit(©, App::app()->localContext(), ExpressionNode::ReductionTarget::User, &units);
|
||||
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(copy, App::app()->localContext());
|
||||
ExpressionNode::ReductionContext reductionContext(
|
||||
App::app()->localContext(),
|
||||
|
||||
@@ -255,8 +255,7 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
|
||||
}
|
||||
if (o.hasUnit()) {
|
||||
Expression unit;
|
||||
PoincareHelpers::Reduce(&o, App::app()->localContext(), ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined, ExpressionNode::UnitConversion::None);
|
||||
o = o.removeUnit(&unit);
|
||||
PoincareHelpers::ReduceAndRemoveUnit(&o, App::app()->localContext(), ExpressionNode::ReductionTarget::User, &unit, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined, ExpressionNode::UnitConversion::None);
|
||||
double value = PoincareHelpers::ApproximateToScalar<double>(o, App::app()->localContext());
|
||||
return (Unit::ShouldDisplayAdditionalOutputs(value, unit, GlobalPreferences::sharedGlobalPreferences()->unitFormat())) ? AdditionalInformationType::Unit : AdditionalInformationType::None;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,11 @@ inline void Reduce(Poincare::Expression * e, Poincare::Context * context, Poinca
|
||||
*e = e->reduce(Poincare::ExpressionNode::ReductionContext(context, complexFormat, preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), target, symbolicComputation, unitConversion));
|
||||
}
|
||||
|
||||
inline void ReduceAndRemoveUnit(Poincare::Expression * e, Poincare::Context * context, Poincare::ExpressionNode::ReductionTarget target, Poincare::Expression * unit, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion unitConversion = Poincare::ExpressionNode::UnitConversion::Default) {
|
||||
PoincareHelpers::Reduce(e, context, target, symbolicComputation, unitConversion);
|
||||
*e = e->removeUnit(unit);
|
||||
}
|
||||
|
||||
inline void ParseAndSimplifyAndApproximate(const char * text, Poincare::Expression * simplifiedExpression, Poincare::Expression * approximateExpression, Poincare::Context * context, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) {
|
||||
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
|
||||
Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text);
|
||||
|
||||
@@ -248,6 +248,7 @@ public:
|
||||
static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default);
|
||||
void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default);
|
||||
Expression reduce(ExpressionNode::ReductionContext context);
|
||||
Expression reduceAndRemoveUnit(ExpressionNode::ReductionContext context, Expression * Unit);
|
||||
|
||||
Expression mapOnMatrixFirstChild(ExpressionNode::ReductionContext reductionContext);
|
||||
/* 'ExpressionWithoutSymbols' returns an uninitialized expression if it is
|
||||
|
||||
@@ -827,6 +827,12 @@ Expression Expression::angleUnitToRadian(Preferences::AngleUnit angleUnit) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Expression Expression::reduceAndRemoveUnit(ExpressionNode::ReductionContext reductionContext, Expression * Unit) {
|
||||
/* RemoveUnit has to be called on reduced expression. reduce method is called
|
||||
* instead of deepReduce to catch interrupted simplification. */
|
||||
return reduce(reductionContext).removeUnit(Unit);
|
||||
}
|
||||
|
||||
Expression Expression::reduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
sSimplificationHasBeenInterrupted = false;
|
||||
Expression result = deepReduce(reductionContext);
|
||||
|
||||
@@ -425,8 +425,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext * re
|
||||
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 = self.reduce(ExpressionNode::ReductionContext::NonInvasiveReductionContext(*reductionContext));
|
||||
self = self.removeUnit(&units);
|
||||
self = self.reduceAndRemoveUnit(ExpressionNode::ReductionContext::NonInvasiveReductionContext(*reductionContext), &units);
|
||||
|
||||
if (self.isUndefined() || units.isUninitialized()) {
|
||||
// TODO: handle error "Invalid unit"
|
||||
@@ -500,11 +499,9 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext * re
|
||||
}
|
||||
// Apply simplifications
|
||||
if (unitsAccu.numberOfChildren() > 0) {
|
||||
// Divide by derived units
|
||||
units = Division::Builder(units, unitsAccu.clone()).reduce(*reductionContext);
|
||||
Expression newUnits;
|
||||
// Separate units and generated values
|
||||
units = units.removeUnit(&newUnits);
|
||||
// Divide by derived units, separate units and generated values
|
||||
units = Division::Builder(units, unitsAccu.clone()).reduceAndRemoveUnit(*reductionContext, &newUnits);
|
||||
// Assemble final value
|
||||
Multiplication m = Multiplication::Builder(units);
|
||||
self.replaceWithInPlace(m);
|
||||
|
||||
@@ -77,7 +77,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext * reduc
|
||||
reductionContext->target(),
|
||||
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined);
|
||||
Expression unit;
|
||||
Expression childWithoutUnit = childAtIndex(1).clone().reduce(reductionContextWithUnits).removeUnit(&unit);
|
||||
Expression childWithoutUnit = childAtIndex(1).clone().reduceAndRemoveUnit(reductionContextWithUnits, &unit);
|
||||
if (childWithoutUnit.isUndefined() || unit.isUninitialized()) {
|
||||
// There is no unit on the right
|
||||
return replaceWithUndefinedInPlace();
|
||||
@@ -104,9 +104,8 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext * reduc
|
||||
|
||||
// Divide the left member by the new unit
|
||||
Expression division = Division::Builder(childAtIndex(0), unit.clone());
|
||||
division = division.reduce(*reductionContext);
|
||||
Expression divisionUnit;
|
||||
division = division.removeUnit(&divisionUnit);
|
||||
division = division.reduceAndRemoveUnit(*reductionContext, &divisionUnit);
|
||||
if (!divisionUnit.isUninitialized()) {
|
||||
// The left and right members are not homogeneous
|
||||
return replaceWithUndefinedInPlace();
|
||||
|
||||
@@ -401,13 +401,11 @@ void assert_reduced_expression_unit_is(const char * expression, const char * uni
|
||||
Shared::GlobalContext globalContext;
|
||||
ExpressionNode::ReductionContext redContext(&globalContext, Real, Degree, Metric, SystemForApproximation);
|
||||
Expression e = parse_expression(expression, &globalContext, false);
|
||||
e = e.reduce(redContext);
|
||||
Expression u1;
|
||||
e = e.removeUnit(&u1);
|
||||
e = e.reduceAndRemoveUnit(redContext, &u1);
|
||||
Expression e2 = parse_expression(unit, &globalContext, false);
|
||||
Expression u2;
|
||||
e2 = e2.reduce(redContext);
|
||||
e2.removeUnit(&u2);
|
||||
e2.reduceAndRemoveUnit(redContext, &u2);
|
||||
quiz_assert_print_if_failure(u1.isUninitialized() == u2.isUninitialized() && (u1.isUninitialized() || u1.isIdenticalTo(u2)), expression);
|
||||
}
|
||||
|
||||
@@ -425,9 +423,8 @@ void assert_additional_results_compute_to(const char * expression, const char *
|
||||
assert(length <= maxNumberOfResults);
|
||||
Expression additional[maxNumberOfResults];
|
||||
ExpressionNode::ReductionContext reductionContext = ExpressionNode::ReductionContext(&globalContext, Cartesian, Degree, unitFormat, User, ReplaceAllSymbolsWithUndefined, DefaultUnitConversion);
|
||||
Expression e = parse_expression(expression, &globalContext, false).reduce(reductionContext);
|
||||
Expression units;
|
||||
e = e.removeUnit(&units);
|
||||
Expression e = parse_expression(expression, &globalContext, false).reduceAndRemoveUnit(reductionContext, &units);
|
||||
double value = e.approximateToScalar<double>(&globalContext, Cartesian, Degree);
|
||||
|
||||
if (!Unit::ShouldDisplayAdditionalOutputs(value, units, unitFormat)) {
|
||||
|
||||
Reference in New Issue
Block a user