rubysolo / dentaku

math and logic formula parser and evaluator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrect results from solve() when key is already in memory

vlazar opened this issue · comments

Results from solve can sometimes be incorrect (depend on expression ordering) when one of the named expressions were already in calculator memory.

  1. Incorrect behavior
require "dentaku"

calculator = Dentaku::Calculator.new

# Notice :discount is already present in calculator memory

calculator.store(discount: 20, foo: 20) do
  # Correct result
  # => {:discount=>50, :discount_not_applicable=>true}
  p calculator.solve(
    discount: "foo + 30",
    discount_not_applicable: "IF(discount > 30, true, false)", # discount is 50 here (correct)
  )
end

calculator.store(discount: 20, foo: 20) do
  # BUG discount_not_applicable should be true
  # => {:discount_not_applicable=>false, :discount=>50}
  # Apparently :discount_not_applicable is evaluated first (uses discount: 20 value from memory)
  # Then :discount is evaluated and becomes 50 from that moment.
  p calculator.solve(
    discount_not_applicable: "IF(discount > 30, true, false)", # discount is 20 here (BUG)
    discount: "foo + 30",
  )
end
  1. Correct behavior
# Notice :discount is not present in calculator memory

# Solver sorts expressions properly before evaluation, so results are correct

calculator.store(foo: 20) do
  # Correct result
  # => {:discount=>50, :discount_not_applicable=>true}
  p calculator.solve(
    discount: "foo + 30",
    discount_not_applicable: "IF(discount > 30, true, false)", # discount is 50 here (correct)
  )
end

calculator.store(foo: 20) do
  # Correct result
  # => {:discount_not_applicable=>true, :discount=>50}
  p calculator.solve(
    discount_not_applicable: "IF(discount > 30, true, false)", # discount is 50 here (correct)
    discount: "foo + 30",
  )
end

I ran in to this same issue today. v3.5.0.