class Logica::Predicates::Compounds::Base

Attributes

predicates[R]

Public Class Methods

new(predicates) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 15
def initialize(predicates)
  @predicates = predicates
  validate_composability
end
new_from_list(predicates) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 11
def self.new_from_list(predicates)
  predicates.reduce(internal_binary_operation) || neutral_element
end
new_from_pair(first_predicate, second_predicate) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 7
def self.new_from_pair(first_predicate, second_predicate)
  new([first_predicate]).with_extra_predicate_last(second_predicate)
end

Public Instance Methods

arity() click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 33
def arity
  predicates.first.arity
end
name_and_attributes() click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 37
def name_and_attributes
  "#{name}(#{attributes_string})"
end
with_extra_predicate_last(extra_predicate) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 27
def with_extra_predicate_last(extra_predicate)
  with_extra_predicate(extra_predicate) do |subsumed, extra|
    predicates - subsumed + [extra]
  end
end
with_extra_predicates(extra_predicates) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 20
def with_extra_predicates(extra_predicates)
  extra_predicates.reduce(self) do |compound, extra_predicate|
    return compound if compound == absorbing_element
    compound.with_extra_predicate_last(extra_predicate)
  end
end
without(predicate_or_predicates, options = {}) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 41
def without(predicate_or_predicates, options = {})
  without_predicates([predicate_or_predicates].flatten(1), options)
end

Protected Instance Methods

without_predicates(preds, options = {}) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 47
def without_predicates(preds, options = {})
  default_options = {
    recursive: false
  }
  options = default_options.merge(options)

  difference = predicates - preds

  remaining = if options[:recursive]
                difference.flat_map { |pred| pred.without_predicates(preds, options) }
              else
                difference
              end

  new_from_list(remaining)
end

Private Instance Methods

absorbing_element() click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 124
def absorbing_element
  self.class.absorbing_element
end
annihilated_by?(other) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 82
def annihilated_by?(other)
  ([self] + predicates).any? { |pred| annihilation?(pred, other) }
end
attributes_string() click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 128
def attributes_string
  predicates.map(&:name_and_attributes).join(', ')
end
composability_error_message() click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 74
def composability_error_message
  "cannot compose predicates #{predicates} (arity mismatch)"
end
new_from_list(preds) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 120
def new_from_list(preds)
  self.class.new_from_list(preds)
end
new_with_predicates(new_predicates) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 116
def new_with_predicates(new_predicates)
  self.class.new(new_predicates)
end
predicates_are_composable?() click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 78
def predicates_are_composable?
  predicates.map(&:arity).uniq.size <= 1
end
predicates_satisfied_by(*arguments) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 108
def predicates_satisfied_by(*arguments)
  predicates.select { |predicate| predicate.satisfied_by?(*arguments) }
end
predicates_unsatisfied_by(*arguments) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 112
def predicates_unsatisfied_by(*arguments)
  predicates.select { |predicate| predicate.unsatisfied_by?(*arguments) }
end
raise_composability_error() click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 70
def raise_composability_error
  raise ArgumentError, composability_error_message
end
subsumes?(other) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 86
def subsumes?(other)
  predicates.any? { |own_predicate| subsumption?(own_predicate, other) }
end
validate_composability() click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 66
def validate_composability
  raise_composability_error unless predicates_are_composable?
end
with_extra_predicate(extra_predicate) { |predicates_subsumed, extra_predicate| ... } click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 96
def with_extra_predicate(extra_predicate)
  return absorbing_element if annihilated_by?(extra_predicate)

  candidates = if subsumes?(extra_predicate)
                 predicates
               else
                 predicates_subsumed = predicates.select { |pred| subsumption?(extra_predicate, pred) }
                 yield predicates_subsumed, extra_predicate
               end
  candidates.one? ? candidates.first : new_with_predicates(candidates)
end
with_extra_predicate_first(extra_predicate) click to toggle source
# File lib/logica/predicates/compounds/base.rb, line 90
def with_extra_predicate_first(extra_predicate)
  with_extra_predicate(extra_predicate) do |subsumed, extra|
    [extra] + predicates - subsumed
  end
end