wongi-engine 0.3.9 → 0.4.0.pre.alpha1
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.
- checksums.yaml +4 -4
 - data/.github/workflows/test.yml +2 -2
 - data/.gitignore +2 -0
 - data/README.md +12 -12
 - data/lib/wongi-engine/alpha_index.rb +58 -0
 - data/lib/wongi-engine/alpha_memory.rb +2 -24
 - data/lib/wongi-engine/beta/aggregate_node.rb +16 -15
 - data/lib/wongi-engine/beta/assignment_node.rb +7 -2
 - data/lib/wongi-engine/beta/beta_node.rb +27 -23
 - data/lib/wongi-engine/beta/filter_node.rb +8 -13
 - data/lib/wongi-engine/beta/join_node.rb +15 -28
 - data/lib/wongi-engine/beta/ncc_node.rb +14 -26
 - data/lib/wongi-engine/beta/ncc_partner.rb +18 -18
 - data/lib/wongi-engine/beta/neg_node.rb +23 -55
 - data/lib/wongi-engine/beta/optional_node.rb +24 -48
 - data/lib/wongi-engine/beta/or_node.rb +24 -1
 - data/lib/wongi-engine/beta/production_node.rb +9 -3
 - data/lib/wongi-engine/beta/root_node.rb +47 -0
 - data/lib/wongi-engine/beta.rb +1 -1
 - data/lib/wongi-engine/compiler.rb +6 -34
 - data/lib/wongi-engine/dsl/action/{base.rb → base_action.rb} +5 -1
 - data/lib/wongi-engine/dsl/action/error_generator.rb +1 -1
 - data/lib/wongi-engine/dsl/action/simple_action.rb +1 -1
 - data/lib/wongi-engine/dsl/action/simple_collector.rb +1 -1
 - data/lib/wongi-engine/dsl/action/statement_generator.rb +21 -22
 - data/lib/wongi-engine/dsl/action/trace_action.rb +1 -1
 - data/lib/wongi-engine/dsl/clause/fact.rb +2 -6
 - data/lib/wongi-engine/dsl.rb +1 -25
 - data/lib/wongi-engine/graph.rb +1 -1
 - data/lib/wongi-engine/network/debug.rb +2 -10
 - data/lib/wongi-engine/network.rb +44 -105
 - data/lib/wongi-engine/overlay.rb +589 -0
 - data/lib/wongi-engine/template.rb +22 -2
 - data/lib/wongi-engine/token.rb +10 -26
 - data/lib/wongi-engine/token_assignment.rb +15 -0
 - data/lib/wongi-engine/version.rb +1 -1
 - data/lib/wongi-engine/wme.rb +10 -39
 - data/lib/wongi-engine.rb +3 -1
 - data/spec/alpha_index_spec.rb +78 -0
 - data/spec/bug_specs/issue_4_spec.rb +11 -11
 - data/spec/high_level_spec.rb +8 -101
 - data/spec/network_spec.rb +8 -6
 - data/spec/overlay_spec.rb +161 -3
 - data/spec/rule_specs/any_rule_spec.rb +39 -0
 - data/spec/rule_specs/assign_spec.rb +1 -1
 - data/spec/rule_specs/maybe_rule_spec.rb +58 -1
 - data/spec/rule_specs/ncc_spec.rb +78 -19
 - data/spec/rule_specs/negative_rule_spec.rb +12 -14
 - data/spec/spec_helper.rb +4 -0
 - data/spec/wme_spec.rb +0 -32
 - metadata +11 -9
 - data/lib/wongi-engine/beta/beta_memory.rb +0 -60
 - data/lib/wongi-engine/data_overlay.rb +0 -149
 - data/spec/rule_specs/or_rule_spec.rb +0 -40
 
| 
         @@ -1,15 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Wongi
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Engine
         
     | 
| 
       3 
     | 
    
         
            -
                NegJoinResult = Struct.new :token, :wme 
     | 
| 
       4 
     | 
    
         
            -
                  def unlink
         
     | 
| 
       5 
     | 
    
         
            -
                    wme.neg_join_results.delete self
         
     | 
| 
       6 
     | 
    
         
            -
                    token.neg_join_results.delete self
         
     | 
| 
       7 
     | 
    
         
            -
                  end
         
     | 
| 
       8 
     | 
    
         
            -
                end
         
     | 
| 
      
 3 
     | 
    
         
            +
                NegJoinResult = Struct.new :token, :wme
         
     | 
| 
       9 
4 
     | 
    
         | 
| 
       10 
5 
     | 
    
         
             
                class NegNode < BetaNode
         
     | 
| 
       11 
     | 
    
         
            -
                  include TokenContainer
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
6 
     | 
    
         
             
                  attr_reader :alpha, :tests
         
     | 
| 
       14 
7 
     | 
    
         | 
| 
       15 
8 
     | 
    
         
             
                  def initialize(parent, tests, alpha, unsafe)
         
     | 
| 
         @@ -19,79 +12,60 @@ module Wongi 
     | 
|
| 
       19 
12 
     | 
    
         
             
                    @unsafe = unsafe
         
     | 
| 
       20 
13 
     | 
    
         
             
                  end
         
     | 
| 
       21 
14 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                  def alpha_activate(wme)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def alpha_activate(wme, children: self.children)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    # p alpha_activate: {class: self.class, object_id:, wme:}
         
     | 
| 
       23 
17 
     | 
    
         
             
                    tokens.each do |token|
         
     | 
| 
       24 
18 
     | 
    
         
             
                      next unless matches?(token, wme) && (@unsafe || !token.generated?(wme)) # feedback loop protection
         
     | 
| 
       25 
19 
     | 
    
         | 
| 
       26 
20 
     | 
    
         
             
                      # order matters for proper invalidation
         
     | 
| 
       27 
     | 
    
         
            -
                       
     | 
| 
       28 
     | 
    
         
            -
                       
     | 
| 
       29 
     | 
    
         
            -
                      children.each do |child|
         
     | 
