# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

fuzzyvar.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "nel/ai/fuzzy/fuzzyvar.h"
00027 #include "nel/ai/script/compilateur.h"
00028 #include "nel/ai/script/constraint.h"
00029 #include "nel/ai/script/type_def.h"
00030 #include "nel/ai/agent/agent.h"
00031 #include "nel/ai/agent/agent_digital.h"
00032 #include "nel/ai/fuzzy/fuzzycond.h"
00033 
00034 namespace NLAIFUZZY 
00035 {       
00036         using namespace NLAIAGENT;
00037 
00038         CFuzzyVar::CFuzzyVar(const NLAIAGENT::IVarName &name, double min, double max, NLAIAGENT::IObjetOp *value) : IBaseVar(name)
00039         {
00040                 if ( value )
00041                         _Value = ((NLAIAGENT::INombre<double> *)value)->getValue();
00042                 else
00043                         _Value = 0;
00044 
00045                 _Min = min;
00046                 _Max = max;
00047         }
00048 
00049         CFuzzyVar::CFuzzyVar(const NLAIAGENT::IVarName &name, double min, double max, double value) : IBaseVar(name)
00050         {
00051                 _Value = value;
00052                 _Min = min;
00053                 _Max = max;
00054         }
00055 
00056         CFuzzyVar::CFuzzyVar(const CFuzzyVar &cp) : IBaseVar( cp )
00057         {
00058                 _Value = cp._Value;
00059                 _Min = cp._Min;
00060                 _Max = cp._Max;
00061         }
00062 
00063         CFuzzyVar::~CFuzzyVar()
00064         {
00065                 
00066                 std::vector<IFuzzySet *>::const_iterator it_fs = _sets.begin();
00067                 while ( it_fs != _sets.end() )
00068                 {
00069                         ( *it_fs )->release();
00070                         it_fs++;
00071                 }
00072 
00073                 std::vector<CFuzzyFact *>::const_iterator it_f = _facts.begin();
00074                 while ( it_f != _facts.end() )
00075                 {
00076                         ( *it_f )->release();
00077                         it_f++;
00078                 }
00079 
00080                 std::vector<NLAIAGENT::CStringVarName *>::const_iterator it_q = _qual.begin();
00081                 while ( it_q != _qual.end() )
00082                 {
00083                         ( *it_q )->release();
00084                         it_q++;
00085                 }
00086         }
00087 
00088         void CFuzzyVar::addSet(IFuzzySet *my_set, char *set_name)
00089         {
00090                 _sets.push_back(my_set);
00091                 my_set->incRef();
00092                 NLAIAGENT::CStringVarName *qual = new NLAIAGENT::CStringVarName( set_name );
00093                 _qual.push_back( qual );
00094         }
00095 
00096         std::list<CFuzzyFact *> *CFuzzyVar::fuzzify(double val)
00097         {
00098                 std::list<CFuzzyFact *> *result = new std::list<CFuzzyFact *>;
00099                 for ( sint32 i = 0; i < (sint32) _sets.size(); i++ )
00100                 {
00101                         if ( _sets[i]->isIn( val ) )
00102                         {
00103                                 result->push_back( new CFuzzyFact( _sets[i], _sets[i]->membership(val) ) );
00104                         }
00105                 }
00106                 return result;
00107         }
00108 
00109         double CFuzzyVar::unfuzify()
00110         {
00111                 double total_membership = 0.0;
00112                 double set_membership;
00113                 double set_center;
00114 
00115                 _Value = 0.0;
00116                 for( sint32 i = 0; i < (sint32) _sets.size() ; i++ )
00117                 {
00118                         set_membership = _sets[i]->agregate();
00119                         if ( set_membership )
00120                         {
00121                                 set_center = _sets[i]->center();
00122                                 _Value = _Value + set_membership * set_center;
00123                                 total_membership = total_membership + set_membership;
00124                         }
00125                 }
00126 
00127                 if ( total_membership > 0 )
00128                         _Value = _Value / total_membership;
00129                 else 
00130                         _Value = 0;
00131 
00132                 return _Value;
00133         }
00134 
00135         void CFuzzyVar::addFact(CFuzzyFact *f)
00136         {
00137                 _facts.push_back(f);
00138         }
00139 
00140         IFuzzySet *CFuzzyVar::getSet(char *name)
00141         {
00142                 std::vector<IFuzzySet *>::iterator it_set = _sets.begin();
00143                 while ( it_set != _sets.end() )
00144                 {
00145                         if ( !strcmp( (*it_set) ->getName(), name) )
00146                                 return *it_set;
00147                         it_set++;
00148                 }
00149                 return NULL;
00150         }
00151 
00152         void CFuzzyVar::addFact(char *set_name, double membership)
00153         {
00154                 IFuzzySet *set = getSet( set_name );
00155                 if ( set )
00156                         _facts.push_back( new CFuzzyFact(set, membership) );
00157         }
00158 
00159         void CFuzzyVar::setValue(NLAIAGENT::IObjetOp *obj)
00160         {
00161                 _Value = ((NLAIAGENT::INombre<double> *)obj)->getValue();
00162         }
00163 
00164         void CFuzzyVar::setValue(float value)
00165         {
00166                 _Value = value;
00167         }
00168 
00169         NLAIAGENT::IObjetOp *CFuzzyVar::getValue() const
00170         {
00171                 return new NLAIAGENT::DigitalType( (float) _Value );
00172         }
00173 
00174         const NLAIC::IBasicType *CFuzzyVar::clone() const
00175         {
00176                 CFuzzyVar *clone = new CFuzzyVar(*this);
00177                 return clone;
00178         }
00179 
00180         const NLAIC::IBasicType *CFuzzyVar::newInstance() const
00181         {      
00182           NLAIAGENT::CStringVarName x("Inst");
00183           CFuzzyVar *instance = new CFuzzyVar(x,0,0);
00184           return instance;
00185         }
00186 
00187         void CFuzzyVar::save(NLMISC::IStream &os)
00188         {
00189                 IObjectIA::save(os);
00190                 os.serial( (double &) _Value );
00191                 os.serial( (double &) _Min );
00192                 os.serial( (double &) _Max );
00193                 sint32 size = _sets.size();
00194                 os.serial( size );
00195                 for (sint32 i = 0; i < size; i++ )
00196                 {
00197                         _sets[i]->save(os);
00198                 }
00199         }
00200 
00201         void CFuzzyVar::load(NLMISC::IStream &is)
00202         {
00203                 IObjectIA::load( is );
00204 
00205                 is.serial( _Value );
00206                 is.serial( _Min );
00207                 is.serial( _Max );
00208 
00209                 sint32 nb_sets;
00210                 is.serial( nb_sets );
00211                 for (sint32 i = 0; i < nb_sets; i++ )
00212                 {
00213                         NLAIC::CIdentTypeAlloc id;
00214                         is.serial( id );
00215                         IFuzzySet *tmp_val = (IFuzzySet *) id.allocClass();
00216                         tmp_val->load( is );
00217                         _sets.push_back( tmp_val );
00218                 }
00219         }
00220  
00221         void CFuzzyVar::getDebugString(std::string &txt) const
00222         {
00223                 txt += NLAIC::stringGetBuild("CFuzzyVar<%s> = %f\n", getName().getString(), _Value);
00224                 for(sint32 i = 0; i < (sint32) _sets.size(); i++)
00225                 {
00226                         if ( _sets[i]->isIn( _Value ) )
00227                         {
00228                                 std::string buf;                                
00229                                 _sets[i]->getDebugString(buf);
00230                                 txt += NLAIC::stringGetBuild("  %s %f\n", buf.c_str(), _sets[i]->membership( _Value ) );                                
00231                         }
00232                 }
00233         }
00234 
00235         bool CFuzzyVar::isEqual(const CFuzzyVar &a) const
00236         {
00237                 return _Value == a._Value;
00238         }
00239 
00240         bool CFuzzyVar::isEqual(const NLAIAGENT::IBasicObjectIA &a) const
00241         {
00242                 return _Value == ((CFuzzyVar &)a)._Value;
00243         }
00244 
00245         bool CFuzzyVar::isTrue() const
00246         {
00247                 return false;
00248         }
00249 
00250         const NLAIC::CIdentType &CFuzzyVar::getType() const
00251         {
00252                 return IdFuzzyVar;
00253         }
00254 
00255         bool CFuzzyVar::operator==(NLAILOGIC::IBaseVar *var)
00256         {
00257                 return false;// _Value = var->getValue()
00258         }
00259 
00260         bool CFuzzyVar::unify(NLAILOGIC::IBaseVar *, bool assign)
00261         {
00262                 return false;
00263         }
00264 
00265         bool CFuzzyVar::unify(NLAIAGENT::IObjetOp *, bool assign)
00266         {
00267                 return false;
00268         }
00269 
00270         NLAIAGENT::IObjetOp *CFuzzyVar::operator == (NLAIAGENT::IObjetOp &a) const
00271         {
00272                 return NULL;
00273         }
00274 
00275         const NLAIAGENT::IObjectIA::CProcessResult &CFuzzyVar::run()
00276         {
00277                 return IObjectIA::ProcessRun;
00278         }
00279 
00280         bool CFuzzyVar::isIn(IFuzzySet *my_set)
00281         {
00282                 return my_set->isIn(_Value);
00283         }
00284 
00285         float CFuzzyVar::membership(IFuzzySet *my_set)
00286         {
00287                 return (float) my_set->membership( _Value);
00288         }
00289 
00290         CSimpleFuzzyCond *CFuzzyVar::getCond(char *name)
00291         {
00292                 IFuzzySet *my_set = getSet( name );
00293                 if ( my_set )
00294                 {
00295                         return new CSimpleFuzzyCond( this, my_set );
00296                 }
00297                 else
00298                         return NULL;
00299         }
00300 
00301         sint32 CFuzzyVar::getMethodIndexSize() const
00302         {
00303                 return IObjetOp::getMethodIndexSize() + 2;
00304         }
00305 
00306         // Executes a method from its index id and with its parameters
00307         IObjectIA::CProcessResult CFuzzyVar::runMethodeMember(sint32 id, IObjectIA *params)
00308         {
00309                 if ( id <= IBaseVar::getMethodIndexSize() )
00310                         return IBaseVar::runMethodeMember(id, params);
00311 
00312                 IObjectIA::CProcessResult r;
00313 
00314                 std::string buf;
00315                 NLAIAGENT::IObjetOp *x= NULL;
00316                 if ( ( (NLAIAGENT::IBaseGroupType *) params)->size() )
00317                 {
00318                         ( ((NLAIAGENT::IBaseGroupType *)params))->popFront();
00319 
00320 #ifdef NL_DEBUG
00321                         x->getDebugString(buf);
00322 #endif
00323                 }
00324 #ifdef NL_DEBUG
00325                 getDebugString(buf);
00326 #endif
00327 
00328                 sint32 base = IBaseVar::getMethodIndexSize();
00329                 sint32 op_add_subset = base+1;
00330                 sint32 op_unfuzify      = base+2;
00331                 
00332                 if ( id == op_add_subset )
00333                 {
00334                         addSet( (IFuzzySet *) x, ((IFuzzySet *)x)->getName());
00335                         r.ResultState =  NLAIAGENT::processIdle;
00336                         r.Result = NULL;
00337                 }
00338 
00339 
00340                 if ( id == op_unfuzify )
00341                 {
00342                         unfuzify();
00343                         IObjectIA::CProcessResult r;
00344                         r.ResultState =  NLAIAGENT::processIdle;
00345                         r.Result = new NLAIAGENT::DigitalType( (float) _Value);
00346                 }
00347 
00348                 // TODO: throw exception....
00349                 return r;
00350         }
00351 
00352         IObjectIA::CProcessResult CFuzzyVar::runMethodeMember(sint32 inheritance, sint32 id, IObjectIA *params)
00353         {
00354                 return runMethodeMember(id,params);
00355         }
00356 
00357 
00358         void CFuzzyVar::init(IObjectIA *p)
00359         {
00360                 NLAIAGENT::IBaseGroupType *params = ((NLAIAGENT::IBaseGroupType *)p);
00361 
00362                 if ( params->size() < 2 ) 
00363                 {
00364                 //      throw Exc::
00365                 }
00366 
00367                 // Nom
00368                 IObjectIA * arg = (IObjectIA *) params->popFront();
00369                 strcpy(_Name, ((NLAIAGENT::IVarName *) arg)->getString() );
00370                 
00371                 // Sous ensembles
00372                 while (  params->size() )
00373                 {
00374                         IFuzzySet *set = (IFuzzySet *) params->getFront()->clone();
00375                         addSet( set, set->getName() );
00376                         params->popFront();
00377                 }
00378         }
00379 
00380 
00381         tQueue CFuzzyVar::isMember(const NLAIAGENT::IVarName *className,const NLAIAGENT::IVarName *name,const IObjectIA &param) const
00382         {
00383                 tQueue result;
00384 
00385                 result = IBaseVar::isMember(className, name, param);
00386 
00387                 if ( result.size() )
00388                         return result;
00389 
00390                 if(className != NULL) 
00391                 {
00392                         if ( *name == CStringVarName( _ADDSUBSET_ ) )
00393                         {
00394                                 IObjectIA *op_type = (IObjectIA *) new NLAISCRIPT::COperandVoid();
00395                                 result.push( NLAIAGENT::CIdMethod(1 + IObjetOp::getMethodIndexSize(), 0.0,NULL, op_type ) );
00396                         }
00397                         if ( *name == CStringVarName(_UNFUZIFY_) )
00398                         {
00399                                 IObjectIA *op_type = (IObjectIA *) new NLAISCRIPT::COperandSimple( new NLAIC::CIdentType( DigitalType::IdDigitalType) );
00400                                 result.push( NLAIAGENT::CIdMethod(2 + IObjetOp::getMethodIndexSize(), 0.0, NULL, op_type ) );
00401                         }
00402                 }
00403                 return result;
00404         }
00405 }