Class: Wallace::Koza::KozaTree
- Inherits:
-
Object
- Object
- Wallace::Koza::KozaTree
- Defined in:
- lib/modules/koza/koza_tree.rb
Overview
This class is used to represent Koza Trees, which in turn represent computer programs using Lisp-style S-expressions (program trees).
-
remove(n)
Instance Attribute Summary collapse
-
#depth ⇒ Object
readonly
Returns the value of attribute depth.
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
-
#root ⇒ Object
Returns the value of attribute root.
Class Method Summary collapse
-
.to_lambda(args, tree) ⇒ Object
Compiles a given Koza Tree into a Ruby lambda function.
Instance Method Summary collapse
-
#[](index) ⇒ Object
Returns a node at a given index in the tree.
-
#add(parent, child) ⇒ Object
Adds a node to the tree as the child of another node.
-
#calculate! ⇒ Object
(Re)calculates the list of nodes in the tree and their respective depths.
-
#clone ⇒ Object
Creates a clone of this tree (along with its nodes).
-
#eval(args) ⇒ Object
Evaluates the S-expression given by this tree.
-
#initialize(root) ⇒ KozaTree
constructor
Parameters: * root, the root node of this tree.
-
#replace(n1, n2) ⇒ Object
Replaces a subtree in the tree with another subtree.
-
#sample(opts = {}) ⇒ Object
Samples a node (or number of nodes) from the tree at random.
-
#size ⇒ Object
(also: #length)
Returns the number of nodes in the tree.
-
#to_lambda(args) ⇒ Object
Compiles this Koza Tree into a Ruby lambda function.
-
#to_ruby ⇒ Object
(also: #to_s)
Converts this tree into a Ruby program string.
Constructor Details
Instance Attribute Details
#depth ⇒ Object (readonly)
Returns the value of attribute depth.
7 8 9 |
# File 'lib/modules/koza/koza_tree.rb', line 7 def depth @depth end |
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
7 8 9 |
# File 'lib/modules/koza/koza_tree.rb', line 7 def nodes @nodes end |
#root ⇒ Object
Returns the value of attribute root.
7 8 9 |
# File 'lib/modules/koza/koza_tree.rb', line 7 def root @root end |
Class Method Details
.to_lambda(args, tree) ⇒ Object
Compiles a given Koza Tree into a Ruby lambda function.
Parameters:
-
args, an array of the arguments to the function.
-
tree, the tree to compile to a lambda function.
Returns: the compiled lambda function.
NOTE: Trying to call ‘eval’ in an object method causes huge problems! Totally different semantics.
144 145 146 |
# File 'lib/modules/koza/koza_tree.rb', line 144 def self.to_lambda(args, tree) eval("lambda { |#{args.join(',')}| #{tree.to_ruby} }") end |
Instance Method Details
#[](index) ⇒ Object
Returns a node at a given index in the tree.
33 34 35 |
# File 'lib/modules/koza/koza_tree.rb', line 33 def [](index) @nodes[index] end |
#add(parent, child) ⇒ Object
Adds a node to the tree as the child of another node.
Parameters:
-
parent, The node to use as the parent of the new node.
-
child, The node to add to the tree.
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/modules/koza/koza_tree.rb', line 78 def add(parent, child) # Could throw an exception if there is no room for the child. parent.children << child child.parent = parent child.depth = parent.depth + 1 @nodes << child @depth = child.depth if child.depth > @depth end |
#calculate! ⇒ Object
(Re)calculates the list of nodes in the tree and their respective depths.
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/modules/koza/koza_tree.rb', line 54 def calculate! queue = [@root] @nodes = [@root] @root.depth = @depth = 0 until queue.empty? n = queue.shift @depth = [@depth, n.depth].max n.children.each { |c| c.depth = n.depth + 1 } queue += n.children @nodes << n end end |
#clone ⇒ Object
Creates a clone of this tree (along with its nodes).
69 70 71 |
# File 'lib/modules/koza/koza_tree.rb', line 69 def clone Wallace::Koza::KozaTree.new(@root.clone) end |
#eval(args) ⇒ Object
Evaluates the S-expression given by this tree.
Parameters:
-
args, the arguments to the function / program (as a hash).
122 123 124 |
# File 'lib/modules/koza/koza_tree.rb', line 122 def eval(args) @root.eval(args) end |
#replace(n1, n2) ⇒ Object
Replaces a subtree in the tree with another subtree.
Parameters:
-
n1, the root node of the sub-tree being replaced.
-
n2, the root node of the replacement sub-tree.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/modules/koza/koza_tree.rb', line 95 def replace(n1, n2) # Create a clone of n2 (to avoid affecting another tree). n2 = n2.clone # If n1 is the root of the tree then change the root to n2. if @root == n1 @root = n2 n2.parent = nil # Otherwise replace n1 with n2 in n1's parents list of children. else i = n1.parent.children.index(n1) n1.parent.children[i] = n2 n2.parent = n1.parent n1.parent = nil end # Recalculate the node list and tree depth. calculate! end |
#sample(opts = {}) ⇒ Object
Samples a node (or number of nodes) from the tree at random.
Parameters:
-
n, the number of nodes to sample from the tree.
-
opts, a hash of keyword options for this method. -> size, the number of nodes to sample. -> random, the RNG to use for sampling.
27 28 29 30 |
# File 'lib/modules/koza/koza_tree.rb', line 27 def sample(opts = {}) @nodes.sample(opts[:size], random: opts[:random] || Random.new) unless opts[:size].nil? @nodes.sample(random: opts[:random] || Random.new) end |
#size ⇒ Object Also known as: length
Returns the number of nodes in the tree.
38 39 40 |
# File 'lib/modules/koza/koza_tree.rb', line 38 def size @nodes.length end |
#to_lambda(args) ⇒ Object
Compiles this Koza Tree into a Ruby lambda function.
Parameters:
-
args, an array of the arguments to the function.
Returns: the compiled lambda function.
155 156 157 |
# File 'lib/modules/koza/koza_tree.rb', line 155 def to_lambda(args) self.class.to_lambda(args, self) end |
#to_ruby ⇒ Object Also known as: to_s
Converts this tree into a Ruby program string.
127 128 129 |
# File 'lib/modules/koza/koza_tree.rb', line 127 def to_ruby @root.to_ruby end |