class Axiom::Optimizer::PredicatePartition

Partition a predicate to distribute it over binary operations

Constants

TAUTOLOGY

Attributes

left[R]

Returns the predicate for the left header

@return [Function]

@api private

remainder[R]

Returns the remainder predicate

@return [Function]

@api private

right[R]

Returns the predicate for the right header

@return [Function]

@api private

Public Class Methods

new(predicate, left_header, right_header) click to toggle source

Initialize a Predication Partition

@example

partition = PredicatePartition.new(predicate, left_header, right_header)

@param [Function] predicate

@param [Header] left_header

@param [Header] right_header

@return [undefined]

@api private

# File lib/axiom/optimizer/support/predicate_partition.rb, line 47
def initialize(predicate, left_header, right_header)
  @left = @right = @remainder = TAUTOLOGY

  @left_header  = left_header
  @right_header = right_header

  partition(predicate)
end

Private Instance Methods

each_conjunction(conjunction, &block) click to toggle source

Yield each operand of the conjunction

@param [Function::Connective::Conjunction] conjunction

@yield [operand]

@yieldparam [Function] operand

each operand in the conjunction

@yieldreturn [undefined]

@return [undefined]

@api private

# File lib/axiom/optimizer/support/predicate_partition.rb, line 172
def each_conjunction(conjunction, &block)
  each_operand(conjunction.left,  &block)
  each_operand(conjunction.right, &block)
end
each_operand(predicate, &block) click to toggle source

Yield each operand in the predicate recursively

@param [Function] predicate

@yield [operand]

@yieldparam [Function] operand

each operand in the predicate

@yieldreturn [undefined]

@return [undefined]

@api private

# File lib/axiom/optimizer/support/predicate_partition.rb, line 149
def each_operand(predicate, &block)
  case predicate
  when Axiom::Function::Connective::Disjunction then each_operand(predicate.inverse.optimize, &block)
  when Axiom::Function::Connective::Conjunction then each_conjunction(predicate, &block)
  else
    block.call(predicate)
  end
end
partition(predicate) click to toggle source

Partition the predicate into a left, right and remainder predicates

@param [Function] predicate

@return [undefined]

@api private

# File lib/axiom/optimizer/support/predicate_partition.rb, line 65
def partition(predicate)
  each_operand(predicate) do |operand|
    case operand
    when Axiom::Function::Binary   then partition_binary(operand)
    when Axiom::Function::Unary    then partition_unary(operand)
    when Axiom::Attribute::Boolean then partition_attribute(operand)
    else
      partition_proposition(operand)
    end
  end
end
partition_attribute(attribute) click to toggle source

Partition the attribute up into the left and right predicates

@param [Attribute] attribute

@return [undefined]

@api private

# File lib/axiom/optimizer/support/predicate_partition.rb, line 117
def partition_attribute(attribute)
  @left  &= attribute if @left_header.include?(attribute)
  @right &= attribute if @right_header.include?(attribute)
end
partition_binary(function) click to toggle source

Partition the binary function up into a left, right and remainder predicates

@param [Function::Binary] function

@return [undefined]

@api private

# File lib/axiom/optimizer/support/predicate_partition.rb, line 84
def partition_binary(function)
  operands       = [function.left, function.right].grep(Axiom::Attribute)
  left_operands  = @left_header  & operands
  right_operands = @right_header & operands

  if (left_operands - right_operands).empty? || (right_operands - left_operands).empty?
    @left  &= function if left_operands.any?
    @right &= function if right_operands.any?
  else
    @remainder &= function
  end
end
partition_proposition(proposition) click to toggle source

Partition the proposition up into the left, right and remainder predicates

@param [Function::Proposition] proposition

@return [undefined]

@api private

# File lib/axiom/optimizer/support/predicate_partition.rb, line 129
def partition_proposition(proposition)
  @remainder &= proposition
  @left      &= proposition
  @right     &= proposition
end
partition_unary(function) click to toggle source

Partition the unary function up into the left and right predicates

@param [Function::Unary] function

@return [undefined]

@api private

# File lib/axiom/optimizer/support/predicate_partition.rb, line 104
def partition_unary(function)
  operand = function.operand
  @left  &= function if @left_header.include?(operand)
  @right &= function if @right_header.include?(operand)
end