| 
       30 
     | 
    
         
            -
                        child.tokens.each do |t|
         
     | 
| 
       31 
     | 
    
         
            -
                          if t.parent == token
         
     | 
| 
       32 
     | 
    
         
            -
                            child.beta_deactivate t
         
     | 
| 
       33 
     | 
    
         
            -
                            # token.destroy
         
     | 
| 
       34 
     | 
    
         
            -
                          end
         
     | 
| 
       35 
     | 
    
         
            -
                        end
         
     | 
| 
       36 
     | 
    
         
            -
                      end
         
     | 
| 
      
 21 
     | 
    
         
            +
                      overlay.add_neg_join_result(NegJoinResult.new(token, wme))
         
     | 
| 
      
 22 
     | 
    
         
            +
                      beta_deactivate_children(token: token, children: children)
         
     | 
| 
       37 
23 
     | 
    
         
             
                    end
         
     | 
| 
       38 
24 
     | 
    
         
             
                  end
         
     | 
| 
       39 
25 
     | 
    
         | 
| 
       40 
26 
     | 
    
         
             
                  def alpha_deactivate(wme)
         
     | 
| 
       41 
     | 
    
         
            -
                     
     | 
| 
      
 27 
     | 
    
         
            +
                    # p alpha_deactivate: {class: self.class, object_id:, wme:}
         
     | 
| 
      
 28 
     | 
    
         
            +
                    overlay.neg_join_results_for(wme: wme).each do |njr|
         
     | 
| 
       42 
29 
     | 
    
         
             
                      tokens.each do |token|
         
     | 
| 
       43 
30 
     | 
    
         
             
                        next unless token == njr.token
         
     | 
| 
       44 
31 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                        njr 
     | 
| 
       46 
     | 
    
         
            -
                        next unless token. 
     | 
| 
      
 32 
     | 
    
         
            +
                        overlay.remove_neg_join_result(njr)
         
     | 
| 
      
 33 
     | 
    
         
            +
                        next unless overlay.neg_join_results_for(token: token).empty?
         
     | 
| 
       47 
34 
     | 
    
         | 
| 
       48 
35 
     | 
    
         
             
                        children.each do |child|
         
     | 
| 
       49 
     | 
    
         
            -
                          child.beta_activate 
     | 
| 
      
 36 
     | 
    
         
            +
                          child.beta_activate(Token.new(child, token, nil))
         
     | 
| 
       50 
37 
     | 
    
         
             
                        end
         
     | 
| 
       51 
38 
     | 
    
         
             
                      end
         
     | 
| 
       52 
39 
     | 
    
         
             
                    end
         
     | 
| 
       53 
40 
     | 
    
         
             
                  end
         
     | 
| 
       54 
41 
     | 
    
         | 
| 
       55 
42 
     | 
    
         
             
                  def beta_activate(token)
         
     | 
| 
       56 
     | 
    
         
            -
                     
     | 
| 
      
 43 
     | 
    
         
            +
                    # p beta_activate: {class: self.class, object_id:, token:}
         
     | 
| 
      
 44 
     | 
    
         
            +
                    return if tokens.find { |t| t.duplicate? token }
         
     | 
| 
       57 
45 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
                     
     | 
| 
       59 
     | 
    
         
            -
                    alpha. 
     | 
| 
       60 
     | 
    
         
            -
                       
     | 
| 
      
 46 
     | 
    
         
            +
                    overlay.add_token(token)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    select_wmes(alpha.template).each do |wme|
         
     | 
| 
      
 48 
     | 
    
         
            +
                      overlay.add_neg_join_result(NegJoinResult.new(token, wme)) if matches?(token, wme)
         
     | 
| 
       61 
49 
     | 
    
         
             
                    end
         
     | 
| 
       62 
     | 
    
         
            -
                    return  
     | 
| 
      
 50 
     | 
    
         
            +
                    return if overlay.neg_join_results_for(token: token).any?
         
     | 
| 
       63 
51 
     | 
    
         | 
| 
       64 
52 
     | 
    
         
             
                    children.each do |child|
         
     | 
| 
       65 
     | 
    
         
            -
                      child.beta_activate 
     | 
| 
      
 53 
     | 
    
         
            +
                      child.beta_activate(Token.new(child, token, nil, {}))
         
     | 
| 
       66 
54 
     | 
    
         
             
                    end
         
     | 
| 
       67 
55 
     | 
    
         
             
                  end
         
     | 
| 
       68 
56 
     | 
    
         | 
| 
       69 
57 
     | 
    
         
             
                  def beta_deactivate(token)
         
     | 
| 
       70 
     | 
    
         
            -
                     
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                     
     | 
| 
       73 
     | 
    
         
            -
                    token.deleted!
         
     | 
| 
       74 
     | 
    
         
            -
                    if token.parent
         
     | 
| 
       75 
     | 
    
         
            -
                      token.parent.children.delete token # should this go into Token#destroy?
         
     | 
| 
       76 
     | 
    
         
            -
                    end
         
     | 
| 
       77 
     | 
    
         
            -
                    token.neg_join_results.each(&:unlink)
         
     | 
| 
       78 
     | 
    
         
            -
                    children.each do |child|
         
     | 
| 
       79 
     | 
    
         
            -
                      child.tokens.each do |t|
         
     | 
| 
       80 
     | 
    
         
            -
                        if t.parent == token
         
     | 
| 
       81 
     | 
    
         
            -
                          child.beta_deactivate t
         
     | 
| 
       82 
     | 
    
         
            -
                          # token.destroy
         
     | 
| 
       83 
     | 
    
         
            -
                        end
         
     | 
| 
       84 
     | 
    
         
            -
                      end
         
     | 
| 
       85 
     | 
    
         
            -
                    end
         
     | 
| 
       86 
     | 
    
         
            -
                    token
         
     | 
| 
      
 58 
     | 
    
         
            +
                    # p beta_deactivate: {class: self.class, object_id:, token:}
         
     | 
| 
      
 59 
     | 
    
         
            +
                    overlay.remove_token(token)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    beta_deactivate_children(token: token)
         
     | 
