Package ec.gp.push

Class Nonterminal

java.lang.Object
ec.gp.GPNode
ec.gp.push.Nonterminal
All Implemented Interfaces:
GPNodeParent, Prototype, Setup, Serializable, Cloneable

public class Nonterminal extends GPNode
ECJ implements Push's s-expressions as trees of nonterminals and terminals. The nonterminals are all dummies -- this is the class in question. Notably the nonterminals also have an arbitrary arity, requiring a custom tree builder (see PushBuilder). The terminals are instances of Terminal.java.
See Also:
  • Constructor Details

    • Nonterminal

      public Nonterminal()
  • Method Details

    • toString

      public String toString()
      Description copied from class: GPNode
      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.
      Specified by:
      toString in class GPNode
    • toStringForHumans

      public String toStringForHumans()
      Description copied from class: GPNode
      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().
      Overrides:
      toStringForHumans in class GPNode
    • eval

      public void eval(EvolutionState state, int thread, GPData input, ADFStack stack, GPIndividual individual, Problem problem)
      Description copied from class: GPNode
      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;
          }
              
      Specified by:
      eval in class GPNode