1

module VersatileDiamond

2

module Organizers

3


4

# Provides method for minuend behavior

5

module MinuendSpec

6

include Modules::OrderProvider

7

include Modules::ProcsReducer

8

include Organizers::LinksCleaner

9

include Organizers::Minuend

10


11

# Compares two minuend instances

12

# @param [Minuend] other the comparable minuend instance

13

# @return [Integer] the result of comparation

14

def <=>(other)

15

compare_with(other)

16

end

17


18

# Checks that current instance is less than other

19

# @param [Minuend] other the comparable minuend instance

20

# @return [Boolean] is less or not

21

def <(other)

22

compare_with(other, strong_types_order: false) < 0

23

end

24


25

# Checks that current instance is less than other or equal

26

# @param [Minuend] other the comparable minuend instance

27

# @return [Boolean] is less or equal or not

28

def <=(other)

29

self == other  self < other

30

end

31


32

# Provides relations of atom in current resudual

33

# @param [Concepts::Atom  Concepts::AtomRelation] atom for which relations will

34

# be got

35

# @option [Boolean] :with_atoms if true, then relations will contain neighbour

36

# atoms too

37

# @return [Array] the array of atom relations

38

def relations_of(atom, with_atoms: false)

39

relations = links[atom]

40

with_atoms ? relations : relations.map(&:last)

41

end

42


43

# Removes excess positions from current links graph

44

# @return [Hash] the links of concept specie without excess positions

45

def clean_links

46

@_clean_links = erase_excess_positions(cleanable_links)

47

end

48


49

# Finds first intersec with some spec

50

# @param [DependentBaseSpec] spec the checkable specie

51

# @return [Array] the array of each pair of intersection or nil if intersection

52

# have not fond

53

def mirror_to(spec)

54

Mcs::SpeciesComparator.make_mirror(self, spec)

55

end

56


57


58

protected

59


60

# Counts the relations number in current links

61

# @return [Integer] the number of relations

62

def relations_num

63

links.values.map(&:size).reduce(:+)

64

end

65


66

# Gets the array of used relations without excess position relations

67

# @param [Atom] atom see at #relations_of same argument

68

# @return [Array] the array of relations without excess position relations

69

def used_relations_of(atom)

70

pairs = relations_of(atom, with_atoms: true).reject do a, r

71

excess_position?(r, atom, a)

72

end

73

pairs.map(&:last)

74

end

75


76

private

77


78

# Makes residual of difference between top and possible parent

79

# @param [DependentBaseSpec  DependentSpecificSpec] other the subtrahend spec

80

# @param [Hash] mirror from self to other spec

81

# @return [SpecResidual] the residual of diference between arguments or nil if

82

# it doesn't exist

83

def subtract(other, mirror)

84

# the proxy should be maked just one time

85

proxy = ProxyParentSpec.new(other, owner, mirror)

86


87

atoms_to_parents = {}

88

residuals = rest_links(other, mirror) do own_atom

89

atoms_to_parents[own_atom] = [proxy]

90

end

91


92

SpecResidual.new(owner, residuals, atoms_to_parents)

93

end

94


95

# Compares two minuend instances

96

# @param [Minuend] other the comparable minuend instance

97

# @option [Boolean] :strong_types_order is the flag which if set then types info

98

# also used for ordering

99

# @return [Integer] the result of comparation

100

def compare_with(other, strong_types_order: true)

101

inlay_procs(comparing_core(other)) do nest

102

nest[:order, self, other, :links, :size]

103

nest[:order_classes, other] if strong_types_order

104

nest[:order_relations, other]

105

end

106

end

107


108

# Provides comparison by number of relations

109

# @param [Minuend] other see at #<=> same argument

110

# @return [Integer] the result of comparation

111

def order_relations(other, &block)

112

order(self, other, :relations_num, &block)

113

end

114


115

# Provides the lowest level of comparing two minuend instances

116

# @param [MinuendSpec] other comparing instance

117

# @return [Proc] the core of comparison

118

def comparing_core(other)

119

> do

120

order(self, other, :parents, :size) do

121

order(self, other, :name) do

122

order(self, other, :object_id)

123

end

124

end

125

end

126

end

127


128

# Provides comparison by class of each instance

129

# @param [MinuendSpec] other see at #<=> same argument

130

# @return [Integer] the result of comparation

131

def order_classes(other, &block)

132

typed_order(self, other, DependentSpecificSpec) do

133

typed_order(self, other, DependentBaseSpec) do

134

typed_order(self, other, SpecResidual, &block)

135

end

136

end

137

end

138


139

# Checks that passed relation between atoms is not excess

140

# @param [Concepts::Atom  Concepts::AtomReference  Concepts::SpecificAtom]

141

# neighbour_key the neighbour key of iterable key

142

# @param [Concepts::Atom  Concepts::AtomReference  Concepts::SpecificAtom]

143

# checking_key the key which checks that it used

144

# @param [Concepts::Bond] relation between iterable key and neighbour key

145

# @return [Boolean] is realy used checking key or not

146

def excess_neighbour?(neighbour_key, checking_key, relation)

147

excess_position?(relation, checking_key, neighbour_key)

148

end

149

end

150


151

end

152

end