| 
       87 
61 
     | 
    
         
             
                  end
         
     | 
| 
       88 
62 
     | 
    
         | 
| 
       89 
63 
     | 
    
         
             
                  def refresh_child(child)
         
     | 
| 
       90 
64 
     | 
    
         
             
                    tokens.each do |token|
         
     | 
| 
       91 
     | 
    
         
            -
                      child.beta_activate 
     | 
| 
      
 65 
     | 
    
         
            +
                      child.beta_activate(Token.new(child, token, nil, {})) if overlay.neg_join_results_for(token: token).empty?
         
     | 
| 
       92 
66 
     | 
    
         
             
                    end
         
     | 
| 
       93 
     | 
    
         
            -
                    alpha. 
     | 
| 
       94 
     | 
    
         
            -
                      alpha_activate wme
         
     | 
| 
      
 67 
     | 
    
         
            +
                    select_wmes(alpha.template).each do |wme|
         
     | 
| 
      
 68 
     | 
    
         
            +
                      alpha_activate wme, children: [child]
         
     | 
| 
       95 
69 
     | 
    
         
             
                    end
         
     | 
| 
       96 
70 
     | 
    
         
             
                  end
         
     | 
| 
       97 
71 
     | 
    
         | 
| 
         @@ -104,12 +78,6 @@ module Wongi 
     | 
|
| 
       104 
78 
     | 
    
         
             
                    end
         
     | 
| 
       105 
79 
     | 
    
         
             
                    true
         
     | 
| 
       106 
80 
     | 
    
         
             
                  end
         
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
                  def make_join_result(token, wme)
         
     | 
| 
       109 
     | 
    
         
            -
                    njr = NegJoinResult.new token, wme, self
         
     | 
| 
       110 
     | 
    
         
            -
                    token.neg_join_results << njr
         
     | 
| 
       111 
     | 
    
         
            -
                    wme.neg_join_results << njr
         
     | 
| 
       112 
     | 
    
         
            -
                  end
         
     | 
| 
       113 
81 
     | 
    
         
             
                end
         
     | 
| 
       114 
82 
     | 
    
         
             
              end
         
     | 
| 
       115 
83 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,15 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Wongi
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Engine
         
     | 
| 
       3 
     | 
    
         
            -
                OptionalJoinResult = Struct.new :token, :wme 
     | 
| 
       4 
     | 
    
         
            -
                  def unlink
         
     | 
| 
       5 
     | 
    
         
            -
                    wme.opt_join_results.delete self
         
     | 
| 
       6 
     | 
    
         
            -
                    token.opt_join_results.delete self
         
     | 
| 
       7 
     | 
    
         
            -
                  end
         
     | 
| 
       8 
     | 
    
         
            -
                end
         
     | 
| 
      
 3 
     | 
    
         
            +
                OptionalJoinResult = Struct.new :token, :wme
         
     | 
| 
       9 
4 
     | 
    
         | 
| 
       10 
5 
     | 
    
         
             
                class OptionalNode < BetaNode
         
     | 
| 
       11 
     | 
    
         
            -
                  include TokenContainer
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
6 
     | 
    
         
             
                  attr_reader :alpha, :tests, :assignment_pattern
         
     | 
| 
       14 
7 
     | 
    
         | 
| 
       15 
8 
     | 
    
         
             
                  def initialize(parent, alpha, tests, assignments)
         
     | 
| 
         @@ -19,56 +12,51 @@ module Wongi 
     | 
|
| 
       19 
12 
     | 
    
         
             
                    @assignment_pattern = assignments
         
     | 
| 
       20 
13 
     | 
    
         
             
                  end
         
     | 
| 
       21 
14 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                  def  
     | 
| 
       23 
     | 
    
         
            -
                    jr = OptionalJoinResult.new token, wme
         
     | 
| 
       24 
     | 
    
         
            -
                    token.opt_join_results << jr
         
     | 
| 
       25 
     | 
    
         
            -
                    wme.opt_join_results << jr
         
     | 
| 
       26 
     | 
    
         
            -
                  end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                  def alpha_activate(wme)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def alpha_activate(wme, children: self.children)
         
     | 
| 
       29 
16 
     | 
    
         
             
                    assignments = collect_assignments(wme)
         
     | 
| 
       30 
17 
     | 
    
         
             
                    tokens.each do |token|
         
     | 
| 
       31 
18 
     | 
    
         
             
                      next unless matches? token, wme
         
     | 
| 
       32 
19 
     | 
    
         | 
| 
      
 20 
     | 
    
         
            +
                      optional = overlay.opt_join_results_for(token: token).empty?
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
       33 
22 
     | 
    
         
             
                      children.each do |child|
         
     | 
| 
       34 
     | 
    
         
            -
                        if  
     | 
| 
       35 
     | 
    
         
            -
                           
     | 
| 
      
 23 
     | 
    
         
            +
                        if optional
         
     | 
| 
      
 24 
     | 
    
         
            +
                          # we're going to change the optional state so the old ones need to be removed
         
     | 
| 
       36 
25 
     | 
    
         
             
                          child.tokens.each do |ct|
         
     | 
| 
       37 
26 
     | 
    
         
             
                            child.beta_deactivate(ct) if ct.parent == token
         
     | 
| 
       38 
27 
     | 
    
         
             
                          end
         
     | 
| 
       39 
28 
     | 
    
         
             
                        end
         
     | 
| 
       40 
29 
     | 
    
         
             
                        child.beta_activate Token.new(child, token, wme, assignments)
         
     | 
| 
       41 
30 
     | 
    
         
             
                      end
         
     | 
| 
       42 
     | 
    
         
            -
                       
     | 
| 
      
 31 
     | 
    
         
            +
                      overlay.add_opt_join_result(OptionalJoinResult.new(token, wme))
         
     | 
| 
       43 
32 
     | 
    
         
             
                    end
         
     | 
| 
       44 
33 
     | 
    
         
             
                  end
         
     | 
| 
       45 
34 
     | 
    
         | 
| 
       46 
35 
     | 
    
         
             
                  def alpha_deactivate(wme)
         
     | 
| 
       47 
     | 
    
         
            -
                     
     | 
| 
      
 36 
     | 
    
         
            +
                    # p alpha_deactivate: {wme:}
         
     | 
| 
      
 37 
     | 
    
         
            +
                    overlay.opt_join_results_for(wme: wme).each do |ojr|
         
     | 
| 
       48 
38 
     | 
    
         
             
                      tokens.each do |token|
         
     | 
| 
       49 
39 
     | 
    
         
             
                        next unless token == ojr.token
         
     | 
| 
       50 
40 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                        ojr 
     | 
| 
       52 
     | 
    
         
            -
                        next unless token. 
     | 
| 
      
 41 
     | 
    
         
            +
                        overlay.remove_opt_join_result(ojr)
         
     | 
| 
      
 42 
     | 
    
         
            +
                        next unless overlay.opt_join_results_for(token: token).empty?
         
     | 
| 
       53 
43 
     | 
    
         | 
| 
       54 
44 
     | 
    
         
             
                        children.each do |child|
         
     | 
| 
       55 
45 
     | 
    
         
             
                          child.tokens.each do |ct|
         
     | 
| 
       56 
46 
     | 
    
         
             
                            child.beta_deactivate(ct) if ct.parent == token
         
     | 
| 
       57 
47 
     | 
    
         
             
                          end
         
     | 
| 
       58 
     | 
    
         
            -
                          token.optional!
         
     | 
| 
       59 
48 
     | 
    
         
             
                          child.beta_activate Token.new(child, token, nil, {})
         
     | 
| 
       60 
49 
     | 
    
         
             
                        end
         
     | 
| 
       61 
50 
     | 
    
         
             
                      end
         
     | 
| 
       62 
51 
     | 
    
         
             
                    end
         
     | 
| 
       63 
52 
     | 
    
         
             
                  end
         
     | 
| 
       64 
