[poincare] Force Float(1) in front of an orphan (Power of) Unit

This commit is contained in:
Ruben Dashyan
2020-02-04 17:31:47 +01:00
committed by Léa Saviot
parent d8e36e3cf1
commit 3aea607be2
4 changed files with 124 additions and 116 deletions

View File

@@ -506,50 +506,49 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
units = unitsUnits;
}
if (result.isUninitialized()) {
result = units;
double value = 1.0;
if (!result.isUninitialized()) {
value = result.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();
} else {
double value = result.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();
Expression resultWithoutUnit;
if (std::isinf(value)) {
resultWithoutUnit = Infinity::Builder(value < 0.0);
} else {
Expression resultWithoutUnit;
if (std::isinf(value)) {
resultWithoutUnit = Infinity::Builder(value < 0.0);
} else {
// Find the right unit prefix when the value ≠ 0
if (value != 0.0) {
// Identify the first Unit factor and its exponent
Expression firstFactor = units;
int exponent = 1;
if (firstFactor.type() == ExpressionNode::Type::Multiplication) {
firstFactor = firstFactor.childAtIndex(0);
}
if (firstFactor.type() == ExpressionNode::Type::Power) {
Expression exp = firstFactor.childAtIndex(1);
firstFactor = firstFactor.childAtIndex(0);
assert(exp.type() == ExpressionNode::Type::Rational && static_cast<Rational &>(exp).isInteger());
Integer expInt = static_cast<Rational &>(exp).signedIntegerNumerator();
if (expInt.isLowerThan(Integer(Integer::k_maxExtractableInteger))) {
exponent = expInt.extractedInt();
} else {
// The exponent is too large to be extracted, so do not try to use it.
exponent = 0;
}
}
assert(firstFactor.type() == ExpressionNode::Type::Unit);
// Choose its multiple and update value accordingly
if (exponent != 0) {
static_cast<Unit&>(firstFactor).chooseBestMultipleForValue(value, exponent, reductionContext);
// Find the right unit prefix when the value ≠ 0
if (value != 0.0 && value != 1.0) {
// Identify the first Unit factor and its exponent
Expression firstFactor = units;
int exponent = 1;
if (firstFactor.type() == ExpressionNode::Type::Multiplication) {
firstFactor = firstFactor.childAtIndex(0);
}
if (firstFactor.type() == ExpressionNode::Type::Power) {
Expression exp = firstFactor.childAtIndex(1);
firstFactor = firstFactor.childAtIndex(0);
assert(exp.type() == ExpressionNode::Type::Rational && static_cast<Rational &>(exp).isInteger());
Integer expInt = static_cast<Rational &>(exp).signedIntegerNumerator();
if (expInt.isLowerThan(Integer(Integer::k_maxExtractableInteger))) {
exponent = expInt.extractedInt();
} else {
// The exponent is too large to be extracted, so do not try to use it.
exponent = 0;
}
}
resultWithoutUnit = Float<double>::Builder(value);
assert(firstFactor.type() == ExpressionNode::Type::Unit);
// Choose its multiple and update value accordingly
if (exponent != 0) {
static_cast<Unit&>(firstFactor).chooseBestMultipleForValue(value, exponent, reductionContext);
}
}
// Build final Expression
result = Multiplication::Builder(resultWithoutUnit, units);
static_cast<Multiplication &>(result).mergeMultiplicationChildrenInPlace();
resultWithoutUnit = Float<double>::Builder(value);
}
// Build final Expression
result = Multiplication::Builder(resultWithoutUnit, units);
static_cast<Multiplication &>(result).mergeMultiplicationChildrenInPlace();
}
}

View File

@@ -5,6 +5,7 @@
#include <poincare/constant.h>
#include <poincare/cosine.h>
#include <poincare/division.h>
#include <poincare/float.h>
#include <poincare/horizontal_layout.h>
#include <poincare/infinity.h>
#include <poincare/matrix.h>
@@ -904,6 +905,14 @@ Expression Power::shallowBeautify(ExpressionNode::ReductionContext reductionCont
return result;
}
// Step 4: Force Float(1) in front of an orphan Power of Unit
if (parent().isUninitialized() && childAtIndex(0).type() == ExpressionNode::Type::Unit) {
Multiplication m = Multiplication::Builder(Float<double>::Builder(1.0));
replaceWithInPlace(m);
m.addChildAtIndexInPlace(*this, 1, 1);
return std::move(m);
}
return *this;
}

View File

@@ -1,5 +1,6 @@
#include <poincare/unit.h>
#include <poincare/division.h>
#include <poincare/float.h>
#include <poincare/multiplication.h>
#include <poincare/power.h>
#include <poincare/rational.h>
@@ -250,6 +251,13 @@ Expression Unit::shallowReduce(ExpressionNode::ReductionContext reductionContext
Expression Unit::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
Expression ancestor = parent();
// Force Float(1) in front of an orphan Unit
if (ancestor.isUninitialized()) {
Multiplication m = Multiplication::Builder(Float<double>::Builder(1.0));
replaceWithInPlace(m);
m.addChildAtIndexInPlace(*this, 1, 1);
return std::move(m);
}
// Check that the exponent, if any, of a Unit is an integer
if (!ancestor.isUninitialized() && ancestor.type() == ExpressionNode::Type::Power) {
Expression exponent = ancestor.childAtIndex(1);

View File

@@ -196,47 +196,43 @@ QUIZ_CASE(poincare_simplification_multiplication) {
QUIZ_CASE(poincare_simplification_units) {
/* SI base units */
assert_parsed_expression_simplify_to("_s", "_s");
assert_parsed_expression_simplify_to("_m", "_m");
assert_parsed_expression_simplify_to("_kg", "_kg");
assert_parsed_expression_simplify_to("_A", "_A");
assert_parsed_expression_simplify_to("_K", "_K");
assert_parsed_expression_simplify_to("_mol", "_mol");
assert_parsed_expression_simplify_to("_cd", "_cd");
assert_parsed_expression_simplify_to("_s", "1×_s");
assert_parsed_expression_simplify_to("_m", "1×_m");
assert_parsed_expression_simplify_to("_kg", "1×_kg");
assert_parsed_expression_simplify_to("_A", "1×_A");
assert_parsed_expression_simplify_to("_K", "1×_K");
assert_parsed_expression_simplify_to("_mol", "1×_mol");
assert_parsed_expression_simplify_to("_cd", "1×_cd");
/* Inverses of SI base units */
assert_parsed_expression_simplify_to("_s^-1", "_s^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_m^-1", "_m^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_kg^-1", "_kg^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_A^-1", "_A^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_K^-1", "_K^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_mol^-1", "_mol^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_cd^-1", "_cd^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_s^-1", "1×_s^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_m^-1", "1×_m^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_kg^-1", "1×_kg^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_A^-1", "1×_A^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_K^-1", "1×_K^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_mol^-1", "1×_mol^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_cd^-1", "1×_cd^\u0012-1\u0013");
/* SI derived units with special names and symbols */
assert_parsed_expression_simplify_to("_kg×_m×_s^(-2)", "_N");
assert_parsed_expression_simplify_to("_kg×_m^(-1)×_s^(-2)", "_Pa");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)", "_J");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-3)", "_W");
assert_parsed_expression_simplify_to("_A×_s", "_C");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-3)×_A^(-1)", "_V");
assert_parsed_expression_simplify_to("_m^(-2)×_kg^(-1)×_s^4×_A^2", "_F");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-3)×_A^(-2)", "");
assert_parsed_expression_simplify_to("_kg×_m×_s^(-2)", "1×_N");
assert_parsed_expression_simplify_to("_kg×_m^(-1)×_s^(-2)", "1×_Pa");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)", "1×_J");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-3)", "1×_W");
assert_parsed_expression_simplify_to("_A×_s", "1×_C");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-3)×_A^(-1)", "1×_V");
assert_parsed_expression_simplify_to("_m^(-2)×_kg^(-1)×_s^4×_A^2", "1×_F");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-3)×_A^(-2)", "1×");
// FIXME _S should not be simplified to _Ω^(-1)
// A possible solution: a unit with exponent +1 is simpler than a unit with exponent -1.
// The same should probably go for Hz.
// assert_parsed_expression_simplify_to("_kg^(-1)×_m^(-2)×_s^3×_A^2", "_S");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)×_A^(-1)", "_Wb");
assert_parsed_expression_simplify_to("_kg×_s^(-2)×_A^(-1)", "_T");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)×_A^(-2)", "_H");
assert_parsed_expression_simplify_to("_mol×_s^-1", "_kat");
// assert_parsed_expression_simplify_to("_kg^(-1)×_m^(-2)×_s^3×_A^2", "1×_S");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)×_A^(-1)", "1×_Wb");
assert_parsed_expression_simplify_to("_kg×_s^(-2)×_A^(-1)", "1×_T");
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)×_A^(-2)", "1×_H");
assert_parsed_expression_simplify_to("_mol×_s^-1", "1×_kat");
/* Test simplification of all possible (prefixed) unit symbols.
* Some symbols are however excluded:
* - Observe that _ms is simplified to 1×_ms but _s stays the same. Indeed
* a constant 1 is generally introduced if not already there, except when
* a unit is the standard unit with the standard prefix in a dimension.
* Thus the latter case is not tested.
* - At present, some units will not appear as simplification output:
* t, Hz, S, ha, L. These exceptions are tested below. */
for (const Unit::Dimension * dim = Unit::DimensionTable; dim < Unit::DimensionTableUpperBound; dim++) {
@@ -246,16 +242,12 @@ QUIZ_CASE(poincare_simplification_units) {
}
static constexpr size_t bufferSize = 12;
char buffer[bufferSize] = "1×";
if (rep != dim->stdRepresentative()) {
Unit::Builder(dim, rep, &Unit::EmptyPrefix).serialize(buffer+strlen("1×"), bufferSize-strlen("1×"), Preferences::PrintFloatMode::Decimal, Preferences::VeryShortNumberOfSignificantDigits);
assert_parsed_expression_simplify_to(buffer, buffer);
}
Unit::Builder(dim, rep, &Unit::EmptyPrefix).serialize(buffer+strlen("1×"), bufferSize-strlen("1×"), Preferences::PrintFloatMode::Decimal, Preferences::VeryShortNumberOfSignificantDigits);
assert_parsed_expression_simplify_to(buffer, buffer);
if (rep->isPrefixable()) {
for (const Unit::Prefix * pre = rep->outputPrefixes(); pre < rep->outputPrefixesUpperBound(); pre++) {
if (rep != dim->stdRepresentative() || pre->exponent() != dim->stdRepresentativePrefix()->exponent()) {
Unit::Builder(dim, rep, pre).serialize(buffer+strlen("1×"), bufferSize-strlen("1×"), Preferences::PrintFloatMode::Decimal, Preferences::VeryShortNumberOfSignificantDigits);
assert_parsed_expression_simplify_to(buffer, buffer);
}
Unit::Builder(dim, rep, pre).serialize(buffer+strlen("1×"), bufferSize-strlen("1×"), Preferences::PrintFloatMode::Decimal, Preferences::VeryShortNumberOfSignificantDigits);
assert_parsed_expression_simplify_to(buffer, buffer);
}
}
}
@@ -263,51 +255,51 @@ QUIZ_CASE(poincare_simplification_units) {
/* Units that do not appear as output yet */
assert_parsed_expression_simplify_to("_t", "1×_Mg");
assert_parsed_expression_simplify_to("_Hz", "_s^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_S", "_Ω^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_Hz", "1×_s^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_S", "1×_Ω^\u0012-1\u0013");
assert_parsed_expression_simplify_to("_L", "0.001×_m^3");
assert_parsed_expression_simplify_to("_ha", "0.01×_km^2");
/* Usual physical quantities */
assert_parsed_expression_simplify_to("_A×_s×_m^(-3)", "_C×_m^\u0012-3\u0013"); // Charge density
assert_parsed_expression_simplify_to("_kg×_m×_s^(-3)×_K^(-1)", "_N×_K^\u0012-1\u0013×_s^\u0012-1\u0013"); // Thermal conductivity _W×_m^-1×_K^-1
assert_parsed_expression_simplify_to("_K×_kg^(-1)×_m^(-2)×_s^3", "_W^\u0012-1\u0013×_K"); // Thermal resistance
assert_parsed_expression_simplify_to("_kg×_m×_s^(-3)×_A^(-1)", "_V×_m^\u0012-1\u0013"); // Electrical field
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-1)", "_J×_s"); // Action
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)×_K^(-1)", "_J×_K^\u0012-1\u0013"); // Entropy | Heat capacity
assert_parsed_expression_simplify_to("_m^2×_s^(-2)×_K^(-1)", "_K^\u0012-1\u0013×_m^2×_s^\u0012-2\u0013"); // Specific heat capacity _J×_K^-1×_kg^-1
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)×_K^(-1)×_mol^(-1)", "_J×_mol^\u0012-1\u0013×_K^\u0012-1\u0013"); // Molar heat capacity
assert_parsed_expression_simplify_to("_kg×_m^(-1)×_s^(-2)×_K^(-1)", "_Pa×_K^\u0012-1\u0013"); // Volumetric heat capacity _J×_K^-1×_m^-3
assert_parsed_expression_simplify_to("_kg×_s^(-3)×_K^(-1)", "_K^\u0012-1\u0013×_kg×_s^\u0012-3\u0013"); // Heat transfer coefficient _W×_m^-2×_K^-1
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-3)×_K^(-1)", "_W×_K^\u0012-1\u0013"); // Thermal conductivity
assert_parsed_expression_simplify_to("_kg^(-1)×_m^(-3)×_s^3×_A^2", "_Ω^\u0012-1\u0013×_m^\u0012-1\u0013"); // Electrical conductivity _S×_m^-1
assert_parsed_expression_simplify_to("_kg×_s^(-2)", "_kg×_s^\u0012-2\u0013"); // Stiffness _N×_m^-1
assert_parsed_expression_simplify_to("_kg×_m^(-1)×_s^(-3)", "_Pa×_s^\u0012-1\u0013"); // Power density _W×_m^-3
assert_parsed_expression_simplify_to("_kg×_m^3×_s^(-3)×_A^(-1)", "_V×_m"); // Electric flux
assert_parsed_expression_simplify_to("_K×_kg^(-1)×_s^(3)", "_K×_kg^\u0012-1\u0013×_s^3"); // Superficial thermal resistance _m^2×_K×_W^-1
assert_parsed_expression_simplify_to("_kg^(-1)×_m^(-2)×_s^2", "_J^\u0012-1\u0013"); // Thermodynamic beta
assert_parsed_expression_simplify_to("_kg×_m^(-1)×_s^(-1)", "_Pa×_s"); // Dynamic viscosity
assert_parsed_expression_simplify_to("_m^2×_s^(-2)", "_m^2×_s^\u0012-2\u0013"); // Gray/Sievert _J×_kg^\u0012-1\u0013
assert_parsed_expression_simplify_to("_m^2×_kg×_s^(-1)", "_J×_s"); // Angular momentum _N×_m×_s
assert_parsed_expression_simplify_to("_m^(-1)×_kg×_s^(-2)", "_Pa"); // Energy density _J×_m^-3
assert_parsed_expression_simplify_to("_m×_kg×_s^(-3)", "_N×_s^\u0012-1\u0013"); // Spectral power _W×_m^-1
assert_parsed_expression_simplify_to("_m×_kg^(-1)×_s^2", "_Pa^\u0012-1\u0013"); // Compressibility
assert_parsed_expression_simplify_to("_kg^(-1)×_s^3×_A^2×_mol^(-1)", "_Ω^\u0012-1\u0013×_mol^\u0012-1\u0013×_m^2"); // Molar conductivity _S×_m^2×_mol^-1
assert_parsed_expression_simplify_to("_m^(-2)×_s×_A", "_C×_m^\u0012-2\u0013"); // Polarization density
assert_parsed_expression_simplify_to("_kg^(-1)×_s×_A", "_C×_kg^\u0012-1\u0013"); // Exposure
assert_parsed_expression_simplify_to("_kg×_m^3×_s^(-3)×_A^(-2)", "×_m"); // Electrical resistivity
assert_parsed_expression_simplify_to("_m^(-1)×_s×_A", "_C×_m^\u0012-1\u0013"); // Dipole moment
assert_parsed_expression_simplify_to("_kg^(-1)×_s^2×_A", "_T^\u0012-1\u0013"); // Electron mobility _m^2×_V^-1×_s^-1
assert_parsed_expression_simplify_to("_m^(-2)×_kg^(-1)×_s^2×_A^2", "_H^\u0012-1\u0013"); // Magnetic reluctance
assert_parsed_expression_simplify_to("_m×_kg×_s^(-2)×_A^(-1)", "_N×_A^\u0012-1\u0013"); // Magnetic vector potential _Wb×_m^-1 and Magnetic rigidity _T×_m
assert_parsed_expression_simplify_to("_m^3×_kg×_s^(-2)×_A^(-1)", "_Wb×_m"); // Magnetic moment
assert_parsed_expression_simplify_to("_m^(-1)×_kg^(-1)×_s^2×_A^2", "_N^\u0012-1\u0013×_A^2"); // Magnetic susceptibility _H^-1×_m
assert_parsed_expression_simplify_to("_A×_s×_m^(-3)", "1×_C×_m^\u0012-3\u0013"); // Charge density
assert_parsed_expression_simplify_to("_kg×_m×_s^(-3)×_K^(-1)", "1×_N×_K^\u0012-1\u0013×_s^\u0012-1\u0013"); // Thermal conductivity _W×_m^-1×_K^-1
assert_parsed_expression_simplify_to("_K×_kg^(-1)×_m^(-2)×_s^3", "1×_W^\u0012-1\u0013×_K"); // Thermal resistance
assert_parsed_expression_simplify_to("_kg×_m×_s^(-3)×_A^(-1)", "1×_V×_m^\u0012-1\u0013"); // Electrical field
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-1)", "1×_J×_s"); // Action
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)×_K^(-1)", "1×_J×_K^\u0012-1\u0013"); // Entropy | Heat capacity
assert_parsed_expression_simplify_to("_m^2×_s^(-2)×_K^(-1)", "1×_K^\u0012-1\u0013×_m^2×_s^\u0012-2\u0013"); // Specific heat capacity _J×_K^-1×_kg^-1
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-2)×_K^(-1)×_mol^(-1)", "1×_J×_mol^\u0012-1\u0013×_K^\u0012-1\u0013"); // Molar heat capacity
assert_parsed_expression_simplify_to("_kg×_m^(-1)×_s^(-2)×_K^(-1)", "1×_Pa×_K^\u0012-1\u0013"); // Volumetric heat capacity _J×_K^-1×_m^-3
assert_parsed_expression_simplify_to("_kg×_s^(-3)×_K^(-1)", "1×_K^\u0012-1\u0013×_kg×_s^\u0012-3\u0013"); // Heat transfer coefficient _W×_m^-2×_K^-1
assert_parsed_expression_simplify_to("_kg×_m^2×_s^(-3)×_K^(-1)", "1×_W×_K^\u0012-1\u0013"); // Thermal conductivity
assert_parsed_expression_simplify_to("_kg^(-1)×_m^(-3)×_s^3×_A^2", "1×_Ω^\u0012-1\u0013×_m^\u0012-1\u0013"); // Electrical conductivity _S×_m^-1
assert_parsed_expression_simplify_to("_kg×_s^(-2)", "1×_kg×_s^\u0012-2\u0013"); // Stiffness _N×_m^-1
assert_parsed_expression_simplify_to("_kg×_m^(-1)×_s^(-3)", "1×_Pa×_s^\u0012-1\u0013"); // Power density _W×_m^-3
assert_parsed_expression_simplify_to("_kg×_m^3×_s^(-3)×_A^(-1)", "1×_V×_m"); // Electric flux
assert_parsed_expression_simplify_to("_K×_kg^(-1)×_s^(3)", "1×_K×_kg^\u0012-1\u0013×_s^3"); // Superficial thermal resistance _m^2×_K×_W^-1
assert_parsed_expression_simplify_to("_kg^(-1)×_m^(-2)×_s^2", "1×_J^\u0012-1\u0013"); // Thermodynamic beta
assert_parsed_expression_simplify_to("_kg×_m^(-1)×_s^(-1)", "1×_Pa×_s"); // Dynamic viscosity
assert_parsed_expression_simplify_to("_m^2×_s^(-2)", "1×_m^2×_s^\u0012-2\u0013"); // Gray/Sievert _J×_kg^\u0012-1\u0013
assert_parsed_expression_simplify_to("_m^2×_kg×_s^(-1)", "1×_J×_s"); // Angular momentum _N×_m×_s
assert_parsed_expression_simplify_to("_m^(-1)×_kg×_s^(-2)", "1×_Pa"); // Energy density _J×_m^-3
assert_parsed_expression_simplify_to("_m×_kg×_s^(-3)", "1×_N×_s^\u0012-1\u0013"); // Spectral power _W×_m^-1
assert_parsed_expression_simplify_to("_m×_kg^(-1)×_s^2", "1×_Pa^\u0012-1\u0013"); // Compressibility
assert_parsed_expression_simplify_to("_kg^(-1)×_s^3×_A^2×_mol^(-1)", "1×_Ω^\u0012-1\u0013×_mol^\u0012-1\u0013×_m^2"); // Molar conductivity _S×_m^2×_mol^-1
assert_parsed_expression_simplify_to("_m^(-2)×_s×_A", "1×_C×_m^\u0012-2\u0013"); // Polarization density
assert_parsed_expression_simplify_to("_kg^(-1)×_s×_A", "1×_C×_kg^\u0012-1\u0013"); // Exposure
assert_parsed_expression_simplify_to("_kg×_m^3×_s^(-3)×_A^(-2)", "1××_m"); // Electrical resistivity
assert_parsed_expression_simplify_to("_m^(-1)×_s×_A", "1×_C×_m^\u0012-1\u0013"); // Dipole moment
assert_parsed_expression_simplify_to("_kg^(-1)×_s^2×_A", "1×_T^\u0012-1\u0013"); // Electron mobility _m^2×_V^-1×_s^-1
assert_parsed_expression_simplify_to("_m^(-2)×_kg^(-1)×_s^2×_A^2", "1×_H^\u0012-1\u0013"); // Magnetic reluctance
assert_parsed_expression_simplify_to("_m×_kg×_s^(-2)×_A^(-1)", "1×_N×_A^\u0012-1\u0013"); // Magnetic vector potential _Wb×_m^-1 and Magnetic rigidity _T×_m
assert_parsed_expression_simplify_to("_m^3×_kg×_s^(-2)×_A^(-1)", "1×_Wb×_m"); // Magnetic moment
assert_parsed_expression_simplify_to("_m^(-1)×_kg^(-1)×_s^2×_A^2", "1×_N^\u0012-1\u0013×_A^2"); // Magnetic susceptibility _H^-1×_m
// Physical constants
assert_parsed_expression_simplify_to("_kg^(-1)×_m^3×_s^(-2)", "_kg^\u0012-1\u0013×_m^3×_s^\u0012-2\u0013"); // Gravitational constant G _N×_m^2×_kg^-2
assert_parsed_expression_simplify_to("_kg×_m×_s^(-2)×_A^(-2)", "_N×_A^\u0012-2\u0013"); // Vacuum electric permittivity µ0 _H×_m^-1
assert_parsed_expression_simplify_to("_A^2×_s^4×_kg^(-1)×_m^(-3)", "_F×_m^\u0012-1\u0013"); // Vacuum magnetic permeability 𝝴0
assert_parsed_expression_simplify_to("_kg×_s^(-3)×_K^(-4)", "_K^\u0012-4\u0013×_kg×_s^\u0012-3\u0013"); // StefanBoltzmann constant _W×_m^-2×_K^-4
assert_parsed_expression_simplify_to("_kg^(-1)×_m^3×_s^(-2)", "1×_kg^\u0012-1\u0013×_m^3×_s^\u0012-2\u0013"); // Gravitational constant G _N×_m^2×_kg^-2
assert_parsed_expression_simplify_to("_kg×_m×_s^(-2)×_A^(-2)", "1×_N×_A^\u0012-2\u0013"); // Vacuum electric permittivity µ0 _H×_m^-1
assert_parsed_expression_simplify_to("_A^2×_s^4×_kg^(-1)×_m^(-3)", "1×_F×_m^\u0012-1\u0013"); // Vacuum magnetic permeability 𝝴0
assert_parsed_expression_simplify_to("_kg×_s^(-3)×_K^(-4)", "1×_K^\u0012-4\u0013×_kg×_s^\u0012-3\u0013"); // StefanBoltzmann constant _W×_m^-2×_K^-4
/* Keep units for 0, infinity float results, Remove unit for undefined
* expression */