mirror of
https://gitlab.com/c3d/db48x.git
synced 2024-09-29 05:36:58 +02:00
units: Add factoring
variable to limit simplifications
When factoring out units, we don't need to run through each simplification in `expression::simplify`. We should also not lookup names as symbols, but just let symbols as is. Fixes: #988 Fixes: #976 Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
parent
05b9a6acee
commit
5c551ce194
7 changed files with 23 additions and 15 deletions
|
@ -1343,7 +1343,7 @@ algebraic_p arithmetic::evaluate(id op,
|
|||
x = expression::make(op, x, y);
|
||||
if (x)
|
||||
if (expression_p expr = x->as<expression>())
|
||||
if (Settings.AutoSimplify())
|
||||
if (!unit::factoring && Settings.AutoSimplify())
|
||||
x = expr->simplify();
|
||||
return x;
|
||||
}
|
||||
|
|
|
@ -1248,9 +1248,10 @@ algebraic_p expression::simplify_products() const
|
|||
if (inner->is_algebraic())
|
||||
return algebraic_p(inner);
|
||||
|
||||
// Save auto-simplify and set it
|
||||
// Save auto-simplify and set it, and evaluate units normally
|
||||
settings::SaveAutoSimplify sas(true);
|
||||
save<bool> save(unit::mode, false);
|
||||
save<bool> smode(unit::mode, false);
|
||||
save<bool> sexpr(unit::factoring, true);
|
||||
|
||||
// Need a GC pointer since stack operations may move us
|
||||
expression_g eq = this;
|
||||
|
|
|
@ -64,7 +64,7 @@ algebraic_p function::symbolic(id op, algebraic_r x)
|
|||
if (!x)
|
||||
return nullptr;
|
||||
expression_p result = expression::make(op, x);
|
||||
if (result && Settings.AutoSimplify())
|
||||
if (result && !unit::factoring && Settings.AutoSimplify())
|
||||
result = result->simplify();
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -51,16 +51,19 @@ EVAL_BODY(symbol)
|
|||
// Evaluate a symbol by looking it up
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
if (unit::mode)
|
||||
if (unit_p u = unit::lookup(o))
|
||||
if (rt.push(u))
|
||||
return OK;
|
||||
if (object_p found = directory::recall_all(o, false))
|
||||
if (!unit::factoring)
|
||||
{
|
||||
if (unit::ignore)
|
||||
if (unit_p uval = found->as<unit>())
|
||||
found = uval->value();
|
||||
return program::run_program(found);
|
||||
if (unit::mode)
|
||||
if (unit_p u = unit::lookup(o))
|
||||
if (rt.push(u))
|
||||
return OK;
|
||||
if (object_p found = directory::recall_all(o, false))
|
||||
{
|
||||
if (unit::ignore)
|
||||
if (unit_p uval = found->as<unit>())
|
||||
found = uval->value();
|
||||
return program::run_program(found);
|
||||
}
|
||||
}
|
||||
if (object_g eq = expression::make(o))
|
||||
if (rt.push(eq))
|
||||
|
|
|
@ -4140,7 +4140,7 @@ void tests::units_and_conversions()
|
|||
.test(SHIFT, KEY5, KEY4, KEY2, F2, F3).expect("42 km/h")
|
||||
.test(ADD).expect("101.54572 8 km/h");
|
||||
step("Unit parsing on command line")
|
||||
.test(CLEAR, "12_km/s^2", ENTER).expect("12 km/s²");
|
||||
.test(CLEAR, "12_km/s^2", ENTER).expect("12 km/s↑2");
|
||||
step("Parsing degrees as a unit")
|
||||
.test(CLEAR, "DEG", ENTER).noerror()
|
||||
.test("1∡90", ENTER).expect("1∡90°")
|
||||
|
@ -6904,7 +6904,7 @@ void tests::insertion_of_variables_constants_and_units()
|
|||
.expect("6.02213 67²³ mol⁻¹");
|
||||
step("Programmatic equation lookup (text)")
|
||||
.test(CLEAR, "\"IdealGas\" LIBEQ", ENTER)
|
||||
.expect("'(P Pa)·(V m³)=(n mol)·R·(T K)'");
|
||||
.expect("'(P Pa)·(V m↑3)=(n mol)·R·(T K)'");
|
||||
step("Programmatic library lookup (text)")
|
||||
.test(CLEAR, "\"LibraryHelp\" XLIB", ENTER)
|
||||
.expect("\"To modify the library, edit the config/library.csv file\"");
|
||||
|
|
|
@ -256,6 +256,9 @@ HELP_BODY(unit)
|
|||
// This variable is true while evaluating a uexpr
|
||||
bool unit::mode = false;
|
||||
|
||||
// This variable is true while factoring out a uexpr (limit simplifications)
|
||||
bool unit::factoring = false;
|
||||
|
||||
// This variable is true to ignore units while solving an equation
|
||||
bool unit::ignore = false;
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ struct unit : complex
|
|||
unit_p custom_cycle(symbol_r sym) const;
|
||||
|
||||
static bool mode; // Set to true to evaluate units
|
||||
static bool factoring; // Set to true when factoring out units
|
||||
static bool ignore; // Set to true to drop units from variables
|
||||
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue