GPNode is a GPNodeParent which is the abstract superclass of
all GP function nodes in trees. GPNode contains quite a few functions
for cloning subtrees in special ways, counting the number of nodes
in subtrees in special ways, and finding specific nodes in subtrees.
GPNode's lightClone() method does not clone its children (it copies the
array, but that's it). If you want to deep-clone a tree or subtree, you
should use one of the cloneReplacing(...) methods instead.

GPNodes contain a number of important items:

A constraints object which defines the name of the node,
its arity, and its type constraints. This
object is shared with all GPNodes of the same function name/arity/returntype/childtypes.

A parent. This is either another GPNode, or (if this node
is the root) a GPTree.

Zero or more children, which are GPNodes.

An argument position in its parent.

In addition to serialization for checkpointing, GPNodes may read and write themselves to streams in three ways.

writeNode(...,DataOutput)/readNode(...,DataInput) This method
transmits or receives a GPNode in binary. It is the most efficient approach to sending
GPNodes over networks, etc. The default versions of writeNode/readNode both generate errors.
GPNode subclasses should override them to provide more functionality, particularly if you're planning on using
ECJ in a distributed fashion. Both of these functions are called by GPNode's readRootedTree/writeRootedTree
respectively, which handle the reading/printing of the trees as a whole.

printNode(...,PrintWriter)/readNode(...,LineNumberReader) This
approach transmits or receives a GPNode in text encoded such that the GPNode is largely readable
by humans but can be read back in 100% by ECJ as well. To do this, these methods will typically encode numbers
using the ec.util.Code class. These methods are mostly used to write out populations to
files for inspection, slight modification, then reading back in later on. Both of these functions are called by GPNode's readRootedTree/writeRootedTree
respectively, which handle the reading/printing of the trees as a whole. Notably readRootedNode
will try to determine what kind of node is next, then call readNode on the prototype for that
node to generate the node. printNode by default calls toString() and
prints the result, though subclasses often override this to provide additional functionality (notably
ERCs).

printNodeForHumans(...,PrintWriter) This
approach prints a GPNode in a fashion intended for human consumption only.
printNodeForHumans by default calls toStringForHumans() (which by default calls toString()) and
prints the result. printNodeForHumans is called by printRootedTreeForHumans, which handles
printing of the entire GPNode tree.

Produces the LaTeX code for a LaTeX tree of the subtree rooted at this node, using the epic
and fancybox packages, as described in sections 10.5.2 (page 307)
and 10.1.3 (page 278) of The LaTeX Companion, respectively.

Prints out a COMPUTER-readable and Lisp-like atom for the node, which
is also suitable for readNode to read, and returns
the number of bytes in the string that you sent to the log (use print(),
not println()).

Prints out a COMPUTER-readable and Lisp-like atom for the node, which
is also suitable for readNode to read, and returns
the number of bytes in the string that you sent to the log (use print(),
not println()).

Reads the node symbol,
advancing the DecodeReturn to the first character in the string
beyond the node symbol, and returns a new, empty GPNode of the
appropriate class representing that symbol, else null if the
node symbol is not of the correct type for your GPNode class.

parent

children

argposition

public byte argposition

The argument position of the child in its parent.
This is a byte to save space (GPNode is the critical object space-wise) --
besides, how often do you have 256 children? You can change this to a short
or int easily if you absolutely need to. It's possible to eliminate even
this and have the child find itself in its parent, but that's an O(children[])
operation, and probably not inlinable, so I figure a byte is okay.

constraints

public byte constraints

The GPNode's constraints. This is a byte to save space -- how often do
you have 256 different GPNodeConstraints? Well, I guess it's not infeasible.
You can increase this to an int without much trouble. You typically
shouldn't access the constraints through this variable -- use the constraints(state)
method instead.

checkConstraints

You ought to override this method to check to make sure that the
constraints are valid as best you can tell. Things you might
check for:

children.length is correct

certain arguments in constraints.childtypes are
swap-compatible with each other

constraints.returntype is swap-compatible with appropriate
arguments in constraints.childtypes

