/* * Open BEAGLE * Copyright (C) 2001-2005 by Christian Gagne and Marc Parizeau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact: * Laboratoire de Vision et Systemes Numeriques * Departement de genie electrique et de genie informatique * Universite Laval, Quebec, Canada, G1K 7P4 * http://vision.gel.ulaval.ca * */ /*! * \file beagle/GP/src/Module.cpp * \brief Implementation of Module. * \author Christian Gagne * \author Matthew Walker * \author Marc Parizeau * $Revision: 1.7 $ * $Date: 2005/10/04 16:25:10 $ */ #include "beagle/GP.hpp" using namespace Beagle; /*! * \brief Construct a new Module primitive. * \param inIndex Index of the associated tree. * \param inNumberArgs Number of arguments of the module. * \param inName Name of the module primitive. * \param inArgsName Name of the associated argument primitive. */ GP::Module::Module(unsigned int inIndex, unsigned int inNumberArgs, Beagle::string inName, Beagle::string inArgsName) : GP::Invoker(inIndex, inNumberArgs, inName, inArgsName) { } /*! * \brief Generate a new Module primitive from the given specifications. * \param inIndex Tree index for which the primitive is created. * \param inName Name of the primitive generated. * \param inArgsName Name of the arguments associated to the invoker created. * \param ioContext Evolutionary context. */ GP::Invoker::Handle GP::Module::generateInvoker(unsigned int inIndex, Beagle::string inName, Beagle::string inArgsName, GP::Context& ioContext) const { Beagle_StackTraceBeginM(); Component::Handle lComponent = ioContext.getSystem().getComponent("ModuleVector"); GP::ModuleVectorComponent::Handle lModVector = castHandleT(lComponent); if(lModVector==NULL) { throw Beagle_RunTimeExceptionM(string("GP system is not configured with a module vector. ")+ string("Consider adding a GP::ModuleVectorComponent object to the system.")); } GP::Tree::Handle lTree = (*lModVector)[inIndex]; Beagle_AssertM(lTree != NULL); return new GP::Module(inIndex, lTree->getNumberArguments(), inName, inArgsName); Beagle_StackTraceEndM("GP::Invoker::Handle GP::Module::generateInvoker(unsigned int inIndex, string inName, string inArgsName, GP::Context& ioContext) const"); } /*! * \brief Return indices of the trees that can be invoked by the module. * \param outCandidates Indices of tree that can be selected as invokable in the actual context. * \param inNumberArguments Number of arguments for which the selection is desired. * \param ioContext Evolutionary context. */ void GP::Module::getCandidatesToInvoke(std::vector< unsigned int,BEAGLE_STLALLOCATOR >& outCandidates, unsigned int inNumberArguments, GP::Context& ioContext) const { Beagle_StackTraceBeginM(); outCandidates.resize(0); for(unsigned int i=0; igetName() == getName()) return; } Component::Handle lComponent = ioContext.getSystem().getComponent("ModuleVector"); GP::ModuleVectorComponent::Handle lModVector = castHandleT(lComponent); if(lModVector==NULL) { throw Beagle_RunTimeExceptionM(string("GP system is not configured with a module vector. ")+ string("Consider adding a GP::ModuleVectorComponent object to the system.")); } for(unsigned int i=0; isize(); ++i) { if((*lModVector)[i]==NULL) continue; const unsigned int lNbArgsTree = (*lModVector)[i]->getNumberArguments(); if(inNumberArguments == GP::Primitive::eAny) outCandidates.push_back(i); else if((inNumberArguments==GP::Primitive::eBranch) && (lNbArgsTree>0)) outCandidates.push_back(i); else if(inNumberArguments == lNbArgsTree) outCandidates.push_back(i); } Beagle_StackTraceEndM(""); } /*! * \brief Get reference the tree to invoke. * \param ioContext Evolutionary context. * \return Handle to the invoked tree. */ GP::Tree::Handle GP::Module::getInvokedTree(GP::Context& ioContext) const { Beagle_StackTraceBeginM(); Component::Handle lComponent = ioContext.getSystem().getComponent("ModuleVector"); GP::ModuleVectorComponent::Handle lModVector = castHandleT(lComponent); if(lModVector==NULL) { throw Beagle_RunTimeExceptionM(string("GP system is not configured with a module vector. ")+ string("Consider adding a GP::ModuleVectorComponent object to the system.")); } Beagle_AssertM(mIndex < lModVector->size()); Beagle_AssertM((*lModVector)[mIndex] != NULL); return (*lModVector)[mIndex]; Beagle_StackTraceEndM("void GP::Module::getCandidatesToInvoke(std::vector< unsigned int,BEAGLE_STLALLOCATOR >& outCandidates, unsigned int inNumberArguments, GP::Context& ioContext) const"); } /*! * \brief Invoke GP tree to execute as ADF. * \param outResult Result of GP tree invocation * \param ioTree Tree to invoke. * \param ioContext Evolutionary context. */ void GP::Module::invoke(GP::Datum& outResult, GP::Tree::Handle ioTree, GP::Context& ioContext) { Beagle_StackTraceBeginM(); GP::Tree::Handle lOldGenotypeHandle = ioContext.getGenotypeHandle(); unsigned int lOldGenotypeIndex = ioContext.getGenotypeIndex(); ioContext.setGenotypeHandle(ioTree); ioContext.setGenotypeIndex(mIndex); ioContext.incrementNodesExecuted(); ioContext.pushCallStack(0); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "EMA", "Beagle::GP::Module", string("Interpreting the ")+uint2ordinal(mIndex+1)+string(" module") ); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "EMA", "Beagle::GP::Module", string("The tree is: ")+ioTree->serialize() ); (*ioTree)[0].mPrimitive->execute(outResult, ioContext); ioContext.popCallStack(); ioContext.checkExecutionTime(); ioContext.setGenotypeHandle(lOldGenotypeHandle); ioContext.setGenotypeIndex(lOldGenotypeIndex); Beagle_StackTraceEndM("void GP::Module::invoke(GP::Datum& outResult, GP::Tree::Handle ioTree, GP::Context& ioContext)"); } /*! * \brief Validate the module position in the tree. * \param ioContext Evolutionary context. * \return True if the module is correctly positioned, false if not. * \throw Beagle::AssertException If the context is in a bad state. */ bool GP::Module::validate(GP::Context& ioContext) const { Beagle_StackTraceBeginM(); for(unsigned int i=0; igetName() == getName()) return false; } Component::Handle lComponent = ioContext.getSystem().getComponent("ModuleVector"); GP::ModuleVectorComponent::Handle lModVector = castHandleT(lComponent); if(lModVector==NULL) { throw Beagle_RunTimeExceptionM(string("GP system is not configured with a module vector. ")+ string("Consider adding a GP::ModuleVectorComponent object to the system.")); } Beagle_AssertM((*lModVector)[mIndex]!=NULL); if((*lModVector)[mIndex]->getNumberArguments() != getNumberArguments()) return false; return GP::Primitive::validate(ioContext); Beagle_StackTraceEndM("bool GP::Module::validate(GP::Context& ioContext) const"); }