/*
Copyright 2006 by Sean Luke
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package ec.gp;
import ec.*;
import ec.util.*;
/*
* ADFContext.java
*
* Created: Tue Oct 26 13:36:46 1999
* By: Sean Luke
*/
/**
* ADFContext is the object pushed onto an ADF stack which represents
* the current context of an ADM or ADF function call, that is, how to
* get the argument values that argument_terminals need to return.
*
*
adf contains the relevant ADF/ADM node.
* If it's an ADF
* function call, then arguments[] contains the evaluated arguments
* to the ADF. If it's an ADM function call,
* then arguments[] is set to false.
*
*
You set up the ADFContext object for a given ADF or ADM node with
* the prepareADF(...) and prepareADM(...) functions.
*
*
To evaluate an argument number from an ADFContext, call evaluate(...),
* and the results are evaluated and copied into input.
*
Parameter bases
base.data
| (the ADFContext's basic GPData type) |
* @author Sean Luke
* @version 1.0
*/
public class ADFContext implements Prototype
{
public final static String P_DATA = "data";
public final static String P_ADFCONTEXT = "adf-context";
public final static int INITIAL_ARGUMENT_SIZE = 2; // seems reasonable
/** The ADF/ADM node proper */
public ADF adf;
/** A prototypical GPData node. */
public GPData arg_proto;
/** An array of GPData nodes (none of the null, when it's used)
holding an ADF's arguments' return results */
public GPData[] arguments;
public Parameter defaultBase()
{
return GPDefaults.base().push(P_ADFCONTEXT);
}
public ADFContext()
{
arguments = new GPData[INITIAL_ARGUMENT_SIZE];
}
public Object clone()
{
try
{
ADFContext myobj = (ADFContext) (super.clone());
// deep-clone the context proto
myobj.arg_proto = (GPData)(arg_proto.clone());
// deep-clone the contexts
myobj.arguments = new GPData[arguments.length];
for(int x=0;x= adf.children.length || argument < 0) // uh oh
{
individual.printIndividual(state,0);
state.output.fatal("Invalid argument number for " + adf.errorInfo());
}
// Am I an ADM or an ADF?
if (adf==null)
state.output.fatal("ADF is null for " + adf.errorInfo());
else if (adf instanceof ADF) // it's an ADF
arguments[argument].copyTo(input);
else // it's an ADM
{
// get rid of my context temporarily
if (stack.moveOntoSubstack(1)!=1)
state.output.fatal("Substack prematurely empty for " + adf.errorInfo());
// Call the GPNode
adf.children[argument].eval(state,thread,input,stack,individual,problem);
// restore my context
if (stack.moveFromSubstack(1)!=1)
state.output.fatal("Stack prematurely empty for " + adf.errorInfo());
}
}
/** Increases arguments to accommodate space if necessary.
Sets adf to a.
You need to then fill out the arguments yourself. */
public final void prepareADF(ADF a)
{
// set to the length requested or longer
if (a.children.length > arguments.length)
{
GPData[] newarguments = new GPData[a.children.length];
System.arraycopy(arguments,0,newarguments,0,arguments.length);
// fill gap -- ugh, luckily this doesn't happen but a few times
for(int x=arguments.length;x