Example #1
0
        /// <summary>
        /// This must be called <i>after</i> the GPTypes and GPFunctionSets
        /// have been set up.
        /// </summary>
        public void Setup(IEvolutionState state, IParameter paramBase)
        {
            // What's my name?
            Name = state.Parameters.GetString(paramBase.Push(P_NAME), null);
            if (Name == null)
            {
                state.Output.Fatal("No name was given for this function set.", paramBase.Push(P_NAME));
            }

            // Register me
            var tempObject = ((GPInitializer)state.Initializer).TreeConstraintRepository[Name];

            ((GPInitializer)state.Initializer).TreeConstraintRepository[Name] = this;

            var oldConstraints = (GPTreeConstraints)(tempObject);

            if (oldConstraints != null)
            {
                state.Output.Fatal("The GP tree constraint \"" + Name + "\" has been defined multiple times.", paramBase.Push(P_NAME));
            }

            // Load my initializing builder
            Init = (GPNodeBuilder)(state.Parameters.GetInstanceForParameter(paramBase.Push(P_INIT), null, typeof(GPNodeBuilder)));
            Init.Setup(state, paramBase.Push(P_INIT));

            // Load my return type
            var s = state.Parameters.GetString(paramBase.Push(P_RETURNS), null);

            if (s == null)
            {
                state.Output.Fatal("No return type given for the GPTreeConstraints " + Name, paramBase.Push(P_RETURNS));
            }

            TreeType = GPType.TypeFor(s, state);

            // Load my function set
            s = state.Parameters.GetString(paramBase.Push(P_FUNCTIONSET), null);
            if (s == null)
            {
                state.Output.Fatal("No function set given for the GPTreeConstraints " + Name, paramBase.Push(P_RETURNS));
            }

            FunctionSet = GPFunctionSet.FunctionSetFor(s, state);
            state.Output.ExitIfErrors(); // otherwise checkFunctionSetValidity might crash below

            // Determine the validity of the function set
            // the way we do that is by gathering all the types that
            // are transitively used, starting with treetype, as in:
            var typ = Hashtable.Synchronized(new Hashtable());

            CheckFunctionSetValidity(state, typ, TreeType);

            // next we make sure that for every one of these types,
            // there's a terminal with that return type, and *maybe*
            // a nonterminal
            var e = typ.Values.GetEnumerator();

            while (e.MoveNext())
            {
                var t = (GPType)(e.Current);
                var i = FunctionSet.Nodes[t.Type];
                if (i.Length == 0) // yeesh
                {
                    state.Output.Error("In function set " + FunctionSet + " for the GPTreeConstraints "
                                       + this + ", no nodes at all are given with the return type "
                                       + t + " which is required by other functions in the function set or by the tree's return type."
                                       + " This almost certainly indicates a serious typing error.", paramBase);
                }
                else
                {
                    i = FunctionSet.Terminals[t.Type];
                    if (i.Length == 0)
                    // uh oh
                    {
                        state.Output.Warning("In function set " + FunctionSet + " for the GPTreeConstraints "
                                             + this + ", no terminals are given with the return type "
                                             + t + " which is required by other functions in the function set or by the tree's return type."
                                             + " Nearly all tree-builders in ECJ require the ability to add a terminal of any type for which "
                                             + " there is a nonterminal, and at any time.  Without terminals, your code may not work."
                                             + " One common indication that a tree-builder has failed due to this problem is if you get"
                                             + " the MersenneTwister error 'n must be positive'.", paramBase);
                    }
                    i = FunctionSet.Nonterminals[t.Type];
                    if (i.Length == 0)
                    // uh oh
                    {
                        state.Output.Warning("In function set " + FunctionSet + " for the GPTreeConstraints "
                                             + this + ", no *nonterminals* are given with the return type "
                                             + t + " which is required by other functions in the function set or by the tree's return type."
                                             + " This may or may not be a problem for you.", paramBase);
                    }
                }
            }
            state.Output.ExitIfErrors();
        }