Project

General

Profile

Bug #12278 » minuend_spec.rb

ProcsReducer#inlay_procs usage - newmen (Gleb Averchuk), 04/13/2016 06:25 PM

 
module VersatileDiamond
module Organizers

# Provides method for minuend behavior
module MinuendSpec
include Modules::OrderProvider
include Modules::ProcsReducer
include Organizers::LinksCleaner
include Organizers::Minuend

# Compares two minuend instances
# @param [Minuend] other the comparable minuend instance
# @return [Integer] the result of comparation
def <=>(other)
compare_with(other)
end

# Checks that current instance is less than other
# @param [Minuend] other the comparable minuend instance
# @return [Boolean] is less or not
def <(other)
compare_with(other, strong_types_order: false) < 0
end

# Checks that current instance is less than other or equal
# @param [Minuend] other the comparable minuend instance
# @return [Boolean] is less or equal or not
def <=(other)
self == other || self < other
end

# Provides relations of atom in current resudual
# @param [Concepts::Atom | Concepts::AtomRelation] atom for which relations will
# be got
# @option [Boolean] :with_atoms if true, then relations will contain neighbour
# atoms too
# @return [Array] the array of atom relations
def relations_of(atom, with_atoms: false)
relations = links[atom]
with_atoms ? relations : relations.map(&:last)
end

# Removes excess positions from current links graph
# @return [Hash] the links of concept specie without excess positions
def clean_links
@_clean_links ||= erase_excess_positions(cleanable_links)
end

# Finds first intersec with some spec
# @param [DependentBaseSpec] spec the checkable specie
# @return [Array] the array of each pair of intersection or nil if intersection
# have not fond
def mirror_to(spec)
Mcs::SpeciesComparator.make_mirror(self, spec)
end


protected

# Counts the relations number in current links
# @return [Integer] the number of relations
def relations_num
links.values.map(&:size).reduce(:+)
end

# Gets the array of used relations without excess position relations
# @param [Atom] atom see at #relations_of same argument
# @return [Array] the array of relations without excess position relations
def used_relations_of(atom)
pairs = relations_of(atom, with_atoms: true).reject do |a, r|
excess_position?(r, atom, a)
end
pairs.map(&:last)
end

private

# Makes residual of difference between top and possible parent
# @param [DependentBaseSpec | DependentSpecificSpec] other the subtrahend spec
# @param [Hash] mirror from self to other spec
# @return [SpecResidual] the residual of diference between arguments or nil if
# it doesn't exist
def subtract(other, mirror)
# the proxy should be maked just one time
proxy = ProxyParentSpec.new(other, owner, mirror)

atoms_to_parents = {}
residuals = rest_links(other, mirror) do |own_atom|
atoms_to_parents[own_atom] = [proxy]
end

SpecResidual.new(owner, residuals, atoms_to_parents)
end

# Compares two minuend instances
# @param [Minuend] other the comparable minuend instance
# @option [Boolean] :strong_types_order is the flag which if set then types info
# also used for ordering
# @return [Integer] the result of comparation
def compare_with(other, strong_types_order: true)
inlay_procs(comparing_core(other)) do |nest|
nest[:order, self, other, :links, :size]
nest[:order_classes, other] if strong_types_order
nest[:order_relations, other]
end
end

# Provides comparison by number of relations
# @param [Minuend] other see at #<=> same argument
# @return [Integer] the result of comparation
def order_relations(other, &block)
order(self, other, :relations_num, &block)
end

# Provides the lowest level of comparing two minuend instances
# @param [MinuendSpec] other comparing instance
# @return [Proc] the core of comparison
def comparing_core(other)
-> do
order(self, other, :parents, :size) do
order(self, other, :name) do
order(self, other, :object_id)
end
end
end
end

# Provides comparison by class of each instance
# @param [MinuendSpec] other see at #<=> same argument
# @return [Integer] the result of comparation
def order_classes(other, &block)
typed_order(self, other, DependentSpecificSpec) do
typed_order(self, other, DependentBaseSpec) do
typed_order(self, other, SpecResidual, &block)
end
end
end

# Checks that passed relation between atoms is not excess
# @param [Concepts::Atom | Concepts::AtomReference | Concepts::SpecificAtom]
# neighbour_key the neighbour key of iterable key
# @param [Concepts::Atom | Concepts::AtomReference | Concepts::SpecificAtom]
# checking_key the key which checks that it used
# @param [Concepts::Bond] relation between iterable key and neighbour key
# @return [Boolean] is realy used checking key or not
def excess_neighbour?(neighbour_key, checking_key, relation)
excess_position?(relation, checking_key, neighbour_key)
end
end

end
end
(4-4/4)