Class: Wongi::Engine::Compiler

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#alpha_deafObject

Returns the value of attribute alpha_deaf

Returns:

  • (Object)

    the current value of alpha_deaf



2
3
4
# File 'lib/wongi-engine/compiler.rb', line 2

def alpha_deaf
  @alpha_deaf
end

#conditionsObject

Returns the value of attribute conditions

Returns:

  • (Object)

    the current value of conditions



2
3
4
# File 'lib/wongi-engine/compiler.rb', line 2

def conditions
  @conditions
end

#nodeObject

Returns the value of attribute node

Returns:

  • (Object)

    the current value of node



2
3
4
# File 'lib/wongi-engine/compiler.rb', line 2

def node
  @node
end

#parametersObject

Returns the value of attribute parameters

Returns:

  • (Object)

    the current value of parameters



2
3
4
# File 'lib/wongi-engine/compiler.rb', line 2

def parameters
  @parameters
end

#reteObject

Returns the value of attribute rete

Returns:

  • (Object)

    the current value of rete



2
3
4
# File 'lib/wongi-engine/compiler.rb', line 2

def rete
  @rete
end

Instance Method Details

#assignment_node(variable, body) ⇒ Object



43
44
45
46
47
# File 'lib/wongi-engine/compiler.rb', line 43

def assignment_node(variable, body)
  beta_memory
  self.node = AssignmentNode.new(self.node, variable, body).tap &:refresh
  declare(variable)
end

#beta_memoryObject

TODO: should the following be the responsibility of Compiler or of each individual DSL clause?



32
33
34
35
36
37
38
39
40
41
# File 'lib/wongi-engine/compiler.rb', line 32

def beta_memory
  return if node.is_a?(BetaMemory)
  self.node = if existing = node.children.find { |n| n.is_a?(BetaMemory) }
    existing
  else
    BetaMemory.new(node).tap do |memory|
      memory.refresh
    end
  end
end

#compileObject



4
5
6
7
8
# File 'lib/wongi-engine/compiler.rb', line 4

def compile
  conditions.inject(self) do |context, condition|
    condition.compile context
  end.node
end

#declare(v) ⇒ Object



14
15
16
17
18
# File 'lib/wongi-engine/compiler.rb', line 14

def declare(v)
  unless declared_variables.include?(v)
    declared_variables << v
  end
end

#declared_variablesObject



20
21
22
# File 'lib/wongi-engine/compiler.rb', line 20

def declared_variables
  @declared_variables ||= []
end

#declares_variable?(v) ⇒ Boolean

Returns:

  • (Boolean)


10
11
12
# File 'lib/wongi-engine/compiler.rb', line 10

def declares_variable?(v)
  parameters.include?(v) || declared_variables.include?(v)
end

#dupObject



24
25
26
27
28
# File 'lib/wongi-engine/compiler.rb', line 24

def dup
  Compiler.new(rete, node, conditions, parameters, alpha_deaf).tap do |compiler|
    declared_variables.each { |v| compiler.declare(v) }
  end
end

#filter_node(filter) ⇒ Object



110
111
112
113
# File 'lib/wongi-engine/compiler.rb', line 110

def filter_node(filter)
  beta_memory
  self.node = FilterNode.new(node, filter)
end

#join_node(condition, tests, assignment) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/wongi-engine/compiler.rb', line 49

def join_node(condition, tests, assignment)
  alpha = rete.compile_alpha(condition)
  beta_memory
  self.node = if existing = node.children.find { |n| n.is_a?(JoinNode) && n.equivalent?(alpha, tests, assignment) }
    existing
  else
    JoinNode.new(node, tests, assignment).tap do |join|
      join.alpha = alpha
      alpha.betas << join unless alpha_deaf
    end
  end
end

#ncc_node(subrule, alpha_deaf) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/wongi-engine/compiler.rb', line 90

def ncc_node(subrule, alpha_deaf)
  beta_memory
  subcompiler = Compiler.new(rete, node, subrule.conditions, parameters, alpha_deaf)
  declared_variables.each { |v| subcompiler.declare(v) }
  bottom = subcompiler.compile
  if existing = node.children.find { |n| n.kind_of?( NccNode ) and n.partner.parent == bottom }
    self.node = existing
    return
  end
  ncc = NccNode.new node
  partner = NccPartner.new subcompiler.tap(&:beta_memory).node
  ncc.partner = partner
  partner.ncc = ncc
  partner.divergent = node
  #    partner.conjuncts = condition.children.size
  ncc.refresh
  partner.refresh
  self.node = ncc
end

#neg_node(condition, tests, unsafe) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/wongi-engine/compiler.rb', line 62

def neg_node(condition, tests, unsafe)
  alpha = rete.compile_alpha(condition)
  self.node = NegNode.new(node, tests, alpha, unsafe).tap do |node|
    alpha.betas << node unless alpha_deaf
    node.refresh
  end
end

#opt_node(condition, tests, assignment) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/wongi-engine/compiler.rb', line 70

def opt_node(condition, tests, assignment)
  alpha = rete.compile_alpha(condition)
  beta_memory
  self.node = OptionalNode.new(node, alpha, tests, assignment).tap do |node|
    alpha.betas << node unless alpha_deaf
  end
end

#or_node(variants) ⇒ Object



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

def or_node(variants)
  beta_memory
  branches = variants.map do |variant|
    subcompiler = Compiler.new(rete, node, variant.conditions, parameters, false)
    declared_variables.each { |v| subcompiler.declare(v) }
    subcompiler.compile
    subcompiler.declared_variables.each { |v| declare(v) }
    subcompiler.node
  end
  self.node = OrNode.new(branches).tap &:refresh
end