wongi-engine 0.4.0.pre.alpha11 → 0.4.0.pre.alpha12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/wongi-engine/alpha_index.rb +0 -21
- data/lib/wongi-engine/beta/beta_node.rb +1 -1
- data/lib/wongi-engine/entity_iterator.rb +60 -0
- data/lib/wongi-engine/network.rb +13 -21
- data/lib/wongi-engine/overlay.rb +35 -27
- data/lib/wongi-engine/template.rb +4 -0
- data/lib/wongi-engine/version.rb +1 -1
- data/lib/wongi-engine.rb +1 -0
- data/spec/entity_iterator_spec.rb +88 -0
- data/spec/overlay_spec.rb +17 -17
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18bc1bfbc38b0ae08b505d3209fb6f0776c9abfa532d8c90b4ef8c6d26461c44
|
4
|
+
data.tar.gz: b10cc7b4fae950742ae4471d7385d745f23bb875d6436a80139c355e35c9370f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f480873ccb3c7292b143cfdff082829e8e52b9ab8424e86caa6a8929d544f1f6d0aa3bfbd266bf12d2c2cf1de42282a5183244db27a8d15e3e51d681f2a0bb6
|
7
|
+
data.tar.gz: 04dbbba150bbb6d01336fab7d041769d986e8602838ed79e4e321ebf2c9c914344377e5cf7e82a753d1324ac87daa730640006595ce645f259d572fe2fe5cd33
|
@@ -25,27 +25,6 @@ module Wongi::Engine
|
|
25
25
|
index[hashed_key(wme)]
|
26
26
|
end
|
27
27
|
|
28
|
-
def collections_for_template(template)
|
29
|
-
return nil unless template_matches_pattern?(template)
|
30
|
-
|
31
|
-
# here we know that all fields on which we're indexing are concrete in the template
|
32
|
-
collection_for_wme(template)
|
33
|
-
end
|
34
|
-
|
35
|
-
private def template_matches_pattern?(template)
|
36
|
-
template_element_matches_pattern?(:subject, template.subject) &&
|
37
|
-
template_element_matches_pattern?(:predicate, template.predicate) &&
|
38
|
-
template_element_matches_pattern?(:object, template.object)
|
39
|
-
end
|
40
|
-
|
41
|
-
private def template_element_matches_pattern?(member, template_element)
|
42
|
-
if Template.concrete?(template_element)
|
43
|
-
pattern.include?(member)
|
44
|
-
else
|
45
|
-
!pattern.include?(member)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
28
|
private def key(wme)
|
50
29
|
pattern.map { wme.public_send(_1) }
|
51
30
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Wongi::Engine
|
2
|
+
class EntityIterator
|
3
|
+
|
4
|
+
attr_reader :entity, :collection
|
5
|
+
private :entity, :collection
|
6
|
+
|
7
|
+
def initialize(entity, collection)
|
8
|
+
@entity = entity
|
9
|
+
@collection = collection
|
10
|
+
end
|
11
|
+
|
12
|
+
def each
|
13
|
+
if block_given?
|
14
|
+
@collection.each do |wme|
|
15
|
+
yield wme.predicate, wme.object
|
16
|
+
end
|
17
|
+
else
|
18
|
+
Enumerator.new do |y|
|
19
|
+
@collection.each do |wme|
|
20
|
+
y << [wme.predicate, wme.object]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(name)
|
27
|
+
each { |k, v| return v if k == name }
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](name)
|
32
|
+
get(name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_all(name)
|
36
|
+
each.filter_map { |k, v| v if k == name }
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch(name, *args, &block)
|
40
|
+
each { |k, v| return v if k == name }
|
41
|
+
if args.first
|
42
|
+
args.first
|
43
|
+
elsif block
|
44
|
+
block.call(name)
|
45
|
+
else
|
46
|
+
raise KeyError
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_missing(name)
|
51
|
+
each { |k, v| return v if k == name }
|
52
|
+
raise NoMethodError
|
53
|
+
end
|
54
|
+
|
55
|
+
def respond_to_missing?(name, _include_private)
|
56
|
+
each { |k, v| return true if k == name }
|
57
|
+
super
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/wongi-engine/network.rb
CHANGED
@@ -109,6 +109,10 @@ module Wongi::Engine
|
|
109
109
|
overlays.last
|
110
110
|
end
|
111
111
|
|
112
|
+
def entity(subject)
|
113
|
+
current_overlay.entity(subject)
|
114
|
+
end
|
115
|
+
|
112
116
|
def assert(wme)
|
113
117
|
default_overlay.assert(wme)
|
114
118
|
end
|
@@ -130,7 +134,7 @@ module Wongi::Engine
|
|
130
134
|
end
|
131
135
|
|
132
136
|
def wmes
|
133
|
-
|
137
|
+
each.to_a
|
134
138
|
end
|
135
139
|
|
136
140
|
alias statements wmes
|
@@ -168,6 +172,7 @@ module Wongi::Engine
|
|
168
172
|
else
|
169
173
|
raise Error, "I don't know how to accept a #{something.class}"
|
170
174
|
end
|
175
|
+
self
|
171
176
|
end
|
172
177
|
end
|
173
178
|
|
@@ -206,7 +211,7 @@ module Wongi::Engine
|
|
206
211
|
end
|
207
212
|
|
208
213
|
def initial_fill(alpha)
|
209
|
-
default_overlay.
|
214
|
+
default_overlay.each(:_, :_, :_).to_a.each do |wme|
|
210
215
|
alpha.activate wme if wme =~ alpha.template
|
211
216
|
end
|
212
217
|
end
|
@@ -234,32 +239,19 @@ module Wongi::Engine
|
|
234
239
|
end
|
235
240
|
|
236
241
|
def exists?(wme)
|
237
|
-
find(wme.subject, wme.predicate, wme.object)
|
242
|
+
!find(wme.subject, wme.predicate, wme.object).nil?
|
238
243
|
end
|
239
244
|
|
240
245
|
def each(*args, &block)
|
241
|
-
|
242
|
-
when 0
|
243
|
-
Template.new(:_, :_, :_)
|
244
|
-
when 3
|
245
|
-
Template.new(*args)
|
246
|
-
else
|
247
|
-
raise Error, "Network#each expect a template or nothing at all"
|
248
|
-
end
|
249
|
-
matching = current_overlay.select(template)
|
250
|
-
if block_given?
|
251
|
-
matching.each(&block)
|
252
|
-
else
|
253
|
-
matching.each
|
254
|
-
end
|
246
|
+
current_overlay.each(*args, &block)
|
255
247
|
end
|
256
248
|
|
257
|
-
def select(
|
258
|
-
|
249
|
+
def select(*args, &block)
|
250
|
+
each(*args, &block)
|
259
251
|
end
|
260
252
|
|
261
|
-
def find(
|
262
|
-
|
253
|
+
def find(*args)
|
254
|
+
each(*args).first
|
263
255
|
end
|
264
256
|
|
265
257
|
protected
|
data/lib/wongi-engine/overlay.rb
CHANGED
@@ -22,12 +22,14 @@ module Wongi::Engine
|
|
22
22
|
|
23
23
|
@wmes = Set.new
|
24
24
|
@indexes = [
|
25
|
-
|
26
|
-
AlphaIndex.new(%i[predicate]),
|
25
|
+
nil,
|
27
26
|
AlphaIndex.new(%i[object]),
|
28
|
-
AlphaIndex.new(%i[
|
29
|
-
AlphaIndex.new(%i[subject object]),
|
27
|
+
AlphaIndex.new(%i[predicate]),
|
30
28
|
AlphaIndex.new(%i[predicate object]),
|
29
|
+
AlphaIndex.new(%i[subject]),
|
30
|
+
AlphaIndex.new(%i[subject object]),
|
31
|
+
AlphaIndex.new(%i[subject predicate]),
|
32
|
+
nil,
|
31
33
|
]
|
32
34
|
@hidden_parent_wmes = {}
|
33
35
|
|
@@ -69,6 +71,8 @@ module Wongi::Engine
|
|
69
71
|
else
|
70
72
|
raise Error, "overlays can only accept data"
|
71
73
|
end
|
74
|
+
|
75
|
+
self
|
72
76
|
end
|
73
77
|
|
74
78
|
def assert(wme, generator: nil)
|
@@ -76,6 +80,8 @@ module Wongi::Engine
|
|
76
80
|
queue.push(operation)
|
77
81
|
|
78
82
|
run_queue if queue.length == 1
|
83
|
+
|
84
|
+
self
|
79
85
|
end
|
80
86
|
|
81
87
|
def retract(wme, options = {})
|
@@ -87,9 +93,11 @@ module Wongi::Engine
|
|
87
93
|
queue.push(operation)
|
88
94
|
|
89
95
|
run_queue if queue.length == 1
|
96
|
+
|
97
|
+
self
|
90
98
|
end
|
91
99
|
|
92
|
-
def run_queue
|
100
|
+
private def run_queue
|
93
101
|
until queue.empty?
|
94
102
|
operation, wme, options = queue.shift
|
95
103
|
|
@@ -117,19 +125,6 @@ module Wongi::Engine
|
|
117
125
|
self == rete.default_overlay
|
118
126
|
end
|
119
127
|
|
120
|
-
# TODO: this is inconsistent.
|
121
|
-
# A WME retracted in-flight will be visible in active enumerators
|
122
|
-
# but a token will not.
|
123
|
-
# But this is how it works.
|
124
|
-
|
125
|
-
# def wmes(template)
|
126
|
-
# DuplicatingEnumerator.new(index(template))
|
127
|
-
# end
|
128
|
-
|
129
|
-
# def tokens(beta)
|
130
|
-
# DeleteSafeEnumerator.new(raw_tokens(beta))
|
131
|
-
# end
|
132
|
-
|
133
128
|
def find(wme)
|
134
129
|
if wme.is_a?(Array)
|
135
130
|
wme = WME.new(*wme)
|
@@ -137,20 +132,35 @@ module Wongi::Engine
|
|
137
132
|
find_wme(wme)
|
138
133
|
end
|
139
134
|
|
140
|
-
def
|
135
|
+
def each(*args, &block)
|
136
|
+
template = nil
|
141
137
|
case args.length
|
138
|
+
when 0
|
139
|
+
template = Template.new(:_, :_, :_)
|
142
140
|
when 1
|
143
|
-
|
141
|
+
arg = args.first
|
142
|
+
case arg
|
143
|
+
when Array
|
144
|
+
template = Template.new(*arg)
|
144
145
|
when Template
|
145
|
-
|
146
|
+
template = arg
|
147
|
+
when WME
|
148
|
+
template = Template.new(arg.subject, arg.predicate, arg.object)
|
146
149
|
else
|
147
150
|
raise ArgumentError
|
148
151
|
end
|
149
152
|
when 3
|
150
|
-
|
153
|
+
template = Template.new(*args)
|
151
154
|
else
|
152
155
|
raise ArgumentError
|
153
156
|
end
|
157
|
+
|
158
|
+
each_by_template(template, &block)
|
159
|
+
end
|
160
|
+
|
161
|
+
def entity(subject)
|
162
|
+
# 4 is the bitmap for <s _ _>
|
163
|
+
EntityIterator.new(subject, indexes[4].collection_for_wme(Template.new(subject, :_, :_)))
|
154
164
|
end
|
155
165
|
|
156
166
|
def manual?(wme)
|
@@ -230,9 +240,7 @@ module Wongi::Engine
|
|
230
240
|
elsif template.root?
|
231
241
|
wmes.each { y << _1 }
|
232
242
|
else
|
233
|
-
indexes.
|
234
|
-
index.collections_for_template(template)
|
235
|
-
}.compact.first.each { y << _1 }
|
243
|
+
indexes[template.bitmap].collection_for_wme(template).each { y << _1 }
|
236
244
|
end
|
237
245
|
end
|
238
246
|
|
@@ -250,7 +258,7 @@ module Wongi::Engine
|
|
250
258
|
|
251
259
|
unless has_own_wme?(wme)
|
252
260
|
wmes.add(wme)
|
253
|
-
indexes.each { _1.add(wme) }
|
261
|
+
indexes[1..6].each { _1.add(wme) }
|
254
262
|
end
|
255
263
|
|
256
264
|
if generator
|
@@ -270,7 +278,7 @@ module Wongi::Engine
|
|
270
278
|
# no remaining reasons to keep this WME around
|
271
279
|
if !own_generated?(wme) && !own_manual?(wme)
|
272
280
|
wmes.delete(wme)
|
273
|
-
indexes.each { _1.remove(wme) }
|
281
|
+
indexes[1..6].each { _1.remove(wme) }
|
274
282
|
end
|
275
283
|
|
276
284
|
neg_join_results.remove_wme(wme)
|
@@ -28,6 +28,10 @@ module Wongi::Engine
|
|
28
28
|
Template.concrete?(subject) && Template.concrete?(predicate) && Template.concrete?(object)
|
29
29
|
end
|
30
30
|
|
31
|
+
def bitmap
|
32
|
+
(Template.concrete?(subject) ? 4 : 0) | (Template.concrete?(predicate) ? 2 : 0) | (Template.concrete?(object) ? 1 : 0)
|
33
|
+
end
|
34
|
+
|
31
35
|
def variables
|
32
36
|
[].tap do |a|
|
33
37
|
a << subject if Template.variable?(subject)
|
data/lib/wongi-engine/version.rb
CHANGED
data/lib/wongi-engine.rb
CHANGED
@@ -31,6 +31,7 @@ require 'wongi-engine/compiler'
|
|
31
31
|
require 'wongi-engine/join_results'
|
32
32
|
require 'wongi-engine/generator_tracker'
|
33
33
|
require 'wongi-engine/overlay'
|
34
|
+
require 'wongi-engine/entity_iterator'
|
34
35
|
require 'wongi-engine/enumerators'
|
35
36
|
require 'wongi-engine/network'
|
36
37
|
require 'wongi-engine/graph'
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Wongi::Engine::EntityIterator do
|
4
|
+
let(:engine) { Wongi::Engine.create }
|
5
|
+
let(:x) { engine.entity(:x) }
|
6
|
+
let(:y) { engine.entity(:y) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
engine << [:x, :prop1, 1]
|
10
|
+
engine << [:x, :prop1, 2]
|
11
|
+
engine << [:x, :prop2, :y]
|
12
|
+
engine << [:y, :prop3, 3]
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#each" do
|
16
|
+
it 'returns an enumerator' do
|
17
|
+
expect(x.each.to_h).to eq(prop1: 2, prop2: :y)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'iterates over properties' do
|
21
|
+
results = {}
|
22
|
+
x.each { |k, v| results[k] = v }
|
23
|
+
expect(results).to eq(prop1: 2, prop2: :y)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#get" do
|
28
|
+
specify do
|
29
|
+
expect(x.get(:prop1)).to eq(1)
|
30
|
+
expect(x.get(:prop2)).to eq(:y)
|
31
|
+
expect(x.get(:prop3)).to eq(nil)
|
32
|
+
|
33
|
+
expect(y.get(:prop3)).to eq(3)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#[]" do
|
38
|
+
specify do
|
39
|
+
expect(x[:prop1]).to eq(1)
|
40
|
+
expect(x[:prop2]).to eq(:y)
|
41
|
+
expect(x[:prop3]).to eq(nil)
|
42
|
+
|
43
|
+
expect(y[:prop3]).to eq(3)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#fetch" do
|
48
|
+
specify do
|
49
|
+
expect(x.fetch(:prop1)).to eq(1)
|
50
|
+
expect(x.fetch(:prop2)).to eq(:y)
|
51
|
+
expect(x.fetch(:prop3, 42)).to eq(42)
|
52
|
+
expect(x.fetch(:prop3) { 42 }).to eq(42)
|
53
|
+
expect { x.fetch(:prop3) }.to raise_error(KeyError)
|
54
|
+
|
55
|
+
expect(y.fetch(:prop3)).to eq(3)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#get_all" do
|
60
|
+
it 'returns all matching values' do
|
61
|
+
expect(x.get_all(:prop1)).to eq([1, 2])
|
62
|
+
expect(x.get_all(:prop2)).to eq([:y])
|
63
|
+
expect(x.get_all(:prop3)).to eq([])
|
64
|
+
|
65
|
+
expect(y.get_all(:prop3)).to eq([3])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#method_missing" do
|
70
|
+
it 'can access properties directly' do
|
71
|
+
expect(x.prop1).to eq(1)
|
72
|
+
expect(x.prop2).to eq(:y)
|
73
|
+
expect { x.prop3 }.to raise_error(NoMethodError)
|
74
|
+
|
75
|
+
expect(y.prop3).to eq(3)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#respond_to_missing?" do
|
80
|
+
specify do
|
81
|
+
expect(x.respond_to?(:prop1)).to be true
|
82
|
+
expect(x.respond_to?(:prop2)).to be true
|
83
|
+
expect(x.respond_to?(:prop3)).to be false
|
84
|
+
|
85
|
+
expect(y.respond_to?(:prop3)).to be true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/spec/overlay_spec.rb
CHANGED
@@ -52,21 +52,21 @@ describe Wongi::Engine::Overlay do
|
|
52
52
|
]
|
53
53
|
wmes.each { overlay.assert(_1) }
|
54
54
|
|
55
|
-
expect(overlay.
|
56
|
-
expect(overlay.
|
57
|
-
expect(overlay.
|
58
|
-
expect(overlay.
|
59
|
-
expect(overlay.
|
60
|
-
expect(overlay.
|
61
|
-
expect(overlay.
|
62
|
-
expect(overlay.
|
63
|
-
expect(overlay.
|
64
|
-
expect(overlay.
|
65
|
-
|
66
|
-
expect(overlay.
|
67
|
-
|
68
|
-
expect(overlay.
|
69
|
-
expect(overlay.
|
55
|
+
expect(overlay.each(1, :_, :_)).to have(5).items
|
56
|
+
expect(overlay.each(2, :_, :_)).to have(4).items
|
57
|
+
expect(overlay.each(3, :_, :_)).to have(3).items
|
58
|
+
expect(overlay.each(1, 11, :_)).to have(3).items
|
59
|
+
expect(overlay.each(:_, 11, :_)).to have(5).items
|
60
|
+
expect(overlay.each(:_, :_, 113)).to have(2).items
|
61
|
+
expect(overlay.each(:_, 22, :_)).to have(2).items
|
62
|
+
expect(overlay.each(:_, 22, 222)).to have(1).items
|
63
|
+
expect(overlay.each(:_, :_, 222)).to have(2).items
|
64
|
+
expect(overlay.each(:_, :_, 223)).to have(1).items
|
65
|
+
|
66
|
+
expect(overlay.each(:_, :_, :_)).to have(wmes.length).items
|
67
|
+
|
68
|
+
expect(overlay.each(1, 11, 111)).to have(1).items
|
69
|
+
expect(overlay.each(1, 11, 111).first).to eq(wmes.first)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -85,10 +85,10 @@ describe Wongi::Engine::Overlay do
|
|
85
85
|
wme = Wongi::Engine::WME.new(1, 11, 111)
|
86
86
|
|
87
87
|
overlay.assert(wme)
|
88
|
-
expect(overlay.
|
88
|
+
expect(overlay.each(:_, :_, :_)).to have(1).items
|
89
89
|
|
90
90
|
overlay.retract(wme)
|
91
|
-
expect(overlay.
|
91
|
+
expect(overlay.each(:_, :_, :_)).to have(0).items
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wongi-engine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.0.pre.
|
4
|
+
version: 0.4.0.pre.alpha12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Valeri Sokolov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -128,6 +128,7 @@ files:
|
|
128
128
|
- lib/wongi-engine/dsl/ncc_subrule.rb
|
129
129
|
- lib/wongi-engine/dsl/query.rb
|
130
130
|
- lib/wongi-engine/dsl/rule.rb
|
131
|
+
- lib/wongi-engine/entity_iterator.rb
|
131
132
|
- lib/wongi-engine/enumerators.rb
|
132
133
|
- lib/wongi-engine/error.rb
|
133
134
|
- lib/wongi-engine/filter.rb
|
@@ -163,6 +164,7 @@ files:
|
|
163
164
|
- spec/beta_node_spec.rb
|
164
165
|
- spec/bug_specs/issue_4_spec.rb
|
165
166
|
- spec/dataset_spec.rb
|
167
|
+
- spec/entity_iterator_spec.rb
|
166
168
|
- spec/generation_spec.rb
|
167
169
|
- spec/greater_than_equality_test_spec.rb
|
168
170
|
- spec/high_level_spec.rb
|