class Wongi::Engine::Overlay
Attributes
generator_tracker[R]
indexes[R]
ncc_tokens[R]
ncc_tokens_owner[R]
neg_join_results[R]
opt_join_results[R]
parent[R]
queue[R]
rete[R]
tokens[R]
wme_manual[R]
wmes[R]
Public Class Methods
new(rete, parent = nil)
click to toggle source
# 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
Public Instance Methods
<<(thing)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 403 def add_opt_join_result(ojr) opt_join_results.add(ojr) end
add_token(token)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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?()
click to toggle source
# File lib/wongi-engine/overlay.rb, line 124 def default? self == rete.default_overlay end
each(*args, &block)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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
generated?(wme)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 173 def generated?(wme) generators(wme).any? end
generated_wmes(token)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 451 def ncc_owner(ncc) ncc_tokens_owner[ncc] end
ncc_tokens_for(token)
click to toggle source
# 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)
click to toggle source
# 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_child()
click to toggle source
# File lib/wongi-engine/overlay.rb, line 54 def new_child Overlay.new(rete, self) end
node_tokens(beta)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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 = {})
click to toggle source
# 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
Private Instance Methods
add_wme(wme, generator:)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 253 def add_wme(wme, generator:) # p add_wme: { wme:, generator: !!generator } # if we previously hid this locally, unhide it hidden_parent_wmes.delete(wme) unless has_own_wme?(wme) wmes.add(wme) indexes[1..6].each { _1.add(wme) } end if generator generator_tracker.add(wme, generator) else hidden_parent_wme_manual.delete(wme) wme_manual[wme] = true end end
each_own_wme_by_template(template, y)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 236 def each_own_wme_by_template(template, y) if template.concrete? wme = find_own_wme(WME.from_concrete_template(template)) y << wme if wme elsif template.root? wmes.each { y << _1 } else indexes[template.bitmap].collection_for_wme(template).each { y << _1 } end end
each_parent_wme_by_template(template, y)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 247 def each_parent_wme_by_template(template, y) if parent parent.each_by_template(template).reject { hidden_wme?(_1) }.each { y << _1 } end end
find_own_wme(wme)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 207 def find_own_wme(wme) has_own_wme?(wme) ? wme : nil end
find_parents_wme(wme)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 215 def find_parents_wme(wme) return unless parent parent_wme = parent.find(wme) parent_wme unless hidden_wme?(parent_wme) end
find_wme(wme)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 203 def find_wme(wme) find_own_wme(wme) || find_parents_wme(wme) end
has_own_wme?(wme)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 211 def has_own_wme?(wme) wmes.include?(wme) end
hide_token(token)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 481 def hide_token(token) hidden_parent_tokens.add(token.object_id) end
own_generated?(wme)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 199 def own_generated?(wme) generator_tracker.for_wme(wme).any? end
own_manual?(wme)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 195 def own_manual?(wme) wme_manual.key?(wme) end
own_ncc_tokens_for(token)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 459 def own_ncc_tokens_for(token) ncc_tokens.key?(token) ? ncc_tokens[token] : [] end
own_node_tokens(beta)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 373 def own_node_tokens(beta) tokens[beta.object_id] end
parent_ncc_tokens_for(token)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 463 def parent_ncc_tokens_for(token) if parent parent.ncc_tokens_for(token).reject { |parent_token| hidden_ncc_tokens.key?(token) && hidden_ncc_tokens[token].key?(parent_token) } else [] end end
parent_neg_join_results_for(wme: nil, token: nil)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 430 def parent_neg_join_results_for(wme: nil, token: nil) if parent parent.neg_join_results_for(wme: wme, token: token).reject { neg_join_results.hidden?(_1) } else [] end end
parent_opt_join_results_for(wme: nil, token: nil)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 422 def parent_opt_join_results_for(wme: nil, token: nil) if parent parent.opt_join_results_for(wme: wme, token: token).reject { opt_join_results.hidden?(_1) } else [] end end
parents_node_tokens(beta)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 377 def parents_node_tokens(beta) if parent parent.node_tokens(beta).reject { hidden_token?(_1) } else [] end end
remove_wme(wme, generator: nil)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 272 def remove_wme(wme, generator: nil) # p remove_wme: { wme:, generator: !!generator } if find_own_wme(wme) wme_manual.delete(wme) if generator.nil? # no remaining reasons to keep this WME around if !own_generated?(wme) && !own_manual?(wme) wmes.delete(wme) indexes[1..6].each { _1.remove(wme) } end neg_join_results.remove_wme(wme) opt_join_results.remove_wme(wme) end # did we also have an unshadowed parent version? return unless find_parents_wme(wme) # must be parents' then if generator.nil? wme_manual.delete(wme) # if still manual, it must be from the parent hidden_parent_wme_manual[wme] = true if manual?(wme) end if !manual?(wme) && !generated?(wme) hidden_parent_wmes[wme] = true end end
run_queue()
click to toggle source
# File lib/wongi-engine/overlay.rb, line 100 def run_queue until queue.empty? operation, wme, options = queue.shift case operation when :assert existing_wme = find_ignoring_hidden(wme) wme = existing_wme || wme visible = !find(wme).nil? add_wme(wme, **options) rete.real_assert(wme) unless visible when :retract wme = find_ignoring_hidden(wme) if wme # it's perhaps better to return quietly, because complicated cascades may delete a WME while we're going through the queue visible = !find(wme).nil? remove_wme(wme, **options) rete.real_retract(wme) if visible end end end end
unhide_token(token)
click to toggle source
# File lib/wongi-engine/overlay.rb, line 485 def unhide_token(token) hidden_parent_tokens.delete(token.object_id) end