You can't check for everything, of course, but you might try some
obvious checks for blunders. The default version of this method
simply calls numChildren() if it's defined (it returns something >= 0).
If the value doesn't match the current number of children, an error is raised.
This is a simple constraints check.
The ultimate caller of this method must guarantee that he will eventually
call state.output.exitIfErrors(), so you can freely use state.output.error
instead of state.output.fatal(), which will help a lot.
Warning: this method may get called more than once.

expectedChildren

public int expectedChildren()

Returns the number of children this node expects to have. This method is
only called by the default implementation of checkConstraints(...), and by default
it returns CHILDREN_UNKNOWN. You can override this method to return a value >= 0,
which will be checked for in the default checkConstraints(...), or you can leave
this method alone and override checkConstraints(...) to check for more complex constraints
as you see fit.

setup

Sets up a prototypical GPNode with those features all nodes of that
prototype share, and nothing more. So no filled-in children,
no argposition, no parent. Yet.
This must be called after the GPTypes and GPNodeConstraints
have been set up. Presently they're set up in GPInitializer,
which gets called before this does, so we're safe.
You should override this if you need to load some special features on
a per-function basis. Note that base hangs off of a function set, so
this method may get called for different instances in the same GPNode
class if they're being set up as prototypes for different GPFunctionSets.
If you absolutely need some global base, then you should use something
hanging off of GPDefaults.base().
The ultimate caller of this method must guarantee that he will eventually
call state.output.exitIfErrors(), so you can freely use state.output.error
instead of state.output.fatal(), which will help a lot.

iterator

nodeInPosition

Returns the p'th node, constrained by nodesearch,
in the subtree for which this GPNode is root.
Use numNodes(nodesearch) to determine the total number.
g.test(...) is used as the constraining predicate.
p ranges from 0 to this number minus 1. O(n). The
resultant node is returned in g.

nodeInPosition

Returns the p'th node, constrained by nodesearch,
in the subtree for which this GPNode is root.
Use numNodes(nodesearch) to determine the total number.
g.test(...) is used as the constraining predicate.
p ranges from 0 to this number minus 1. O(n). The
resultant node is returned in g.

contains

resetNode

Starts a node in a new life immediately after it has been cloned.
The default version of this function does nothing. The purpose of
this function is to give ERCs a chance to set themselves to a new
random value after they've been cloned from the prototype.
You should not assume that the node is properly connected to other
nodes in the tree at the point this method is called.

errorInfo

public java.lang.String errorInfo()

A convenience function for identifying a GPNode in an error message

lightClone

clone

public java.lang.Object clone()

Deep-clones the tree rooted at this node, and returns the entire
copied tree. The result has everything set except for the root
node's parent and argposition. This method is identical to
cloneReplacing for historical reasons, except that it returns
the object as an Object, not a GPNode.

cloneReplacing

Deep-clones the tree rooted at this node, and returns the entire
copied tree. The result has everything set except for the root
node's parent and argposition. This method is identical to
cloneReplacing for historical reasons, except that it returns
the object as a GPNode, not an Object.

cloneReplacing

Deep-clones the tree rooted at this node, and returns the entire
copied tree. If the node oldSubtree is located somewhere in this
tree, then its subtree is replaced with a deep-cloned copy of
newSubtree. The result has everything set except for the root
node's parent and argposition.

cloneReplacingNoSubclone

Deep-clones the tree rooted at this node, and returns the entire
copied tree. If the node oldSubtree is located somewhere in this
tree, then its subtree is replaced with
newSubtree (not a copy of newSubtree).
The result has everything set except for the root
node's parent and argposition.

cloneReplacing

Deep-clones the tree rooted at this node, and returns the entire
copied tree. If a node in oldSubtrees is located somewhere in this
tree, then its subtree is replaced with a deep-cloned copy of the
subtree rooted at its equivalent number in
newSubtrees. The result has everything set except for the root
node's parent and argposition.

cloneReplacingAtomic

Clones a new subtree, but with the single node oldNode
(which may or may not be in the subtree)
replaced with a newNode (not a clone of newNode).
These nodes should be
type-compatible both in argument and return types, and should have
the same number of arguments obviously. This function will not
check for this, and if they are not the result is undefined.

cloneReplacingAtomic

Clones a new subtree, but with each node in oldNodes[] respectively
(which may or may not be in the subtree) replaced with
the equivalent
nodes in newNodes[] (and not clones).
The length of oldNodes[] and newNodes[] should
be the same of course. These nodes should be
type-compatible both in argument and return types, and should have
the same number of arguments obviously. This function will not
check for this, and if they are not the result is undefined.

replaceWith

Replaces the node with another node in its position in the tree.
newNode should already have been cloned and ready to go.
We presume that the other node is type-compatible and
of the same arity (these things aren't checked).

nodeEquivalentTo

Returns true if I and the provided node are the same kind of
node -- that is, we could have both been cloned() and reset() from
the same prototype node. The default form of this function returns
true if I and the node have the same class, the same length children
array, and the same constraints. You may wish to override this in
certain circumstances. Here's an example of how nodeEquivalentTo(node)
differs from nodeEquals(node): two ERCs, both of
the same class, but one holding '1.23' and the other holding '2.45', which
came from the same prototype node in the same function set.
They should NOT be nodeEquals(...) but *should* be nodeEquivalent(...).

nodeHashCode

public int nodeHashCode()

Returns a hashcode usually associated with all nodes that are
equal to you (using nodeEquals(...)). The default form
of this method returns the hashcode of the node's class.
ERCs in particular probably will want to override this method.

rootedTreeHashCode

public int rootedTreeHashCode()

Returns a hashcode associated with all the nodes in the tree.
The default version adds the hash of the node plus its child
trees, rotated one-off each time, which seems reasonable.

nodeEquals

Returns true if I am the "genetically" identical to this node, and our
children arrays are the same length, though
we may have different parents and children. The default form
of this method simply calls the much weaker nodeEquivalentTo(node).
You may need to override this to perform exact comparisons, if you're
an ERC, ADF, or ADM for example. Here's an example of how nodeEquivalentTo(node)
differs from nodeEquals(node): two ERCs, both of
the same class, but one holding '1.23' and the other holding '2.45', which
came from the same prototype node in the same function set.
They should NOT be nodeEquals(...) but *should* be nodeEquivalent(...).

printNodeForHumans

Prints out a human-readable and Lisp-like atom for the node,
and returns the number of bytes in the string that you sent
to the log (use print(),
not println()). The default version gets the atom from
toStringForHumans().

printNodeForHumans

Prints out a human-readable and Lisp-like atom for the node,
and returns the number of bytes in the string that you sent
to the log (use print(),
not println()). The default version gets the atom from
toStringForHumans().

printNode

Prints out a COMPUTER-readable and Lisp-like atom for the node, which
is also suitable for readNode to read, and returns
the number of bytes in the string that you sent to the log (use print(),
not println()). The default version gets the atom from toString().
O(1).

printNode

Prints out a COMPUTER-readable and Lisp-like atom for the node, which
is also suitable for readNode to read, and returns
the number of bytes in the string that you sent to the log (use print(),
not println()). The default version gets the atom from toString().
O(1).

printNode

Prints out a COMPUTER-readable and Lisp-like atom for the node, which
is also suitable for readNode to read, and returns
the number of bytes in the string that you sent to the log (use print(),
not println()). The default version gets the atom from toString().
O(1).

name

public java.lang.String name()

Returns a Lisp-like atom for the node and any nodes of the same class.
This will almost always be identical to the result of toString() (and the default
does exactly this), but for ERCs it'll be different: toString will include the
encoded constant data, whereas name() will not include this information and will
be the same for all ERCs of this type. If two nodes are nodeEquivalentTo(...)
each other, then they will have the same name(). If two nodes are nodeEquals(...)
each other, then they will have the same toString().

toString

public abstract java.lang.String toString()

Returns a Lisp-like atom for the node which can be read in again by computer.
If you need to encode an integer or a float or whatever for some reason
(perhaps if it's an ERC), you should use the ec.util.Code library.

Overrides:

toString in class java.lang.Object

toStringForHumans

public java.lang.String toStringForHumans()

Returns a Lisp-like atom for the node which is intended for human
consumption, and not to be read in again. The default version
just calls toString().

toStringForError

public java.lang.String toStringForError()

Returns a description of the node that can make it easy to identify
in error messages (by default, at least its name and the tree it's found in).
It's okay if this is a reasonably expensive procedure -- it won't be called
a lot.

makeGraphvizTree

public java.lang.String makeGraphvizTree()

Produces the Graphviz code for a Graphviz tree of the subtree rooted at this node.
For this to work, the output of toString() must not contain a double-quote.
Note that this isn't particularly efficient and should only be used to generate
occasional trees for display, not for storing individuals or sending them over networks.

makeGraphvizSubtree

Produces the inner code for a graphviz subtree. Called from makeGraphvizTree().
Note that this isn't particularly efficient and should only be used to generate
occasional trees for display, not for storing individuals or sending them over networks.

makeLatexTree

public java.lang.String makeLatexTree()

Produces the LaTeX code for a LaTeX tree of the subtree rooted at this node, using the epic
and fancybox packages, as described in sections 10.5.2 (page 307)
and 10.1.3 (page 278) of The LaTeX Companion, respectively. For this to
work, the output of toStringForHumans() must not contain any weird latex characters, notably { or } or % or \,
unless you know what you're doing. See the documentation for ec.gp.GPTree for information
on how to take this code snippet and insert it into your LaTeX file.
Note that this isn't particularly efficient and should only be used to generate
occasional trees for display, not for storing individuals or sending them over networks.

makeCTree

Producess a String consisting of the tree in pseudo-C form, given that the parent already will wrap the
expression in parentheses (or not). In pseudo-C form, functions with one child are printed out as a(b),
functions with more than two children are printed out as a(b, c, d, ...), and functions with exactly two
children are either printed as a(b, c) or in operator form as (b a c) -- for example, (b * c). Whether
or not to do this depends on the setting of useOperatorForm. Additionally, terminals will be
printed out either in variable form -- a -- or in zero-argument function form -- a() -- depending on
the setting of printTerminalsAsVariables.
Note that this isn't particularly efficient and should only be used to generate
occasional trees for display, not for storing individuals or sending them over networks.

makeLispTree

Produces a tree for human consumption in Lisp form similar to that generated by printTreeForHumans().
Note that this isn't particularly efficient and should only be used to generate
occasional trees for display, not for storing individuals or sending them over networks.

printRootedTree

Prints out the tree on a single line, with no ending \n, in a fashion that can
be read in later by computer. O(n). Returns the number of bytes printed.
You should call this method with printbytes == 0.

readNode

Reads the node symbol,
advancing the DecodeReturn to the first character in the string
beyond the node symbol, and returns a new, empty GPNode of the
appropriate class representing that symbol, else null if the
node symbol is not of the correct type for your GPNode class. You may
assume that initial whitespace has been eliminated. Generally should
be case-SENSITIVE, unlike in Lisp. The default
version usually works for "simple" function names, that is, not ERCs
or other stuff where you have to encode the symbol.

writeNode

Override this to write any additional node-specific information to dataOutput besides: the number of arguments,
the specific node class, the children, and the parent. The default version of this method does nothing.

Throws:

java.io.IOException

readNode

Override this to read any additional node-specific information from dataInput besides: the number of arguments,
the specific node class, the children, and the parent. The default version of this method does nothing.

eval

Evaluates the node with the given thread, state, individual, problem, and stack.
Your random number generator will be state.random[thread].
The node should, as appropriate, evaluate child nodes with these same items
passed to eval(...).

About input: input is special; it is how data is passed between
parent and child nodes. If children "receive" data from their parent node when
it evaluates them, they should receive this data stored in input.
If (more likely) the parent "receives" results from its children, it should
pass them an input object, which they'll fill out, then it should
check this object for the returned value.

A tree is typically evaluated by dropping a GPData into the root. When the
root returns, the resultant input should hold the return value.

In general, you should not be creating new GPDatas.
If you think about it, in most conditions (excepting ADFs and ADMs) you
can use and reuse input for most communications purposes between
parents and children.

So, let's say that your GPNode function implements the boolean AND function,
and expects its children to return return boolean values (as it does itself).
You've implemented your GPData subclass to be, uh, BooleanData, which
looks like