omf_rete 0.5

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.
@@ -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