Class: Wongi::Engine::Overlay

Inherits:
Object
  • Object
show all
Defined in:
lib/wongi-engine/overlay.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rete, parent = nil) ⇒ Overlay

Returns a new instance of Overlay.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/wongi-engine/overlay.rb', line 19

def initialize(rete, parent = nil)
  @rete = rete
  @parent = parent

  @wmes = Set.new
  @indexes = [
    nil,
    AlphaIndex.new(%i[object]),
    AlphaIndex.new(%i[predicate]),
    AlphaIndex.new(%i[predicate object]),
    AlphaIndex.new(%i[subject]),
    AlphaIndex.new(%i[subject object]),
    AlphaIndex.new(%i[subject predicate]),
    nil,
  ]
  @hidden_parent_wmes = {}

  @tokens = Hash.new { |h, k| h[k] = [] }
  @hidden_parent_tokens = Set.new

  @generator_tracker = GeneratorTracker.new

  @wme_manual = {}
  @hidden_parent_wme_manual = {}

  @neg_join_results = JoinResults.new
  @opt_join_results = JoinResults.new

  @ncc_tokens = Hash.new { |h, k| h[k] = [] }
  @ncc_tokens_owner = {}
  @hidden_ncc_tokens = Hash.new { |h, k| h[k] = {} }

  @queue = []
end

Instance Attribute Details

#parentObject (readonly)

Returns the value of attribute parent.



4
5
6
# File 'lib/wongi-engine/overlay.rb', line 4

def parent
  @parent
end

#reteObject (readonly)

Returns the value of attribute rete.



4
5
6
# File 'lib/wongi-engine/overlay.rb', line 4

def rete
  @rete
end

Instance Method Details

#<<(thing) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/wongi-engine/overlay.rb', line 65

def <<(thing)
  case thing
  when Array
    assert(WME.new(*thing))
  when WME
    assert(thing)
  else
    raise Error, "overlays can only accept data"
  end

  self
end

#add_ncc_token(owner, ncc) ⇒ Object



438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/wongi-engine/overlay.rb', line 438

def add_ncc_token(owner, ncc)
  if hidden_ncc_tokens.key?(owner) && hidden_ncc_tokens[token].include?(ncc)
    hidden_ncc_tokens[owner].delete(ncc)
    if hidden_ncc_tokens[owner].empty?
      hidden_ncc_tokens.delete(owner)
    end
    return
  end

  ncc_tokens[owner] << ncc
  ncc_tokens_owner[ncc] = owner
end

#add_neg_join_result(njr) ⇒ Object



385
386
387
# File 'lib/wongi-engine/overlay.rb', line 385

def add_neg_join_result(njr)
  neg_join_results.add(njr)
end

#add_opt_join_result(ojr) ⇒ Object



403
404
405
# File 'lib/wongi-engine/overlay.rb', line 403

def add_opt_join_result(ojr)
  opt_join_results.add(ojr)
end

#add_token(token) ⇒ Object



304
305
306
307
308
309
310
311
312
313
314
# File 'lib/wongi-engine/overlay.rb', line 304

def add_token(token)
  # p add_token: {token:}
  # TODO: is this really likely to happen? we don't normally restore deleted tokens but rather create new ones in the activation
  if hidden_token?(token)
    puts "odd case"
    unhide_token(token)
    return
  end

  tokens[token.node.object_id].push(token) # unless tokens.include?(token) # TODO: pretty unlikely to somehow trigger a repeated evaluation for the same token?..
end

#ancestor?(other) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
# File 'lib/wongi-engine/overlay.rb', line 58

def ancestor?(other)
  return false if parent.nil?
  return true if parent == other

  parent.ancestor?(other)
end

#assert(wme, generator: nil) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/wongi-engine/overlay.rb', line 78

def assert(wme, generator: nil)
  operation = [:assert, wme, { generator: generator }]
  queue.push(operation)

  run_queue if queue.length == 1

  self
end

#default?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/wongi-engine/overlay.rb', line 124

def default?
  self == rete.default_overlay
end

#each(*args, &block) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/wongi-engine/overlay.rb', line 135

def each(*args, &block)
  template = nil
  case args.length
  when 0
    template = Template.new(:_, :_, :_)
  when 1
    arg = args.first
    case arg
    when Array
      template = Template.new(*arg)
    when Template
      template = arg
    when WME
      template = Template.new(arg.subject, arg.predicate, arg.object)
    else
      raise ArgumentError
    end
  when 3
    template = Template.new(*args)
  else
    raise ArgumentError
  end

  each_by_template(template).each(&block)
end

#each_by_template(template) ⇒ Object



229
230
231
232
233
234
# File 'lib/wongi-engine/overlay.rb', line 229

def each_by_template(template)
  Enumerator.new do |y|
    each_own_wme_by_template(template, y)
    each_parent_wme_by_template(template, y)
  end
end

#entity(subject) ⇒ Object



161
162
163
164
# File 'lib/wongi-engine/overlay.rb', line 161

def entity(subject)
  # 4 is the bitmap for <s _ _>
  EntityIterator.new(subject, indexes[4].collection_for_wme(Template.new(subject, :_, :_)))
end

#find(wme) ⇒ Object



128
129
130
131
132
133
# File 'lib/wongi-engine/overlay.rb', line 128

def find(wme)
  if wme.is_a?(Array)
    wme = WME.new(*wme)
  end
  find_wme(wme)
end

#find_ignoring_hidden(wme) ⇒ Object



222
223
224
225
226
227
# File 'lib/wongi-engine/overlay.rb', line 222

def find_ignoring_hidden(wme)
  find_own_wme(wme) ||
    if parent
      parent.find_ignoring_hidden(wme)
    end
