omf_rete 0.5 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,197 +0,0 @@
1
- require 'set'
2
- require 'omf_rete/store/alpha/alpha_inner_element'
3
- require 'omf_rete/store/alpha/alpha_leaf_element'
4
-
5
- module OMF::Rete::Store::Alpha
6
-
7
- # Module internal class, will only be instantiated by +Store+
8
- #
9
- class AlphaElement
10
-
11
- def self.create(level, length)
12
- rem = length - level
13
- if (rem > 1)
14
- AlphaInnerElement.new(level, length)
15
- else
16
- AlphaLeafElement.new(level)
17
- end
18
- end
19
-
20
- def initialize(level)
21
- @level = level
22
- end
23
-
24
- end
25
-
26
- class AlphaInnerElement < AlphaElement
27
-
28
- def initialize(level, length)
29
- super(level)
30
- @length = length
31
- @children = {}
32
- if (level < length)
33
- @wildChild = AlphaElement.create(level + 1, length)
34
- end
35
- end
36
-
37
- # see Store
38
- #
39
- def registerTSet(tset, pattern)
40
- pitem = pattern[@level]
41
- if (pitem) # not nil
42
- child = (@children[pitem] ||= AlphaElement.create(@level + 1, @length))
43
- child.registerTSet(tset, pattern)
44
- else # wildcard
45
- @wildChild.registerTSet(tset, pattern)
46
- end
47
- end
48
-
49
-
50
- def addTuple(tarray)
51
- el = tarray[@level]
52
- if (child = @children[el])
53
- child.addTuple(tarray)
54
- end
55
- @wildChild.addTuple(tarray) if (@wildChild)
56
- end
57
- end # AlphaInnerElement
58
-
59
- # Module internal class, will only be instantiated by +Store+
60
- #
61
- class AlphaLeafElement < AlphaElement
62
-
63
- def initialize(level)
64
- super
65
- @tsetIndex = {}
66
- @tsetWildcards = []
67
- end
68
-
69
- # see Store
70
- #
71
- def registerTSet(tset, pattern)
72
- pitem = pattern[@level]
73
- leaf = (@level == @length)
74
- if (pitem) # not nil
75
- (@tsetIndex[pitem] ||= []) << tset
76
- else # wildcard
77
- @tsetWildcards << tset
78
- end
79
- end
80
-
81
- def addTuple(tarray)
82
- # check if we have any matching tsets
83
- item = tarray[@level]
84
- if (arr = @tsetIndex[item])
85
- arr.each do |s|
86
- s.addTuple(tarray)
87
- end
88
- end
89
- @tsetWildcards.each do |s|
90
- s.addTuple(tarray)
91
- end
92
- end
93
-
94
-
95
-
96
- end # AlphaLeafElement
97
-
98
- #
99
- # Class to store tuples for use in MoanaFilter
100
- #
101
- class Store #< MObject
102
- include OMF::Rete::Store
103
-
104
- attr_reader :length
105
-
106
- # Initialize a tuple store for tuples of
107
- # fixed length +length+.
108
- #
109
- def initialize(length, opts = {})
110
- @length = length
111
- @root = AlphaInnerElement.new(0, length)
112
- @index = []
113
- length.times do @index << {} end
114
- end
115
-
116
- def query(queryPattern, projectPattern = nil, &block)
117
- pb = PlanBuilder.new(queryPattern, self)
118
- pb.build
119
- pb.materialize(projectPattern, &block)
120
- end
121
-
122
- # Register a +TSet+ and add all tuples currently
123
- # and in the future matching +pattern+
124
- #
125
- def registerTSet(tset, pattern)
126
- pat = pattern.collect do |el|
127
- (el.is_a?(Symbol) && el.to_s.end_with?('?')) ? nil : el
128
- end
129
- @root.registerTSet(tset, pat)
130
- # seed tset which already stored data
131
- find(pattern).each do |t|
132
- tset.addTuple(t)
133
- end
134
- tset
135
- end
136
-
137
- def createTSet(description, indexPattern)
138
- tset = Moana::Filter::IndexedTupleSet.new(description, indexPattern)
139
- registerTSet(tset, description)
140
- tset
141
- end
142
-
143
- def addTuple(tarray)
144
- @length.times do |i|
145
- item = tarray[i]
146
- ia = @index[i][item] ||= Set.new
147
- unless ia.add?(tarray)
148
- return # this is a duplicate
149
- end
150
- end
151
- @root.addTuple(tarray)
152
- end
153
-
154
- # Return a set of tuples which match +pattern+. Pattern is
155
- # a tuples of the same length this store is configured for
156
- # where any non-nil element is matched directly and any
157
- # nil element is considered a wildcard.
158
- #
159
- def find(pattern)
160
- seta = []
161
- allWildcards = true
162
- @length.times do |i|
163
- if (item = pattern[i])
164
- allWildcards = false
165
- res = @index[i][item]
166
- #puts "res: index #{i}, res: #{res.inspect}"
167
- seta << res if res # only add if non-nil
168
- end
169
- end
170
- if (allWildcards)
171
- res = Set.new
172
- @index[0].each_value do |s|
173
- res.merge(s)
174
- end
175
- return res
176
- end
177
- # get intersection of all returned sets
178
- if (seta.empty?)
179
- return Set.new
180
- end
181
- res = nil
182
- seta.each do |s|
183
- if res
184
- res = res.intersection(s)
185
- else
186
- res = s
187
- end
188
- #puts "merge: in: #{s.inspect}, res: #{res.inspect}"
189
- end
190
- return res
191
- end
192
-
193
- def to_s()
194
- "Store"
195
- end
196
- end # Store
197
- end # Moana