/// <summary> /// Evaluates the argument number in the current context /// </summary> public virtual void Evaluate(IEvolutionState state, int thread, GPData input, ADFStack stack, GPIndividual individual, IProblem problem, int argument) { // do I have that many Arguments? if ((argument >= 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 is ADM)) // 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()); } } }
public override void Eval(IEvolutionState state, int thread, GPData input, ADFStack stack, GPIndividual individual, IProblem problem) { // get a context and prepare it var c = stack.Take(); c.PrepareADF(this, (GPProblem)problem); // evaluate my Arguments and load 'em in for (var x = 0; x < Children.Length; x++) { input.CopyTo(c.Arguments[x]); Children[x].Eval(state, thread, c.Arguments[x], stack, individual, problem); } // Now push the context onto the stack. stack.Push(c); // evaluate the top of the associatedTree individual.Trees[AssociatedTree].Child.Eval(state, thread, input, stack, individual, problem); // pop the context off, and we're done! if (stack.Pop(1) != 1) { state.Output.Fatal("Stack prematurely empty for " + ToStringForError()); } }
public override void Eval(IEvolutionState state, int thread, GPData input, ADFStack stack, GPIndividual individual, IProblem problem) { // get the current context var c = stack.Top(0); if (c == null) { // uh oh state.Output.Fatal("No context with which to evaluate ADFArgument terminal " + ToStringForError() + ". This often happens if you evaluate a tree by hand which is supposed to only be an ADF's associated tree."); } c.Evaluate(state, thread, input, stack, individual, problem, Argument); }
/// <summary> /// Checks type-compatibility constraints between the ADF, its argument terminals, /// and the tree type of its associated tree, and also checks to make sure the tree exists, /// there aren't invalid argument terminals in it, and there are sufficient argument terminals (a warning). Whew! /// </summary> public override void CheckConstraints(IEvolutionState state, int tree, GPIndividual typicalIndividual, IParameter individualBase) { base.CheckConstraints(state, tree, typicalIndividual, individualBase); // does the associated tree exist? if (AssociatedTree < 0 || AssociatedTree >= typicalIndividual.Trees.Length) { state.Output.Error("The node " + ToStringForError() + " of individual " + individualBase + " must have an associated tree that is >= 0 and < " + typicalIndividual.Trees.Length + ". Value provided was: " + AssociatedTree); } else { // is the associated tree of the correct type? Issue an error. var initializer = ((GPInitializer)state.Initializer); if (!Constraints(initializer).ReturnType.CompatibleWith(initializer, typicalIndividual.Trees[AssociatedTree].Constraints(initializer).TreeType)) { state.Output.Error("The return type of the node " + ToStringForError() + " of individual " + individualBase + "is not type-compatible with the tree type of its associated tree."); } var funcs = typicalIndividual.Trees[AssociatedTree].Constraints(initializer).FunctionSet.Nodes; var validArgument = new ADFArgument[Children.Length]; for (var w = 0; w < funcs.Length; w++) { // does the tree's function set have argument terminals // that are beyond what I can provide? (issue an error) var gpfi = funcs[w]; for (var x = 0; x < gpfi.Length; x++) { if (gpfi[x] is ADFArgument) { var argument = (ADFArgument)(gpfi[x]); var arg = argument.Argument; if (arg >= Children.Length) // uh oh { state.Output.Error("The node " + ToStringForError() + " in individual " + individualBase + " would call its associated tree, which has an argument terminal with an argument number (" + arg + ") >= the ADF/ADM's arity (" + Children.Length + "). The argument terminal in question is " + gpfi[x].ToStringForError()); } else { if (validArgument[arg] != null && validArgument[arg] != argument) // got one already { state.Output.Warning("There exists more than one Argument terminal for argument #" + arg + " for the node " + ToStringForError() + " in individual " + individualBase); } else { validArgument[arg] = argument; } // is the argument terminal of the correct return type? Issue an error. if ( !gpfi[x].Constraints(initializer).ReturnType.CompatibleWith(initializer, Constraints(initializer).ChildTypes[arg])) { state.Output.Error("The node " + ToStringForError() + " in individual " + individualBase + " would call its associated tree, which has an argument terminal which is not type-compatible with the related argument position of the ADF/ADM. The argument terminal in question is " + gpfi[x].ToStringForError()); } } } } } // does the tree's function set have fewer argument terminals // than I can provide? (issue a warning) for (var x = 0; x < Children.Length; x++) { if (validArgument[x] == null) { state.Output.Warning("There is no argument terminal for argument #" + x + " for the node " + ToStringForError() + " in individual " + individualBase); } } } }
public override void Eval(IEvolutionState state, int thread, GPData input, ADFStack stack, GPIndividual individual, IProblem problem) { // prepare a context var c = stack.Push(stack.Take()); c.PrepareADM(this); // evaluate the top of the associatedTree individual.Trees[AssociatedTree].Child.Eval(state, thread, input, stack, individual, problem); // pop the context off, and we're done! if (stack.Pop(1) != 1) { state.Output.Fatal("Stack prematurely empty for " + ToStringForError()); } }