class Keisan::AST::Times

Public Class Methods

new(children = [], parsing_operators = []) click to toggle source
Calls superclass method
# File lib/keisan/ast/times.rb, line 4
def initialize(children = [], parsing_operators = [])
  super
  convert_divide_to_inverse!(parsing_operators)
end
symbol() click to toggle source
# File lib/keisan/ast/times.rb, line 9
def self.symbol
  :*
end

Public Instance Methods

blank_value() click to toggle source
# File lib/keisan/ast/times.rb, line 13
def blank_value
  1
end
differentiate(variable, context = nil) click to toggle source
# File lib/keisan/ast/times.rb, line 53
def differentiate(variable, context = nil)
  # Product rule
  Plus.new(
    children.map.with_index do |child,i|
      Times.new(
        children.slice(0,i) + [child.differentiate(variable, context)] + children.slice(i+1,children.size)
      )
    end
  ).simplify(context)
end
evaluate(context = nil) click to toggle source
# File lib/keisan/ast/times.rb, line 17
def evaluate(context = nil)
  children[1..-1].inject(children.first.evaluate(context)) {|total, child| total * child.evaluate(context)}
end
simplify(context = nil) click to toggle source
Calls superclass method
# File lib/keisan/ast/times.rb, line 21
def simplify(context = nil)
  context ||= Context.new

  super(context)

  # Commutative, so pull in operands of any `Times` operators
  @children = children.inject([]) do |new_children, cur_child|
    case cur_child
    when Times
      new_children + cur_child.children
    else
      new_children << cur_child
    end
  end

  constants, non_constants = *children.partition {|child| child.is_a?(Number)}
  constant = constants.inject(Number.new(1), &:*).simplify(context)

  return Number.new(0) if constant.value(context) == 0

  if non_constants.empty?
    constant
  else
    @children = constant.value(context) == 1 ? [] : [constant]
    @children += non_constants

    return @children.first.simplify(context) if @children.size == 1

    self
  end
end

Private Instance Methods

convert_divide_to_inverse!(parsing_operators) click to toggle source
# File lib/keisan/ast/times.rb, line 66
def convert_divide_to_inverse!(parsing_operators)
  parsing_operators.each.with_index do |parsing_operator, index|
    if parsing_operator.is_a?(Parsing::Divide)
      @children[index+1] = UnaryInverse.new(@children[index+1])
    end
  end
end