omf_rete 0.5 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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