Package ec.gp

# Class GPNode

java.lang.Object
ec.gp.GPNode

All Implemented Interfaces:
  `GPNodeParent`, `Prototype`, `Setup`, `Serializable`, `Cloneable`

Direct Known Subclasses:
  `ADF`, `ADFArgument`, `ERC`, `Nonterminal`

public abstract class GPNode extends Object implements GPNodeParent, Prototype
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.

Parameters

base.`nc` String | (name of the node constraints for the GPNode)

Default Base
gp.node

See Also:
  - Serialized Form

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `byte`
  `argposition`
  The argument position of the child in its parent.
  `GPNode[]`
  `children`
  `static final int`
  `CHILDREN_UNKNOWN`
  `byte`
  `constraints`
  The GPNode's constraints.
  `static final String`
  `GPNODEPRINTTAB`
  `static final int`
  `MAXPRINTBYTES`
  `static final int`
  `NODESEARCH_ALL`
  `static final int`
  `NODESEARCH_NONTERMINALS`
  `static final int`
  `NODESEARCH_TERMINALS`
  `static final String`
  `P_NODE`
  `static final String`
  `P_NODECONSTRAINTS`
  `GPNodeParent`
  `parent`
  The GPNode's parent.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `GPNode()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `int`
  `atDepth()`
  Returns the depth at which I appear in the tree, which is a value >= 0.
  `void`
  `checkConstraints(EvolutionState state, int tree, GPIndividual typicalIndividual, Parameter individualBase)`
  You ought to override this method to check to make sure that the constraints are valid as best you can tell.
  `Object`
  `clone()`
  Deep-clones the tree rooted at this node, and returns the entire copied tree.
  `final GPNode`
  `cloneReplacing()`
  Deep-clones the tree rooted at this node, and returns the entire copied tree.
  `final GPNode`
  `cloneReplacing(GPNode[] newSubtrees, GPNode[] oldSubtrees)`
  Deep-clones the tree rooted at this node, and returns the entire copied tree.
  `final GPNode`
  `cloneReplacing(GPNode newSubtree, GPNode oldSubtree)`
  Deep-clones the tree rooted at this node, and returns the entire copied tree.
  `final GPNode`
  `cloneReplacingAtomic(GPNode[] newNodes, GPNode[] oldNodes)`
  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).
  `final GPNode`
  `cloneReplacingAtomic(GPNode newNode, GPNode oldNode)`
  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).
  `final GPNode`
  `cloneReplacingNoSubclone(GPNode newSubtree, GPNode oldSubtree)`
  Deep-clones the tree rooted at this node, and returns the entire copied tree.
  `final GPNodeConstraints`
  `constraints(GPInitializer initializer)`
  `boolean`
  `contains(GPNode subnode)`
  Returns true if the subtree rooted at this node contains subnode.
  `Parameter`
  `defaultBase()`
  The default base for GPNodes -- defined even though GPNode is abstract so you don't have to in subclasses.
  `int`
  `depth()`
  Returns the depth of the tree, which is a value >= 1.
  `String`
  `errorInfo()`
  A convenience function for identifying a GPNode in an error message
  `abstract void`
  `eval(EvolutionState state, int thread, GPData input, ADFStack stack, GPIndividual individual, Problem problem)`
  Evaluates the node with the given thread, state, individual, problem, and stack.
  `int`
  `expectedChildren()`
  Returns the number of children this node expects to have.
  `Iterator`
  `iterator()`
  Returns an iterator over all the GPNodes in the subtree rooted by this GPNode.
  `Iterator`
  `iterator(int nodesearch)`
  Returns an iterator over all the GPNodes in the subtree rooted by this GPNode, filtered by the provided nodesearch option (either NODSEARCH_TERMINALS, NODESEARCH_NONTERMINALS, or NODESEARCH_ALL)
  `Iterator`
  `iterator(GPNodeGatherer g)`
  Returns an iterator over all the GPNodes in the subtree rooted by this GPNode, filtered by the provided GPNodeGatherer.
  `GPNode`
  `lightClone()`
  `String`
  `makeCTree(boolean parentMadeParens, boolean printTerminalsAsVariables, boolean useOperatorForm)`
  Producess a String consisting of the tree in pseudo-C form, given that the parent already will wrap the expression in parentheses (or not).
  `protected String`
  `makeGraphvizSubtree(String prefix)`
  Produces the inner code for a graphviz subtree.
  `String`
  `makeGraphvizTree()`
  Produces the Graphviz code for a Graphviz tree of the subtree rooted at this node.
  `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.
  `String`
  `makeLispTree()`
  `StringBuilder`
  `makeLispTree(StringBuilder buf)`
  Produces a tree for human consumption in Lisp form similar to that generated by printTreeForHumans().
  `String`
  `name()`
  Returns a Lisp-like atom for the node and any nodes of the same class.
  `boolean`
  `nodeEquals(GPNode node)`
  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.
  `boolean`
  `nodeEquivalentTo(GPNode node)`
  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.
  `int`
  `nodeHashCode()`
  Returns a hashcode usually associated with all nodes that are equal to you (using nodeEquals(...)).
  `GPNode`
  `nodeInPosition(int p, int nodesearch)`
  Returns the p'th node, constrained by nodesearch, in the subtree for which this GPNode is root.
  `GPNode`
  `nodeInPosition(int p, GPNodeGatherer g)`
  Returns the p'th node, constrained by nodesearch, in the subtree for which this GPNode is root.
  `int`
  `numNodes(int nodesearch)`
  Returns the number of nodes, constrained by nodesearch, in the subtree for which this GPNode is root.
  `int`
  `numNodes(GPNodeGatherer g)`
  Returns the number of nodes, constrained by g.test(...) in the subtree for which this GPNode is root.
  `final GPType`
  `parentType(GPInitializer initializer)`
  Returns the argument type of the slot that I fit into in my parent.
  `int`
  `pathLength(int nodesearch)`
  Returns the path length of the tree, which is the sum of all paths from all nodes to the root.
  `int`
  `printNode(EvolutionState state, int log)`
  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()).
  `int`
  `printNode(EvolutionState state, int log, int verbosity)`
  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()).
  `int`
  `printNode(EvolutionState state, PrintWriter writer)`
  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()).
  `int`
  `printNodeForHumans(EvolutionState state, int log)`
  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()).
  `int`
  `printNodeForHumans(EvolutionState state, int log, int verbosity)`
  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()).
  `int`
  `printRootedTree(EvolutionState state, int log, int printbytes)`
  Prints out the tree on a single line, with no ending \n, in a fashion that can be read in later by computer.
  `int`
  `printRootedTree(EvolutionState state, int log, int verbosity, int printbytes)`
  Prints out the tree on a single line, with no ending \n, in a fashion that can be read in later by computer.
  `int`
  `printRootedTree(EvolutionState state, PrintWriter writer, int printbytes)`
  Prints out the tree on a single line, with no ending \n, in a fashion that can be read in later by computer.
  `int`
  `printRootedTreeForHumans(EvolutionState state, int log, int tablevel, int printbytes)`
  Prints out the tree in a readable Lisp-like multi-line fashion.
  `int`
  `printRootedTreeForHumans(EvolutionState state, int log, int verbosity, int tablevel, int printbytes)`
  Prints out the tree in a readable Lisp-like multi-line fashion.
  `void`
  `readNode(EvolutionState state, DataInput dataInput)`
  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.
  `GPNode`
  `readNode(DecodeReturn dret)`
  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.
  `static GPNode`
  `readRootedTree(int linenumber, DecodeReturn dret, GPType expectedType, GPFunctionSet set, GPNodeParent parent, int argposition, EvolutionState state)`
  Reads the node and its children from the form printed out by printRootedTree.
  `static GPNode`
  `readRootedTree(EvolutionState state, DataInput dataInput, GPType expectedType, GPFunctionSet set, GPNodeParent parent, int argposition)`
  `final void`
  `replaceWith(GPNode newNode)`
  Replaces the node with another node in its position in the tree.
  `void`
  `resetNode(EvolutionState state, int thread)`
  Starts a node in a new life immediately after it has been cloned.
  `boolean`
  `rootedTreeEquals(GPNode node)`
  Returns true if the two rooted trees are "genetically" equal, though they may have different parents.
  `int`
  `rootedTreeHashCode()`
  Returns a hashcode associated with all the nodes in the tree.
  `GPNodeParent`
  `rootParent()`
  Returns the root ancestor of this node.
  `void`
  `setup(EvolutionState state, Parameter base)`
  Sets up a prototypical GPNode with those features all nodes of that prototype share, and nothing more.
  `final boolean`
  `swapCompatibleWith(GPInitializer initializer, GPNode node)`
  Returns true if I can swap into node's position.
  `abstract String`
  `toString()`
  Returns a Lisp-like atom for the node which can be read in again by computer.
  `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).
  `String`
  `toStringForHumans()`
  Returns a Lisp-like atom for the node which is intended for human consumption, and not to be read in again.
  `void`
  `writeNode(EvolutionState state, DataOutput dataOutput)`
  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.
  `void`
  `writeRootedTree(EvolutionState state, GPType expectedType, GPFunctionSet set, DataOutput dataOutput)`

  ### Methods inherited from class java.lang.Object

  `equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### P_NODE

    public static final String P_NODE
    See Also:
      - Constant Field Values

  - ### P_NODECONSTRAINTS

    public static final String P_NODECONSTRAINTS
    See Also:
      - Constant Field Values

  - ### GPNODEPRINTTAB

    public static final String GPNODEPRINTTAB
    See Also:
      - Constant Field Values

  - ### MAXPRINTBYTES

    public static final int MAXPRINTBYTES
    See Also:
      - Constant Field Values

  - ### NODESEARCH_ALL

    public static final int NODESEARCH_ALL
    See Also:
      - Constant Field Values

  - ### NODESEARCH_TERMINALS

    public static final int NODESEARCH_TERMINALS
    See Also:
      - Constant Field Values

  - ### NODESEARCH_NONTERMINALS

    public static final int NODESEARCH_NONTERMINALS
    See Also:
      - Constant Field Values

  - ### CHILDREN_UNKNOWN

    public static final int CHILDREN_UNKNOWN
    See Also:
      - Constant Field Values

  - ### parent

    public GPNodeParent parent
    The GPNode's parent. 4 bytes. :-( But it really helps simplify breeding.

  - ### children

    public GPNode[] 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.

- ## Constructor Details

  - ### GPNode

    public GPNode()

- ## Method Details

  - ### constraints

    public final GPNodeConstraints constraints(GPInitializer initializer)

  - ### defaultBase

    public Parameter defaultBase()
    The default base for GPNodes -- defined even though GPNode is abstract so you don't have to in subclasses.
    Specified by:
      `defaultBase` in interface `Prototype`

  - ### checkConstraints

    public void checkConstraints(EvolutionState state, int tree, GPIndividual typicalIndividual, Parameter individualBase)
    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

    public void setup(EvolutionState state, Parameter base)
    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.
    Specified by:
      `setup` in interface `Prototype`
    Specified by:
      `setup` in interface `Setup`

  - ### parentType

    public final GPType parentType(GPInitializer initializer)
    Returns the argument type of the slot that I fit into in my parent. If I'm the root, returns the treetype of the GPTree.

  - ### swapCompatibleWith

    public final boolean swapCompatibleWith(GPInitializer initializer, GPNode node)
    Returns true if I can swap into node's position.

  - ### numNodes

    public int numNodes(GPNodeGatherer g)
    Returns the number of nodes, constrained by g.test(...) in the subtree for which this GPNode is root. This might be sped up by caching the value. O(n).

  - ### numNodes

    public int numNodes(int nodesearch)
    Returns the number of nodes, constrained by nodesearch, in the subtree for which this GPNode is root. This might be sped up by cacheing the value somehow. O(n).

  - ### depth

    public int depth()
    Returns the depth of the tree, which is a value >= 1. O(n).

  - ### pathLength

    public int pathLength(int nodesearch)
    Returns the path length of the tree, which is the sum of all paths from all nodes to the root. O(n).

  - ### atDepth

    public int atDepth()
    Returns the depth at which I appear in the tree, which is a value >= 0. O(ln n) avg.

  - ### iterator

    public Iterator iterator(GPNodeGatherer g)
    Returns an iterator over all the GPNodes in the subtree rooted by this GPNode, filtered by the provided GPNodeGatherer.

  - ### iterator

    public Iterator iterator(int nodesearch)
    Returns an iterator over all the GPNodes in the subtree rooted by this GPNode, filtered by the provided nodesearch option (either NODSEARCH_TERMINALS, NODESEARCH_NONTERMINALS, or NODESEARCH_ALL)

  - ### iterator

    public Iterator iterator()
    Returns an iterator over all the GPNodes in the subtree rooted by this GPNode.

  - ### nodeInPosition

    public GPNode nodeInPosition(int p, GPNodeGatherer g)
    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

    public GPNode nodeInPosition(int p, int nodesearch)
    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.

  - ### rootParent

    public GPNodeParent rootParent()
    Returns the root ancestor of this node. O(ln n) average case, O(n) worst case.

  - ### contains

    public boolean contains(GPNode subnode)
    Returns true if the subtree rooted at this node contains subnode. O(n).

  - ### resetNode

    public void resetNode(EvolutionState state, int thread)
    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 String errorInfo()
    A convenience function for identifying a GPNode in an error message

  - ### lightClone

    public GPNode lightClone()

  - ### clone

    public 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.
    Specified by:
      `clone` in interface `Prototype`
    Overrides:
      `clone` in class `Object`

  - ### cloneReplacing

    public final 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

    public final GPNode cloneReplacing(GPNode newSubtree, GPNode oldSubtree)
    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

    public final GPNode cloneReplacingNoSubclone(GPNode newSubtree, GPNode oldSubtree)
    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

    public final GPNode cloneReplacing(GPNode[] newSubtrees, GPNode[] oldSubtrees)
    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

    public final GPNode cloneReplacingAtomic(GPNode newNode, GPNode oldNode)
    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

    public final GPNode cloneReplacingAtomic(GPNode[] newNodes, GPNode[] oldNodes)
    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

    public final void replaceWith(GPNode newNode)
    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

    public boolean nodeEquivalentTo(GPNode node)
    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

    public boolean nodeEquals(GPNode node)
    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(...).

  - ### rootedTreeEquals

    public boolean rootedTreeEquals(GPNode node)
    Returns true if the two rooted trees are "genetically" equal, though they may have different parents. O(n).

  - ### printNodeForHumans

    public int printNodeForHumans(EvolutionState state, int log)
    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

    public int printNodeForHumans(EvolutionState state, int log, int verbosity)
    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

    public int printNode(EvolutionState state, int log)
    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

    public int printNode(EvolutionState state, int log, int verbosity)
    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

    public int printNode(EvolutionState state, PrintWriter writer)
    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 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 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 `Object`

  - ### toStringForHumans

    public 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 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 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

    protected String makeGraphvizSubtree(String prefix)
    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 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

    public String makeCTree(boolean parentMadeParens, boolean printTerminalsAsVariables, boolean useOperatorForm)
    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

    public StringBuilder makeLispTree(StringBuilder buf)
    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.

  - ### makeLispTree

    public String makeLispTree()

  - ### printRootedTree

    public int printRootedTree(EvolutionState state, int log, int printbytes)
    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). You should call this method with printbytes == 0.

  - ### printRootedTree

    public int printRootedTree(EvolutionState state, int log, int verbosity, int printbytes)
    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). You should call this method with printbytes == 0.

  - ### printRootedTree

    public int printRootedTree(EvolutionState state, PrintWriter writer, int printbytes)
    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.

  - ### printRootedTreeForHumans

    public int printRootedTreeForHumans(EvolutionState state, int log, int tablevel, int printbytes)
    Prints out the tree in a readable Lisp-like multi-line fashion. O(n). You should call this method with tablevel and printbytes == 0. No ending '\n' is printed.

  - ### printRootedTreeForHumans

    public int printRootedTreeForHumans(EvolutionState state, int log, int verbosity, int tablevel, int printbytes)
    Prints out the tree in a readable Lisp-like multi-line fashion. O(n). You should call this method with tablevel and printbytes == 0. No ending '\n' is printed.

  - ### readNode

    public GPNode readNode(DecodeReturn dret)
    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.

  - ### writeRootedTree

    public void writeRootedTree(EvolutionState state, GPType expectedType, GPFunctionSet set, DataOutput dataOutput) throws IOException
    Throws:
      `IOException`

  - ### readRootedTree

    public static GPNode readRootedTree(EvolutionState state, DataInput dataInput, GPType expectedType, GPFunctionSet set, GPNodeParent parent, int argposition) throws IOException
    Throws:
      `IOException`

  - ### writeNode

    public void writeNode(EvolutionState state, DataOutput dataOutput) throws IOException
    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:
      `IOException`

  - ### readNode

    public void readNode(EvolutionState state, DataInput dataInput) throws IOException
    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.
    Throws:
      `IOException`

  - ### readRootedTree

    public static GPNode readRootedTree(int linenumber, DecodeReturn dret, GPType expectedType, GPFunctionSet set, GPNodeParent parent, int argposition, EvolutionState state)
    Reads the node and its children from the form printed out by printRootedTree.

  - ### eval

    public abstract void eval(EvolutionState state, int thread, GPData input, ADFStack stack, GPIndividual individual, Problem problem)
    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 ``

        public class BooleanData extends GPData
            {
            public boolean result;
            public GPData copyTo(GPData gpd)
              {
              ((BooleanData)gpd).result = result;
              }
            }

    ...so, you might implement your eval(...) function as follows: ``

        public void eval(final EvolutionState state,
                             final int thread,
                             final GPData input,
                             final ADFStack stack,
                             final GPIndividual individual,
                             final Problem problem
            {
            BooleanData dat = (BooleanData)input;
            boolean x;

            // evaluate the first child
            children[0].eval(state,thread,input,stack,individual,problem);

            // store away its result
            x = dat.result;

            // evaluate the second child
            children[1].eval(state,thread,input,stack,individual,problem);

            // return (in input) the result of the two ANDed

            dat.result = dat.result invalid input: '&'invalid input: '&' x;
            return;
            }