end

#generated?(wme) ⇒ Boolean

Returns:

  • (Boolean)


173
174
175
# File 'lib/wongi-engine/overlay.rb', line 173

def generated?(wme)
  generators(wme).any?
end

#generated_wmes(token) ⇒ Object



186
187
188
189
190
191
192
193
# File 'lib/wongi-engine/overlay.rb', line 186

def generated_wmes(token)
  Enumerator.new do |y|
    generator_tracker.for_token(token).each { y << _1 }
    if parent && !hidden_token?(token)
      parent.generated_wmes(token).reject { hidden_wme?(_1) }.each { y << _1 }
    end
  end
end

#generators(wme) ⇒ Object



177
178
179
180
181
182
183
184
# File 'lib/wongi-engine/overlay.rb', line 177

def generators(wme)
  Enumerator.new do |y|
    generator_tracker.for_wme(wme).each {  y << _1 }
    if parent
      parent.generators(wme).reject { hidden_token?(_1) }.each { y << _1 }
    end
  end
end

#manual?(wme) ⇒ Boolean

Returns:

  • (Boolean)


166
167
168
169
170
171
# File 'lib/wongi-engine/overlay.rb', line 166

def manual?(wme)
  wme_manual.key?(wme) ||
    if parent
      parent.manual?(wme) && !hidden_parent_wme_manual.key?(wme)
    end
end

#ncc_owner(ncc) ⇒ Object



451
452
453
# File 'lib/wongi-engine/overlay.rb', line 451

def ncc_owner(ncc)
  ncc_tokens_owner[ncc]
end

#ncc_tokens_for(token) ⇒ Object



455
456
457
# File 'lib/wongi-engine/overlay.rb', line 455

def ncc_tokens_for(token)
  own_ncc_tokens_for(token) + parent_ncc_tokens_for(token)
end

#neg_join_results_for(wme: nil, token: nil) ⇒ Object



393
394
395
396
397
398
399
400
401
# File 'lib/wongi-engine/overlay.rb', line 393

def neg_join_results_for(wme: nil, token: nil)
  if wme
    neg_join_results.for(wme: wme) + parent_neg_join_results_for(wme: wme)
  elsif token
    neg_join_results.for(token: token) + parent_neg_join_results_for(token: token)
  else
    []
  end
end

#new_childObject



54
55
56
# File 'lib/wongi-engine/overlay.rb', line 54

def new_child
  Overlay.new(rete, self)
end

#node_tokens(beta) ⇒ Object



367
368
369
370
371
# File 'lib/wongi-engine/overlay.rb', line 367

def node_tokens(beta)
  parents = parents_node_tokens(beta)
  own = own_node_tokens(beta)
  parents + own
end

#opt_join_results_for(wme: nil, token: nil) ⇒ Object



412
413
414
415
416
417
418
419
420
# File 'lib/wongi-engine/overlay.rb', line 412

def opt_join_results_for(wme: nil, token: nil)
  if wme
    opt_join_results.for(wme: wme) + parent_opt_join_results_for(wme: wme)
  elsif token
    opt_join_results.for(token: token) + parent_opt_join_results_for(token: token)
  else
    []
  end
end

#remove_neg_join_result(njr) ⇒ Object



389
390
391
# File 'lib/wongi-engine/overlay.rb', line 389

def remove_neg_join_result(njr)
  neg_join_results.remove(njr)
end

#remove_opt_join_result(ojr) ⇒ Object



407
408
409
410
# File 'lib/wongi-engine/overlay.rb', line 407

def remove_opt_join_result(ojr)
  # p remove_opt_join_result: {ojr:}
  opt_join_results.remove(ojr)
end

#remove_own_token(token) ⇒ Object



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/wongi-engine/overlay.rb', line 342

def remove_own_token(token)
  # p remove_own_token: {token:}
  tokens[token.node.object_id].delete(token)
  neg_join_results.remove_token(token)
  opt_join_results.remove_token(token)
  generator_tracker.remove_token(token)

  # if this is an NCC partner token
  if (owner = ncc_tokens_owner[token])
    if ncc_tokens.key?(owner)
      ncc_tokens[owner].delete(token)
    end
    if hidden_ncc_tokens.key?(owner)
      hidden_ncc_tokens[owner].delete(token)
    end
  end

  # if this is an NCC owner token
  own_ncc_tokens_for(token).each do |ncc|
    ncc_tokens_owner.delete(ncc)
  end
  ncc_tokens.delete(token)
  hidden_ncc_tokens.delete(token)
end

#remove_token(token) ⇒ Object



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/wongi-engine/overlay.rb', line 316

def remove_token(token)
  # p remove_token: {token:}

  # capture the entire enumerated state
  wmes = generated_wmes(token).to_a

  if own_node_tokens(token.node).find { _1.equal?(token) }.nil?
    if parents_node_tokens(token.node).find { _1.equal?(token) }
      hide_token(token)

      # do not hide JRs from the WME side: it will be done in the alpha deactivation and the JRs have to stay visible until then
      parent_neg_join_results_for(token: token).each { neg_join_results.hide(_1) }
      parent_opt_join_results_for(token: token).each { opt_join_results.hide(_1) }

      parent_ncc_tokens_for(token).each do |ncc|
        hidden_ncc_tokens[token][ncc] = true
      end
    end
  else
    remove_own_token(token)
  end

  wmes.each { retract(_1, generator: token) }

end

#retract(wme, options = {}) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/wongi-engine/overlay.rb', line 87

def retract(wme, options = {})
  if wme.is_a?(Array)
    wme = WME.new(*wme)
  end

  operation = [:retract, wme, options]
  queue.push(operation)

  run_queue if queue.length == 1

  self
end