omf_rete 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,95 @@
1
+
2
+ module OMF::Rete::Store::Alpha
3
+
4
+ # Module internal class, will only be instantiated by +Store+
5
+ #
6
+ class AlphaElement
7
+
8
+ def self.create(level, length)
9
+ rem = length - level
10
+ if (rem > 1)
11
+ AlphaInnerElement.new(level, length)
12
+ else
13
+ AlphaLeafElement.new(level)
14
+ end
15
+ end
16
+
17
+ def initialize(level)
18
+ @level = level
19
+ end
20
+
21
+ end
22
+
23
+ class AlphaInnerElement < AlphaElement
24
+
25
+ def initialize(level, length)
26
+ super(level)
27
+ @length = length
28
+ @children = {}
29
+ if (level < length)
30
+ @wildChild = AlphaElement.create(level + 1, length)
31
+ end
32
+ end
33
+
34
+ # see Store
35
+ #
36
+ def registerTSet(tset, pattern)
37
+ pitem = pattern[@level]
38
+ if (pitem) # not nil
39
+ child = (@children[pitem] ||= AlphaElement.create(@level + 1, @length))
40
+ child.registerTSet(tset, pattern)
41
+ else # wildcard
42
+ @wildChild.registerTSet(tset, pattern)
43
+ end
44
+ end
45
+
46
+
47
+ def addTuple(tarray)
48
+ el = tarray[@level]
49
+ if (child = @children[el])
50
+ child.addTuple(tarray)
51
+ end
52
+ @wildChild.addTuple(tarray) if (@wildChild)
53
+ end
54
+ end # AlphaInnerElement
55
+
56
+ # Module internal class, will only be instantiated by +Store+
57
+ #
58
+ class AlphaLeafElement < AlphaElement
59
+
60
+ def initialize(level)
61
+ super
62
+ @tsetIndex = {}
63
+ @tsetWildcards = []
64
+ end
65
+
66
+ # see Store
67
+ #
68
+ def registerTSet(tset, pattern)
69
+ pitem = pattern[@level]
70
+ leaf = (@level == @length)
71
+ if (pitem) # not nil
72
+ (@tsetIndex[pitem] ||= []) << tset
73
+ else # wildcard
74
+ @tsetWildcards << tset
75
+ end
76
+ end
77
+
78
+ def addTuple(tarray)
79
+ # check if we have any matching tsets
80
+ item = tarray[@level]
81
+ if (arr = @tsetIndex[item])
82
+ arr.each do |s|
83
+ s.addTuple(tarray)
84
+ end
85
+ end
86
+ @tsetWildcards.each do |s|
87
+ s.addTuple(tarray)
88
+ end
89
+ end
90
+
91
+
92
+
93
+ end # AlphaLeafElement
94
+
95
+ end # Moana::Filter::Store::Alpha
@@ -0,0 +1,96 @@
1
+ require 'omf_rete/store/alpha/alpha_element'
2
+
3
+ module OMF::Rete::Store::Alpha
4
+
5
+ # Module internal class, will only be instantiated by +Store+
6
+ #
7
+ class AlphaElement
8
+
9
+ def self.create(level, length)
10
+ rem = length - level
11
+ if (rem > 1)
12
+ AlphaInnerElement.new(level, length)
13
+ else
14
+ AlphaLeafElement.new(level)
15
+ end
16
+ end
17
+
18
+ def initialize(level)
19
+ @level = level
20
+ end
21
+
22
+ end
23
+
24
+ class AlphaInnerElement < AlphaElement
25
+
26
+ def initialize(level, length)
27
+ super(level)
28
+ @length = length
29
+ @children = {}
30
+ if (level < length)
31
+ @wildChild = AlphaElement.create(level + 1, length)
32
+ end
33
+ end
34
+
35
+ # see Store
36
+ #
37
+ def registerTSet(tset, pattern)
38
+ pitem = pattern[@level]
39
+ if (pitem) # not nil
40
+ child = (@children[pitem] ||= AlphaElement.create(@level + 1, @length))
41
+ child.registerTSet(tset, pattern)
42
+ else # wildcard
43
+ @wildChild.registerTSet(tset, pattern)
44
+ end
45
+ end
46
+
47
+
48
+ def addTuple(tarray)
49
+ el = tarray[@level]
50
+ if (child = @children[el])
51
+ child.addTuple(tarray)
52
+ end
53
+ @wildChild.addTuple(tarray) if (@wildChild)
54
+ end
55
+ end # AlphaInnerElement
56
+
57
+ # Module internal class, will only be instantiated by +Store+
58
+ #
59
+ class AlphaLeafElement < AlphaElement
60
+
61
+ def initialize(level)
62
+ super
63
+ @tsetIndex = {}
64
+ @tsetWildcards = []
65
+ end
66
+
67
+ # see Store
68
+ #
69
+ def registerTSet(tset, pattern)
70
+ pitem = pattern[@level]
71
+ leaf = (@level == @length)
72
+ if (pitem) # not nil
73
+ (@tsetIndex[pitem] ||= []) << tset
74
+ else # wildcard
75
+ @tsetWildcards << tset
76
+ end
77
+ end
78
+
79
+ def addTuple(tarray)
80
+ # check if we have any matching tsets
81
+ item = tarray[@level]
82
+ if (arr = @tsetIndex[item])
83
+ arr.each do |s|
84
+ s.addTuple(tarray)
85
+ end
86
+ end
87
+ @tsetWildcards.each do |s|
88
+ s.addTuple(tarray)
89
+ end
90
+ end
91
+
92
+
93
+
94
+ end # AlphaLeafElement
95
+
96
+ end # Moana::Filter::Store::Alpha
@@ -0,0 +1,41 @@
1
+
2
+ require 'omf_rete/store/alpha/alpha_element'
3
+
4
+ module OMF::Rete::Store::Alpha
5
+
6
+ # Module internal class, will only be instantiated by +Store+
7
+ #
8
+ class AlphaLeafElement < AlphaElement
9
+
10
+ def initialize(level)
11
+ super
12
+ @tsetIndex = {}
13
+ @tsetWildcards = []
14
+ end
15
+
16
+ # see Store
17
+ #
18
+ def registerTSet(tset, pattern)
19
+ pitem = pattern[@level]
20
+ leaf = (@level == @length)
21
+ if (pitem) # not nil
22
+ (@tsetIndex[pitem] ||= []) << tset
23
+ else # wildcard
24
+ @tsetWildcards << tset
25
+ end
26
+ end
27
+
28
+ def addTuple(tarray)
29
+ # check if we have any matching tsets
30
+ item = tarray[@level]
31
+ if (arr = @tsetIndex[item])
32
+ arr.each do |s|
33
+ s.addTuple(tarray)
34
+ end
35
+ end
36
+ @tsetWildcards.each do |s|
37
+ s.addTuple(tarray)
38
+ end
39
+ end
40
+ end # AlphaLeafElement
41
+ end # Moana::Filter::Store::Alpha
@@ -0,0 +1,197 @@
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
@@ -0,0 +1,57 @@
1
+
2
+ require 'omf_rete'
3
+
4
+
5
+ module OMF::Rete::Store
6
+ DEF_TYPE = :alpha
7
+
8
+ def self.create(length, opts = {})
9
+ case (type = opts[:type] || DEF_TYPE)
10
+ when :alpha
11
+ require 'omf_rete/store/alpha/alpha_store'
12
+ return OMF::Rete::Store::Alpha::Store.new(length, opts)
13
+ else
14
+ raise "Unknown store type '#{type}'"
15
+ end
16
+ end
17
+
18
+ #--- INTERFACE ---
19
+
20
+ def query(queryPattern, projectPattern = nil, &block)
21
+ raise "'query' - Not implemented."
22
+ end
23
+
24
+ def subscribe(name, query, out_pattern = nil, &block)
25
+ require 'omf_rete/planner/plan_builder'
26
+
27
+ pb = OMF::Rete::Planner::PlanBuilder.new(query, self)
28
+ pb.build
29
+ pb.materialize(out_pattern, &block)
30
+ end
31
+
32
+ def addTuple(tarray)
33
+ end
34
+
35
+ # alias
36
+ def add(*els)
37
+ addTuple(els)
38
+ end
39
+
40
+ # Return a set of tuples which match +pattern+. Pattern is
41
+ # a tuples of the same length this store is configured for
42
+ # where any non-nil element is matched directly and any
43
+ # nil element is considered a wildcard.
44
+ #
45
+ def find(pattern)
46
+ end
47
+
48
+ # Register a function to be called whenever a query is performed
49
+ # on the store. The arguments to the proc are identical to that
50
+ # of +query+. The returned tuple set is added to the store and
51
+ # returned with any other tuples stored which match the query
52
+ # pattern.
53
+ #
54
+ def on_query(&requestProc)
55
+ end
56
+
57
+ end