53 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
                  def beta_activate( 
     | 
| 
       66 
     | 
    
         
            -
                    return if tokens.find { | 
     | 
| 
      
 54 
     | 
    
         
            +
                  def beta_activate(token)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    return if tokens.find { |t| t.duplicate? token }
         
     | 
| 
       67 
56 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
                     
     | 
| 
       69 
     | 
    
         
            -
                    token.overlay.add_token(token, self)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    overlay.add_token(token)
         
     | 
| 
       70 
58 
     | 
    
         
             
                    match = false
         
     | 
| 
       71 
     | 
    
         
            -
                    alpha. 
     | 
| 
      
 59 
     | 
    
         
            +
                    select_wmes(alpha.template).each do |wme|
         
     | 
| 
       72 
60 
     | 
    
         
             
                      assignments = collect_assignments(wme)
         
     | 
| 
       73 
61 
     | 
    
         
             
                      next unless matches? token, wme
         
     | 
| 
       74 
62 
     | 
    
         | 
| 
         @@ -80,36 +68,24 @@ module Wongi 
     | 
|
| 
       80 
68 
     | 
    
         
             
                    end
         
     | 
| 
       81 
69 
     | 
    
         
             
                    return if match
         
     | 
| 
       82 
70 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
                    token.optional!
         
     | 
| 
       84 
71 
     | 
    
         
             
                    children.each do |child|
         
     | 
| 
       85 
72 
     | 
    
         
             
                      child.beta_activate Token.new(child, token, nil, {})
         
     | 
| 
       86 
73 
     | 
    
         
             
                    end
         
     | 
| 
       87 
74 
     | 
    
         
             
                  end
         
     | 
| 
       88 
75 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
                  def beta_deactivate( 
     | 
| 
       90 
     | 
    
         
            -
                     
     | 
| 
       91 
     | 
    
         
            -
                     
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
                    token.overlay.remove_token(token, self)
         
     | 
| 
       94 
     | 
    
         
            -
                    token.deleted!
         
     | 
| 
       95 
     | 
    
         
            -
                    token.parent.children.delete token if token.parent
         
     | 
| 
       96 
     | 
    
         
            -
                    token.opt_join_results.each(&:unlink)
         
     | 
| 
       97 
     | 
    
         
            -
                    children.each do |child|
         
     | 
| 
       98 
     | 
    
         
            -
                      child.tokens.each do |child_token|
         
     | 
| 
       99 
     | 
    
         
            -
                        child.beta_deactivate(child_token) if child_token.parent == token
         
     | 
| 
       100 
     | 
    
         
            -
                      end
         
     | 
| 
       101 
     | 
    
         
            -
                    end
         
     | 
| 
       102 
     | 
    
         
            -
                    token
         
     | 
| 
      
 76 
     | 
    
         
            +
                  def beta_deactivate(token)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    # p beta_deactivate: {class: self.class, object_id:, token:}
         
     | 
| 
      
 78 
     | 
    
         
            +
                    overlay.remove_token(token)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    beta_deactivate_children(token: token)
         
     | 
| 
       103 
80 
     | 
    
         
             
                  end
         
     | 
| 
       104 
81 
     | 
    
         | 
| 
       105 
82 
     | 
    
         
             
                  def refresh_child(child)
         
     | 
| 
       106 
     | 
    
         
            -
                     
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
                     
     | 
| 
       109 
     | 
    
         
            -
                    alpha. 
     | 
| 
       110 
     | 
    
         
            -
                      alpha_activate wme
         
     | 
| 
      
 83 
     | 
    
         
            +
                    tokens.each do |token|
         
     | 
| 
      
 84 
     | 
    
         
            +
                      child.beta_activate(Token.new(child, token, nil, {}))
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                    select_wmes(alpha.template).each do |wme|
         
     | 
| 
      
 87 
     | 
    
         
            +
                      alpha_activate wme, children: [child]
         
     | 
| 
       111 
88 
     | 
    
         
             
                    end
         
     | 
| 
       112 
     | 
    
         
            -
                    self.children = tmp
         
     | 
| 
       113 
89 
     | 
    
         
             
                  end
         
     | 
| 
       114 
90 
     | 
    
         | 
| 
       115 
91 
     | 
    
         
             
                  private
         
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Wongi
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Engine
         
     | 
| 
       3 
     | 
    
         
            -
                class OrNode <  
     | 
| 
      
 3 
     | 
    
         
            +
                class OrNode < BetaNode
         
     | 
| 
       4 
4 
     | 
    
         
             
                  attr_reader :parents, :rete
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
                  def initialize(parents)
         
     | 
| 
         @@ -24,11 +24,34 @@ module Wongi 
     | 
|
| 
       24 
24 
     | 
    
         
             
                    parents.map(&:depth).max + 1
         
     | 
| 
       25 
25 
     | 
    
         
             
                  end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
      
 27 
     | 
    
         
            +
                  def beta_activate(token)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    # p beta_activate: {class: self.class, object_id:, token:}
         
     | 
| 
      
 29 
     | 
    
         
            +
                    return if tokens.find { token.duplicate?(_1) }
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    overlay.add_token(token)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    children.each do |child|
         
     | 
| 
      
 34 
     | 
    
         
            +
                      child.beta_activate(Token.new(child, token, nil))
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def beta_deactivate(token)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    # p beta_deactivate: {class: self.class, object_id:, token:}
         
     | 
| 
      
 40 
     | 
    
         
            +
                    overlay.remove_token(token)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    beta_deactivate_children(token: token)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
       27 
44 
     | 
    
         
             
                  def refresh
         
     | 
| 
       28 
45 
     | 
    
         
             
                    parents.each do |parent|
         
     | 
| 
       29 
46 
     | 
    
         
             
                      parent.refresh_child self
         
     | 
| 
       30 
47 
     | 
    
         
             
                    end
         
     | 
| 
       31 
48 
     | 
    
         
             
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  def refresh_child(child)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    tokens.each do |token|
         
     | 
| 
      
 52 
     | 
    
         
            +
                      child.beta_activate(Token.new(child, token, nil))
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
       32 
55 
     | 
    
         
             
                end
         
     | 
| 
       33 
56 
     | 
    
         
             
              end
         
     | 
| 
       34 
57 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Wongi
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Engine
         
     | 
| 
       3 
     | 
    
         
            -
                class ProductionNode <  
     | 
| 
      
 3 
     | 
    
         
            +
                class ProductionNode < BetaNode
         
     | 
| 
       4 
4 
     | 
    
         
             
                  attr_accessor :tracer, :compilation_context
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
                  def initialize(parent, actions)
         
     | 
| 
         @@ -9,7 +9,10 @@ module Wongi 
     | 
|
| 
       9 
9 
     | 
    
         
             
                  end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
                  def beta_activate(token)
         
     | 
| 
       12 
     | 
    
         
            -
                     
     | 
| 
      
 12 
     | 
    
         
            +
                    # p beta_activate: {class: self.class, object_id:, token:}
         
     | 
| 
      
 13 
     | 
    
         
            +
                    return if tokens.find { |t| t.duplicate? token }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    overlay.add_token(token)
         
     | 
| 
       13 
16 
     | 
    
         | 
| 
       14 
17 
     | 
    
         
             
                    @actions.each do |action|
         
     | 
| 
       15 
18 
     | 
    
         
             
                      action.execute token if action.respond_to? :execute
         
     | 
| 
         @@ -17,7 +20,10 @@ module Wongi 
     | 
|
| 
       17 
20 
     | 
    
         
             
                  end
         
     | 
| 
       18 
21 
     | 
    
         | 
| 
       19 
22 
     | 
    
         
             
                  def beta_deactivate(token)
         
     | 
| 
       20 
     | 
    
         
            -
                     
     | 
| 
      
 23 
     | 
    
         
            +
                    # p beta_deactivate: {class: self.class, object_id:, token:}
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    # we should remove before the actions because otherwise the longer rule chains (like the infinite neg-gen cycle) don't work as expected
         
     | 
| 
      
 26 
     | 
    
         
            +
                    overlay.remove_token(token)
         
     | 
| 
       21 
27 
     | 
    
         | 
| 
       22 
28 
     | 
    
         
             
                    @actions.each do |action|
         
     | 
| 
       23 
29 
     | 
    
         
             
                      action.deexecute token if action.respond_to? :deexecute
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Wongi::Engine
         
     | 
| 
      
 2 
     | 
    
         
            +
              class RootNode < BetaNode
         
     | 
| 
      
 3 
     | 
    
         
            +
                def seed(assignments = {})
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @seed = assignments
         
     | 
| 
      
 5 
     | 
    
         
            +
                  t = Token.new(self, nil, nil, assignments)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  rete.default_overlay.add_token(t)
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def subst(valuations)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  beta_deactivate(tokens.first)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  token = Token.new(self, nil, nil, @seed)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  valuations.each { |variable, value| token.subst variable, value }
         
     | 
| 
      
 13 
     | 
    
         
            +
                  beta_activate(token)
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def beta_activate(token)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # existing = tokens.find { |et| et.duplicate? token }
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # return if existing # TODO: really?
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  overlay.add_token(token)
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  children.each do |child|
         
     | 
| 
      
 23 
     | 
    
         
            +
                    child.beta_activate(Token.new(child, token, nil))
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def beta_deactivate(token)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  return nil unless tokens.find token
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  overlay.remove_token(token)
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  children.each do |child|
         
     | 
| 
      
 35 
     | 
    
         
            +
                    child.tokens.select { _1.parent == token }.each { child.beta_deactivate(_1) }
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def refresh_child(child)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  tokens.each do |token|
         
     | 
| 
      
 43 
     | 
    
         
            +
                    child.beta_activate(Token.new(child, token, nil))
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/wongi-engine/beta.rb
    CHANGED
    
    
| 
         @@ -24,37 +24,13 @@ module Wongi::Engine 
     | 
|
| 
       24 
24 
     | 
    
         
             
                  end
         
     | 
| 
       25 
25 
     | 
    
         
             
                end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                # TODO: should the following be the responsibility of Compiler or of each individual DSL clause?
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                def beta_memory
         
     | 
| 
       30 
     | 
    
         
            -
                  return if node.is_a?(BetaMemory)
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                  self.node = if (existing = node.children.find { |n| n.is_a?(BetaMemory) })
         
     | 
| 
       33 
     | 
    
         
            -
                                existing
         
     | 
| 
       34 
     | 
    
         
            -
                              else
         
     | 
| 
       35 
     | 
    
         
            -
                                BetaMemory.new(node).tap(&:refresh)
         
     | 
| 
       36 
     | 
    
         
            -
                              end
         
     | 
| 
       37 
     | 
    
         
            -
                end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                def singleton_beta_memory
         
     | 
| 
       40 
     | 
    
         
            -
                  return if node.is_a?(SingletonBetaMemory)
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                  self.node = if (existing = node.children.find { |n| n.is_a?(SingletonBetaMemory) })
         
     | 
| 
       43 
     | 
    
         
            -
                                existing
         
     | 
| 
       44 
     | 
    
         
            -
                              else
         
     | 
| 
       45 
     | 
    
         
            -
                                SingletonBetaMemory.new(node).tap(&:refresh)
         
     | 
| 
       46 
     | 
    
         
            -
                              end
         
     | 
| 
       47 
     | 
    
         
            -
                end
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
27 
     | 
    
         
             
                def assignment_node(variable, body)
         
     | 
| 
       50 
     | 
    
         
            -
                  beta_memory
         
     | 
| 
       51 
28 
     | 
    
         
             
                  self.node = AssignmentNode.new(node, variable, body).tap(&:refresh)
         
     | 
| 
       52 
29 
     | 
    
         
             
                  declare(variable)
         
     | 
| 
       53 
30 
     | 
    
         
             
                end
         
     | 
| 
       54 
31 
     | 
    
         | 
| 
       55 
32 
     | 
    
         
             
                def join_node(condition, tests, assignment)
         
     | 
| 
       56 
33 
     | 
    
         
             
                  alpha = rete.compile_alpha(condition)
         
     | 
| 
       57 
     | 
    
         
            -
                  beta_memory
         
     | 
| 
       58 
34 
     | 
    
         
             
                  self.node = if (existing = node.children.find { |n| n.is_a?(JoinNode) && n.equivalent?(alpha, tests, assignment) && !n.children.map(&:class).include?(Wongi::Engine::OrNode) })
         
     | 
| 
       59 
35 
     | 
    
         
             
                                existing
         
     | 
| 
       60 
36 
     | 
    
         
             
                              else
         
     | 
| 
         @@ -63,6 +39,7 @@ module Wongi::Engine 
     | 
|
| 
       63 
39 
     | 
    
         
             
                                  alpha.betas << join unless alpha_deaf
         
     | 
| 
       64 
40 
     | 
    
         
             
                                end
         
     | 
| 
       65 
41 
     | 
    
         
             
                              end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  node.tap(&:refresh)
         
     | 
| 
       66 
43 
     | 
    
         
             
                end
         
     | 
| 
       67 
44 
     | 
    
         | 
| 
       68 
45 
     | 
    
         
             
                def neg_node(condition, tests, unsafe)
         
     | 
| 
         @@ -75,24 +52,21 @@ module Wongi::Engine 
     | 
|
| 
       75 
52 
     | 
    
         | 
| 
       76 
53 
     | 
    
         
             
                def opt_node(condition, tests, assignment)
         
     | 
| 
       77 
54 
     | 
    
         
             
                  alpha = rete.compile_alpha(condition)
         
     | 
| 
       78 
     | 
    
         
            -
                  beta_memory
         
     | 
| 
       79 
55 
     | 
    
         
             
                  self.node = OptionalNode.new(node, alpha, tests, assignment).tap do |node|
         
     | 
| 
       80 
56 
     | 
    
         
             
                    alpha.betas << node unless alpha_deaf
         
     | 
| 
      
 57 
     | 
    
         
            +
                    node.refresh
         
     | 
| 
       81 
58 
     | 
    
         
             
                  end
         
     | 
| 
       82 
59 
     | 
    
         
             
                end
         
     | 
| 
       83 
60 
     | 
    
         | 
| 
       84 
61 
     | 
    
         
             
                def aggregate_node(condition, tests, assignment, map, function, assign)
         
     | 
| 
       85 
62 
     | 
    
         
             
                  declare(assign)
         
     | 
| 
       86 
63 
     | 
    
         
             
                  alpha = rete.compile_alpha(condition)
         
     | 
| 
       87 
     | 
    
         
            -
                  beta_memory
         
     | 
| 
       88 
64 
     | 
    
         
             
                  self.node = AggregateNode.new(node, alpha, tests, assignment, map, function, assign).tap do |node|
         
     | 
| 
       89 
65 
     | 
    
         
             
                    alpha.betas << node unless alpha_deaf
         
     | 
| 
       90 
     | 
    
         
            -
                  end
         
     | 
| 
       91 
     | 
    
         
            -
                  beta_memory
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end.tap(&:refresh)
         
     | 
| 
       92 
67 
     | 
    
         
             
                end
         
     | 
| 
       93 
68 
     | 
    
         | 
| 
       94 
69 
     | 
    
         
             
                def or_node(variants)
         
     | 
| 
       95 
     | 
    
         
            -
                  beta_memory
         
     | 
| 
       96 
70 
     | 
    
         
             
                  subvariables = []
         
     | 
| 
       97 
71 
     | 
    
         
             
                  branches = variants.map do |variant|
         
     | 
| 
       98 
72 
     | 
    
         
             
                    subcompiler = Compiler.new(rete, node, variant.conditions, parameters, false)
         
     | 
| 
         @@ -110,7 +84,6 @@ module Wongi::Engine 
     | 
|
| 
       110 
84 
     | 
    
         
             
                end
         
     | 
| 
       111 
85 
     | 
    
         | 
| 
       112 
86 
     | 
    
         
             
                def ncc_node(subrule, alpha_deaf)
         
     | 
| 
       113 
     | 
    
         
            -
                  beta_memory
         
     | 
| 
       114 
87 
     | 
    
         
             
                  subcompiler = Compiler.new(rete, node, subrule.conditions, parameters, alpha_deaf)
         
     | 
| 
       115 
88 
     | 
    
         
             
                  declared_variables.each { |v| subcompiler.declare(v) }
         
     | 
| 
       116 
89 
     | 
    
         
             
                  bottom = subcompiler.compile
         
     | 
| 
         @@ -118,8 +91,8 @@ module Wongi::Engine 
     | 
|
| 
       118 
91 
     | 
    
         
             
                    self.node = existing
         
     | 
| 
       119 
92 
     | 
    
         
             
                    return
         
     | 
| 
       120 
93 
     | 
    
         
             
                  end
         
     | 
| 
       121 
     | 
    
         
            -
                  ncc = NccNode.new 
     | 
| 
       122 
     | 
    
         
            -
                  partner = NccPartner.new 
     | 
| 
      
 94 
     | 
    
         
            +
                  ncc = NccNode.new(node)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  partner = NccPartner.new(subcompiler.node)
         
     | 
| 
       123 
96 
     | 
    
         
             
                  ncc.partner = partner
         
     | 
| 
       124 
97 
     | 
    
         
             
                  partner.ncc = ncc
         
     | 
| 
       125 
98 
     | 
    
         
             
                  partner.divergent = node
         
     | 
| 
         @@ -130,8 +103,7 @@ module Wongi::Engine 
     | 
|
| 
       130 
103 
     | 
    
         
             
                end
         
     | 
| 
       131 
104 
     | 
    
         | 
| 
       132 
105 
     | 
    
         
             
                def filter_node(filter)
         
     | 
| 
       133 
     | 
    
         
            -
                   
     | 
| 
       134 
     | 
    
         
            -
                  self.node = FilterNode.new(node, filter)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  self.node = FilterNode.new(node, filter).tap(&:refresh)
         
     | 
| 
       135 
107 
     | 
    
         
             
                end
         
     | 
| 
       136 
108 
     | 
    
         
             
              end
         
     | 
| 
       137 
109 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,45 +1,44 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Wongi::Engine
         
     | 
| 
       2 
2 
     | 
    
         
             
              module DSL::Action
         
     | 
| 
       3 
     | 
    
         
            -
                class StatementGenerator <  
     | 
| 
      
 3 
     | 
    
         
            +
                class StatementGenerator < BaseAction
         
     | 
| 
      
 4 
     | 
    
         
            +
                  GeneratorOrigin = Struct.new(:token, :action)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  attr_reader :template
         
     | 
| 
      
 7 
     | 
    
         
            +
                  private :template
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
       4 
9 
     | 
    
         
             
                  def initialize(template)
         
     | 
| 
       5 
10 
     | 
    
         
             
                    super()
         
     | 
| 
       6 
11 
     | 
    
         
             
                    @template = template
         
     | 
| 
       7 
12 
     | 
    
         
             
                  end
         
     | 
| 
       8 
13 
     | 
    
         | 
| 
       9 
14 
     | 
    
         
             
                  def execute(token)
         
     | 
| 
       10 
     | 
    
         
            -
                     
     | 
| 
      
 15 
     | 
    
         
            +
                    # p execute: {token:}
         
     | 
| 
      
 16 
     | 
    
         
            +
                    subject, predicate, object = template.resolve!(token)
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    wme = WME.new(subject, predicate, object)
         
     | 
| 
       11 
19 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                     
     | 
| 
       13 
     | 
    
         
            -
                    wme = WME.new subject, predicate, object, rete
         
     | 
| 
       14 
     | 
    
         
            -
                    wme.manual = false
         
     | 
| 
       15 
     | 
    
         
            -
                    wme.overlay = token.overlay
         
     | 
| 
      
 20 
     | 
    
         
            +
                    origin = GeneratorOrigin.new(token, self)
         
     | 
| 
       16 
21 
     | 
    
         | 
| 
       17 
22 
     | 
    
         
             
                    production.tracer.trace(action: self, wme: wme) if production.tracer
         
     | 
| 
       18 
     | 
    
         
            -
                    if (existing =  
     | 
| 
       19 
     | 
    
         
            -
                      generated  
     | 
| 
       20 
     | 
    
         
            -
                       
     | 
| 
      
 23 
     | 
    
         
            +
                    if (existing = overlay.find(wme))
         
     | 
| 
      
 24 
     | 
    
         
            +
                      # do not mark purely manual tokens as generated, because a circular rule such as the symmetric friend generator this would cause both sides to become self-sustaining
         
     | 
| 
      
 25 
     | 
    
         
            +
                      # TODO: but this may have to be smarter, because there may be more indirect ways of creating such a situation
         
     | 
| 
      
 26 
     | 
    
         
            +
                      if overlay.generated?(wme)
         
     | 
| 
       21 
27 
     | 
    
         
             
                        token.generated_wmes << existing
         
     | 
| 
       22 
     | 
    
         
            -
                        existing 
     | 
| 
      
 28 
     | 
    
         
            +
                        overlay.assert(existing, generator: origin)
         
     | 
| 
       23 
29 
     | 
    
         
             
                      end
         
     | 
| 
       24 
30 
     | 
    
         
             
                    else
         
     | 
| 
       25 
31 
     | 
    
         
             
                      token.generated_wmes << wme
         
     | 
| 
       26 
     | 
    
         
            -
                      wme 
     | 
| 
       27 
     | 
    
         
            -
                      # this MUST be done after we link the wme and the token
         
     | 
| 
       28 
     | 
    
         
            -
                      # in order for neg rule invalidation to work
         
     | 
| 
       29 
     | 
    
         
            -
                      wme.overlay.assert wme
         
     | 
| 
      
 32 
     | 
    
         
            +
                      overlay.assert(wme, generator: origin)
         
     | 
| 
       30 
33 
     | 
    
         
             
                    end
         
     | 
| 
       31 
34 
     | 
    
         
             
                  end
         
     | 
| 
       32 
35 
     | 
    
         | 
| 
       33 
36 
     | 
    
         
             
                  def deexecute(token)
         
     | 
| 
       34 
     | 
    
         
            -
                     
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                    wmes_for_deletion = generated.each_with_object([]) do |wme, acc|
         
     | 
| 
       37 
     | 
    
         
            -
                      wme.generating_tokens.delete token
         
     | 
| 
       38 
     | 
    
         
            -
                      acc << wme if wme.generating_tokens.empty?
         
     | 
| 
       39 
     | 
    
         
            -
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
                    origin = GeneratorOrigin.new(token, self)
         
     | 
| 
       40 
38 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                     
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
                    generated = token.generated_wmes.select { overlay.generators(_1).include?(origin) }
         
     | 
| 
      
 40 
     | 
    
         
            +
                    generated.each do |wme|
         
     | 
| 
      
 41 
     | 
    
         
            +
                      overlay.retract wme, generator: origin
         
     | 
| 
       43 
42 
     | 
    
         
             
                    end
         
     | 
| 
       44 
43 
     | 
    
         
             
                  end
         
     | 
| 
       45 
44 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1,17 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Wongi::Engine
         
     | 
| 
       2 
2 
     | 
    
         
             
              module DSL::Clause
         
     | 
| 
       3 
     | 
    
         
            -
                Has = Struct.new(:subject, :predicate, :object 
     | 
| 
      
 3 
     | 
    
         
            +
                Has = Struct.new(:subject, :predicate, :object) do
         
     | 
| 
       4 
4 
     | 
    
         
             
                  include CoreExt
         
     | 
| 
       5 
5 
     | 
    
         
             
                  attr_predicate :debug
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                  def initialize(s, p, o, options = {})
         
     | 
| 
       8 
     | 
    
         
            -
                    time = options[:time] || 0
         
     | 
| 
       9 
8 
     | 
    
         
             
                    @unsafe = options[:unsafe] || false
         
     | 
| 
       10 
9 
     | 
    
         
             
                    debug! if options[:debug]
         
     | 
| 
       11 
     | 
    
         
            -
                     
     | 
| 
       12 
     | 
    
         
            -
                    raise "Cannot look into the future" if time.positive?
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                    super(s, p, o, time)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(s, p, o)
         
     | 
| 
       15 
11 
     | 
    
         
             
                  end
         
     | 
| 
       16 
12 
     | 
    
         | 
| 
       17 
13 
     | 
    
         
             
                  def compile(context)
         
     | 
    
        data/lib/wongi-engine/dsl.rb
    CHANGED
    
    | 
         @@ -36,7 +36,7 @@ require 'wongi-engine/dsl/clause/fact' 
     | 
|
| 
       36 
36 
     | 
    
         
             
            require 'wongi-engine/dsl/clause/aggregate'
         
     | 
| 
       37 
37 
     | 
    
         
             
            require 'wongi-engine/dsl/clause/assign'
         
     | 
| 
       38 
38 
     | 
    
         
             
            require 'wongi-engine/dsl/clause/gen'
         
     | 
| 
       39 
     | 
    
         
            -
            require 'wongi-engine/dsl/action/ 
     | 
| 
      
 39 
     | 
    
         
            +
            require 'wongi-engine/dsl/action/base_action'
         
     | 
| 
       40 
40 
     | 
    
         
             
            require 'wongi-engine/dsl/rule'
         
     | 
| 
       41 
41 
     | 
    
         
             
            require 'wongi-engine/dsl/ncc_subrule'
         
     | 
| 
       42 
42 
     | 
    
         
             
            require 'wongi-engine/dsl/any_rule'
         
     | 
| 
         @@ -110,30 +110,6 @@ module Wongi::Engine::DSL 
     | 
|
| 
       110 
110 
     | 
    
         
             
                clause :assign, :introduce, :let
         
     | 
| 
       111 
111 
     | 
    
         
             
                accept Clause::Assign
         
     | 
| 
       112 
112 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
                clause :asserted, :added
         
     | 
| 
       114 
     | 
    
         
            -
                body { |s, p, o|
         
     | 
| 
       115 
     | 
    
         
            -
                  has s, p, o, time: 0
         
     | 
| 
       116 
     | 
    
         
            -
                  missing s, p, o, time: -1
         
     | 
| 
       117 
     | 
    
         
            -
                }
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                clause :retracted, :removed
         
     | 
| 
       120 
     | 
    
         
            -
                body { |s, p, o|
         
     | 
| 
       121 
     | 
    
         
            -
                  has s, p, o, time: -1
         
     | 
| 
       122 
     | 
    
         
            -
                  missing s, p, o, time: 0
         
     | 
| 
       123 
     | 
    
         
            -
                }
         
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
                clause :kept, :still_has
         
     | 
| 
       126 
     | 
    
         
            -
                body { |s, p, o|
         
     | 
| 
       127 
     | 
    
         
            -
                  has s, p, o, time: -1
         
     | 
| 
       128 
     | 
    
         
            -
                  has s, p, o, time: 0
         
     | 
| 
       129 
     | 
    
         
            -
                }
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
                clause :kept_missing, :still_missing
         
     | 
| 
       132 
     | 
    
         
            -
                body { |s, p, o|
         
     | 
| 
       133 
     | 
    
         
            -
                  missing s, p, o, time: -1
         
     | 
| 
       134 
     | 
    
         
            -
                  missing s, p, o, time: 0
         
     | 
| 
       135 
     | 
    
         
            -
                }
         
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
113 
     | 
    
         
             
                clause :assuming
         
     | 
| 
       138 
114 
     | 
    
         
             
                accept Wongi::Engine::AssumingClause
         
     | 
| 
       139 
115 
     | 
    
         |