Skip to content

Simplify { l: 'log(e)', r: '1' } ignores second argument of log #2087

@quentintruong

Description

@quentintruong

Hi, I believe that the simplify function mistakenly ignores the second argument of the log. I'm on MathJS v9.0.0, commit c560002, running Node v14.15.4.

Reproduction:

const { create, all } = require('mathjs')

const math = create(all, {
  number: 'BigNumber',      // Default type of number:
  precision: 15             // Number of significant digits for BigNumbers
})

let expr = 'log(e,9)' // Rule ignores second argument
console.log(math.evaluate(expr).toString()) // 0.455119613313419
console.log(math.simplify(expr).toString()) // 1

let rules = math.simplify.rules
rules.splice(1,1) // Remove rule `{ l: 'log(e)', r: '1' }`
console.log(math.evaluate(expr).toString()) // 0.455119613313419
console.log(math.simplify(expr, rules).toString()) // log(e, 9)

This bug is also reproducible by going to mathjs.org and typing simplify("log(e,9)") into the demo window.

Although log(e) == 1 (because log in mathjs is natural log), log(e,9) != 1.

I believe the root cause may be in src/function/algebra/simplify.js:_ruleMatch(). Based on my debugging it looks like

if ((node.args.length === 1 && rule.args.length === 1) || !isAssociative(node) || isSplit) {
  // Expect non-associative operators to match exactly
  const childMatches = []
  for (let i = 0; i < rule.args.length; i++) {
    const childMatch = _ruleMatch(rule.args[i], node.args[i])
    if (childMatch.length === 0) {
      // Child did not match, so stop searching immediately
      return []
    }
    // The child matched, so add the information returned from the child to our result
    childMatches.push(childMatch)
  }
  res = mergeChildMatches(childMatches)
}

ignores whether or not the node and rule have the same number arguments.

Changing conditional to

if ((node.args.length === 1 && rule.args.length === 1) || (!isAssociative(node) && node.args.length == rule.args.length) || isSplit)

fixes the log issue. Running npm run test:src and npm run test:generated show the unit and generated tests continue to pass.

Can someone verify this as a bug?

Happy to send a PR with unit tests if the above fix is correct.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions