Skip to content

'simplify()' over-eagerly numerically evaluates lazy-flagged operator definition operands, without considering rules #306

@samueltlg

Description

@samueltlg

Description

As outlined in PR 301, specifically in 'workaround' commit #5d974d2, simplification of built-in operators with a lazy flag is overly eager with respect to numeric-evaluation of operands.
Presently, simplification of these operators involve full numeric evaluation of operands, despite the presence of absence of any rules which would ordinarily handle the simplification (or evaluation) of these operands.

Some edited excerpts from the linked commit describing the issue:

...for example, consider the simplification of an 'Add' expression with
(evaluable) Ln or Log operands...
If the contextual/accompanying simplify rule-set does not with it include rules covering the
simplification (i.e. 'evaluation' here) of these, or this category of functions, then it is dubious
that these should be evaluated prior to the evaluation of the containing Add: (- not all use-cases
would desire this: particularly if a custom rule-list constituted only by the default 'Add'-rule
were given).
Instead - assuming that simplification were to proceed with a single 'Add' rule, one would expect only fundamental addition operations to take place (symbolic; or BoxedNumber operands).
For instance, for 'Ln(e) + Ln(e)' to reduce to 2 * Ln(e), in contrast to 2 (the current
behaviour).
Similarly again, with only the 'Add' rule, it would be permissible that (x * x) + (x * x) would
simplify to 2 * x * x in contrast to 2 * x^2 (present behaviour).
Naturally, with all simplification-rules (the default RuleList) supplied, 'full' / natural
simplification would proceed.

(Note that the patch/workaround employed to block this behaviour can also be found in the linked PR commit..)

Steps to Reproduce

Simplify an expression corresponding to a built-in operator with a 'lazy' flag - such as Add or Multiply - with a rule-set constituted solely by the rule handling the simplification of that operator.
For instance, given an expression boxed from the parsing of (x * x) + (x * x) + \\ln{e} + \\ln{e}, the simplification of this with the single built-in rule which handles 'Add' (wholly) results in full simplification, despite there being no rules for simplifying Multiply or Ln:

const expr = ce.parse(`(x * x) + (x * x) + \ln{e} + \ln{e}`);

// At v58, the rule indexed at `[8]` corresponds to the primary rule handling 'Add'
const addRule = ce.getRuleSet()!.rules[8];
const singleRuleSimplified = fullyCanon.simplify({ rules: [addRule]});

singleRuleSimplified.toString() // => `2x^2 + 2`

Expected Result

(See description)

Environment

CE v58

(This behaviour has at least been present for a few months; at least going as far back as February 2026 - according to git history the point at which function evaluateNumericSubexpressions() has been present.
Is possible also that has existed in previous forms (this function having assumed a different name for instance).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions