You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
constexpr=ce.parse(`(x * x) + (x * x) + \ln{e} + \ln{e}`);// At v58, the rule indexed at `[8]` corresponds to the primary rule handling 'Add'constaddRule=ce.getRuleSet()!.rules[8];constsingleRuleSimplified=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).
Fixed in c1b83f2. simplify() now does constant folding itself, independent of the rules option: the default rules, a custom list and rules: null fold the same subexpressions, and the rule list controls the symbolic rewrites only. The per-operand evaluation was removed from the Add and Multiply rules. So with only the addition rule, (x·x)+(x·x)+ln e+ln e still gives 2x² + 2: ln e folds because it is a constant, and x·x + x·x → 2x² is the like-term collection of the addition rule. A Sum or Product, a Hold, an Annotated wrapper and an impure expression such as Random() are never folded. The design and its reasons are in docs/SIMPLIFY.md ("The method is rule-based and value-blind").
Activity
arnog commentedon Oct 12, 2026
Fixed in c1b83f2.
simplify()now does constant folding itself, independent of the rules option: the default rules, a custom list and rules: null fold the same subexpressions, and the rule list controls the symbolic rewrites only. The per-operand evaluation was removed from theAddandMultiplyrules. So with only the addition rule,(x·x)+(x·x)+ln e+ln estill gives2x² + 2:ln efolds because it is a constant, andx·x + x·x → 2x²is the like-term collection of the addition rule. ASumorProduct, aHold, anAnnotatedwrapper and an impure expression such asRandom()are never folded. The design and its reasons are in docs/SIMPLIFY.md ("The method is rule-based and value-blind").